はじめに
最新のchakra ui v3をインストールし、ビルドすると上記のエラーが出たので解決策をまとめます。
問題
vite環境でのセットアップを完了させ、npm run build
をするとtoasetr.tsx
ファイルでエラーが出ました。
"use client";
import {
Toaster as ChakraToaster,
Portal,
Spinner,
Stack,
Toast,
createToaster,
} from "@chakra-ui/react";
export const toaster = createToaster({
placement: "bottom-end",
pauseOnPageIdle: true,
});
export const Toaster = () => {
return (
<Portal>
<ChakraToaster toaster={toaster} insetInline={{ mdDown: "4" }}>
{(toast) => (
<Toast.Root width={{ md: "sm" }}>
{toast.type === "loading" ? (
<Spinner size="sm" color="blue.solid" />
) : (
<Toast.Indicator />
)}
<Stack gap="1" flex="1" maxWidth="100%">
{toast.title && <Toast.Title>{toast.title}</Toast.Title>}
{toast.description && (
<Toast.Description>{toast.description}</Toast.Description>
)}
</Stack>
{toast.action && (
<Toast.ActionTrigger>{toast.action.label}</Toast.ActionTrigger>
)}
{toast.meta?.closable && <Toast.CloseTrigger />}
</Toast.Root>
)}
</ChakraToaster>
</Portal>
);
};
エラー文はこちらです。
Type '{ children: (toast: any) => Element; toaster: any; insetInline: { mdDown: string; }; asChild: boolean; }' is not assignable to type 'IntrinsicAttributes & ToasterProps'. Property 'children' does not exist on type 'IntrinsicAttributes & ToasterProps'.
要約すると、toaster.tsx
ではchildrenを渡す際に関数型children形式で ChakraToaster
に渡しているのに、定義がありません と怒られています。
import { Toaster as ChakraToaster ...
を基に、ネットでchakra uiのgithubや依存関係のフレームワークを辿っていくと、、
// chakra ui v3
// Toasterのexport宣言箇所
export declare const Toaster: React.FC<ToasterProps>;
// ---
// chakra ui v3
// ToasterPropsのexport宣言箇所
export interface ToasterProps
extends HTMLChakraProps<"div", ToasterBaseProps> {}
// ---
// ToasterBasePropsは chakra uiから ark uiを参照していたので
// ToasterBasePropsのexport宣言箇所
export interface ToasterBaseProps extends PolymorphicProps {}
// ---
// ark ui
// PolymorphicPropsのexport宣言箇所
export interface PolymorphicProps {
/**
* Use the provided child element as the default rendered element, combining their props and behavior.
*/
asChild?: boolean
}
最終まで追跡しても、関数型のchildren定義は存在しませんでした。
多分、issueをchakra uiに出してもよいかと思います。
解決方法
とりあえず、@chakra-ui/react
の既存の ToasterProps
を拡張し、関数型のchildrenをサポートする独自のインターフェースを作成することで解決しました。
元々、ChakraToaster
にpropとして渡していた insetInline
は Toast.Root
にpropsとして渡すように変更しました。
/* eslint-disable @typescript-eslint/no-explicit-any */
"use client";
import {
ToasterProps as ChakraToasterProps,
Toaster as ChakraToasterBase,
Portal,
Spinner,
Stack,
Toast,
createToaster,
CreateToasterReturn,
} from "@chakra-ui/react";
import { FC, ReactElement } from "react";
interface CustomChakraToasterProps extends ChakraToasterProps {
children?: (toast: any) => ReactElement;
toaster: ReturnType<typeof CreateToasterReturn>; // createToaster の戻り値の型
}
export const ChakraToasterWithType =
ChakraToasterBase as FC<CustomChakraToasterProps>;
export const toaster = createToaster({
placement: "bottom-end",
pauseOnPageIdle: true,
});
export const Toaster = () => {
return (
<Portal>
<ChakraToasterWithType toaster={toaster}>
{(toast) => (
<Toast.Root width={{ md: "sm" }} insetInline={{ mdDown: "4" }}>
{toast.type === "loading" ? (
<Spinner size="sm" color="blue.solid" />
) : (
<Toast.Indicator />
)}
<Stack gap="1" flex="1" maxWidth="100%">
{toast.title && <Toast.Title>{toast.title}</Toast.Title>}
{toast.description && (
<Toast.Description>{toast.description}</Toast.Description>
)}
</Stack>
{toast.action && (
<Toast.ActionTrigger>{toast.action.label}</Toast.ActionTrigger>
)}
{toast.meta?.closable && <Toast.CloseTrigger />}
</Toast.Root>
)}
</ChakraToasterWithType>
</Portal>
);
};
おわりに
他のQiita記事でも解決策は載っていたのですが、なぜそれで解決されるのかが明記されておらず、今回は調査することにしました。きちんと理解することが大事だと思っています。
有名なフレームワークでもバグは存在するということが勉強になりました!
ひとまず chakra ui の git に issue を上げようと思います。
参考