DrawerList

Description

The DrawerList component is a fragment inside other components.

It is used e.g. in the Dropdown.

Data structure

// as array
const data = [
// Every data item can, beside "content" - contain what ever
{
// (optional) can be what ever
selected_key: 'key_0',
// Item content as a string or array
content: 'Item 1 Content',
},
// more items ...
{
selected_key: 'key_1',
content: ['Item 2 Value', 'Item 2 Content'],
},
{
selected_key: 'key_2',
content: ['Item 3 Content A', 'Item 3 Content B'],
},
{
selected_key: 'key_3',
content: ['Item 4 Content A', <>Custom Component</>],
},
]
// as object
const data = {
a: 'A',
b: 'B',
}

Example usage of options_render

render(
<DrawerList
options_render={({ Items, Item, data }) => (
<>
<Items />
<Item>Addition</Item>
{data.length > 1 && <li>Addition</li>}
</>
)}
/>
)

data-dnb-drawer-list-active

When a DrawerList is open, it will set an HTML attribute on the main HTML Element called data-dnb-drawer-list-active. The attribute value will be the ID of the current DrawerList.

This can be used to handle z-index issues from within CSS only:

html[data-dnb-drawer-list-active='DrawerList-ID'] {
/* Your css */
}

Demos

Default DrawerList, triggered by a ToggleButton

const DrawerListWithState = props => {
const [opened, setOpened] = React.useState(false)
const Relative = styled.span`
position: relative;
`
return (
<Relative>
<ToggleButton
text="Toggle"
checked={opened}
icon={'chevron_' + (opened ? 'up' : 'down')}
icon_position="left"
on_change={({ checked }) => setOpened(checked)}
/>
<DrawerList
skip_portal
data={data}
opened={opened}
on_hide={() => setOpened(false)}
{...props}
/>
</Relative>
)
}
render(<DrawerListWithState />)

DrawerList list - only to visualize

  • Brukskonto - Kari Nordmann
  • 12 34 56 78 90 2Sparekonto - Ole Nordmann
  • 11 34 56 78 96 2Feriekonto - Kari Nordmann med et kjempelangt etternavnsen
  • 15 34 96 48 90 1Oppussing - Ole Nordmann

Default DrawerList

<DrawerList
skip_portal
opened
prevent_close
triangle_position="left"
data={data}
value={3}
on_change={({ data: selectedDataItem }) => {
console.log('on_change', selectedDataItem)
}}
on_show={() => {
console.log('on_show')
}}
/>

Custom event and link on single item

const CustomComponent = () => (
<CustomComponentInner
onTouchStart={preventDefault}
onClick={e => {
console.log('Do something different')
preventDefault(e)
}}
>
Custom event handler
</CustomComponentInner>
)
const CustomComponentInner = styled.span`
display: block;
width: 100%;
margin: -1rem -2rem -1rem -1rem;
padding: 1rem 2rem 1rem 1rem;
`
const preventDefault = e => {
e.stopPropagation()
e.preventDefault()
}
const CustomWidth = styled(DrawerList)`
.dnb-drawer-list__list {
width: var(--drawer-list-width);
}
`
render(
<CustomWidth
skip_portal
opened
prevent_close
more_menu
right
title="Choose an item"
data={() => [
<Link href="/">Go to this Link</Link>,
'Or press on me',
<CustomComponent />
]}
on_change={({ value }) => {
console.log('More menu:', value)
}}
suffix={<HelpButton title="Modal Title">Modal content</HelpButton>}
/>
)

Using List and Items markup

NB: By using this method you lose currently a lot of the core functionality like keyboard support and other accessibility features.

  • A
  • B
  • C
const list = [
{ value: 'A' },
{ value: 'B' },
{ value: 'C' }
]
const CustomWidth = styled(DrawerList)`
.dnb-drawer-list__list {
width: var(--drawer-list-width);
}
`
const DrawerListWithState = props => {
const [selected, setSelected] = React.useState('C')
return (
<CustomWidth
skip_portal
opened
prevent_close
>
<DrawerList.Options>
{list.map(({ value, ...props }, i) => (
<DrawerList.Item
key={i}
{...props}
selected={value === selected}
value={value}
on_click={({ value }) => setSelected(value)}
{...props}
>
{value}
</DrawerList.Item>
))}
</DrawerList.Options>
</CustomWidth>
)
}
render(<DrawerListWithState />)