github chakra-ui/chakra-ui @chakra-ui/core
[Pre-release] Chakra UI V1

latest releases: @chakra-ui/system@2.6.2, @chakra-ui/styled-system@2.9.2, @chakra-ui/storybook-addon@5.1.0...
pre-release3 years ago

Chakra UI v1.0 🎉

A simple guide to upgrade your existing Chakra UI projects to v1.0.

Chakra UI v1.0 is focused on improving the ideas and concepts from 0.x to make
even easier to create, theme, and extend components.

While there's quite a number of new exciting features we've added, we focused on
making Chakra UI a stable base to build your own design systems on, so that you
can 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 or locally using a chakra factory function.

Color mode improvement: We've fixed the bugs related to Color mode and it's
now easy 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, etc. will
support the as prop and types will be extracted properly.

Theme-aware css prop: Just like theme-ui, we've added a __css prop you
can use to add theme-aware styles.

Upgrade steps

Here's a list of steps to take in order to migrate your project safely. Don't
worry if your styles aren't exactly the same—this is to be expected.

1. Update your dependencies

Chakra no longer requires @emotion/styled, @emotion/core and
@emotion/theming. If you're not using these libraries in your code, you can
safely remove them and update Chakra UI to v1.

We use only @emotion/core internally.

"dependencies": {
  "@chakra-ui/core": "1.0.0-beta",
-  "@emotion/styled": "10.X",
-  "@emotion/theming": "10.x",
-  "@emotion/core": "10.x"
}

Note on bundle size: Chakra UI now exports all components as separate
packages to make it easier to consume individual packages. For example, if you
use only Button, you can now install @chakra-ui/button along side its peer
dependency @chakra-ui/system, and you're good to go!

2. Clone Chakra's default theme (Work in Progress)

Chakra no longer comes with the default theme pre-installed, so you'll need to
add it manually. Luckily for you, we've added a CLI tool for generating the
theme.

We believe that having the theme cloned to your project will help you learn
about the theme tokens (colors, fonts, component styles) and make it less
stressful for you to customize theme.


  1. Run npx chakra init --theme to clone the theme to your project. This
    creates a chakra folder with the default theme inside.
npx chakra-cli init --theme
  1. Update the ThemeProvider in your app's root by passing the theme prop.
import { ThemeProvider, CSSReset } from "@chakra-ui/core"
import theme from "./chakra"

function AppRoot() {
  return (
    <ThemeProvider theme={theme}>
      <CSSReset />
      <App />
    </ThemeProvider>
  )
}

3. 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
  • PortalManager: Manages portals and nested portals without using z-index
    in your application.
  • GlobalStyle: Provides the global styles defined in theme.styles.global
    to your application.
-  <ThemeProvider theme={theme}>
+    <ChakraProvider theme={theme}>
      <CSSReset />
      <App />
+    </ChakraProvider>
-  </ThemeProvider>

4. Rename variantColor to colorScheme

Fire up your "Find and Replace" tool in VSCode or IntelliJ. Find variantColor
and replace with colorScheme.

Reason: We named this prop to make it easier to understand that this prop
represents a visual color scheme, not a css color attribute.

5. 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. The size 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. Update these prop names

These style props still work but we recommend renaming them to the new prop.
We now show a console warning when you use any of these deprecated props.

Deprecated Prop New Prop
rounded borderRadius
roundedLeft borderLeftRadius
roundedRight borderRightRadius
roundedTop borderTopRadius
roundedTopLeft borderTopLeftRadius
roundedTopRight borderTopRightRadius
roundedBottomLeft borderBottomLeftRadius
roundedBottomRight borderBottomRightRadius
roundedBottom borderBottomRadius
bgImg bgImage
bgPos bgPosition
shadow boxShadow
listStyleImg listStyleImage
listStylePos listStylePosition

Component Updates

We've updated the API of some components to fix bugs and improve usability,
types and accessibility.

  • All components now take the pseudo style props (_hover, _active, etc.)
  • Improved TypeScript support for the as prop

Accordion

Can install as a stand-alone package: @chakra-ui/accordion

Changes

  • Update all imports of AccordionHeader to AccordionButton. This is to
    remove the notion that it's a header when it's actually a button.
- import { AccordionHeader } from "@chakra-ui/core"
+ import { AccordionButton } from "@chakra-ui/core"

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 within
    Accordion. We think most users don't do this by default but it's worth
    noting.

Features

Keyboard Navigation: Accordion now supports keyboard navigation between
accordion buttons. Pressing the up and down arrow keys will move focus
between accordion buttons.

