List
Lists are useful for rendering collections of documents or references, like emails, actions, documents, and so on.
Sancho exports the following components to create lists:
- List: The wrapper component for ListItem and ListSection children.
- ListSection: A labelled wrapper component for ListItem components.
- ListItem: The list item itself.
Basic usage
Ben McMahenMinim do minim cupidatat veniam aliquip sunt exercitation enim nisi nulla.
Joe ChenProident irure cupidatat cupidatat elit eiusmod mollit.
Lynn AppleProident irure cupidatat cupidatat elit eiusmod mollit.
Mary JoeProident irure cupidatat cupidatat elit eiusmod mollit.
/** @jsx jsx */ function Example() { return ( <Layer css={{ overflow: "hidden", maxWidth: "100%", width: "450px" }}> <List> <ListItem contentBefore={ <Avatar name={"Ben McMahen"} src={faker.image.avatar()} /> } primary="Ben McMahen" secondary="Minim do minim cupidatat veniam aliquip sunt exercitation enim nisi nulla." contentAfter={<IconChevronRight />} /> <ListItem contentBefore={ <Avatar name={"Ben McMahen"} src={faker.image.avatar()} /> } primary="Joe Chen" secondary="Proident irure cupidatat cupidatat elit eiusmod mollit." contentAfter={<IconChevronRight />} /> <ListItem contentBefore={ <Avatar name={"Lynn Apple"} src={faker.image.avatar()} /> } primary="Lynn Apple" secondary="Proident irure cupidatat cupidatat elit eiusmod mollit." contentAfter={<IconChevronRight />} /> <ListItem contentBefore={ <Avatar name={"Mary Joe"} src={faker.image.avatar()} /> } primary="Mary Joe" secondary="Proident irure cupidatat cupidatat elit eiusmod mollit." contentAfter={<IconChevronRight />} /> </List> </Layer> ); }
/** @jsx jsx */ function Example() { const [index, setIndex] = React.useState(0); return ( <Layer className="List-example"> <Toolbar className="List-toolbar"> <Text gutter={false} variant="h6"> Messenger </Text> </Toolbar> <Tabs className="List-tabs" variant="evenly-spaced" onChange={i => setIndex(i)} value={index} > <Tab id="family">Family</Tab> <Tab id="work">Work</Tab> <Tab id="favorites">Favorites</Tab> <Tab id="groups">Groups</Tab> </Tabs> <Pager value={index} onRequestChange={i => setIndex(i)}> <TabPanel id="family"> <List> <ListItem contentBefore={ <Avatar name={"Lynn Apple"} src={faker.image.avatar()} /> } primary="Lynn Apple" wrap={false} secondary="Proident irure cupidatat cupidatat elit eiusmod mollit." contentAfter={<Badge>1</Badge>} /> <ListItem contentBefore={ <Avatar name={"Mary Joe"} src={faker.image.avatar()} /> } primary="Mary Joe" wrap={false} secondary="Proident irure cupidatat cupidatat elit eiusmod mollit." contentAfter={<Badge>4</Badge>} /> </List> </TabPanel> <TabPanel id="work" className="Tab-panel"> <Text>Work</Text> </TabPanel> <TabPanel id="favorites" className="Tab-panel"> <Text>Favorites</Text> </TabPanel> <TabPanel id="groups" className="Tab-panel"> <Text>Groups</Text> </TabPanel> </Pager> </Layer> ); }
Show Code
Using sections
Sections provide sticky headers via the title
prop.
Friends
Ben McMahenMinim do minim cupidatat veniam aliquip sunt exercitation enim nisi nulla.
Joe ChenProident irure cupidatat cupidatat elit eiusmod mollit.
Family
Lynn AppleProident irure cupidatat cupidatat elit eiusmod mollit.
Mary JoeProident irure cupidatat cupidatat elit eiusmod mollit.
Mary JoeProident irure cupidatat cupidatat elit eiusmod mollit.
/** @jsx jsx */ function Example() { return ( <Layer css={{ overflowY: "scroll", maxHeight: "300px", maxWidth: "100%", width: "450px" }} > <List> <ListSection title="Friends"> <ListItem contentBefore={ <Avatar name={"Ben McMahen"} src={faker.image.avatar()} /> } primary="Ben McMahen" secondary="Minim do minim cupidatat veniam aliquip sunt exercitation enim nisi nulla." contentAfter={<IconChevronRight />} /> <ListItem contentBefore={ <Avatar name={"Ben McMahen"} src={faker.image.avatar()} /> } primary="Joe Chen" secondary="Proident irure cupidatat cupidatat elit eiusmod mollit." contentAfter={<IconChevronRight />} /> </ListSection> <ListSection title="Family"> <ListItem contentBefore={ <Avatar name={"Lynn Apple"} src={faker.image.avatar()} /> } primary="Lynn Apple" secondary="Proident irure cupidatat cupidatat elit eiusmod mollit." contentAfter={<IconChevronRight />} /> <ListItem contentBefore={ <Avatar name={"Mary Joe"} src={faker.image.avatar()} /> } primary="Mary Joe" secondary="Proident irure cupidatat cupidatat elit eiusmod mollit." contentAfter={<IconChevronRight />} /> <ListItem contentBefore={ <Avatar name={"Mary Joe"} src={faker.image.avatar()} /> } primary="Mary Joe" secondary="Proident irure cupidatat cupidatat elit eiusmod mollit." contentAfter={<IconChevronRight />} /> </ListSection> </List> </Layer> ); }
Show Code
Disabling wrap
You can disable text wrapping via the wrap
prop.
<Layer style={{ overflow: "hidden", maxWidth: "100%", width: "450px" }}> <List> <ListItem wrap={false} contentBefore={<Avatar name={"Ben McMahen"} src={faker.image.avatar()} />} primary="Ben McMahen" secondary="Minim do minim cupidatat veniam aliquip sunt exercitation enim nisi nulla." contentAfter={<IconChevronRight />} /> </List> </Layer>
Show Code
Using links
You can use an anchor by setting the component
and href
props. Alternatively, you could use something like React-router's Link component.
<List> <ListItem component="a" href="/" contentBefore={<Avatar name={"Ben McMahen"} src={faker.image.avatar()} />} primary="Ben McMahen" wrap={false} secondary="Minim do minim cupidatat veniam aliquip sunt exercitation enim nisi nulla." contentAfter={<IconChevronRight />} /> </List>
Show Code
Non interactive
By default, list items are treated as interactive buttons. You can disable this.
Ben McMahen
Learn more
<List> <ListItem interactive={false} contentBefore={<Avatar name={"Ben McMahen"} src={faker.image.avatar()} />} primary="Ben McMahen" wrap={false} contentAfter={<Button onPress={() => alert("Hey!")}>Learn more</Button>} /> </List>
Show Code
Loading example
You can combine ListItem
with Skeleton
to create loading states.
<List> <ListItem interactive={false} aria-live="polite" aria-busy="true" primary={<Skeleton style={{ width: "100px" }} />} secondary={<Skeleton />} contentBefore={ <Skeleton style={{ width: "3.27rem", height: "3.27rem", borderRadius: "50%" }} /> } /> </List>
Show Code
Infinite scroll
You can combine useInfiniteScroll
, ScrollView
, and List
to create infinitely scrollable lists.
For very long lists you may want to consider using a windowing infinite scroller instead.
Bartholome
Harrison
Caterina
Jo
Charity
Ezequiel
Royal
Armand
Jazmyne
Monica
/** @jsx jsx */ function Example() { const ref = React.useRef(); const [items, setItems] = React.useState( Array.from(new Array(10)).map(() => faker.name.firstName()) ); function fetchdata() { return new Promise(resolve => { setTimeout(() => { resolve(); }, 500); }); } const [page, setPage] = React.useState(0); const [fetching] = useInfiniteScroll({ container: ref, hasMore: page < 4, onFetch: () => { return fetchdata().then(() => { setItems([ ...items, ...Array.from(new Array(10)).map(() => faker.name.firstName()) ]); setPage(page + 1); }); } }); return ( <ScrollView overflowY css={{ height: "300px" }} innerRef={ref}> <List> {items.map(item => ( <ListItem key={item} primary={item} /> ))} {fetching && ( <ListItem interactive={false} aria-live="polite" aria-busy="true" primary={<Skeleton animated css={{ width: "150px" }} />} /> )} </List> </ScrollView> ); }
Show Code
API
List
childrenReactNode
A series of ListItem elements
cssInterpolationWithTheme<any>
ListItem
onPressOnPressFunction
componentReactType<any>
contentBeforeReactNode
An icon or avatar to appear to the left of the text content
contentAfterReactNode
an icon to appear to the right of the text content
interactiveboolean
whether the list item is interactive (ie., can be clicked as a button)
childrenReactNode
optional third row of content
wrapboolean
whether primary and secondary text should be wrapped
primary*ReactNode
The primary text content of the list item
secondaryReactNode
the secondary text content
cssInterpolationWithTheme<any>
ListSection
title*string
A title of the section
stickyboolean
whether the title should stick to the top of the scrollable content
cssInterpolationWithTheme<any>