Honeycomb

Honeycomb React 11 migration guide

Upgrade package

First upgrade to the latest version of Honeycomb-React:

npm install @flixbus/honeycomb-react@latest

Then proceed to the breaking changes.

Breaking Changes

The Dropdown no longer supports an array of objects with props for the links prop.

You should pass an array of DropdownItem components instead.

Before:

<Dropdown links={[
  { key: "edit", text: "Edit", href: "/", InlineIcon: { regular: IconEdit, active: IconEditSolid }, activeItem: true },
  { key: "share", text: "Share", href: "/", InlineIcon: { regular: IconShare, active: IconShareSolid }},
  { key: "divider", divider: true },
  { key: "delete", text: "Delete", Elem: "button", InlineIcon: { regular: IconDelete, active: IconDeleteSolid }},
]}>
  <Button>Old dropdown links</Button>
</Dropdown>

Now:

import { Dropdown, DropdownItem, Button } from '@flixbus/honeycomb-react';
import { IconOffer, IconOfferSolid, IconEdit, IconEditSolid, IconDelete, IconDeleteSolid } from '@flixbus/honeycomb-icons-react';

<Dropdown links={[
  <DropdownItem key="create" href="/" InlineIcon={{ regular: IconOffer, active: IconOfferSolid }}>Create</DropdownItem>,
  <DropdownItem key="edit" href="/" InlineIcon={{ regular: IconEdit, active: IconEditSolid }}>Edit</DropdownItem>,
  <DropdownItem key="divider" divider />,
  <DropdownItem key="delete" href="/" InlineIcon={{ regular: IconDelete, active: IconDeleteSolid }}>Delete</DropdownItem>,
]}>
  <Button>New dropdown links</Button>
</Dropdown>

Header children are now props

In order to make it easier to validate which header children components are being provided and which are not, we have removed the children prop from the Header component.

Now each header child component has a dedicated prop on the Header, you can pass the components as they are to their respective props.

This will then allow you to use conditionals inside of the props more easily, and not worry about the old flimsy header children validation function.

Before:

import { Header, HeaderSkipLinks, HeaderBrand, HeaderBurgerMenu, HeaderNavigation, SkipLink, NavItem } from '@flixbus/honeycomb-react';

const MainNavigation = ({ isBurger = false }) => (
  <HeaderNavigation aria-label='Main'>
    <NavItem active href='/'>Nav item</NavItem>
    <NavItem href='/'>Nav item</NavItem>
    {isBurger && <NavItem href='/'>Nav item</NavItem>}
  </HeaderNavigation>
);

MainNavigation.displayName = 'HeaderNavigation';

<Header>
  <HeaderSkipLinks>
    <SkipLink to='main-content'>Skip to main content</SkipLink>
    <SkipLink to='site-search'>Skip to site search</SkipLink>
  </HeaderSkipLinks>
  <HeaderBrand
    appearance='square'
    alt='Honeycomb'
    href='/'
    src='https://honeycomb.flixbus.com/dist/7.0.0/img/logos/svg/honeycomb-white.svg'
  />
  <MainNavigation />
  <HeaderBurgerMenu openPanelLabel='Open me' closePanelLabel='Close me' panelId='burger-panel'>
    <MainNavigation isBurger />
  </HeaderBurgerMenu>
</Header>

Now:

import { Header, HeaderSkipLinks, HeaderBrand, HeaderBurgerMenu, HeaderNavigation, SkipLink, NavItem } from '@flixbus/honeycomb-react';

const MainNavigation = ({ isBurger = false }) => (
  <HeaderNavigation aria-label='Main'>
    <NavItem active href='/'>Nav item</NavItem>
    <NavItem href='/'>Nav item</NavItem>
    <NavItem href='/'>Nav item</NavItem>
    {isBurger && <NavItem href='/'>Nav item</NavItem>}
  </HeaderNavigation>
);

MainNavigation.displayName = 'MainNavigation(HeaderNavigation)';

