The RhListContainer and RhListItem components are used to create sequential lists of text or images with primary and secondary actions represented by icons and text. These customizable components make it easy to build lists quickly and efficiently.
Once installed, you can import the RhListContainer component into your React application:
import {RhListContainer,RhListItem} from "@rhythm-ui/react"
Then, you can use the RhListContainer component in your JSX code:
function PrimaryText() { const CustomPrimary = () => ( <RhGrid container className="text-red-500" alignItems="items-center"> <RhGrid item className="mr-1"> Tasks </RhGrid> <RhGrid item container alignItems="items-center"> <RhIcon icon="heroicons:clipboard-document-check-solid" className="text-lg" /> </RhGrid> </RhGrid> ); return ( <RhListContainer className="w-80 m-auto border dark:border-transparent"> <RhListItem> <RhListItemText primary="Inbox" /> </RhListItem> <RhListItem onClick={() => null}> <RhListItemText primary="Drafts" /> </RhListItem> <RhListItem> <RhListItemText primary={<CustomPrimary />} /> </RhListItem> </RhListContainer> ); }
Name | Type | Default | Description |
---|---|---|---|
header | React.ReactNode | Provide header for the RhList | |
className | string | Use this to override RhList's styles using custom classes | |
style | CSSProperties | Provide inline styling | |
children | React.ReactNode | Provide children to RhList |
Name | Type | Default | Description |
---|---|---|---|
children | React.ReactNode | Provide children to RhListItem | |
onClick | (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => void | onClick handler of RhListItem | |
style | CSSProperties | Provide inline styling | |
className | string | Use this to override RhListItem's styles using custom classes |
The sequential lists of primary and secondary text
function SecondaryText() { const CustomSecondary = () => ( <RhGrid container alignItems="items-center"> <RhGrid item container alignItems="items-center" className="mr-1"> <RhIcon icon="heroicons:check-circle-solid" className="text-lg text-[#33b864]" /> </RhGrid> <RhGrid item container alignItems="items-center"> Everthing Done </RhGrid> </RhGrid> ); const CustomPrimary = () => ( <RhGrid container className="text-red-500" alignItems="items-center"> <RhGrid item className="mr-1"> Tasks </RhGrid> <RhGrid item container alignItems="items-center"> <RhIcon icon="heroicons:clipboard-document-check-solid" className="text-lg" /> </RhGrid> </RhGrid> ); return ( <RhListContainer className="w-80 m-auto border dark:border-transparent"> <RhListItem> <RhListItemText primary="Inbox" secondary="7+ unread emails" /> </RhListItem> <RhListItem onClick={() => null}> <RhListItemText primary="Drafts" secondary="Deleting soon..." /> </RhListItem> <RhListItem> <RhListItemText primary={<CustomPrimary />} secondary={<CustomSecondary />} /> </RhListItem> </RhListContainer> ); }
The sequential lists of primary icons along with the primary and secondary text.
function PrimaryIcon() { const CustomPrimary = () => ( <RhGrid container className="text-red-500" alignItems="items-center"> <RhGrid item className="mr-1"> Tasks </RhGrid> <RhGrid item container alignItems="items-center"> <RhIcon icon="heroicons:clipboard-document-check-solid" className="text-lg" /> </RhGrid> </RhGrid> ); const CustomSecondary = () => ( <RhGrid container alignItems="items-center"> <RhGrid item container alignItems="items-center" className="mr-1"> <RhIcon icon="heroicons:check-circle-solid" className="text-lg text-[#33b864]" /> </RhGrid> <RhGrid item container alignItems="items-center"> Everthing Done </RhGrid> </RhGrid> ); return ( <RhListContainer className="w-80 m-auto border dark:border-transparent"> <RhListItem> <RhListItemIcon variant="primary"> <RhIcon icon="heroicons:envelope-solid" className="text-2xl text-gray-400" /> </RhListItemIcon> <RhListItemText primary="Inbox" secondary="7+ unread emails" /> </RhListItem> <RhListItem onClick={() => null}> <RhListItemIcon variant="primary"> <RhIcon icon="heroicons:envelope-open" className="text-2xl text-gray-400" /> </RhListItemIcon> <RhListItemText primary="Drafts" secondary="Deleting soon..." /> </RhListItem> <RhListItem className="flex items-center"> <RhListItemIcon variant="primary" align="start"> <RhAvatar name="primary" type="image" size="sm" src="https://www.gravatar.com/avatar/2c7d99fe281ecd3bcd65ab915bac6dd5?s=250" /> </RhListItemIcon> <RhListItemText primary={<CustomPrimary />} secondary={<CustomSecondary />} /> </RhListItem> </RhListContainer> ); }
The sequential lists of primary and secondary icons along with the primary and secondary text.
function CustomSecondary() { const CustomPrimary = () => ( <RhGrid container className="text-red-500" alignItems="items-center"> <RhGrid item className="mr-1"> Tasks </RhGrid> <RhGrid item container alignItems="items-center"> <RhIcon icon="heroicons:clipboard-document-check-solid" className="text-lg" /> </RhGrid> </RhGrid> ); const CustomSecondary = () => ( <RhGrid container alignItems="items-center"> <RhGrid item container alignItems="items-center" className="mr-1"> <RhIcon icon="heroicons:check-circle-solid" className="text-lg text-[#33b864]" /> </RhGrid> <RhGrid item container alignItems="items-center"> Everthing Done </RhGrid> </RhGrid> ); return ( <RhListContainer className="w-80 m-auto border dark:border-transparent"> <RhListItem> <RhListItemIcon variant="primary"> <RhIcon icon="heroicons:envelope-solid" className="text-2xl text-gray-400" /> </RhListItemIcon> <RhListItemText primary="Inbox" secondary="7+ unread emails" /> <RhListItemIcon variant="secondary"> <RhIcon icon="heroicons:star" className="text-lg text-gray-400" /> </RhListItemIcon> </RhListItem> <RhListItem onClick={() => null}> <RhListItemIcon variant="primary"> <RhIcon icon="heroicons:envelope-open" className="text-2xl text-gray-400" /> </RhListItemIcon> <RhListItemText primary="Drafts" secondary="Deleting soon..." /> <RhListItemIcon variant="secondary"> <RhIcon icon="heroicons:star" className="text-lg text-gray-400" /> </RhListItemIcon> </RhListItem> <RhListItem className="flex items-center"> <RhListItemIcon variant="primary" align="start"> <RhAvatar name="primary" type="image" size="sm" src="https://www.gravatar.com/avatar/2c7d99fe281ecd3bcd65ab915bac6dd5?s=250" /> </RhListItemIcon> <RhListItemText primary={<CustomPrimary />} secondary={<CustomSecondary />} /> <RhListItemIcon onClick={() => null} variant="secondary"> <RhIcon icon="heroicons:trash-solid" className="text-lg text-gray-400" /> </RhListItemIcon> </RhListItem> </RhListContainer> ); }
The sequential lists of primary and secondary text and icons with header
function ListHeader() { const CustomPrimary = () => ( <RhGrid container className="text-red-500" alignItems="items-center"> <RhGrid item className="mr-1"> Tasks </RhGrid> <RhGrid item container alignItems="items-center"> <RhIcon icon="heroicons:clipboard-document-check-solid" className="text-lg" /> </RhGrid> </RhGrid> ); const CustomSecondary = () => ( <RhGrid container alignItems="items-center"> <RhGrid item container alignItems="items-center" className="mr-1"> <RhIcon icon="heroicons:check-circle-solid" className="text-lg text-[#33b864]" /> </RhGrid> <RhGrid item container alignItems="items-center"> Everthing Done </RhGrid> </RhGrid> ); const Header = () => ( <div className="bg-black dark:bg-white dark:bg-opacity-60 dark:text-black text-white text-xl text-semibold px-4 py-4"> Header </div> ); return ( <RhListContainer className="w-80 m-auto border dark:border-transparent" header={<Header />} > <RhListItem> <RhListItemIcon variant="primary"> <RhIcon icon="heroicons:envelope-solid" className="text-2xl text-gray-400" /> </RhListItemIcon> <RhListItemText primary="Inbox" secondary="7+ unread emails" /> <RhListItemIcon variant="secondary"> <RhIcon icon="heroicons:star" className="text-lg text-gray-400" /> </RhListItemIcon> </RhListItem> <RhListItem onClick={() => null}> <RhListItemIcon variant="primary"> <RhIcon icon="heroicons:envelope-open" className="text-2xl text-gray-400" /> </RhListItemIcon> <RhListItemText primary="Drafts" secondary="Deleting soon..." /> <RhListItemIcon variant="secondary"> <RhIcon icon="heroicons:star" className="text-lg text-gray-400" /> </RhListItemIcon> </RhListItem> <RhListItem className="flex items-center"> <RhListItemIcon variant="primary" align="start"> <RhAvatar name="primary" type="image" size="sm" src="https://www.gravatar.com/avatar/2c7d99fe281ecd3bcd65ab915bac6dd5?s=250" /> </RhListItemIcon> <RhListItemText primary={<CustomPrimary />} secondary={<CustomSecondary />} /> <RhListItemIcon onClick={() => null} variant="secondary"> <RhIcon icon="heroicons:trash-solid" className="text-lg text-gray-400" /> </RhListItemIcon> </RhListItem> </RhListContainer> ); }
Creating a sequential list of primary and secondary text and icons with a header, as well as primary and secondary actions, using dropdown menus.
function NestedList() { const CustomPrimary = () => ( <RhGrid container className="text-red-500" alignItems="items-center"> <RhGrid item className="mr-1"> Tasks </RhGrid> <RhGrid item container alignItems="items-center"> <RhIcon icon="heroicons:clipboard-document-check-solid" className="text-lg" /> </RhGrid> </RhGrid> ); const CustomSecondary = () => ( <RhGrid container alignItems="items-center"> <RhGrid item container alignItems="items-center" className="mr-1"> <RhIcon icon="heroicons:check-circle-solid" className="text-lg text-[#33b864]" /> </RhGrid> <RhGrid item container alignItems="items-center"> Everthing Done </RhGrid> </RhGrid> ); const Header = () => ( <div className="bg-black dark:bg-white dark:bg-opacity-60 dark:text-black text-white text-xl text-semibold px-4 py-4"> Header </div> ); return ( <RhListContainer className="w-80 m-auto border dark:border-transparent" header={<Header />} > <RhListItem> <RhListItemIcon variant="primary"> <RhIcon icon="heroicons:envelope-solid" className="text-2xl text-gray-400" /> </RhListItemIcon> <RhListItemText primary="Inbox" secondary="7+ unread emails" /> <RhListContainer> <RhListItem style={{ paddingLeft: "2rem" }}> <RhListItemIcon variant="primary"> <RhIcon icon="akar-icons:circle" className="text-lg text-gray-400" /> </RhListItemIcon> <RhListItemText primary="Item 1" /> </RhListItem> <RhListItem style={{ paddingLeft: "2rem" }}> <RhListItemIcon variant="primary"> <RhIcon icon="akar-icons:circle" className="text-lg text-gray-400" /> </RhListItemIcon> <RhListItemText primary="Item 2" /> </RhListItem> </RhListContainer> </RhListItem> <RhListItem onClick={() => null}> <RhListItemIcon variant="primary"> <RhIcon icon="heroicons:envelope-open" className="text-2xl text-gray-400" /> </RhListItemIcon> <RhListItemText primary="Drafts" secondary="Deleting soon..." /> <RhListItemIcon variant="secondary"> <RhIcon icon="heroicons:star" className="text-lg text-gray-400" /> </RhListItemIcon> </RhListItem> <RhListItem className="flex items-center"> <RhListItemIcon variant="primary" align="start"> <RhAvatar name="primary" type="image" size="sm" src="https://www.gravatar.com/avatar/2c7d99fe281ecd3bcd65ab915bac6dd5?s=250" /> </RhListItemIcon> <RhListItemText primary={<CustomPrimary />} secondary={<CustomSecondary />} /> <RhListItemIcon onClick={() => null} variant="secondary"> <RhIcon icon="heroicons:trash-solid" className="text-lg text-gray-400" /> </RhListItemIcon> </RhListItem> </RhListContainer> ); }