AspectRatioBox

  • Change all imports of AspectRatioBox to AspectRatio
- import { AspectRatioBox } from "@chakra-ui/core"
+ import  { AspectRatio } from "@chakra-ui/core"

Avatar

Features

  • You can now use a custom fallback avatar icon by passing the icon prop:
<Avatar src="john.png" name="John Doe" icon={<UserIcon />} />
  • You can now change the borderRadius of the avatar

  • Theming Support: All design decisions for the Avatar are located in
    chakra/components/Avatar in your cloned theme, which means you can customize
    the styles to suit your brand needs.

  • Added getInitials prop to allow users to manage how initials are generated
    from name. By default we merge the first characters of each word in the name
    prop.

Breadcrumb

  • Removed support for the addSeparator prop

Button

Changes

  • We've unified the usage of all icon props to only accept a React element.
    Update all icon names used in leftIcon or rightIcon to the equivalent icon
    React element.

    Replacement logic: If leftIcon is email, then replace it with
    <EmailIcon/> from Chakra.

import { PhoneIcon } from "@chakra-ui/core"

- <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 to colorScheme

Features

  • Added support for custom spinners using the spinner prop
import { BeatLoader } from "react-spinners"

function Example() {
  return (
    <Button isLoading colorScheme="blue" spinner={<BeatLoader color="white" />}>
      Click me
    </Button>
  )
}

Checkbox

Changes

  • Change variantColor to colorScheme
- <Checkbox variantColor="blue">Option</Checkbox>
+ <Checkbox colorScheme="blue">Option</Checkbox>
  • Deprecated the isFullWidth prop. Checkbox now takes up the width of the
    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, and
    colorScheme in addition to CheckboxGroup-specific props (value,
    defaultValue, and onChange).

// 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
using SimpleGrid or made to wrap automatically using Wrap.

Features

  • Added the iconColor and iconSize props to customize the default check icon
<Checkbox iconColor="blue" iconSize="1rem">
  Option
</Checkbox>
  • Added the spacing prop to customize the spacing between the checkbox and
    label text
<Checkbox spacing="1rem">Option</Checkbox>
  • The useCheckbox hook is exported with state and focus management logic for
    use in creating tailor-made checkbox component for your application

  • The useCheckboxGroup hook is exported with state management logic for use in
    creating tailor-made checkbox group component for your application

ColorMode

  • You can now set the initial color mode you want your application to start
    with. Set theme.config.initialColorMode to light or dark

    const theme = {
      config: {
        initialColorMode: "dark",
      },
    }
  • You can now update the color mode based on your user's device preference. Set
    theme.config.useSystemColorMode to true or false

    const theme = {
      config: {
        useSystemColorMode: true,
      },
    }

Bug Fix

  • Color mode now persists correctly when you refresh the page. All you need to
    do is add InitialColorMode script as the first child of body.

    Here's how to add it for Next.js:

// pages/_app.js
import { InitialColorMode } from "@chakra-ui/core"

export default class Document extends NextDocument {
  static async getInitialProps(ctx) {
    const initialProps = await NextDocument.getInitialProps(ctx)
    return { ...initialProps }
  }