<Header
  skipLinks={(
    <HeaderSkipLinks>
      <SkipLink to='main-content'>Skip to main content</SkipLink>
      <SkipLink to='site-search'>Skip to site search</SkipLink>
    </HeaderSkipLinks>
  )}
  brand={(
    <HeaderBrand
      appearance='square'
      alt='Honeycomb'
      href='/'
      src='https://honeycomb.flixbus.com/dist/7.0.0/img/logos/svg/honeycomb-white.svg'
    />
  )}
  navigation={<MainNavigation />}
  burgerMenu={(
    <HeaderBurgerMenu openPanelLabel='Open me' closePanelLabel='Close me' panelId='burger-panel'>
      <MainNavigation isBurger />
    </HeaderBurgerMenu>
  )}
/>

Removed useSmartPosition prop for Tooltip and Dropdown

The smartPosition prop has been removed from the Tooltip and Dropdown components Honeycomb-React 11.

To replace that we provide a hook that will handle the positioning props that can be then passed to the components.

This change was made to reduce code complexity and instability for the majority of users that don't need smart positioning yet were forced to load all of the code responsible for that unnecessarily.

Old smart Tooltip in Honeycomb React 10:

import { Tooltip, Button } from '@flixbus/honeycomb-react';

<Tooltip id="old-smart-tooltip" content="This tooltip was smart!" position="left" smartPosition>
  <Button>Old smart tooltip</Button>
</Tooltip>

New smart Tooltip in Honeycomb React 11:

import React from 'react';
import { Tooltip, Button, useSmartPosition } from '@flixbus/honeycomb-react';

const targetInnerRef = React.useRef();
const balloonInnerRef = React.useRef();
const [isActive, setIsActive] = React.useState(false);
const [smartPosition, smartAlignment] = useSmartPosition({
  active: isActive,
  targetRef: targetInnerRef,
  elementRef: balloonInnerRef,
});

<Tooltip
  innerRef={targetInnerRef}
  balloonRef={balloonInnerRef}
  id="new-smart-tooltip"
  content="This tooltip is smart!"
  position={smartPosition}
  alignment={smartAlignment}
  onToggle={setIsActive}
>
  <Button>New smart tooltip</Button>
</Tooltip>

Old smart Dropdown in Honeycomb React 10:

import { Dropdown, DropdownItem, Button } from '@flixbus/honeycomb-react';

<Dropdown
  smartPosition
  links={[
    <DropdownItem key="share" href="/">Share</DropdownItem>,
    <DropdownItem key="copy" href="/">Copy</DropdownItem>,
    <DropdownItem key="delete" href="/">Delete</DropdownItem>,
  ]}
>
  <Button>Old smart dropdown</Button>
</Dropdown>

New smart Dropdown in Honeycomb React 11:

import React from 'react';
import { Dropdown, DropdownItem, Button, useSmartPosition } from '@flixbus/honeycomb-react';

const targetRef = React.useRef(null);
const dropdownInnerRef = React.useRef(null);
const [isActive, setIsActive] = React.useState(false);
const [smartPosition, smartAlignment] = useSmartPosition({
  active: isActive,
  targetRef: targetRef,
  elementRef: dropdownInnerRef,
  smartPositionAllowedPositions: ['top', 'bottom'],
});

<Dropdown
  menuRef={dropdownInnerRef}
  links={[
    <DropdownItem key="share" href="/">Share</DropdownItem>,
    <DropdownItem key="copy" href="/">Copy</DropdownItem>,
    <DropdownItem key="delete" href="/">Delete</DropdownItem>,
  ]}
  onToggle={setIsActive}
  yPosition={smartPosition}
  xPosition={smartAlignment}
>
  <Button innerRef={targetRef}>
    New smart dropdown
  </Button>
</Dropdown>

Final considerations

If you're interested in the full list of changes check the Changelog page.

And please don't hesitate to contact us in case you face any issues or find any nasty bugs when updating to version 9. We'll gladly assist you as promptly as possible.

Happy coding! 🍯