Description
The DrawerList component is a fragment inside other components.
It is used e.g. in the Dropdown.
Data structure
// as arrayconst data = [// Every data item can, beside "content" - contain what ever{// (optional) can be what everselected_key: 'key_0',// Item content as a string or arraycontent: '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 objectconst data = {a: 'A',b: 'B',}
options_render
Example usage of Code Editor
<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
Code Editor
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
Default DrawerList
Code Editor
<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') }} observer_element=".dnb-live-preview" // prevents direction to change when scrolling in this example />
Custom event and link on single item
Code Editor
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 key="link" href="/"> Go to this Link </Link>, 'Or press on me', <CustomComponent key="custom" />, ]} on_change={({ value }) => { console.log('More menu:', value) }} suffix={<HelpButton title="Modal Title">Modal content</HelpButton>} observer_element=".dnb-live-preview" // prevents direction to change when scrolling in this example />, )
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.
Code Editor
const list = [ { value: 'A', }, { value: 'B', }, { value: 'C', }, ] const CustomWidth = styled(DrawerList)` .dnb-drawer-list__list { width: var(--drawer-list-width); } ` const DrawerListWithState = () => { const [selected, setSelected] = React.useState('C') return ( <CustomWidth skip_portal opened prevent_close> <DrawerList.Options> {list.map(({ value, ...props }, i) => ( <DrawerList.Item key={i} selected={value === selected} value={value} on_click={({ value }) => setSelected(value)} {...props} > {value} </DrawerList.Item> ))} </DrawerList.Options> </CustomWidth> ) } render(<DrawerListWithState />)