  render() {
    return (
      <Html>
        <Head />
        <body>
          {/* 👇 Here's the script */}
          <InitializeColorMode />
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}

Here's how to add it for Gatsby:

// gatsby-ssr.js
export const onRenderBody = ({ setPreBodyComponents }) => {
  setPreBodyComponents([<InitializeColorMode key="chakra-ui-no-flash" />])
}

You can also install the
gatsby-plugin-chakra-ui
package which automatically configures InitializeColorMode along with
ChakraProvider.

FormControl

  • We've improved the accessibility of the FormControl component. Here are the
    changes:

    • id passed to the form control will be passed to the form input directly
    • FormLabel will have htmlFor that points to the id of the form input
    • FormErrorMessage adds aria-describedby and aria-invalid pointing to
      the form input
    • FormHelperText adds/extends aria-describedby pointing to the form input
    • isDisabled, isRequired, isReadOnly props passed to FormControl will
      cascade across all related components
  • FormLabel is now aware of the disabled, focused and error state of the
    form input. This helps you style the label accordingly using the _disabled,
    _focus, and _invalid style props.

  • If you render FormErrorMessage and isInvalid is false or undefined,
    FormErrorMessage won't be visible. The only way to make it visible is by
    passing isInvalid and setting it to true.

Image

Bug Fixes

  • Resolved the common SSR issue with Next.js

Features

  • Added support for the fit prop to specify how to fit an image within its
    dimension. It uses the object-fit property

  • Added support for the align prop to specify how to align the image within
    its dimension. It uses the object-position property

  • Added support for custom fallback component

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.

  • Input now uses paddingY instead of height for its block height.

Link

  • Due to accessibility reasons, we've deprecated the isDisabled prop for
    Link.

Stack

  • To reduce the API surface area, we've deprecated the isInline and
    isReversed props in favor of the direction prop
- <Stack isInline>
+ <Stack direction="row">
    <Box />
    <Box />
  </Stack>
  • We've deprecated the shouldWrapChildren prop because we now use css to
    manage the stack rather than React.cloneElement

  • Added support for responsive direction and spacing props

<Stack direction={["column", "row"]}>
  <Box />
  <Box />
</Stack>
  • Added support for divider prop between stacked element. Dividers also work
    with responsive direction and spacing.
<Stack divider={<StackDivider />}>
  <Box />
  <Box />
</Stack>
  • You can also use the HStack and VStack components to conveniently stack
    elements in the horizontal or vertical directions respectively.

Menu

Features

  • Added support for nested menus or submenus
const PreferencesMenu = forwardRef((props, ref) => {
  return (
    <Menu>
      <MenuButton ref={ref} {...props}>
        Preferences
      </MenuButton>
      <MenuList>
        <MenuItem>Settings</MenuItem>
        <MenuItem isDisabled>Extensions</MenuItem>
        <MenuSeparator />
        <MenuItem>Keyboard shortcuts</MenuItem>
      </MenuList>
    </Menu>
  )
})

function Example() {
  return (
    <Menu>
      <MenuButton>Code</MenuButton>
      <MenuList>
        <MenuItem>About Visual Studio Code</MenuItem>
        <MenuItem>Check for Updates...</MenuItem>
        <MenuSeparator />
        <MenuItem as={PreferencesMenu} />
      </MenuList>
    </Menu>
  )
}
  • Added support for menu icons and commands (or hotkeys)
<Menu>
  <MenuButton size="sm" colorScheme="teal">
    Open menu
  </MenuButton>
  <MenuList>
    <MenuItem command="⌘T">New Tab</MenuItem>
    <MenuItem command="⌘N">New Window</MenuItem>
    <MenuItem command="⌘⇧N">Open Closed Tab</MenuItem>
    <MenuItem command="⌘O">Open File...</MenuItem>
  </MenuList>
</Menu>
  • Support for menu transitions and animations

    It's important to use the css or sx prop for the transitions to work
    properly. For some reason, it doesn't work with the style native prop

<Menu>
  <MenuButton size="sm" colorScheme="teal">
    Open menu
  </MenuButton>
  <MenuTransition>
    {(styles) => (
      <MenuList css={styles}>
        <MenuItem command="⌘T">New Tab</MenuItem>
        <MenuItem command="⌘N">New Window</MenuItem>
        <MenuItem command="⌘⇧N">Open Closed Tab</MenuItem>
        <MenuItem command="⌘O">Open File...</MenuItem>
      </MenuList>
    )}
  </MenuTransition>
</Menu>
  • Added support for Portals. Wrap the MenuList in the Portal component and
    you're good to go!
<Menu>
  <MenuButton size="sm" colorScheme="teal">
    Open menu
  </MenuButton>
  <Portal>
    <MenuList>
      <MenuItem>Menu 1</MenuItem>
      <MenuItem>New Window</MenuItem>
      <MenuItem>Open Closed Tab</MenuItem>
      <MenuItem>Open File</MenuItem>
    </MenuList>
  </Portal>
</Menu>
  • Moved to Popper V2 🥳

Fixes

  • Fixed issue with as prop for MenuItem
  • Fixed issue with Link not navigating to the specified href value
  • Fixed issue where menu popper gets cut off when component is far right
  • Fixed issue where Menu throws if no MenuItem exist
  • Fixed issue where closeOnSelect doesn't work on navigation when using
    MenuItem as link

Modal

Changes

  • Removed addAriaLabels and formatIds props in favor of passing a top-level
    id prop to the modal, and we'll handle the rest.

  • Removed preserveScrollBarGap prop. We preserve scroll bar gap by default to
    prevent any layout shift.

  • Wrap ModalContent with the ModalOverlay component.

// before
<Modal>
-  <ModalOverlay />
  <ModalContent>
    <ModalHeader>Modal header</ModalHeader>
    <ModalCloseButton />
    <ModalBody>Modal body</ModalBody>
    <ModalFooter>Modal footer</ModalFooter>
  </ModalContent>
</Modal>

// after
<Modal>
+  <ModalOverlay>
    <ModalContent>
      <ModalHeader>Modal header</ModalHeader>
      <ModalCloseButton />
      <ModalBody>Modal body</ModalBody>
      <ModalFooter>Modal footer</ModalFooter>
    </ModalContent>
+  </ModalOverlay>
</Modal>
  • Only pass size values defined in the components theme. Hard-coded values
    will be ignored. Update the styles in theme.components.Modal to reflect your
    custom values

  • You can now disable focus trap by passing trapFocus={false}

New Props

  • trapFocus: to disable focus trap
  • autoFocus: to disable autofocus on the first interactive element
  • onOverlayClick: callback fired when the overlay is clicked
  • onEsc: callback fired when esc is pressed

NumberInput

  • Added example where consumers can format and parse number input values (
    #438)

  • Fixed issue where error is thrown if the input value is greater than the max
    prop when focus is blurred (
    #584)

  • Fixed issue where deleting sole digit sets value to 0 (which may be invalid) (
    #533)

  • Fixed issue where input returns NaN value after multiple dots (
    #364)

  • Fixed issue where passing id to NumberInput and adding a label with
    htmlFor that points to that id doesn't focus the input (
    #515)

Progress

  • Change color prop to colorScheme.
- <Progress color="blue"/>
+ <Progress colorScheme="blue"/>
  • Added Support for isIndeterminate prop in the Progress component

CircularProgress

  • trackColor prop now takes a specific theme color or a valid css color.
  • Change the thickness prop to point to an actual thickness value in px
    (e.g. thickness={4})

Radio

  • Change variantColor prop to colorScheme.
- <Radio variantColor="blue">Option</Radio>
+ <Radio colorScheme="blue">Option</Radio>
  • Deprecated the isFullWidth prop. The Radio takes up the width of the
    parent by default.

  • Deprecated RadioButton component. Use the useRadio hook to create 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. The RadioGroup takes up the width of the
    parent by default.

  • To allow for better Radio group layout, the RadioGroup component no longer
    supports every style prop. You can only pass size, variant, and
    colorScheme in addition to RadioGroup props (value, defaultValue, and
    onChange).

// 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>

Slider

  • Update JSX structure: Wrap SliderFilledTrack with SliderTrack.
// before
<Slider defaultValue={30}>
-  <SliderTrack />
-  <SliderFilledTrack />
  <SliderThumb />
</Slider>

// after
<Slider defaultValue={30}>
+  <SliderTrack>
+    <SliderFilledTrack />
+  </SliderTrack>
  <SliderThumb />
</Slider>
  • Added support for the isReversed prop, which allows users to reverse the
    direction and functionality of the slider. This is mostly useful for rtl
    purposes.

  • Added support for the onChangeEnd prop. Dragging the slider can trigger lots
    of updates and user might only be interested in the final result after sliding
    is complete.

  • Added isReadOnly prop to support cases where slider needs to be in read-only
    state.

  • Export the useSlider hook to help users manage and build custom slider UIs.

Popover

  • returnFocusOnClose has been changed to returnFocus for conciseness.

  • autoFocus prop to allow users to control whether the popover should
    automatically receive focus when it opens.

Stat

  • We improved the semantic HTML structure of the Stat components to use dl,
    dd, and dt tags.

Switch

  • Rename the color prop to colorScheme
-  <Switch color="blue"/>
+  <Switch colorScheme="blue"/>

Tabs

  • Change variantColor prop to colorScheme

Tags

  • Change variantColor to colorScheme
- <Tag variantColor="blue"/>
+ <Tag colorScheme="blue"/>
  • Added support for isDisabled prop on the TagCloseButton component
<Tag variant="solid" size="sm" colorScheme="cyan">
  <TagLabel>Tab Label</TagLabel>
  <TagCloseButton isDisabled />
</Tag>

Toast

  • Removed react-spring dependency in favor of react-transition-group
  • Added support for duplicate toast prevention using toast.isActive method
  • Added support to programmatically close one or all toasts using toast.close
    or toast.closeAll methods
  • Added support to programmatically update a toast using toast.update method.
  • Added support for onCloseComplete prop, a callback function to run side
    effects after the toast component has closed.

Tooltip

  • Added support for hideOnClick prop
  • Added support for hideOnMouseDown prop

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

Don't miss a new chakra-ui release

NewReleases is sending notifications on new releases.