Skip to content

Chakra Tips

Segun Adebayo edited this page Nov 28, 2022 · 5 revisions

Tooltip and Fullscreen API

The fullscreen API narrows the DOM to the element that requested fullscreen. Because the Portal is appended to the document.body and the requesting element is within it, the tooltip doesn't show up (but it's the DOM)

To fix this, pass portal-specific props to the tooltip to tell it what element it should append to.

<Tooltip label="should always be visible" portalProps={{ containerRef: ref }}>
    <Button onClick={fullscreenAction.toggle}>Toggle</Button>
</Tooltip>

Token Generation for PNPM

Unfortunately, this is something we can't fix on our end.

To fix this, you can either:

  • Install the styled-system package
  • Specify the --out parameter, create a d.ts and use declaration merging
import { BaseThemeTypings } from "@chakra-ui/styled-system";
import { Tokens } from "../path/to/d.ts"
  
declare module "@chakra-ui/styled-system" {
    export interface CustomThemeTypings extends BaseThemeTypings, Tokens { }
}

Composing Tooltip and Popover

Due to the way refs are forwarded in the Tooltip and Popover, you might run into issues where using the same button to show a tooltip and popover might not work.

Here's how to work around that

const ButtonWithTooltip = forwardRef((props, ref) => {
  const { label, ...rest } = props;
  return (
    <Tooltip label={label}>
      <IconButton
        ref={ref}
        size="sm"
        aria-label={label}
        icon={<AddIcon />}
        {...rest}
      />
    </Tooltip>
  );
});

const Component = () => {
  return (
    <Box padding="10">
      <Popover>
        <PopoverTrigger>
          <ButtonWithTooltip label="Give Feedback" />
        </PopoverTrigger>
        <PopoverContent>
          <PopoverArrow />
          <PopoverCloseButton />
          <PopoverHeader>Confirmation!</PopoverHeader>
          <PopoverBody>
            Are you sure you want to have that milkshake?
          </PopoverBody>
        </PopoverContent>
      </Popover>
    </Box>
  );
};

Working example: https://stackblitz.com/edit/nextjs-nk87b5?file=pages%2Findex.js

Scroll Selected Tab into view

function useScrollTabIntoView(index: number) {
  const tablistRef = useRef<HTMLDivElement>();

  useEffect(() => {
    const selectedTab = tablistRef.current.querySelector(
      "[role=tab][aria-selected]"
    );
    selectedTab?.scrollIntoView();
  }, [index]);

  return tablistRef;
}