ListView
ListView components render an accessible list of items that supports selection and virtualization.
| Install | yarn add @diallink-corp/convergo-react-list |
|---|---|
| Version | 4.1.2 |
| Usage | import {ListView} from '@diallink-corp/convergo-react-list' |
Static Collection
The ListView component can either render static or dynamic collections of data. For simple select components that need to render a list of pre-defined data a static collection should be used. Static collections cannot be changed over time.
<ListView aria-label='Static collection'>
<Item key='apples'>Apples</Item>
<Item key='bananas'>Bananas</Item>
<Item key='grapes'>Grapes</Item>
<Item key='oranges'>Oranges</Item>
</ListView>
<ListView aria-label='Static collection'>
<Item key='apples'>Apples</Item>
<Item key='bananas'>Bananas</Item>
<Item key='grapes'>Grapes</Item>
<Item key='oranges'>Oranges</Item>
</ListView>
<ListView aria-label="Static collection">
<Item key="apples">
Apples
</Item>
<Item key="bananas">
Bananas
</Item>
<Item key="grapes">
Grapes
</Item>
<Item key="oranges">
Oranges
</Item>
</ListView>
Static Collection With Sections
The ListView supports splitting its content into sections. Each section can have a title and a list of items..
<ListView aria-label='Static collection'>
<Section key='tasty' title="Tasty">
<Item key='bananas'>Bananas</Item>
<Item key='oranges'>Oranges</Item>
</Section>
<Section key='neutral' title="Neutral">
<Item key='apples'>Apples</Item>
<Item key='grapes'>Grapes</Item>
</Section>
</ListView>
<ListView aria-label='Static collection'>
<Section key='tasty' title="Tasty">
<Item key='bananas'>Bananas</Item>
<Item key='oranges'>Oranges</Item>
</Section>
<Section key='neutral' title="Neutral">
<Item key='apples'>Apples</Item>
<Item key='grapes'>Grapes</Item>
</Section>
</ListView>
<ListView aria-label="Static collection">
<Section
key="tasty"
title="Tasty"
>
<Item key="bananas">
Bananas
</Item>
<Item key="oranges">
Oranges
</Item>
</Section>
<Section
key="neutral"
title="Neutral"
>
<Item key="apples">
Apples
</Item>
<Item key="grapes">
Grapes
</Item>
</Section>
</ListView>
Dynamic Collection
For data that is non-static, such as data fetched from a backend, the ListView component supports dynamic collections. Dynamic collections support adding, updating and removing of the data that is being rendered.
function Example() {
const [fruits, setFruits] = useState([
{id: 1, name: 'Apples'},
{id: 2, name: 'Bananas'},
{id: 3, name: 'Grapes'},
{id: 4, name: 'Oranges'}
]);
return (
<ListView aria-label='Fruits' items={fruits}>
{(item) => <Item key={item.id}>{item.name}</Item>}
</ListView>
);
}
function Example() {
const [fruits, setFruits] = useState([
{id: 1, name: 'Apples'},
{id: 2, name: 'Bananas'},
{id: 3, name: 'Grapes'},
{id: 4, name: 'Oranges'}
]);
return (
<ListView aria-label='Fruits' items={fruits}>
{(item) => <Item key={item.id}>{item.name}</Item>}
</ListView>
);
}
function Example() {
const [
fruits,
setFruits
] = useState([
{
id: 1,
name: 'Apples'
},
{
id: 2,
name: 'Bananas'
},
{
id: 3,
name: 'Grapes'
},
{
id: 4,
name: 'Oranges'
}
]);
return (
<ListView
aria-label="Fruits"
items={fruits}
>
{(item) => (
<Item
key={item.id}
>
{item.name}
</Item>
)}
</ListView>
);
}
Asynchronous Fetching
The Select component supports asynchronous fetching of data via the onLoadMoreItems prop. The select
component uses its built-in infinite scrolling to achieve this. This means that when the user reaches
the bottom of the list, the component will automatically load more data. If you provide an loadingState
prop, the Select component will show a Spinner component, to indicate to the user, that more data is
being fetched.
function Example() {
const [reversed, setReversed] = useState(false);
const limit = 20;
const list = useAsyncListState({
async loadItems(state) {
const { cursor, signal } = state;
const response = await fetch(
cursor || `https://pokeapi.co/api/v2/pokemon?limit=`,
{ signal }
);
const result = await response.json();
const { results, next } = result;
return { items: results, cursor: next };
},
initialItems: []
});
const items = {
*[Symbol.iterator]() {
let page = 1;
let section = { key: page, items: [] };
for (let item of list.items) {
if (section.items.length < limit) {
section.items.push(item);
} else {
yield section;
page += 1;
section = { key: page, items: [item] };
}
}
if (section.items.length > 0) {
yield section;
}
}
};
return (
<>
<Switch
label="Reverse"
defaultSelected={reversed}
onChange={setReversed}
/>
<ListView
key={reversed}
aria-label="Pokemons"
items={items}
loadingState={list.loadingState}
onLoadMoreItems={list.loadMoreItems}
defaultSelectedKey="vileplume"
style={{ maxHeight: '300px' }}
reverse={reversed}
style={{ maxHeight: '300px' }}
>
{(section) => (
<Section
key={section.key}
title={'Page ' + section.key}
items={section.items}
>
{(item) => <Item key={item.name}>{item.name}</Item>}
</Section>
)}
</ListView>
</>
);
}
function Example() {
const [reversed, setReversed] = useState(false);
const limit = 20;
const list = useAsyncListState({
async loadItems(state) {
const { cursor, signal } = state;
const response = await fetch(
cursor ||
`https://pokeapi.co/api/v2/pokemon?limit=`,
{ signal }
);
const result = await response.json();
const { results, next } = result;
return { items: results, cursor: next };
},
initialItems: []
});
const items = {
*[Symbol.iterator]() {
let page = 1;
let section = { key: page, items: [] };
for (let item of list.items) {
if (section.items.length < limit) {
section.items.push(item);
} else {
yield section;
page += 1;
section = { key: page, items: [item] };
}
}
if (section.items.length > 0) {
yield section;
}
}
};
return (
<>
<Switch
label="Reverse"
defaultSelected={reversed}
onChange={setReversed}
/>
<ListView
key={reversed}
aria-label="Pokemons"
items={items}
loadingState={list.loadingState}
onLoadMoreItems={list.loadMoreItems}
defaultSelectedKey="vileplume"
style={{ maxHeight: '300px' }}
reverse={reversed}
style={{ maxHeight: '300px' }}
>
{(section) => (
<Section
key={section.key}
title={'Page ' + section.key}
items={section.items}
>
{(item) => (
<Item key={item.name}>{item.name}</Item>
)}
</Section>
)}
</ListView>
</>
);
}
function Example() {
const [
reversed,
setReversed
] = useState(false);
const limit = 20;
const list =
useAsyncListState({
async loadItems(
state
) {
const {
cursor,
signal
} = state;
const response =
await fetch(
cursor ||
`https://pokeapi.co/api/v2/pokemon?limit=`,
{ signal }
);
const result =
await response
.json();
const {
results,
next
} = result;
return {
items: results,
cursor: next
};
},
initialItems: []
});
const items = {
*[
Symbol.iterator
]() {
let page = 1;
let section = {
key: page,
items: []
};
for (
let item of list
.items
) {
if (
section.items
.length <
limit
) {
section.items
.push(item);
} else {
yield section;
page += 1;
section = {
key: page,
items: [
item
]
};
}
}
if (
section.items
.length > 0
) {
yield section;
}
}
};
return (
<>
<Switch
label="Reverse"
defaultSelected={reversed}
onChange={setReversed}
/>
<ListView
key={reversed}
aria-label="Pokemons"
items={items}
loadingState={list
.loadingState}
onLoadMoreItems={list
.loadMoreItems}
defaultSelectedKey="vileplume"
style={{
maxHeight:
'300px'
}}
reverse={reversed}
style={{
maxHeight:
'300px'
}}
>
{(section) => (
<Section
key={section
.key}
title={'Page ' +
section
.key}
items={section
.items}
>
{(item) => (
<Item
key={item
.name}
>
{item
.name}
</Item>
)}
</Section>
)}
</ListView>
</>
);
}
Uncontrolled Selection
By default, the ListView component handles its selection uncontrolled. In the uncontrolled variant you can
pass in a defaultSelectedKeys to select one or more values by default. The key that is being referenced here is the
value that is passed to the Item component as a key prop, so in this case item.name.
function Example() {
const fruits = [
{ id: 1, name: 'Apples' },
{ id: 2, name: 'Bananas' },
{ id: 3, name: 'Grapes' },
{ id: 4, name: 'Oranges' }
];
return (
<ListView
aria-label="Fruits"
items={fruits}
defaultSelectedKeys={['Grapes']}
selectionMode="single"
>
{(item) => <Item key={item.name}>{item.name}</Item>}
</ListView>
);
}
function Example() {
const fruits = [
{ id: 1, name: 'Apples' },
{ id: 2, name: 'Bananas' },
{ id: 3, name: 'Grapes' },
{ id: 4, name: 'Oranges' }
];
return (
<ListView
aria-label="Fruits"
items={fruits}
defaultSelectedKeys={['Grapes']}
selectionMode="single"
>
{(item) => <Item key={item.name}>{item.name}</Item>}
</ListView>
);
}
function Example() {
const fruits = [
{
id: 1,
name: 'Apples'
},
{
id: 2,
name: 'Bananas'
},
{
id: 3,
name: 'Grapes'
},
{
id: 4,
name: 'Oranges'
}
];
return (
<ListView
aria-label="Fruits"
items={fruits}
defaultSelectedKeys={[
'Grapes'
]}
selectionMode="single"
>
{(item) => (
<Item
key={item.name}
>
{item.name}
</Item>
)}
</ListView>
);
}
Controlled Selection
The use the controlled selection variant, you can use the selectedKey and onSelectionChange props together.
function Example() {
const fruits = [
{ id: '1', name: 'Apples' },
{ id: '2', name: 'Bananas' },
{ id: '3', name: 'Grapes' },
{ id: '4', name: 'Oranges' }
];
const [selectedFruit, setSelectedFruit] = useState('2');
return (
<ListView
aria-label="What is your favorite fruit?"
items={fruits}
selectionMode="single"
selectedKeys={[selectedFruit]}
onSelectionChange={(value) =>
setSelectedFruit(value.values().next().value)}
>
{(item) => <Item key={item.id}>{item.name}</Item>}
</ListView>
);
}
function Example() {
const fruits = [
{ id: '1', name: 'Apples' },
{ id: '2', name: 'Bananas' },
{ id: '3', name: 'Grapes' },
{ id: '4', name: 'Oranges' }
];
const [selectedFruit, setSelectedFruit] = useState('2');
return (
<ListView
aria-label="What is your favorite fruit?"
items={fruits}
selectionMode="single"
selectedKeys={[selectedFruit]}
onSelectionChange={(value) =>
setSelectedFruit(value.values().next().value)}
>
{(item) => <Item key={item.id}>{item.name}</Item>}
</ListView>
);
}
function Example() {
const fruits = [
{
id: '1',
name: 'Apples'
},
{
id: '2',
name: 'Bananas'
},
{
id: '3',
name: 'Grapes'
},
{
id: '4',
name: 'Oranges'
}
];
const [
selectedFruit,
setSelectedFruit
] = useState('2');
return (
<ListView
aria-label="What is your favorite fruit?"
items={fruits}
selectionMode="single"
selectedKeys={[
selectedFruit
]}
onSelectionChange={(
value
) =>
setSelectedFruit(
value.values()
.next().value
)}
>
{(item) => (
<Item
key={item.id}
>
{item.name}
</Item>
)}
</ListView>
);
}
Density
The ListView supports various densities to control the size of the items.
Compact
<ListView aria-label='Compact list' density='compact'>
<Item key='apples'>Apples</Item>
<Item key='bananas'>Bananas</Item>
<Item key='grapes'>Grapes</Item>
<Item key='oranges'>Oranges</Item>
</ListView>
<ListView aria-label='Compact list' density='compact'>
<Item key='apples'>Apples</Item>
<Item key='bananas'>Bananas</Item>
<Item key='grapes'>Grapes</Item>
<Item key='oranges'>Oranges</Item>
</ListView>
<ListView
aria-label="Compact list"
density="compact"
>
<Item key="apples">
Apples
</Item>
<Item key="bananas">
Bananas
</Item>
<Item key="grapes">
Grapes
</Item>
<Item key="oranges">
Oranges
</Item>
</ListView>
Regular
<ListView aria-label='Regular list' density='regular'>
<Item key='apples'>Apples</Item>
<Item key='bananas'>Bananas</Item>
<Item key='grapes'>Grapes</Item>
<Item key='oranges'>Oranges</Item>
</ListView>
<ListView aria-label='Regular list' density='regular'>
<Item key='apples'>Apples</Item>
<Item key='bananas'>Bananas</Item>
<Item key='grapes'>Grapes</Item>
<Item key='oranges'>Oranges</Item>
</ListView>
<ListView
aria-label="Regular list"
density="regular"
>
<Item key="apples">
Apples
</Item>
<Item key="bananas">
Bananas
</Item>
<Item key="grapes">
Grapes
</Item>
<Item key="oranges">
Oranges
</Item>
</ListView>
Spacious
<ListView aria-label='Spacious list' density='spacious'>
<Item key='apples'>Apples</Item>
<Item key='bananas'>Bananas</Item>
<Item key='grapes'>Grapes</Item>
<Item key='oranges'>Oranges</Item>
</ListView>
<ListView aria-label='Spacious list' density='spacious'>
<Item key='apples'>Apples</Item>
<Item key='bananas'>Bananas</Item>
<Item key='grapes'>Grapes</Item>
<Item key='oranges'>Oranges</Item>
</ListView>
<ListView
aria-label="Spacious list"
density="spacious"
>
<Item key="apples">
Apples
</Item>
<Item key="bananas">
Bananas
</Item>
<Item key="grapes">
Grapes
</Item>
<Item key="oranges">
Oranges
</Item>
</ListView>
Drag & Drop
The ListView component supports drag & drop out of the box.
function Example(props) {
const items = [
{ key: 'a', name: 'A', type: 'file' },
{ key: 'b', name: 'B', type: 'file' },
{ key: 'c', name: 'C', type: 'folder' },
{ key: 'd', name: 'D', type: 'file' },
{ key: 'e', name: 'E', type: 'folder' },
{ key: 'f', name: 'F', type: 'file' },
{ key: 'g', name: 'G', type: 'file' },
{ key: 'h', name: 'H', type: 'file' },
{ key: 'i', name: 'I', type: 'file' },
{ key: 'j', name: 'J', type: 'file' },
{ key: 'k', name: 'K', type: 'file' },
{ key: 'l', name: 'L', type: 'file' },
{ key: 'm', name: 'M', type: 'folder' },
{ key: 'n', name: 'N', type: 'file' }
];
const getItems = (keys) =>
[...keys].map((key) => {
const item = items.find((item) => item.key === key);
return {
'text/plain': item.name
};
});
const allowsDraggingItem = (key) => {
const item = items.find((item) => item.key === key);
return item.type !== 'folder';
};
const { dragHooks } = useDragAndDrop({
allowsDraggingItem,
getItems
});
return (
<ListView
aria-label="Draggable list view"
stlye={{ width: '300px' }}
selectionMode="multiple"
items={items}
disabledKeys={['f']}
dragHooks={dragHooks}
>
{(item) => (
<Item key={item.key} textValue={item.name}>
{item.type === 'folder' && (
<Icon name="FolderIcon" variant="outline" />
)}
{item.key === 'a' && <Icon name="DocumentIcon" variant="outline" />}
<Content>{item.name}</Content>
{item.key === 'b' && <Description>Beta</Description>}
<ActionMenu>
<Item key="edit" textValue="Edit">
<Icon name="PencilIcon" variant="outline" />
<Text>Edit</Text>
</Item>
<Item key="delete" textValue="Delete">
<Icon name="XMarkIcon" variant="outline" />
<Text>Delete</Text>
</Item>
</ActionMenu>
</Item>
)}
</ListView>
);
}
function Example(props) {
const items = [
{ key: 'a', name: 'A', type: 'file' },
{ key: 'b', name: 'B', type: 'file' },
{ key: 'c', name: 'C', type: 'folder' },
{ key: 'd', name: 'D', type: 'file' },
{ key: 'e', name: 'E', type: 'folder' },
{ key: 'f', name: 'F', type: 'file' },
{ key: 'g', name: 'G', type: 'file' },
{ key: 'h', name: 'H', type: 'file' },
{ key: 'i', name: 'I', type: 'file' },
{ key: 'j', name: 'J', type: 'file' },
{ key: 'k', name: 'K', type: 'file' },
{ key: 'l', name: 'L', type: 'file' },
{ key: 'm', name: 'M', type: 'folder' },
{ key: 'n', name: 'N', type: 'file' }
];
const getItems = (keys) =>
[...keys].map((key) => {
const item = items.find((item) => item.key === key);
return {
'text/plain': item.name
};
});
const allowsDraggingItem = (key) => {
const item = items.find((item) => item.key === key);
return item.type !== 'folder';
};
const { dragHooks } = useDragAndDrop({
allowsDraggingItem,
getItems
});
return (
<ListView
aria-label="Draggable list view"
stlye={{ width: '300px' }}
selectionMode="multiple"
items={items}
disabledKeys={['f']}
dragHooks={dragHooks}
>
{(item) => (
<Item key={item.key} textValue={item.name}>
{item.type === 'folder' && (
<Icon name="FolderIcon" variant="outline" />
)}
{item.key === 'a' && (
<Icon name="DocumentIcon" variant="outline" />
)}
<Content>{item.name}</Content>
{item.key === 'b' && (
<Description>Beta</Description>
)}
<ActionMenu>
<Item key="edit" textValue="Edit">
<Icon name="PencilIcon" variant="outline" />
<Text>Edit</Text>
</Item>
<Item key="delete" textValue="Delete">
<Icon name="XMarkIcon" variant="outline" />
<Text>Delete</Text>
</Item>
</ActionMenu>
</Item>
)}
</ListView>
);
}
function Example(props) {
const items = [
{
key: 'a',
name: 'A',
type: 'file'
},
{
key: 'b',
name: 'B',
type: 'file'
},
{
key: 'c',
name: 'C',
type: 'folder'
},
{
key: 'd',
name: 'D',
type: 'file'
},
{
key: 'e',
name: 'E',
type: 'folder'
},
{
key: 'f',
name: 'F',
type: 'file'
},
{
key: 'g',
name: 'G',
type: 'file'
},
{
key: 'h',
name: 'H',
type: 'file'
},
{
key: 'i',
name: 'I',
type: 'file'
},
{
key: 'j',
name: 'J',
type: 'file'
},
{
key: 'k',
name: 'K',
type: 'file'
},
{
key: 'l',
name: 'L',
type: 'file'
},
{
key: 'm',
name: 'M',
type: 'folder'
},
{
key: 'n',
name: 'N',
type: 'file'
}
];
const getItems = (
keys
) =>
[...keys].map(
(key) => {
const item =
items.find((
item
) =>
item.key ===
key
);
return {
'text/plain':
item.name
};
}
);
const allowsDraggingItem =
(key) => {
const item = items
.find((item) =>
item.key ===
key
);
return item
.type !==
'folder';
};
const { dragHooks } =
useDragAndDrop({
allowsDraggingItem,
getItems
});
return (
<ListView
aria-label="Draggable list view"
stlye={{
width: '300px'
}}
selectionMode="multiple"
items={items}
disabledKeys={[
'f'
]}
dragHooks={dragHooks}
>
{(item) => (
<Item
key={item.key}
textValue={item
.name}
>
{item.type ===
'folder' &&
(
<Icon
name="FolderIcon"
variant="outline"
/>
)}
{item.key ===
'a' && (
<Icon
name="DocumentIcon"
variant="outline"
/>
)}
<Content>
{item.name}
</Content>
{item.key ===
'b' && (
<Description>
Beta
</Description>
)}
<ActionMenu>
<Item
key="edit"
textValue="Edit"
>
<Icon
name="PencilIcon"
variant="outline"
/>
<Text>
Edit
</Text>
</Item>
<Item
key="delete"
textValue="Delete"
>
<Icon
name="XMarkIcon"
variant="outline"
/>
<Text>
Delete
</Text>
</Item>
</ActionMenu>
</Item>
)}
</ListView>
);
}
Overflow Mode
By default, the text of the ListView is truncated if it overflows. By setting the overflowMode prop to 'wrap',
you can wrap the text instead.
<ListView
aria-label="Overflow truncate"
overflowMode="truncate"
style={{ width: '300px' }}
>
<Item key="a">
A really really really really really really really really long description
to test
</Item>
<Item key="b">
A really really really really really really really really long description
to test
</Item>
<Item key="c">
A really really really really really really really really long description
to test
</Item>
<Item key="d">
A really really really really really really really really long description
to test
</Item>
</ListView>
<ListView
aria-label="Overflow truncate"
overflowMode="truncate"
style={{ width: '300px' }}
>
<Item key="a">
A really really really really really really really
really long description to test
</Item>
<Item key="b">
A really really really really really really really
really long description to test
</Item>
<Item key="c">
A really really really really really really really
really long description to test
</Item>
<Item key="d">
A really really really really really really really
really long description to test
</Item>
</ListView>
<ListView
aria-label="Overflow truncate"
overflowMode="truncate"
style={{
width: '300px'
}}
>
<Item key="a">
A really really
really really
really really
really really long
description to test
</Item>
<Item key="b">
A really really
really really
really really
really really long
description to test
</Item>
<Item key="c">
A really really
really really
really really
really really long
description to test
</Item>
<Item key="d">
A really really
really really
really really
really really long
description to test
</Item>
</ListView>
<ListView
aria-label="Overflow wrap"
overflowMode="wrap"
style={{ width: '300px' }}
>
<Item key="a">
A really really really really really really really really long description
to test
</Item>
<Item key="b">
A really really really really really really really really long description
to test
</Item>
<Item key="c">
A really really really really really really really really long description
to test
</Item>
<Item key="d">
A really really really really really really really really long description
to test
</Item>
</ListView>
<ListView
aria-label="Overflow wrap"
overflowMode="wrap"
style={{ width: '300px' }}
>
<Item key="a">
A really really really really really really really
really long description to test
</Item>
<Item key="b">
A really really really really really really really
really long description to test
</Item>
<Item key="c">
A really really really really really really really
really long description to test
</Item>
<Item key="d">
A really really really really really really really
really long description to test
</Item>
</ListView>
<ListView
aria-label="Overflow wrap"
overflowMode="wrap"
style={{
width: '300px'
}}
>
<Item key="a">
A really really
really really
really really
really really long
description to test
</Item>
<Item key="b">
A really really
really really
really really
really really long
description to test
</Item>
<Item key="c">
A really really
really really
really really
really really long
description to test
</Item>
<Item key="d">
A really really
really really
really really
really really long
description to test
</Item>
</ListView>
Slots
The ListView comes with several pre-defined slots to define styles of its children.
function Example() {
const [fruits, setFruits] = useState([
{id: 1, name: 'Apples', description: 'Sweet-tart'},
{id: 2, name: 'Bananas', description: 'Fruity'},
{id: 3, name: 'Grapes', description: 'Sweet-sour'},
{id: 4, name: 'Oranges', description: 'Sweet-tart'},
]);
return (
<ListView aria-label='Fruits' items={fruits}>
{(item) => (
<Item key={item.id} textValue={item.name}>
<Avatar name={item.name} size='small' />
<Heading>{item.name}</Heading>
<Description>{item.description}</Description>
</Item>
)}
</ListView>
);
}
function Example() {
const [fruits, setFruits] = useState([
{id: 1, name: 'Apples', description: 'Sweet-tart'},
{id: 2, name: 'Bananas', description: 'Fruity'},
{id: 3, name: 'Grapes', description: 'Sweet-sour'},
{id: 4, name: 'Oranges', description: 'Sweet-tart'},
]);
return (
<ListView aria-label='Fruits' items={fruits}>
{(item) => (
<Item key={item.id} textValue={item.name}>
<Avatar name={item.name} size='small' />
<Heading>{item.name}</Heading>
<Description>{item.description}</Description>
</Item>
)}
</ListView>
);
}
function Example() {
const [
fruits,
setFruits
] = useState([
{
id: 1,
name: 'Apples',
description:
'Sweet-tart'
},
{
id: 2,
name: 'Bananas',
description:
'Fruity'
},
{
id: 3,
name: 'Grapes',
description:
'Sweet-sour'
},
{
id: 4,
name: 'Oranges',
description:
'Sweet-tart'
}
]);
return (
<ListView
aria-label="Fruits"
items={fruits}
>
{(item) => (
<Item
key={item.id}
textValue={item
.name}
>
<Avatar
name={item
.name}
size="small"
/>
<Heading>
{item.name}
</Heading>
<Description>
{item
.description}
</Description>
</Item>
)}
</ListView>
);
}
Empty State
To show the user that the list view is empty when there is no data available you can use the renderEmptyState prop.
<ListView renderEmptyState={() => (
<IllustratedMessage>
<Icon name="MagnifyingGlassIcon" variant="outline" />
<Heading>No results found</Heading>
<Text>
No results could be found. Please create a new entity or modify your
search.
No results could be found. Please create a new entity or modify your
search.
No results could be found. Please create a new entity or modify your
search.
No results could be found. Please create a new entity or modify your
search.
No results could be found. Please create a new entity or modify your
search.
No results could be found. Please create a new entity or modify your
search.
No results could be found. Please create a new entity or modify your
search.
No results could be found. Please create a new entity or modify your
search.
No results could be found. Please create a new entity or modify your
search.
No results could be found. Please create a new entity or modify your
search.
</Text>
</IllustratedMessage>
)}>
{[]}
</ListView>
<ListView
renderEmptyState={() => (
<IllustratedMessage>
<Icon
name="MagnifyingGlassIcon"
variant="outline"
/>
<Heading>No results found</Heading>
<Text>
No results could be found. Please create a new
entity or modify your search. No results could be
found. Please create a new entity or modify your
search. No results could be found. Please create a
new entity or modify your search. No results could
be found. Please create a new entity or modify
your search. No results could be found. Please
create a new entity or modify your search. No
results could be found. Please create a new entity
or modify your search. No results could be found.
Please create a new entity or modify your search.
No results could be found. Please create a new
entity or modify your search. No results could be
found. Please create a new entity or modify your
search. No results could be found. Please create a
new entity or modify your search.
</Text>
</IllustratedMessage>
)}
>
{[]}
</ListView>
<ListView
renderEmptyState={() => (
<IllustratedMessage>
<Icon
name="MagnifyingGlassIcon"
variant="outline"
/>
<Heading>
No results
found
</Heading>
<Text>
No results
could be found.
Please create a
new entity or
modify your
search. No
results could
be found.
Please create a
new entity or
modify your
search. No
results could
be found.
Please create a
new entity or
modify your
search. No
results could
be found.
Please create a
new entity or
modify your
search. No
results could
be found.
Please create a
new entity or
modify your
search. No
results could
be found.
Please create a
new entity or
modify your
search. No
results could
be found.
Please create a
new entity or
modify your
search. No
results could
be found.
Please create a
new entity or
modify your
search. No
results could
be found.
Please create a
new entity or
modify your
search. No
results could
be found.
Please create a
new entity or
modify your
search.
</Text>
</IllustratedMessage>
)}
>
{[]}
</ListView>
Actions
The ListView supports the onAction prop which is triggered when an item from the list is clicked.
function Example() {
const fruits = [
{id: 1, name: 'Apples'},
{id: 2, name: 'Bananas'},
{id: 3, name: 'Grapes'},
{id: 4, name: 'Oranges'}
];
const handleAction = (key) => {
alert(`Item with key was clicked`);
};
return (
<ListView
aria-label='What is your favorite fruit?'
items={fruits}
selectionMode='none'
selectionStyle='highlight'
selectedKeys={new Set(['Bananas'])}
onAction={handleAction}
allowReadOnlySelection
>
{(item) => <Item key={item.name}>{item.name}</Item>}
</ListView>
);
}
function Example() {
const fruits = [
{id: 1, name: 'Apples'},
{id: 2, name: 'Bananas'},
{id: 3, name: 'Grapes'},
{id: 4, name: 'Oranges'}
];
const handleAction = (key) => {
alert(`Item with key was clicked`);
};
return (
<ListView
aria-label='What is your favorite fruit?'
items={fruits}
selectionMode='none'
selectionStyle='highlight'
selectedKeys={new Set(['Bananas'])}
onAction={handleAction}
allowReadOnlySelection
>
{(item) => <Item key={item.name}>{item.name}</Item>}
</ListView>
);
}
function Example() {
const fruits = [
{
id: 1,
name: 'Apples'
},
{
id: 2,
name: 'Bananas'
},
{
id: 3,
name: 'Grapes'
},
{
id: 4,
name: 'Oranges'
}
];
const handleAction = (
key
) => {
alert(
`Item with key was clicked`
);
};
return (
<ListView
aria-label="What is your favorite fruit?"
items={fruits}
selectionMode="none"
selectionStyle="highlight"
selectedKeys={new Set(
['Bananas']
)}
onAction={handleAction}
allowReadOnlySelection
>
{(item) => (
<Item
key={item.name}
>
{item.name}
</Item>
)}
</ListView>
);
}
Accessibility
In order to support internationalization, provide a localized string to the aria-label prop.