見出し画像

ForwardRefをTypescriptで表現する方法について~chakraUIのツールチップを例に~

こんにちわ。nap5です。

今回は小ネタです。

ForwardRefをTypescriptで表現する方法について紹介したいと思います。ツールチップなどは親要素でも使えるように自身のDOM参照を与える必要があるので、forwardRefを使用するユースケースにはマッチします。なので、今回の例に取り上げてみました。デモではchakraUIを使用しています。




デモコードです。



デモサイトです。


以下のようにForwardRefをTypescriptで表現してみました。zodなどうまく使うとスマートに書けるかもです。


オブジェクトリテラルの場合の型定義などは以下のライブラリからポートしてきています。以前の記事でも取り上げたmergicianライブラリになります。

https://github.com/jhildenbiddle/mergician/issues/1#issue-1325247409


定義する側

import {Box, Tag} from '@chakra-ui/react';
import {forwardRef, ForwardedRef} from 'react';

type ObjectLiteral = Record<any, any>;

type Props = {
  children: React.ReactNode;
  rest?: ObjectLiteral[];
};

const CustomCard = (
  {children, ...rest}: Props,
  ref: ForwardedRef<HTMLSpanElement>
) => {
  return (
    <Box p="1">
      <Tag ref={ref} {...rest}>
        {children}
      </Tag>
    </Box>
  );
};

export default forwardRef(CustomCard);


使用する側

import {Box, HStack, Stack} from '@chakra-ui/react';
import {Tooltip} from '@chakra-ui/react';
import CustomCard from '@/components/CustomCard';

export default function Home() {
  return (
    <Box className="max-w-[30rem] mx-auto w-full overflow-hidden p-2">
      <Stack spacing={6}>
        <HStack spacing={12}>
          <Tooltip label="Hover me" hasArrow bg="red.600">
            <CustomCard data-a={'aaa'} data-b={'bbb'}>
              Tag Here
            </CustomCard>
          </Tooltip>
          <Tooltip label="Hover me" hasArrow bg="green.600" placement="right">
            <CustomCard data-a={'aaa'} data-b={'bbb'}>
              Tag Here
            </CustomCard>
          </Tooltip>
        </HStack>
        <HStack spacing={12}>
          <Tooltip label="Hover me" hasArrow bg="blue.600">
            <CustomCard data-a={'aaa'} data-b={'bbb'}>
              Tag Here
            </CustomCard>
          </Tooltip>
          <Tooltip label="Hover me" hasArrow bg="orange.600">
            <CustomCard data-a={'aaa'} data-b={'bbb'}>
              Tag Here
            </CustomCard>
          </Tooltip>
        </HStack>
      </Stack>
    </Box>
  );
}


joyから提供されているツールチップでもやってみました。


デモコードです。


デモサイトです。

https://react-nextjs-tailwind-joy-tooltip.onrender.com/


簡単ですが、以上です。

いいなと思ったら応援しよう!