Upgrading to v1
Chakra UI v1.0 is focused on improving the ideas and concepts from v0.8 to make it even easier to create, theme and extend components.
While there are quite a number of new features we've added, we focused on making Chakra UI a stable base to build your own design systems on top of. In the end, we want make you feel more confident using Chakra UI in production.
Highlights#
Theming API: Chakra UI now provides a new theming API which makes it easy to style components and their modifiers (sizes, variants, and color scheme) from your theme.
Color mode improvement: We've fixed the bugs related to Color mode and made it possible to persist color mode, set initial color mode, and lock specific components to a certain color mode.
Better TypeScript support: This means all components have very good
TypeScript support and most low-level components like Box
, Flex
will support
the as
prop and types will be extracted properly.
Theme-aware sx prop: Just like theme-ui
, we've added support for the sx
prop to help you add theme-aware styles directly on any Chakra component. This
is useful if you're not a fan of style props, and prefer passing all styles in
one object.
Deprecated PseudoBox: We've removed PseudoBox
and merged all its props
with Box
so you can use pseudo style props, like _hover
, _active
in any
Chakra components.
Upgrade steps#
Here's a list of steps to migrate your project to v1. Don't worry if your styles aren't exactly the same, this is to be expected and following these steps will fix it.
1. Update your dependencies#
Install the
framer-motion
package. We use this to manage animations and transitions within components.Remove the
emotion-theming
package. As at emotion v11,emotion-theming
as been removed and all it's functionality as been migrated to@emotion/react
.Rename the
@emotion/core
package to@emotion/react
.@emotion/core
was recently changed to@emotion/react
following the v11 release by the emotionjs team.Rename the
@chakra-ui/core
package to@chakra-ui/react
.Update the
@emotion/styled
package to v11.
"dependencies": {- "@chakra-ui/core": "^0.8.0",+ "@chakra-ui/react": "^1.0.0","framer-motion": ">=3.0.0",- "@emotion/core": "^10.0.10",+ "@emotion/react": "^11.0.0","@emotion/styled": "^11.0.0",- "emotion-theming": "10.0.10"}
Please note that when using Chakra UI in a TypeScript project, a minimum TypeScript version of
3.8.0
is required.
Notes on Icons#
Chakra moved all icons to a separate package @chakra-ui/icons
. We recommend
using react-icons
in your projects considering it has a robust set of icons.
However, you can still install this package.
2. Update the ThemeProvider#
Swap out ThemeProvider
with ChakraProvider
to make setup cleaner.
ChakraProvider
adds the following providers for you automatically:
- ThemeProvider: Provides the theming context for all components.
- ColorModeProvider: Provides color mode (light or dark) context to all components.
- GlobalStyle: Provides the global styles defined in
theme.styles.global
to your application.
Optionally via prop:
- CSSReset: To omit the recommended
CSSReset
, passresetCSS={false}
. - PortalManager: Manages portals and nested portals without using
z-index
in your application. Pass theportalZIndex
prop.
- <ThemeProvider>+ <ChakraProvider>- <CSSReset /><App />+ </ChakraProvider>- </ThemeProvider>
3. Rename variantColor
to colorScheme
#
Fire up your "Find and Replace" tool in VSCode or IntelliJ. Find variantColor
and replace with colorScheme
.
Reason: We renamed this prop to make it easier to understand that this prop represents a visual color scheme, not a css color attribute.
4. Update layout size
prop#
Change size
prop to width
or w
and height
, or h
. If you'd like to use
only one prop to manage this, you can rename it to boxSize
.
- <Box size="40px" />+ <Box w="40px" h="40px" /># or+ <Box boxSize="40px" />
We strongly recommend using the width
and height
props
Reason: We think the
size
prop should only be used for component size modifiers. Thesize
prop has caused a lot of confusion in the past because, in some components (e.g. Button), it means the visual size and in others (e.g Box), it means width and height.
5. Replace elements#
PseudoBox#
PseudoBox
is now deprecated and its props can now be directly applied to
Box
. Replace all PseudoBox
components with Box
.
- <PseudoBox+ <Box>- <PseudoBox+ <Box_hover={{ fontWeight: 'semibold' }}_groupHover={{ color: 'tomato' }}>- </PseudoBox>+ </Box>- </PseudoBox>+ </Box>
Callout#
Callout
is now deprecated and you can use an Alert
instead.
- <Callout+ <Alertmt={4}w="90%"bg="black"variant="left-accent">- </Callout>+ </Alert>
6. Update theme breakpoints#
You may skip this if you didn't customize your breakpoints.
To provide easier extensibility and typesafety, breakpoints should now be
created through createBreakpoints
by passing an object:
+ import { extendTheme } from "@chakra-ui/react"+ import { createBreakpoints } from "@chakra-ui/theme-tools"+ const breakpoints = createBreakpoints({+ sm: "30em",+ md: "48em",+ lg: "62em",+ xl: "80em",+ })const overrides = {- breakpoints: ["30em", "48em", "62em", "80em"]+ breakpoints,}+ const customTheme = extendTheme(overrides)
Please note that unless you plan overriding all components, sm
to xl
are
required.
You may of course add for example xxl
or other breakpoints in between -
createBreakpoints
will sort in ascending order. It is adviseable to not mix
css units.
Reason: Previously, breakpoints on a theme had to be an array with your breakpoints in ascending order which made it hard to reference which value was correlating to
md
etc. Also, you had to manually manipulate the array by defining properties on it, which was often overlooked and not typesafe.
7. ColorModeScript (optional)#
You can skip this if you are not already using the color mode feature.
To keep color mode settings in sync across pages, add the ColorModeScript
.
For exhaustive examples, please visit Features > Color Mode # Add ColorModeScript.
Component Updates#
We've updated the API of some components to fix bugs, improve usability, types and accessibility.
Accordion#
- Update all imports of
AccordionHeader
toAccordionButton
. This is to remove the notion that it is a header when it is actually a button.
- import { AccordionHeader } from "@chakra-ui/react"+ import { AccordionButton } from "@chakra-ui/react"
WAI-ARIA guidelines require that accordion buttons be wrapped in the appropriate heading tag
h2-h6
based on the page heading flow.
We think the name AccordionHeader
might mislead users to think we handle this
out of the box when we don't. Here's how to handle this:
<Accordion><AccordionItem><h3><AccordionButton>This is the button</AccordionButton></h3><AccordionPanel>This is the content</AccordionPanel></AccordionItem></Accordion>
- You can no longer use
AccordionItem
in isolation, it must be used withinAccordion
.
AspectRatioBox#
- Change all imports of
AspectRatioBox
toAspectRatio
.
- import { AspectRatioBox } from "@chakra-ui/react"+ import { AspectRatio } from "@chakra-ui/react"
Breadcrumb#
Removed support for the addSeparator
prop.
Button#
- We've unified the usage of all icon props to only accept a React element.
Update all icon names used in
leftIcon
orrightIcon
to the equivalent icon React element.
Replacement logic: If
leftIcon
is<EmailIcon/>
from Chakra.
import { PhoneIcon } from "@chakra-ui/icons"- <Button leftIcon="phone">Call</Button>+ <Button leftIcon={<PhoneIcon />}>Call</Button>
This reduces the effort needed to use custom icons, eliminates TypeScript errors, and reduces unused icons bloating your app.
Renamed
variantColor
tocolorScheme
Removed negative side margins on
leftIcon
andrightIcon
elements. We believe the user should handle these side margins. #1024
Checkbox#
- Change
variantColor
tocolorScheme
- <Checkbox variantColor="blue">Option</Checkbox>+ <Checkbox colorScheme="blue">Option</Checkbox>
Deprecated the
isFullWidth
prop.Checkbox
now takes up the width of its parent by default.To allow for better checkbox group layout, the
CheckboxGroup
component no longer supports every style prop.You can now only pass
size
,variant
, andcolorScheme
in addition toCheckboxGroup
-specific props (value
,defaultValue
, andonChange
).
// before<CheckboxGroup isInline spacing="40px" defaultValue={["one", "two"]}><Checkbox value="one">One</Checkbox><Checkbox value="two">Two</Checkbox><Checkbox value="three">Three</Checkbox></CheckboxGroup>// after<CheckboxGroup defaultValue={["one", "two"]}><Stack spacing="40px"><Checkbox value="one">One</Checkbox><Checkbox value="two">Two</Checkbox><Checkbox value="three">Three</Checkbox></Stack></CheckboxGroup>
We believe a checkbox group's layout should be managed by your design requirements. The checkboxes can be grouped using
Stack
, placed in a grid usingSimpleGrid
or made to wrap automatically usingWrap
.
ColorMode#
Color mode now persists correctly when you refresh the page. All you need to do is add
ColorModeScript
script as the first child ofbody
.Here's how to add it for Next.js:
// pages/_document.jsimport { ColorModeScript } from "@chakra-ui/react"export default class Document extends NextDocument {static getInitialProps(ctx) {return NextDocument.getInitialProps(ctx)}render() {return (<Html><Head /><body>{/* 👇 Here's the script */}<ColorModeScript /><Main /><NextScript /></body></Html>)}}
Here's how to add it for Gatsby:
Changes#
- The Gatsby plugin has been renamed from
gatsby-plugin-chakra-ui
to@chakra-ui/gatsby-plugin
. Please make sure to have updated this when installing Chakra UI in your next Gatsby project.
// gatsby-ssr.jsexport const onRenderBody = ({ setPreBodyComponents }) => {setPreBodyComponents([<ColorModeScript key="chakra-ui-no-flash" />])}
You can also install the
@chakra-ui/gatsby-plugin
package which automatically configures ColorModeScript
along with
ChakraProvider
.
Editable#
The onRequestEdit
prop has been renamed to onEdit
. This applies to both the
prop passed to Editable
as well as the prop in its render props.
Icons#
Basic interface icons provided by Chakra have moved to the
@chakra-ui/icons
package. Replace all<Icon name="..." />
elements imported from@chakra-ui/react
with equivalent React elements imported from@chakra-ui/icons
.Replacement logic: If
<Icon name="search" />
is used, then replace it with<SearchIcon />
from Chakra icons package.
- import { Icon } from "@chakra-ui/react"- <Icon name="search" />+ import { SearchIcon } from "@chakra-ui/icons"+ <SearchIcon />
Existing icons will appear as a question mark until refactored.
- We changed the way custom icons are created. Instead of adding custom icons to
theme
create your own icons using thecreateIcon
utility:
import { createIcon } from "@chakra-ui/react"export const UpDownIcon = createIcon({displayName: "UpDownIcon",viewBox: "-1 -1 9 11",d:"M 3.5 0L 3.98809 -0.569442L 3.5 -0.987808L 3.01191 -0.569442L 3.5 0ZM 3.5 9L 3.01191 9.56944L 3.5 9.98781L 3.98809 9.56944L 3.5 9ZM 0.488094 3.56944L 3.98809 0.569442L 3.01191 -0.569442L -0.488094 2.43056L 0.488094 3.56944ZM 3.01191 0.569442L 6.51191 3.56944L 7.48809 2.43056L 3.98809 -0.569442L 3.01191 0.569442ZM -0.488094 6.56944L 3.01191 9.56944L 3.98809 8.43056L 0.488094 5.43056L -0.488094 6.56944ZM 3.98809 9.56944L 7.48809 6.56944L 6.51191 5.43056L 3.01191 8.43056L 3.98809 9.56944Z",})
As a convenience you can also import createIcon
from the icons
package along
with other icons:
import { createIcon, MoonIcon, SunIcon } from "@chakra-ui/icons"
Icon Button#
- We've unified the usage of all icon props to only accept a React element.
Update all icon names used in
icon
to the equivalent icon React element.
Replacement logic: If
icon
is<EmailIcon/>
from Chakra.
import { PhoneIcon } from "@chakra-ui/react"- <IconButton icon="phone">Call</IconButton>+ <IconButton icon={<PhoneIcon />}>Call</IconButton>
This reduces the effort needed to use custom icons, eliminates TypeScript errors, and reduces unused icons bloating your app.
- Renamed
variantColor
tocolorScheme
.
Skeleton#
Renamed colorStart
and colorEnd
props to startColor
and endColor
respectively.
Image#
Resolved SSR issue with Next.js. If you still run into issues, we recommend
using the Img
component which is a regular img
tag with support for Chakra
props.
Input#
When using InputAddon
, you no longer need to pass border radius properties to
the Input
. InputGroup
will intelligently detect the addon and apply the
necessary border to the input.
Link#
Due to accessibility reasons, we've deprecated the isDisabled
prop for Link
.
List#
Renamed stylePos
to stylePosition
Stack#
- To reduce the API surface area, we've deprecated the
isReversed
props in favor of thedirection
prop.
- <Stack isReversed>+ <Stack direction="row-reverse"><Box /><Box /></Stack>
- Added support for responsive
direction
andspacing
props.
<Stack spacing={["16px", "32px"]} direction={["column", "row"]}><Box /><Box /></Stack>
Menu#
- All popper related props that used to be passed to
MenuList
component, should now be passed toMenu
. - The
placement
prop has moved fromMenuList
toMenu
.
Modal#
Removed
addAriaLabels
andformatIds
props in favor of passing a top-levelid
prop to the modal.Removed
preserveScrollBarGap
prop. We preserve scroll bar gap by default to prevent any layout shift.Only pass
size
values defined in the components theme. Hard-coded values will be ignored. Update the styles intheme.components.Modal
to reflect your custom values.You can now disable focus trap by passing
trapFocus={false}
.Modal comes with preset transitions to make it easy for you. You can remove any existing
Scale
,ScaleFade
orSlideFade
components.
// before<SlideIn in={isOpen}>{(styles) => (<Modal onClose={onClose} isOpen><ModalOverlay opacity={styles.opacity} /><ModalContent pb={5} {...styles}><ModalHeader>Login now</ModalHeader><ModalCloseButton /><ModalBody><Lorem count={2} /></ModalBody></ModalContent></Modal>)}</SlideIn>// after<Modal motionPreset="slideInBottom" onClose={onClose} isOpen={isOpen}><ModalOverlay /><ModalContent pb={5}><ModalHeader>Login now</ModalHeader><ModalCloseButton /><ModalBody><Lorem count={2} /></ModalBody></ModalContent></Modal>
Progress#
Changed color
prop to colorScheme
.
- <Progress color="blue"/>+ <Progress colorScheme="blue"/>
CircularProgress#
trackColor
prop now takes a specific theme color or a validcss
color.- Changed the
thickness
prop to point to an actual thickness value inpx
(e.g.thickness={4}
)
- <CircularProgress value={59} size="100px" thickness={0.1} />+ <CircularProgress value={59} size="100px" thickness={10} />
Radio#
- Changed
variantColor
prop tocolorScheme
.
- <Radio variantColor="blue">Option</Radio>+ <Radio colorScheme="blue">Option</Radio>
Deprecated the
isFullWidth
prop. TheRadio
takes up the width of its parent by default.Deprecated the
RadioButton
component. Use theuseRadio
hook to create custom radio buttons. Learn more about creating custom radio buttons.The
useRadio
hook is exported with state and focus management logic for use in creating tailor-made radio component for your application
RadioGroup#
Deprecated the
isFullWidth
prop. TheRadioGroup
takes up the width of the parent by default.Deprecated the
RadioButtonGroup
component. Use theuseRadioGroup
hook to control a group of custom radio buttons. Learn more about creating custom radio buttons.To allow for better Radio group layout, the
RadioGroup
component no longer supports every style prop. You can only passsize
,variant
, andcolorScheme
in addition toRadioGroup
props (value
,defaultValue
, andonChange
).
// before<RadioGroup isInline defaultValue="one"><Radio value="one">One</Radio><Radio value="two">Two</Radio><Radio value="three">Three</Radio></RadioGroup>// after<RadioGroup defaultValue="one"><Stack direction="row"><Radio value="one">One</Radio><Radio value="two">Two</Radio><Radio value="three">Three</Radio></Stack></RadioGroup>
- The
onChange
callback now returns the selectedvalue
not theevent
.
const [value, setValue] = React.useState("one")// before<RadioGroup value={value} onChange={e => setValue(e.target.value)}><Radio value="one">One</Radio><Radio value="two">Two</Radio><Radio value="three">Three</Radio></RadioGroup>// after<RadioGroup value={value} onChange={val => setValue(val)}><Stack direction="row"><Radio value="one">One</Radio><Radio value="two">Two</Radio><Radio value="three">Three</Radio></Stack></RadioGroup>
Slider#
- Update JSX structure: Wrap
SliderFilledTrack
withSliderTrack
.
// before<Slider defaultValue={30}><SliderTrack /><SliderFilledTrack /><SliderThumb /></Slider>// after<Slider defaultValue={30}><SliderTrack><SliderFilledTrack /></SliderTrack><SliderThumb /></Slider>
Switch#
Rename the color
prop to colorScheme
.
- <Switch color="blue"/>+ <Switch colorScheme="blue"/>
Tabs#
Change variantColor
prop to colorScheme
.
Tags#
- Change
variantColor
tocolorScheme
.
- <Tag variantColor="blue"/>+ <Tag colorScheme="blue"/>
- Added support for
isDisabled
prop on theTagCloseButton
component.
<Tag variant="solid" size="sm" colorScheme="cyan"><TagLabel>Tab Label</TagLabel><TagCloseButton isDisabled /></Tag>
- Default size was changed from
lg
tomd
.
Toast#
- Removed
react-spring
dependency in favor offramer-motion
. - Added support for duplicate toast prevention using
toast.isActive
method. - Added support to programmatically close one or all toasts using
toast.close
ortoast.closeAll
methods. - Added support to programmatically update a toast using
toast.update
method. - Added support for
onCloseComplete
prop, which is a callback function that is invoked when the toast closes.
Wrap (for rc
versions)#
- Children of
Wrap
must now be wrapped inWrapItem
. This makes it easy to customize theWrapItem
using thesx
prop.
// before<Wrap spacing="30px"><Center w="180px" h="80px" bg="red.200">Box 1</Center><Center w="180px" h="80px" bg="green.200">Box 2</Center><Center w="180px" h="80px" bg="tomato">Box 3</Center></Wrap>// after<Wrap spacing="30px"><WrapItem><Center w="180px" h="80px" bg="red.200">Box 1</Center></WrapItem><WrapItem><Center w="180px" h="80px" bg="green.200">Box 2</Center></WrapItem><WrapItem><Center w="180px" h="80px" bg="tomato">Box 3</Center></WrapItem></Wrap>
Transition Components#
All transition components like Collapse
, Fade
, SlideFade
, etc. use the
in
prop to trigger its transition/animation, instead of isOpen
. Change the
isOpen
prop to in
CSS Reset#
- Removed the
config
prop, in favor of adding global styles totheme.styles.global
. - If you want to remove focus for non-keyboard interactions, install the
focus-visible
package.
yarn add focus-visible# ornpm install focus-visible# at the root of your applicationimport "focus-visible/dist/focus-visible"
Hooks#
useDisclosure
now acceptsobject
instead ofboolean
as initial values.
- const { isOpen, onToggle } = useDisclosure(true);+ const { isOpen, onToggle } = useDisclosure({defaultIsOpen: true});
That's it! Welcome to Chakra UI v1 🥳.
If you still experience issues after migrating, feel free to create an issue or join our Discord chat here: https://discord.gg/dQHfcWF