chakra-ui / chakra-ui-docs

Documentation website for chakra ui
https://chakra-ui.com
MIT License
301 stars 477 forks source link

Documentation Update for Component Style on the use of "createStylesContext" #1522

Open locchuong opened 1 year ago

locchuong commented 1 year ago

Subject

Styling Multipart Components

Description

The current documentation for "Styling Multipart Components" is as follows:

// 1. Import the components and hook
import {
  createStylesContext,
  useMultiStyleConfig,
  useStyles,
} from '@chakra-ui/react'

function Menu(props) {
  const { size, variant, children, ...rest } = props

  // 2. Consume the `useMultiStyleConfig` hook
  const styles = useMultiStyleConfig('Menu', { size, variant })
  const [ StylesProvider ] = createStylesContext('Menu');

  return (
    <Flex __css={styles.menu} {...rest}>
      {/* 3. Mount the computed styles on `StylesProvider` */}
      <StylesProvider value={styles}>{children}</StylesProvider>
    </Flex>
  )
}

function MenuItem(props) {
  // 4. Read computed `item` styles from styles provider
  const styles = useStyles()
  return <Box as='button' __css={styles.item} {...props} />
}

The issue with the documentation is that createStylesContext("Menu") is called inside of the Menu component, when it should really be called outside. Due to this, the useStyles hook called in the MenuItem component comes from the library, rather than the createStylesContext method.

If you try to run the code from the documentation, you will see the following error message:

ContextError: useStyles: `styles` is undefined. Seems you forgot to wrap the components in `<StylesProvider />`

I suggest the following:

// 1. Import the components and hook
import {
  createStylesContext,
  useMultiStyleConfig,
} from '@chakra-ui/react'

const [ StylesProvider , useStyles] = createStylesContext('Menu');

function Menu(props) {
  const { size, variant, children, ...rest } = props

  // 2. Consume the `useMultiStyleConfig` hook
  const styles = useMultiStyleConfig('Menu', { size, variant })

  return (
    <Flex __css={styles.menu} {...rest}>
      {/* 3. Mount the computed styles on `StylesProvider` */}
      <StylesProvider value={styles}>{children}</StylesProvider>
    </Flex>
  )
}

function MenuItem(props) {
  // 4. Read computed `item` styles from styles provider
  const styles = useStyles()
  return <Box as='button' __css={styles.item} {...props} />
}

This caused a lot of headache for me 😅 , so hopefully this helps others who may be running into the same issue!

stale[bot] commented 1 year ago

Hi! This issue has been automatically marked as stale because lack of recent activity. It will be closed if no further activity occurs within 5 days. Thank you for your contributions.