Upgrade to Bifrost 4.0
This migration guide should help you upgrade @intility/bifrost-react from 3.x
to 4.x. If you're currently on 2.x (or older) please see
upgrade to 3 first.
React component changes
Select
<Select> docsThe <Select> component has been moved to a new package. If
you need it, install the package:
npm install @intility/bifrost-react-select
and update your imports:
// old
import { Select } from "@intility/bifrost-react"; // removed in 4.0
// new
import Select from "@intility/bifrost-react-select";
DatePicker
<DatePicker> docsThe <DatePicker> component has been moved to a new
package. If you need it, install the package:
npm install @intility/bifrost-react-datepicker
Then import the CSS (once, globally in your app):
import "@intility/bifrost-react-datepicker/datepicker.css";
and update your imports (in each file you use the DatePicker):
// old
import { DatePicker } from "@intility/bifrost-react"; // removed in 4.0
// new
import DatePicker from "@intility/bifrost-react-datepicker";
Modal
We've rewritten our <Modal> component from scratch, and no
longer rely on the react-modal
dependency.
Removed Modal.Footer
As part of the cleanup, <Modal.Footer> has been removed. You can get a similar
result using the new <Inline> component. Depending on your
layout and css you may need to adjust some spacing.
// old
<Modal.Footer>
<Button>Right-aligned button</Button>
</Modal.Footer>
// new
<Inline>
<Inline.Separator />
<Button>Right-aligned button</Button>
</Inline>
Removed props
noHeaderremoved sinceheaderis now optionalfromBottomremoved (use a<Drawer>)iconremoved (use an<Icon>)overlayClassNameremoved (classNamenow applies to outermost element)centerremoved since modal is no longer rendered fullscreen for mobile
In addition, all of the props previously forwarded to react-modal will no
longer work, please contact us if you're
missing some functionality.
new noCloseOnOverlayClick and noCloseOnEsc props
// old
<Modal shouldCloseOnOverlayClick={false} shouldCloseOnEsc={false} />
// new
<Modal noCloseOnOverlayClick noCloseOnEsc />
fromBottom moved to Drawer
The fromBottom prop has been removed from <Modal>, instead you can use
<Drawer position='bottom'>:
// old
<Modal fromBottom />
// new
<Drawer position='bottom' />
No Modal.setAppElement
Since we now use the browser-native
<dialog>
element under the hood, it's accessible out of the box and if you previously
used the setAppElement method you can safely remove it:
// just remove this line, if you have it present in your app
Modal.setAppElement(rootElement);
Overflow
If you have content that might overflow the <Modal> container (like a
<Select>), the new Modal might create an unwanted scrollbar. See the overflow
section in the Modal docs for solutions.
This should be fixed in latest versions of select and datepicker packages.
SlideDown
We've rewritten our <SlideDown> component from scratch,
and no longer rely on the react-animate-height dependency.
No code changes should be needed, unless:
- you rely on one of the props provided by the
react-animate-heightfrom the old implementation (if so, install and use that instead).
// closedHeight prop removed in 4.0
import { SlideDown } from "@intility/bifrost-react";
<SlideDown open={booleanState} closedHeight={26} />;
// instead, you can use AnimateHeight directly instead
import AnimateHeight from "react-animate-height";
<AnimateHeight height={booleanState ? "auto" : 26} />;
- you have some
paddingdirectly on the<SlideDown>element, move the padding to a child element instead:
// old
<SlideDown open={booleanState} style={{ padding: "16px" }}>
<p>Will not be hidden properly :(</p>
</SlideDown>
// new
<SlideDown open={booleanState}>
<div style={{ padding: "16px" }}>
<p>Ahh, that's much better</p>
</div>
</SlideDown>
Button
The default value for the type prop is now "button" (previously "submit").
If the <Button> is not part of a <form>, this change should not affect
you, and for most cases this is the desired behavior.
However, if you're using a bifrost <Button> inside a <form> (listening to
the onSubmit event), and want it to submit the form, you now need to
explicitly set <Button type="submit">:
// old
<form onSubmit={handleSubmit}>
<Button>Will no longer submit the form</Button>
</form>
// new
<form onSubmit={handleSubmit}>
<Button type="submit">Submit the form</Button>
</form>
Breakpoint
<Breakpoint> docsWe generally recommend using breakpoint css classes instead
of this component, but if you are using it, it should still work, but 4.0
introduces a <div> wrapper , so make sure it still looks right in your app.
If your design doesn't work with the extra element (for instance in a css grid), use the CSS classes instead.
// old
<Breakpoint from="small">
<div>my grid item</div>
</Breakpoint>
// new
<div className="from-small">my grid item</div>
Accordion
Restyled slightly, state indicator icon now placed to the left for
variant="styled".
This should work fine in 99% of cases, but if you've got some custom CSS it might not work the same any more (try removing your custom CSS and see if it looks better without).
Bifrost
<Bifrost> docsRemoved the onThemeChange prop and deprecated theme. We recommend you don't
use this component to control the color mode, and if you need to force a color
mode, simply set a class on the root <html> element.
Nav
Color mode picker
Color mode picker example
The hideTheme prop has been removed since <Nav> no longer renders a color
mode picker.
Collapsible sidebar
Sidebar is no longer collapsible by default. Pass your own state to sideProps.
Input
<Input> docsAll form inputs have been restyled to "outline" styling, therefore we have
removed variant prop from <Input> (since all it did was apply outline
styling).
Checkbox and CheckboxCard
The internal DOM structure and CSS for our <Checkbox> and <CheckboxCard>
components have been quite convoluted since the styling relied on the <input>
state, and without
:has() it's been
impossible to write CSS selectors that target parent (or previous sibling)
elements.
The browser support is now good enough that we've been able to simplify our CSS
and DOM structure for checkboxes, and removed the need for us to generate an
id internally.
The design and usage should stay the same, but if you have any customized checkbox styling, there could be unforeseen side-effects.
Package changes
Components are updated to work with React Server Components out of the box.
We've restructured our internal folder structure and modernized the
package.json.
ES module only
We've dropped support for CommonJS (require()), always use ES module (import
or import()) syntax instead.
Deep imports
Deep import paths should be significantly simpler now:
// old
import Nav from "@intility/bifrost-react/dist/navigation/Nav";
import Accordion from "@intility/bifrost-react/dist/interactive/Accordion";
import "@intility/bifrost-react/dist/bifrost-app.css";
// new
import Nav from "@intility/bifrost-react/Nav";
import Accordion from "@intility/bifrost-react/Accordion";
import "@intility/bifrost-react/bifrost-app.css";
Replaced icons
All previously bundled icons have been removed, and replaced with free
alternatives or custom equivalents. For the most part it shouldn't matter much,
but if you use <Message> for instance, you may prefer to use font awesome pro
icons over the new default icons (font awesome solid).
import { faCircleInfo } from '@fortawesome/pro-regular-svg-icons'
<Message icon={faCircleInfo} ... />
Typography margins removed
Figma designs usually have no margins on elements like headings, paragraphs and lists, instead using gap inside autolayout (roughly equivalent to grid or flexbox in CSS), resulting in developers needing to manually remove the bifrost-applied margins with bifrost 3.x.
To make it easier to implement new designs going forward, we have removed the margin from the following CSS classes in 4.x:
// old
<h4 className="bf-h4" style={{margin: 0}}>Heading without margin</h4>
// new
<h4 className="bf-h4">Heading without margin</h4>
.bf-content mostly unchanged
Since the .bf-content is meant for using on a wrapper around html content you
don't control, it will still apply margins as it always has.
We have, however, lowered the specificity for selectors, so it should be easier to override the bifrost styling with your custom CSS.
New .bf-elements wrapper
Since it gets tiresome to apply the classnames to all headings etc, you can use
the new .bf-elements which does the same as .bf-content but without the
margins!
// old
<div className="bf-content">
<h4 style={{margin: 0}}>Heading without margin</h4>
</div>
// new
<div className="bf-elements">
<h4>Heading without margin</h4>
</div>
Re-apply margin
If you want to keep the margin on a heading (or paragraph etc.) you can either
use the .bf-content class, or apply a margin yourself.
// old
<h4 className="bf-h4">Heading with margin</h4>
// new
<h4 className="bf-h4" style={{ marginBlock: '1rem' }}>Heading with margin</h4>
// or
<div className="bf-content">
<h4>Heading with margin</h4>
</div>
Deprecated
useTheme hook
Deprecated the useTheme() hook, and its setTheme method has been removed.
Prefer to set classes on root element instead.
dateFormat and timeFormat functions
The dateFormat() and timeFormat() functions have proven to be troublesome
when hydrating
since server might format differently (server in different timezone than client,
for instance), and will probably be removed in a future version.
Instead, we are introducing a new useDateTimeFormatter() hook that will
respect current bifrost locale.
// old
import { dateFormat } from "@intility/bifrost-react";
function MyComponent() {
return "Date is " + dateFormat(new Date());
}
// new
import useDateTimeFormatter from "@intility/bifrost-react/hooks/useDateTimeFormatter";
function MyComponent() {
const dateTimeFormatter = useDateTimeFormatter();
return "Date is " + dateTimeFormatter({ date: new Date(), show: "date" });
}
useDateTimeFormatter() hook<FormatDate> componentButton icon prop
The icon and rightIcon props for <Button> have been
deprecated. Use a nested <Icon> instead:
// old
<Button icon={faHome}>Left icon</Button>
<Button icon={faHome} rightIcon>Right icon</Button>
// new
<Button><Icon icon={faHome} /> Left icon</Button>
<Button>Right icon <Icon icon={faHome} /></Button>
Depending on your design, you might find the marginLeft/marginRight props
on <Icon> useful to get the positioning just right.
Border radius
Bifrost 4.0 introduces new standard values for border-radius
- New CSS Variables
--bf-radius-none= 0px--bf-radius-xs= 4px--bf-radius-s= 8px--bf-radiusor--bf-radius-m= 12px--bf-radius-l= 16px--bf-radius-xl= 24px--bf-radius-full= 9999px
- New Corresponding CSS helper classes
.bf-radius-xsapplies 4pxborder-radius.bf-radius-sapplies 8pxborder-radius.bf-radiusor.bf-radius-mapplies 12pxborder-radius.bf-radius-lapplies 16pxborder-radius.bf-radius-xlapplies 24pxborder-radius.bf-radius-fullapplies 9999pxborder-radius
- Old border radius classes and variable
- Deprecated
--bfl-border-radius(use--bf-radius-xsinstead) - Deprecated
.bfl-border-radiusand.bf-border-radius(use.bf-radius-xsinstead)
- Deprecated
bfl CSS prefix
Almost all bifrost class names and CSS variable names are prefixed with bf-,
with a few exceptions:
bfc-*for colorsbfs*for spacingbfl-*for layout
What constitutes "layout" can be confusing, so we're planning on dropping
bfl-* in a future release, and started deprecating some variables and classes
in 4.0:
| Old name | New name |
|---|---|
| bfl-border | bf-border |
| --bfl-border | --bf-border |
| bfl-padding | bf-padding |
| --bfl-box-padding | --bf-box-padding |
| bfl-page-padding | bf-page-padding |
| --bfl-page-padding | --bf-page-padding |
| bfl-autocol | bf-autocol |
| --bfl-autocol-width | --bf-autocol-width |
| --bfl-autocol-gap | --bf-autocol-gap |