🎨
[Chakra UI] MenuButton に as で指定したコンポーネントの props を使えるようにする
こんにちは、よしお (@yoshio__25) です。
Chakra UI の Menu
を使うとき、ドキュメントには以下のような使い方が書かれています。
<Menu>
<MenuButton
as={ Button }
rightIcon={ <ChevronDownIcon /> }
>
Actions
</MenuButton>
<MenuList>
<MenuItem>Download</MenuItem>
<MenuItem>Create a Copy</MenuItem>
<MenuItem>Mark as Draft</MenuItem>
<MenuItem>Delete</MenuItem>
<MenuItem>Attend a Workshop</MenuItem>
</MenuList>
</Menu>
しかし実際にエディタ上で入力していくと、補完が効かず不便を強いられることがありました。
Chakra UI でも過去に Issue で取り上げられています。
そこで今回は as
にコンポーネントを指定したときに、そのコンポーネントの props の補完が効くようにする方法を紹介します。
事前準備
直接 Chakra UI の型定義を編集するわけにはいかないので、まずは中間層を実装します。
import {
MenuButton as ChakraMenuButton,
MenuButtonProps as ChakraMenuButtonProps,
} from '@chakra-ui/react';
type Props = ChakraMenuButtonProps;
const MenuButton = function MenuButton(props: Props) {
const {
...other
} = props;
return (
<ChakraMenuButton
{ ...other }
/>
);
};
export default MenuButton;
しかし、これではまだ状況は何も変わりません。
解決方法
そこで補完が効くように as
のコンポーネントの props の型定義を抽出して、この中間層のコンポーネントに仕込んでいきます。
props の型定義の抽出は React の ComponentProps
が利用できます。
import {
MenuButton as ChakraMenuButton,
MenuButtonProps as ChakraMenuButtonProps,
} from '@chakra-ui/react';
+ import {
+ ComponentProps,
+ ElementType,
+ } from 'react';
- type Props = ChakraMenuButtonProps;
+ type Props<C extends ElementType<any>> =
+ & ChakraMenuButtonProps
+ & ComponentProps<C>;
- const MenuButton = function MenuButton(props: Props) {
+ const MenuButton = function MenuButton<C extends ElementType<any>>(props: Props<C>) {
const {
...other
} = props;
return (
<ChakraMenuButton
{ ...other }
/>
);
};
export default MenuButton;
そして MenuButton
はこの中間層のコンポーネントを利用すると、以下のように補完が効かせられるようになります。
まとめ
Chakra UI の MenuButton
ですが、そのまま利用しても as
で指定したコンポーネントの props の補完が効きませんでした。そこで中間層のコンポーネントを作成し、コンポーネントの props を抽出するようにすることで、補完を効かせられるようにできます。
Discussion