Skip to content

Demos#

Default and Medium-sized icons (Responsive)#

<Icon icon={Bell} title="Give Icons a Title, or ..." />
<Icon icon={BellMedium} aria-hidden />
<Bell title="I'm not responsive!" />
{/* <- Not responsive! */}

Icons with border#

NB: Use it with caution. It should not be used where it can confuse users with being a clickable button.

<Flex.Horizontal align="center">
  <Icon border={true} icon={Bell} />
  <Icon border={true} icon={BellMedium} size="medium" />
  <IconPrimary border={true} icon="information" />
  <IconPrimary border={true} icon="information" size="medium" />
  <Button icon={<IconPrimary icon="add" border />} text="Button" />
</Flex.Horizontal>

Filled icons#

Use the fill prop on a single icon to fill it.

<Flex.Stack>
  <Flex.Horizontal align="center">
    <Icon icon={Star} fill />
    <Icon icon={Heart} fill />
    <Avatar icon={<Icon icon={Star} fill />} size="small" hasLabel />
    <Button icon={<Icon icon={Heart} fill />} title="Favorite" />
  </Flex.Horizontal>
</Flex.Stack>

Animated icon demos#

Animated icons are static by default and only move when you opt in. Import each animated icon directly using its default export. Named imports are intentionally unavailable so each icon's animation code is only included when it is used.

Use a single animation to reinforce an event. Change animationKey to replay it while animate remains enabled.

const App = () => {
  const [animationKey, setAnimationKey] = useState(0)
  return (
    <Flex.Horizontal align="center" gap="small">
      <Icon
        icon={AnimatedBell}
        size="medium"
        animate
        animationKey={animationKey}
        aria-hidden
      />
      <Button
        variant="secondary"
        text="Replay"
        onClick={() => setAnimationKey((key) => key + 1)}
      />
    </Flex.Horizontal>
  )
}
render(<App />)

Animated icons in buttons#

Use hover to invite or preview an action. Play the animation once and keep the button understandable without motion.

<Button
  variant="tertiary"
  text="Continue"
  icon={<Icon icon={AnimatedArrowRight} animateWhen="hover" />}
/>

Responsive to its inherited font-size#

h1 with auto sized icon

<h1 className="dnb-h--xx-large">
  h1 with auto sized <Icon icon={BellMedium} size="auto" aria-hidden />{' '}
  icon
</h1>

Icon color variations#

All of these methods will output the same color

<Icon
  icon={BellMedium}
  color="var(--color-fire-red)"
  title="CSS variable"
/>
<Icon icon={BellMedium} color="#DC2A2A" title="Hex" />
<Icon icon={BellMedium} color="rgb(220,42,42)" title="RGB" />

Icon size variations#

The official supported sizes are default and medium.

NB: If you need to use the large, x-large or xx-large sizes, then you should use the *_medium version of the icon. Ensure you import the *_medium version of the icon.

<Icon icon={BellMedium} title="Beach" size="large" />
<Icon icon={BellMedium} title="Beach" size="x-large" />
<Icon icon={BellMedium} title="Beach" size="xx-large" />

Icon transition#

Use Icon.transition() to animate between SVG icon states. Define named states and use Icon.transition.activate(element, state) to switch between them.

When icons have compatible path structures (same number and type of segments), the transition animates via CSS d property interpolation. This suits directional variants like arrow_downarrow_up or chevron_downchevron_up.

Your browser does not support CSS d path interpolation, so the icon transition will fall back to a simple crossfade.
const directionIcon = Icon.transition({
  down: arrow_down,
  up: arrow_up,
  left: arrow_left,
  right: arrow_right,
})
const handleChange = (direction) => {
  const iconEl = document.querySelector(
    '[data-visual-test="icon-transition"] .dnb-icon'
  ) as HTMLElement
  if (iconEl) {
    Icon.transition.activate(iconEl, direction)
  }
}
render(
  <>
    <Flex.Horizontal align="center" gap="small">
      <Icon icon={directionIcon} />

      <Field.Selection
        variant="button"
        value="down"
        optionsLayout="horizontal"
        onChange={handleChange}
      >
        <Field.Option value="down" title="Down" />
        <Field.Option value="up" title="Up" />
        <Field.Option value="left" title="Left" />
        <Field.Option value="right" title="Right" />
      </Field.Selection>
    </Flex.Horizontal>
    {notSupported}
  </>
)

Icon transition fallback#

When icons have incompatible path structures (e.g. questionclose), Icon.transition() automatically falls back to a transform/opacity crossfade using stacked SVGs. The same Icon.transition.activate() API works for both modes.

const helpIcon = Icon.transition({
  question,
  close,
})
const handleChange = (state) => {
  const iconEl = document.querySelector(
    '[data-visual-test="icon-transition-fallback"] .dnb-icon'
  ) as HTMLElement
  if (iconEl) {
    Icon.transition.activate(iconEl, state)
  }
}
render(
  <Flex.Horizontal align="center" gap="small">
    <Icon icon={helpIcon} />

    <Field.Selection
      variant="button"
      value="question"
      optionsLayout="horizontal"
      onChange={handleChange}
    >
      <Field.Option value="question" title="Question" />
      <Field.Option value="close" title="Close" />
    </Field.Selection>
  </Flex.Horizontal>
)
Suggest an edit