reactjs - Evitando valor nulo nos controles do Storybook
Estou usando class-variance-authority para criar variantes de botão e, em seguida, inferindo tipos a partir disso para as propriedades do botão:
const variants = cva(
{
variants: {
intent: {
primary: [
...
],
secondary: [
...
],
ghost: [
...
],
},
size: {
...
},
},
defaultVariants: {
intent: "primary",
size: "md",
},
}
);
type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> &
VariantProps<typeof variants>
isso funciona bem no app. Consigo adicionar a propriedade intent ao botão ou usar a padrão como fallback.
Mas no Storybook, sob controles para intenção, eu recebo variantes do cva e valor nulo.
captura de tela do storybook
Se eu escolher nulo, meu botão não terá nenhum dos estilos das variantes (eu estava sob a impressão de que ele voltaria para o padrão).
Para evitar nulo, eu tenho que adicionar um tipo adicional nas propriedades do botão, e com isso basicamente sobrescrevo o que foi inferido a partir do cva.
Então, como posso obter um valor alternativo ao clicar em null, ou como não ver o valor null de forma alguma sem sobrescrever o tipo inferido de cva
quando eu adiciono às propriedades do meu botão
type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> &
VariantProps<typeof variants> & {
intent?: string;
};
o valor nulo desapareceu
Resposta #1
Deixei uma pergunta no GitHub do cva e recebi a resposta abaixo. https://github.com/joe-bell/cva/issues/253
Acho que haverá uma atualização em breve, amigos.
Ou, aqui está também uma alternativa. remover null ou undefined das propriedades de um tipo
Resposta #2
Uma solução que eu encontrei é criar um tipo utilitário personalizado VariantProp que exclui o tipo null. Aqui está como:
import { type VariantProp } from 'class-variant-authority';
type ExcludeNull<T> = { [P in keyof T]: Exclude<T[P], null> };
export type CustomVariantProp<Comp extends (...args: any) => any> = ExcludeNull<VariantProps<Comp>>;
Aqui está um exemplo:
const variants = cva(
{
variants: {
color: {
primary: 'bg-primary',
secondary: 'bg-secondary',
}
}
}
);
// ❌
type WierdWithStorybookControls = VariantProps<typeof variants>;
// -> { color: 'primary' | 'secondary' | null | undefined }
// ✅
type WorksWithStorybookControls = CustomVariantProps<typeof variants>;
// -> { color: 'primary' | 'secondary' | undefined }
type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> &
CustomVariantProps<typeof variants> & {
intent?: string;
};
Você também pode ir além para excluir undefined se quiser, passar uma variante padrão para cva OU usar react-docgen-typescript em vez disso. Veja a configuração do storybook - https://storybook.js.org/docs/configure/typescript
Como mencionado, o problema será corrigido no futuro, então fique atento (https://github.com/joe-bell/cva/issues/253#issuecomment-1882982172)
