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 <DrawerListoptions_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><ToggleButtontext="Toggle"checked={opened}icon={'chevron_' + (opened ? 'up' : 'down')}icon_position="left"on_change={({ checked }) => setOpened(checked)}/><DrawerListskip_portaldata={data}opened={opened}on_hide={() => setOpened(false)}{...props}/></Relative>)}render(<DrawerListWithState />)
DrawerList list - only to visualize
Default DrawerList
<DrawerListskip_portalopenedprevent_closetriangle_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
const CustomComponent = () => (<CustomComponentInneronTouchStart={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(<CustomWidthskip_portalopenedprevent_close// more_menurighttitle="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.
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.Itemkey={i}selected={value === selected}value={value}on_click={({ value }) => setSelected(value)}{...props}>{value}</DrawerList.Item>))}</DrawerList.Options></CustomWidth>)}render(<DrawerListWithState />)