Skip to content

Import

import { DrawerList } from '@dnb/eufemia/fragments'

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

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

  • Brukskonto - Kari Nordmann
  • Sparekonto - Ole Nordmann
  • Long link that will wrap over several linesFeriekonto - Kari Nordmann med et kjempelangt etternavnsen
  • Oppussing - Ole Nordmann

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.

  • A
  • B
  • C
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 />)