Search code examples
javascriptcssreactjscanvaschakra-ui

React chakra ui canvas width and height initializing to zero and unable to render?


Here is the codesandbox link

And here is the code

import "./styles.css";
import {
  Flex,
  Tab,
  TabList,
  TabPanel,
  TabPanels,
  Tabs
} from "@chakra-ui/react";
import { SketchField, Tools } from "react-sketch";

export default function App() {
  return (
    <Flex height="100vh" width="100vw">
      <Tabs width="100%" display="flex" flexDirection="column" defaultIndex={0}>
        <TabList>
          {["Play", "Draw"].map((val) => (
            <Tab key={Math.random()}>{val}</Tab>
          ))}
        </TabList>
        <TabPanels flex="1 1 auto">
          <TabPanel padding={0} height="100%">
            <h1>Hello world </h1>
          </TabPanel>
          <TabPanel padding={0} height="100%">
            <Flex height="100%" width="100%">
              <SketchField
                width="100%"
                height="100%"
                widthCorrection={0}
                tool={Tools.Pencil}
                lineColor="#3182CE"
                lineWidth={3}
              />
            </Flex>
          </TabPanel>
        </TabPanels>
      </Tabs>
    </Flex>
  );
}

I am trying to have two tabs; the first tab shows "Hello World" while the second tab has a canvas element(I am using react-sketch). However, when I click the second tab, the canvas element is not being rendered. For some reason, its width and height are zero. I initially thought this was a problem with react-sketch, so I tried another canvas component(react-canvas-draw), the same problem persists with that component. So this is most likely an issue with how Chakra UI tabs work or how react renders things.

How to fix this? I want to let my canvas component take the "remaining height and width" which is why I am using things like '100%' as opposed to vh or vw since I don't know the height or width that would be remaining for my canvas component.

Note: However one interesting thing I've noticed is that if you changed defaultIndex to 1(i.e., make the second tab initially active), the canvas component works. Not sure why this works and the other way doesn't.


Solution

  • I don't know what purpose you're wrapping the element with <Flex> at line26, but remove that and it'll work.

    Update: my bad. I was confused with the sandbox refresh mechanism and thought above worked.

    Actually, it looks like html canvas is not catching up with the chakra UI tabs rendering. Add isLazy prop to Chakra <Tabs> component.

    ref: https://chakra-ui.com/docs/disclosure/tabs#lazily-mounting-tab-panels