Denner Luan
Denner Luan

Reputation: 49

Chakra UI does not work correctly for own components

Chakra works well in the pages folder, but when trying to use it in the components folder, the problems start.

I added ChakraProvider to recognize the properties, so far so good, but the Accordion doesn't work, what is the correct way to make the accordion work on its own component?

I have the following folder structure:

src

"@chakra-ui/react": "^1.3.4",
"next": "10.0.8",
"react": "17.0.1",

pages/app.tsx

import { ChakraProvider } from '@chakra-ui/react';
import {AppProps} from 'next/app'
import guiaTheme from '../styles/theme';
import GlobalStyle from '../styles/global'

const MyApp: React.FC<AppProps> = ({ Component, pageProps }) => {
  return(
    <ChakraProvider theme={guiaTheme}>
      <Component {...pageProps} />
      <GlobalStyle/>
    </ChakraProvider>
  )
}

export default MyApp

pages/_document.tsx

import Document, { Html, Head, Main, NextScript, DocumentInitialProps, DocumentContext } from 'next/document'
import { ServerStyleSheet } from 'styled-components'
import Header from '../components/Header'
import Footer from '../components/Footer'

class MyDocument extends Document {
  static async getInitialProps(ctx: DocumentContext): Promise<DocumentInitialProps> {
    const sheet = new ServerStyleSheet()
    const originalRenderPage = ctx.renderPage

    try {
      ctx.renderPage = () =>
        originalRenderPage({
          enhanceApp: (App) => (props) =>
            sheet.collectStyles(<App {...props} />),
        })

      const initialProps = await Document.getInitialProps(ctx)
      return {
        ...initialProps,
        styles: (
          <>
            {initialProps.styles}
            {sheet.getStyleElement()}
          </>
        ),
      }
    } finally {
      sheet.seal()
    }
  }

  render() {
    return (
      <Html lang="pt">
        <Head />
        <body>
          <Header/>
          <Main />
          <Footer/>
          <NextScript />
        </body>
      </Html>
    )
  }
}

export default MyDocument

Here's the problem. components/Footer/index.tsx

import { ChakraProvider, Center, Img, Box, HStack, VStack, Heading } from '@chakra-ui/react'
import {Accordion, AccordionItem, AccordionButton, AccordionIcon, AccordionPanel} from '@chakra-ui/accordion'
import guiaTheme from '../../styles/theme';

function Footer() {
  return (
    <ChakraProvider theme={guiaTheme}>
      <Box as="footer" bg="guiared.600">
        <VStack>
          <Center py={2}>
            <Img src="header-logo.png" alt="Teste" height="39" />
          </Center>
          <HStack justify="center">
            <Img src="/appstore-icon.png" srcSet="/appstore-icon.png 1x, /[email protected] 2x" />
            <Img src="/googleplay-icon.png" srcSet="/googleplay-icon.png 1x, /[email protected] 2x" />
          </HStack>
        </VStack>

        <Accordion>
          <AccordionItem>
            <Heading>
              <AccordionButton>
                <Box flex="1" textAlign="left">
                  Section 1 title
                </Box>
                <AccordionIcon />
              </AccordionButton>
            </Heading>
            <AccordionPanel pb={4}>
              Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
              tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
              veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
              commodo consequat.
            </AccordionPanel>
          </AccordionItem>

          <AccordionItem>
            <h2>
              <AccordionButton>
                <Box flex="1" textAlign="left">
                  Section 2 title
                </Box>
                <AccordionIcon />
              </AccordionButton>
            </h2>
            <AccordionPanel pb={4}>
              Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
              tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
              veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
              commodo consequat.
            </AccordionPanel>
          </AccordionItem>
        </Accordion>

      </Box>
    </ChakraProvider>
  );
}

export default Footer;

Upvotes: 2

Views: 3329

Answers (2)

princess_hacker
princess_hacker

Reputation: 575

Your ChakraProvider needs to wrap App, and nothing else. It provides "access" to Chakra for the entire app.

Upvotes: 1

Benja Oliva
Benja Oliva

Reputation: 40

I can imagine all the app is wrapped on the MyApp component at pages folder...

You should wrap chakra components only on one ChakraProvider, your Footer component has his own ChakraProvider but is wrapped by the MyApp ChakraProvider as well.

Upvotes: 1

Related Questions