
We will need two Json Rendering components, one for list items and one for container to have the list. For example: MessageListItem, MessageListCard.

NextJS code will looks like as follows for the list item (we have a custom theme)
import { styled } from '@mui/material/styles';
import {
RichText,
RichTextField,
ImageField,
Image,
withDatasourceCheck,
} from '@sitecore-jss/sitecore-jss-nextjs';
import { xxxTheme } from '@xxxx/yyy.theme';
import { xxxText } from '@xxx/yyy.components';
import { ComponentProps } from 'lib/component-props';
interface Fields {
LeadingIconField: ImageField;
MessagesListItemTextField: RichTextField;
TrailingIconField: ImageField;
}
type MessagesListItemParams = ComponentProps & {
fields: Fields;
params: { [key: string]: string };
};
const StyledMessagesListItem = styled('li', { name: 'MessagesListItem' })(
({
theme: {
xxx: { spacing },
},
}: {
theme: xxxTheme;
}) => ({
display: 'flex',
gap: spacing(100),
marginBottom: spacing(200),
'&:last-of-type': {
marginBottom: 0
}
})
);
const MessagesListItem = ({ fields }: MessagesListItemParams): JSX.Element => {
return (
<StyledMessagesListItem>
<Image field={fields.LeadingIconField} />
<xxxText size="bodyLg" component="div" disableSpacing>
<RichText field={fields.MessagesListItemTextField} />
</xxxText>
</StyledMessagesListItem>
);
};
export default withDatasourceCheck()<MessagesListItemParams>(MessagesListItem);
NextJS code for the MessageListCard will looks like
import { styled } from '@mui/material/styles';
import {
ComponentParams,
ComponentRendering,
LinkField,
Placeholder,
} from '@sitecore-jss/sitecore-jss-nextjs';
import { xxxTheme } from '@xxxx/yyy.theme';
interface Fields {
LinkField: LinkField;
}
export interface MessagesListCardProps {
rendering: ComponentRendering;
params: ComponentParams;
fields: Fields;
}
const StyledMessagesListCard = styled('ul', { name: 'MessagesListCard' })(
({
theme: {
xxx: { palette, spacing },
},
}: {
theme: xxxTheme;
}) => ({
backgroundColor: palette.neutral.background.medium,
padding: spacing(600),
width: '100%',
})
);
export const MessagesListCard = (props: MessagesListCardProps): JSX.Element => {
return (
<StyledMessagesListCard>
<Placeholder name='message-list-title' rendering={props.rendering} />
<Placeholder name='message-list-item' rendering={props.rendering} />
</StyledMessagesListCard>
);
};
export default MessagesListCard;
For the list item we will need Datasource template

We will also need a parent / container Datasource template to hold the list

We need to create a couple of placeholders:

And allow placeholders inside the component “MessageListCard”

Finally, when we drop the component on a page and set the Datasource it will looks like
