Honeycomb React 12 migration guide
Upgrade package
First upgrade to the latest version of Honeycomb-React:
npm install @flixbus/honeycomb-react@latestThen proceed to the breaking changes.
Breaking Changes
Input prop id no longer accepts number, only string
Input components id prop used to accept numbers, but to keep in line with React.HTMLAttributes,
now only accept strings. This change shall be implemented in other input related components in the
future as well.
So if you encounter issues related to the input id prop type validation, double check if you are passing the right type.
For example, if before you had an input with id 1:
const id = 1; <Input type="number" name="numeric-field" id={id} label="Numeric field" /> // or <Input type="number" name="numeric-field" id={1} label="Numeric field" />
Now, you can try calling toString or create a string template with the numeric value instead:
const id = 1; <Input type="number" name="numeric-field" id={id.toString()} label="Numeric field" /> // or <Input type="number" name="numeric-field" id={`${1}`} label="Numeric field" />
In the future we might also change the id type of other components that used to support number to only accept string (minimizing overrides of React.HTMLAttributes), so please keep that in mind.
Autocomplete refactored with new API
The Autocomplete component has been refactored and the usage API is very different from the previous version. We are not going to attempt to replicate every single migration case, because there are way too many.
Here is a list of meaningful changes to the new Autocomplete:
idis no longer required, it can be generated automatically via React.useId if it's not provided- Children components removed and replaced with dedicated props, mainly to avoid React children validation hell
AutocompleteInputcomponent props should be passed viacomboboxPropsLegacyAutocompleteOptionscomponent props should be passed vialistBoxProps- event handlers were moved to their own respective props, clearing confusion between which component is triggering the event
valuebecomesinputValueas the newvalueis used for the current selected options insteadhighlightQueryis now internally handled and the prop no longer exists, the newhighlightOptionsprop can be used to configure where the highlight should be applied- The most basic options filtering can also be handled internally by the component (e.g.: filtering by title and subtitle), so you might even see a lot of code reduction on your side
Here is the most basic example of Autocomplete component from old to new, but we encourage you to check the new Autocomplete docs for many examples and details.
Before:
const filterAutocompleteMockData = (searchQuery, data) => ( // Custom async logic to fetch and/or filter data ); <Autocomplete onChange={(e) => { setLoading(true) }} onDebounce={(e) => { setLoading(true); setHighlight(e.target.value); filterAutocompleteMockData(e.target.value, AutocompleteMockData).then( options => { setData(options) setLoading(false) } ) }} onSelect={(item) => { setData([]); setHighlight(); setValue(item.title); }} options={data} value={value} > <AutocompleteInput id="autocomplete-1" placeholder="Try to type Berlin slowly" label="Place:" loading={loading} type="search" autoComplete="off" info={data.length === 0 ? 'No options found.' : `${data.length} option${data.length > 1 ? 's' : ''}.`} /> <AutocompleteOptions label="Places" optionsToDisplay={2} optionHasSubtitle highlightQuery={highlight} /> </Autocomplete>
Now:
<Autocomplete // component id is no longer required, it can be generated automatically with React.useId(). // AutocompleteInput component props should be passed via comboboxProps prop, avoiding React children validation hell comboboxProps={{ label: 'Place:', placeholder: 'Try to type Berlin slowly', type: 'search', loading, autoComplete: 'off', info: data.length === 0 ? 'No options found.' : `${data.length} option${data.length > 1 ? 's' : ''}.`, // event handlers moved to their own component props, to avoid confusion between which component is triggering the event onChange: (e) => { setLoading(true); setValue(e.target.value); }, }} // onDebouce for basic filtering on title and subtitle fields is handled internally options={data} // `value` becomes `inputValue` as the new `value` is used for the current selected options instead inputValue={value} // LegacyAutocompleteOptions component props should be passed via listBoxProps prop, avoiding React children validation hell listBoxProps={{ 'aria-label': 'Places', optionsToDisplay: 2, // highlightQuery is now internally handled, new highlightOptions prop can be used to configure where the highlight should be applied highlightOptions: 'both', }} />
But if you are not ready to migrate to the new component, we still provide the legacy Autocomplete
in a deprecated state and renamed it to LegacyAutocomplete. You can simply rename the components
and types to include Legacy..., and continue using it with the same API as before.
But please note we will not be offering support for the deprecated component anymore, and only high severity bug fixes will be issued from now on.
Now:
<LegacyAutocomplete onChange={(e) => { setLoading(true) }} onDebounce={(e) => { setLoading(true); setHighlight(e.target.value); filterAutocompleteMockData(e.target.value, AutocompleteMockData).then( options => { setData(options) setLoading(false) } ) }} onSelect={(item) => { setData([]); setHighlight(); setValue(item.title); }} options={data} value={value} > {/* configures input field appearance */} <LegacyAutocompleteInput id="autocomplete-1" placeholder="Try to type Berlin slowly" label="Place:" loading={loading} type="search" autoComplete="off" /> {/* displays a dropdown with options */} <LegacyAutocompleteOptions label="Places" optionsToDisplay={2} optionHasSubtitle highlightQuery={highlight} /> </LegacyAutocomplete>
Default margin for Fieldset items changed to spacing-2
The default margin between Fieldset items has been reduced from spacing 4 to 2. This change was made to align the Honeycomb React component with its Honeycomb Static counterpart. The spacing 2 is the recommended value to be used.
If having spacing 4 margins between items was your intentional preference, you can set it using the
itemSpacing prop.
<Fieldset itemSpacing="4" info="Please confirm you're fully aware of the choice made above"> <Checkbox id="my-unique-checkbox" value="Yes!" label="Yes!" /> <Checkbox id="my-unique-checkbox-2" value="Absolutely!" label="Absolutely!" /> </Fieldset>
Sass @import rules replaced with @use or @forward, mixins and variables are no longer visible in the global namespace
Since Sass version 1.80, @import rules are deprecated, so to keep up to date with the Sass specs,
we have moved away from @import and globally available features to use @use and @forward.
This means if you are a consumer of any of our sass files, you have to update your imports too.
The biggest change is replacing all your honeycomb-react sass files imports, like so:
Before:
@import '@flixbus/honeycomb-react/dist/scss/honeycomb-tools.scss';
.my-component {
background: cssvar('box-bg-color');
}Now:
@use '@flixbus/honeycomb-react/dist/scss/honeycomb-tools.scss' as *;
.my-component {
background: cssvar('box-bg-color');
}You can also now take advantage of scoped functions and mixins from Sass @use rule. Check the
Sass docs for more details on scoping and namespaces.
For example:
@use '@flixbus/honeycomb-react/dist/scss/honeycomb-tools.scss' as hcrTools;
.my-component {
background: hcrTools.cssvar('box-bg-color');
}Still related to that, if you relied on global $config-prefix override between HCR and HC files
(most notably but not limited to the theme files), a different approach is required now. If ou were
previously importing files from @flixbus/honeycomb (static) library, they will not contain the
static flix prefix instead of the expected hcr prefix. In this case, update your imports to
fetch your files from @flixbus/honeycomb-react library instead.
The individual themes have been added to the distribution:
Before:
@import '@flixbus/honeycomb-react/dist/scss/honeycomb-config.scss'; // used to override `$config-prefix` global variable
@import '@flixbus/honeycomb/dist/scss/honeycomb-theme-flix.scss'; // expected flix theme with hcr prefix
.my-component {
background: var('--hcr-box-bg-color'); // does not work anymore :(
}Now:
@use '@flixbus/honeycomb-react/dist/scss/honeycomb-config.scss'; // still needed for configured base styles
@use '@flixbus/honeycomb-react/dist/scss/themes/flix.scss'; // flix theme with hcr prefix imported from honeycomb-react
.my-component {
background: var('--hcr-box-bg-color'); // works!
}Incompatible TypeScript versions
There have been reports of incompatible TypeScript versions happening when the project was using version 5.0.2 (while Honeycomb React is now at 5.8).
If you encounter TypeScript errors, specially related to array methods (e.g.: .every, .some, etc),
please upgrade your typescript to the most recent version to see if it helps.
Final considerations
We would like to thank everyone who participated in the creation of this new major release by reporting bugs, beta testing and requesting features! You are the real MVP! 🥂
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 that need to be crushed quickly. We'll gladly assist you as promptly as possible.
Happy coding! 🍯