Honeycomb

Honeycomb React 17 migration guide

Upgrade package

First upgrade to the latest version of Honeycomb React:

npm install @flixbus/honeycomb-react@latest

Then proceed with the checklist below.

Quick migration checklist

Use this as a practical order of execution:

  1. Replace old language switcher component names (LanguageSwitcherPopup, LanguageSwitcherPopupRegion) with new names (LanguageSwitcher, LanguageSwitcherRegion).
  2. Remove LanguageSwitcherToggle and HeaderUserWidget usage.
  3. Remove shouldCloseDialog from LanguageSwitcherItem.
  4. Update PhoneInput usage:
    • use defaultValue for uncontrolled initial value;
    • keep value only for controlled state;
    • update selectRest.onChange logic (it now returns country code in event.target.value).
  5. Remove useFutureValueBehavior from PhoneInput.
  6. Replace PagerArrow with PagerItem + Icon children.
  7. Remove contentFit prop from Pager.
  8. If you were using old flex grid APIs (Grid + GridCol), choose one path:
    • quick compatibility path: rename to LegacyGrid + LegacyGridCol;
    • preferred path: migrate to the new CSS-grid based Grid + GridCell.

Breaking changes

LanguageSwitcherPopup renamed to LanguageSwitcher

Version 17 simplifies language switcher naming. If you import LanguageSwitcherPopup, rename it to LanguageSwitcher.

Before:

import {
  LanguageSwitcherPopup,
  LanguageSwitcherPopupRegion,
  LanguageSwitcherPopupItem,
} from '@flixbus/honeycomb-react';

<LanguageSwitcherPopup>
  <LanguageSwitcherPopupRegion title="Europe">
    <LanguageSwitcherPopupItem href="/en" lang="en">English</LanguageSwitcherPopupItem>
  </LanguageSwitcherPopupRegion>
</LanguageSwitcherPopup>

Now:

import {
  LanguageSwitcher,
  LanguageSwitcherRegion,
  LanguageSwitcherItem,
} from '@flixbus/honeycomb-react';

<LanguageSwitcher>
  <LanguageSwitcherRegion title="Europe">
    <LanguageSwitcherItem href="/en" lang="en">English</LanguageSwitcherItem>
  </LanguageSwitcherRegion>
</LanguageSwitcher>

LanguageSwitcherRegion no longer supports grouping with fragments

If you were using fragments to create multiple separated lists inside one region, this no longer works in v17. Use plain LanguageSwitcherItem children within a region.

PhoneInput: controlled vs uncontrolled usage is now explicit

In v17, PhoneInput follows common controlled-component behavior:

  • value means controlled component;
  • defaultValue means uncontrolled initial value.

If you were passing value only to prefill, switch to defaultValue.

Before:

<PhoneInput
  callingCodes={callingCodes}
  id="phone"
  label="Phone"
  selectLabel="Select your country"
  value="+380501226683"
/>

Now (uncontrolled prefill):

<PhoneInput
  callingCodes={callingCodes}
  id="phone"
  label="Phone"
  selectLabel="Select your country"
  defaultValue="+380501226683"
/>

PhoneInput selectRest.onChange now returns country code in event.target.value

Before, the select callback returned calling code (+39, +1, etc.). Now it returns country code (it, us, ca, etc.).

This helps disambiguate countries sharing one calling code.

Before:

<PhoneInput
  callingCodes={callingCodes}
  selectRest={{
    onChange: (event) => {
      const newCallingCode = event.target.value; // "+39"
      const newValue = phone.replace(oldCallingCode, newCallingCode);
      setValue(newValue);
    },
  }}
/>

Now:

<PhoneInput
  callingCodes={callingCodes}
  selectRest={{
    onChange: (event) => {
      const newCountryCode = event.target.value; // "it"
      const newCallingCode = callingCodes.find(
        (item) => item.countryCode === newCountryCode,
      )?.value;
      const newValue = phone.replace(oldCallingCode, newCallingCode || oldCallingCode);
      setValue(newValue);
    },
  }}
/>

Grid refactor: old flex grid is now legacy

The old flex-box based Grid API was moved to legacy naming.

  • old Grid -> LegacyGrid
  • old GridCol -> LegacyGridCol

You can either:

  1. do a quick rename to keep behavior unchanged, or
  2. migrate to the new CSS-grid based Grid + GridCell API.

Quick compatibility path

Before:

import { Grid, GridCol } from '@flixbus/honeycomb-react';

<Grid align="center">
  <GridCol size={6}>Left</GridCol>
  <GridCol size={6}>Right</GridCol>
</Grid>

Now (compatibility):

import { LegacyGrid, LegacyGridCol } from '@flixbus/honeycomb-react';

