Skip to main content
/
/
/
/
Upgrade to Bifrost 3.0

Upgrade to Bifrost 3.0

Bifrost 3.0 introduces a few breaking changes, this guide should help smoothen the transition.

If you're stuck with something after updating to 3.0 don't hesitate to contact us on slack :)

Also see the changelog for a full list of all changes.

Update Font Awesome

Bifrost 3.0 updated its Font Awesome dependency from 5.* to 6.*

  • Check your packages.json file to see which @fortawesome/* packages you use (if any).
  • Update each to latest version.

If you're using the pro icon packs, you can do something like this:

npm install @fortawesome/pro-solid-svg-icons@6 npm install @fortawesome/pro-regular-svg-icons@6 npm install @fortawesome/pro-light-svg-icons@6 npm install @fortawesome/pro-duotone-svg-icons@6
npm install @fortawesome/pro-solid-svg-icons@6 npm install @fortawesome/pro-regular-svg-icons@6 npm install @fortawesome/pro-light-svg-icons@6 npm install @fortawesome/pro-duotone-svg-icons@6

Removed components and hooks

  • <TabBar> (use reworked <Tabs> instead, see below)
  • <Sidebar> (replaced by <Nav>)
  • <TopBar> (replaced by <Nav>)
  • <Message.Header> (use <Message header=""> instead)
  • useLocalStorage (try use-local-storage-state instead)

Reworked <Tabs> and removed <TabBar>

The API for tabs was previously rather confusing and split between two different use cases;

  1. Easy-to use <Tabs> with its own internal state
  2. Flexible <TabBar> for use cases like routing or jsx in the tab button

We deleted them both and wrote a new <Tabs> from scratch, which should be both flexible and easy-to-use 🎉

  • Changes to <Tabs>:
    • active and onChange (removed) - use active and onClick on <Tabs.Item> instead
  • Changes to <Tabs.Item>:
    • children (changed) - tab button text (previously title)
    • content (new) - the tab panel content, rendered when the tab is active (previously children)
    • title (removed) - used to be the tab button text and required a unique string (now use children, with no limitations, we generate a unique id internally)
    • tabProps (removed) - passed props now apply directly to the tab button
// old <Tabs.Item title='Button text'> <p>Tab panel content</p> </Tabs.Item> // new in 3.0 <Tabs.Item content={<p>Tab panel content</p>}> Button text </Tabs.Item>
// old <Tabs.Item title='Button text'> <p>Tab panel content</p> </Tabs.Item> // new in 3.0 <Tabs.Item content={<p>Tab panel content</p>}> Button text </Tabs.Item>
// old <Tabs.Item tabProps={{ className: 'myClass' }} /> // new in 3.0 <Tabs.Item className='myClass' />
// old <Tabs.Item tabProps={{ className: 'myClass' }} /> // new in 3.0 <Tabs.Item className='myClass' />

Links inside <Tabs> are now rendered as tab buttons. Rename <TabBar> to <Tabs> and remove <TabBar.Item>:

// old <TabBar> <NavLink to='/path'> <TabBar.Item>Button text</TabBar.Item> </NavLink> </TabBar> // new in 3.0 <Tabs> <NavLink to='/path'>Button text</NavLink> </Tabs>
// old <TabBar> <NavLink to='/path'> <TabBar.Item>Button text</TabBar.Item> </NavLink> </TabBar> // new in 3.0 <Tabs> <NavLink to='/path'>Button text</NavLink> </Tabs>

Prop renaming

Default state value

The default value for state prop has been renamed from 'theme' to 'default' .

// old <Input state='theme' /> // new in 3.0 <Input state='default' /> // both are equivalent to not passing a state <Input />
// old <Input state='theme' /> // new in 3.0 <Input state='default' /> // both are equivalent to not passing a state <Input />

The same goes for all components with a state prop, and their respective types have also been rewritten to only include valid values:

ComponentNew valid values for state
<Checkbox>'default', 'success', 'warning', 'alert'
<DatePicker>'default', 'success', 'warning', 'alert'
<Button>'default', 'alert', 'inactive'
<Select>'default', 'alert'
<TextArea>'default', 'warning', 'alert'
<FieldGroup>'default', 'alert'
<Message>'default', 'success', 'warning', 'alert', 'neutral'
<Badge>'default', 'success', 'warning', 'alert', 'attn', 'chill', 'neutral'
<Tooltip>'default', 'neutral'

Inputs containerProps, style, and className

Almost all Bifrost components have always supported style and className props and applied them to the root node (outermost container element) of the component.

Until 3.0 this was not the case with form components where they were forwarded to the internal <input> element, and containerProps was used for the root node.

containerProps is now removed from the following components, use style and className directly instead.

  • <Checkbox>
  • <DatePicker>
  • <Input>
  • <Select>
  • <TextArea>

For classes / styles on the container:

// old <Input containerProps={{ className='myClass', style: { display: 'block' } }} /> // new in 3.0 <Input className='myClass' style={{ display: 'block' }} />
// old <Input containerProps={{ className='myClass', style: { display: 'block' } }} /> // new in 3.0 <Input className='myClass' style={{ display: 'block' }} />

For classes / styles on the internal input element:

// old <Input className='myClass' style={{ display: 'block' }} /> // new in 3.0 <Input inputClassName='myClass' // textAreaClassName for <TextArea>, or selectClassName for <Select> inputStyle={{ display: 'block' }} />
// old <Input className='myClass' style={{ display: 'block' }} /> // new in 3.0 <Input inputClassName='myClass' // textAreaClassName for <TextArea>, or selectClassName for <Select> inputStyle={{ display: 'block' }} />

<ProgressBar> size

The default value for size prop <ProgressBar> has been renamed from 'regular' to 'medium'

// old <Progressbar size='regular' /> // new in 3.0 <Progressbar size='medium' /> // both are equivalent to not passing a size <Progressbar />
// old <Progressbar size='regular' /> // new in 3.0 <Progressbar size='medium' /> // both are equivalent to not passing a size <Progressbar />

Deprecated <Accordion> state

Removed props onChange and active from parent <Accordion> component (you can still use active and onClick on <Accordion.Item> as before, see demo page)

onClick prop on <Accordion.Item> now forwards click event (previously the string from title)

Potentially breaking styling changes

Inline <Checkbox>

The <Checkbox> component is now display: inline-block to behave more like a native <input type='checkbox'> would.

After upgrading, make sure your checkboxes render as you expect. If you want the previous behaviour we recommend you use CSS (put them in a grid?), but a quick and dirty fix can be to wrap it in a block element.

// old <Checkbox /> // if you want the old behavior in 3.0 a quick fix is to wrap each checkbox in a div <div> <Checkbox /> </div>
// old <Checkbox /> // if you want the old behavior in 3.0 a quick fix is to wrap each checkbox in a div <div> <Checkbox /> </div>

Automatically stretching <Button>

CSS width and height constraints are removed from <Button> component, and the stretch prop as well.

This shouldn't break anything, but make sure all your buttons are rendered as you expect after upgrade.

Full-width <StepBar>

Default <StepBar> variant now renders full-width by default (to behave same as 'circle' variant).

<Card.Image> height

<Card.Image> has changed from having a static 150px height to a 16/9 aspect ratio by default.

Double check that all card images and their loading state skeleton render as intended at different screen sizes. Try using <Skeleton.CardImage> as a placeholder if you're not already.

Also see Aspect ratio vs height under Card docs

CSS cleanup

Removed class names

The mostly unused .bfl, .bfl-2col, and .bfl-3col have been removed, use .bfl-grid or <Grid> for column layouts instead.

Removed CSS variables

Find and replace any references you may have.

Removed CSS variableUse instead
--bf-font-size-xxxxl --bf-font-size-h1
--bf-font-size-xxxl --bf-font-size-h2
--bf-font-size-xxl --bf-font-size-h3
--bf-font-size-xl --bf-font-size-h4
--bf-topbar-height --bf-nav-top-height
--bf-sidebar-width --bf-nav-side-width
--bf-sidebar-width-collapsed --bf-nav-side-width
--bf-sidebar-transition --bf-nav-side-transition
--bf-card-image-ratio<Card.Image aspectRatio='...'>
--bf-card-image-height aspect-ratio

Keyboard focus styling

We have removed the focus-visible polyfill from Bifrost since even Safari 15.4+ now supports :focus-visible.

Replace [data-focus-visible-added] (if you have any) with :focus-visible in your CSS selectors.