import clsx from 'clsx' import { type FC, useId, useMemo } from 'react' import { match } from 'ts-pattern' import styles from './Skeleton.module.css' type Variant = 'box' | 'circle' | 'text' type CommonProps = { variant: Variant startColor?: string endColor?: string } type BoxProps = CommonProps & { variant: 'box' width: string height: string } type CircleProps = CommonProps & { variant: 'circle' size: string } type TextProps = CommonProps & { variant: 'text' noOfLines: number gap?: number } const Text: FC = ({ noOfLines, gap, startColor, endColor }) => { const id = useId() const keys = useMemo( () => Array.from({ length: noOfLines }, (_, idx) => `${id}-${idx}`), [id, noOfLines], ) const vars: Record = { ...(startColor ? { ['--skeleton-start']: startColor } : {}), ...(endColor ? { ['--skeleton-end']: endColor } : {}), } return (
{keys.map((key) => (
))}
) } type Props = BoxProps | CircleProps | TextProps export const Skeleton: FC = (props) => { return match(props) .with({ variant: 'box' }, ({ width, height, startColor, endColor }) => { const vars: Record = { ...(startColor ? { ['--skeleton-start']: startColor } : {}), ...(endColor ? { ['--skeleton-end']: endColor } : {}), } return (
) }) .with({ variant: 'circle' }, ({ size, startColor, endColor }) => { const vars: Record = { ...(startColor ? { ['--skeleton-start']: startColor } : {}), ...(endColor ? { ['--skeleton-end']: endColor } : {}), } return (
) }) .with({ variant: 'text' }, (props) => { return }) .exhaustive() }