<LegacyGrid align="center">
  <LegacyGridCol size={6}>Left</LegacyGridCol>
  <LegacyGridCol size={6}>Right</LegacyGridCol>
</LegacyGrid>

Preferred migration path

import { Grid, GridCell } from '@flixbus/honeycomb-react';

<Grid>
  <GridCell colSpan={6}>Left</GridCell>
  <GridCell colSpan={6}>Right</GridCell>
</Grid>

Removed in v17

useFutureValueBehavior prop removed from PhoneInput

This temporary opt-in behavior is now the default behavior. Remove the prop.

Before:

<PhoneInput
  useFutureValueBehavior
  callingCodes={callingCodes}
  id="phone"
  label="Phone"
  selectLabel="Select your country"
  value="+380501226683"
/>

Now:

<PhoneInput
  callingCodes={callingCodes}
  id="phone"
  label="Phone"
  selectLabel="Select your country"
  value="+380501226683"
/>

LanguageSwitcherToggle and HeaderUserWidget removed

You can create your own buttons and control the LanguageSwitcher popup and the user menu Dropdown however best suit your needs.

Check the HeaderWidgets documentation for examples of custom widgets used in the Header.

LanguageSwitcherItem shouldCloseDialog removed

LanguageSwitcherItem active/open behavior is now fully external. Close dialogs from your own onClick handler logic.

PagerArrow removed

PagerArrow was deprecated since v16.0.0. Use PagerItem with Icon children instead.

Before:

import { Pager, PagerItem, PagerArrow } from '@flixbus/honeycomb-react';

<Pager Elem="button" aria-label="Pagination">
  <PagerArrow side="prev" aria-label="Previous page" />
  <PagerItem>1</PagerItem>
  <PagerItem>2</PagerItem>
  <PagerArrow side="next" aria-label="Next page" />
</Pager>

Now:

import { Pager, PagerItem } from '@flixbus/honeycomb-react';
import { Icon, IconArrowLeft, IconArrowRight } from '@flixbus/honeycomb-icons-react';

<Pager Elem="button" aria-label="Pagination">
  <PagerItem aria-label="Previous page">
    <Icon InlineIcon={IconArrowLeft} aria-hidden="true" />
  </PagerItem>
  <PagerItem>1</PagerItem>
  <PagerItem>2</PagerItem>
  <PagerItem aria-label="Next page">
    <Icon InlineIcon={IconArrowRight} aria-hidden="true" />
  </PagerItem>
</Pager>

contentFit prop removed from Pager

The Pager component now reacts to custom content by default. The prop has no effect and you can safely remove it.

completedSrText prop removed from ProgressTrackerItem

Deprecated since v13.0.0. Use srOnly instead.

Before:

<ProgressTrackerItem completed completedSrText="Step completed">Step 1</ProgressTrackerItem>

Now:

<ProgressTrackerItem completed srOnly="Step completed">Step 1</ProgressTrackerItem>

aria-selected removed from ToggleButton

Deprecated since v16.6.2 as aria-selected is not a valid attribute on button role elements. Use aria-pressed or aria-expanded instead.

Before:

<ToggleButton aria-selected={isOpen} aria-label="Toggle">Label</ToggleButton>

Now:

<ToggleButton aria-pressed={isOpen} aria-label="Toggle">Label</ToggleButton>

spacing prop removed from FormRow

Deprecated since v16.5.1 and a no-op since v16.0.0. Use spaceHelpers as extraClasses instead.

Before:

<FormRow spacing={4}>...</FormRow>

Now:

import { spaceHelpers } from '@flixbus/honeycomb-react';
<FormRow extraClasses={spaceHelpers()[4].bottom}>...</FormRow>

Deprecated in v17

LegacyGrid and LegacyGridCol are deprecated

They are available as a migration bridge for existing flex-grid layouts. For new code and long-term maintenance, migrate to Grid + GridCell.

Validation after migration

Recommended UI smoke checks:

  1. Language switcher open/close and keyboard interactions.
  2. Header areas where HeaderUserWidget used to be.
  3. PhoneInput country selection and number replacement logic.
  4. Any page/layout still using legacy grid.

Notes for coding agents

For faster codemods, start with this search list:

  1. LanguageSwitcherPopup
  2. LanguageSwitcherPopupRegion
  3. LanguageSwitcherPopupItem
  4. LanguageSwitcherToggle
  5. HeaderUserWidget
  6. useFutureValueBehavior
  7. shouldCloseDialog
  8. GridCol
  9. PagerArrow
  10. contentFit (on Pager)
  11. completedSrText (on ProgressTrackerItem)
  12. aria-selected (on ToggleButton)
  13. spacing (on FormRow)

Apply replacements in small commits and run validation after each group.