Búsqueda de sitios web

reactjs - Evitando valores nulos en los controles de Storybook


Estoy usando class-variance-authority para crear variantes de botones y luego inferir tipos a partir de esto para las propiedades del botón:

const variants = cva(
  {
    variants: {
      intent: {
        primary: [
          ...
        ],
        secondary: [
          ...
        ],
        ghost: [
          ...
        ],
      },
      size: {
        ...
      },
    },
    defaultVariants: {
      intent: "primary",
      size: "md",
    },
  }
);

type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> &
  VariantProps<typeof variants>

esto funciona bien en la aplicación. Puedo agregar la propiedad intent al botón o usar la predeterminada.

Pero en Storybook, bajo controles para intención obtengo variantes de cva y valor nulo.

captura de pantalla del storybook

Si elijo null, mi botón no tiene ninguno de los estilos de las variantes (tenía la impresión de que volvería a la predeterminada).
Para evitar null, tengo que agregar un tipo adicional bajo las propiedades del botón, y con eso básicamente sobrescribo el que se infiere de cva.

Entonces, ¿cómo puedo obtener un valor de respaldo al hacer clic en null, o cómo no ver el valor null en absoluto sin sobrescribir el tipo inferido de cva

cuando agrego a las propiedades de mi botón

type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> &
  VariantProps<typeof variants> & {
     intent?: string;
  };

el valor nulo ha desaparecido

Respuesta #1

Dejé una consulta en el GitHub de cva y recibí la respuesta a continuación. https://github.com/joe-bell/cva/issues/253

Creo que habrá un parche pronto, amigos.

O, aquí también hay una alternativa. eliminar null o undefined de las propiedades de un tipo

Respuesta #2

Una solución que se me ha ocurrido es crear un tipo de utilidad VariantProp personalizado que excluya el tipo null. Aquí está cómo:

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>>;

Aquí hay un ejemplo:

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;
  };

También puedes ir más allá para excluir undefined si quieres, pasar una variante por defecto a cva O usar react-docgen-typescript en su lugar. Consulta la configuración de Storybook - https://storybook.js.org/docs/configure/typescript

Como se mencionó, el problema se solucionará en el futuro, así que estén atentos (https://github.com/joe-bell/cva/issues/253#issuecomment-1882982172)