import { type JSX, splitProps, For, Show } from 'solid-js'; import { cn } from '../utils/cn'; export type SkeletonVariant = 'text' | 'rect' | 'circle'; export interface SkeletonProps extends JSX.HTMLAttributes { /** Shape preset. `text` = one or more lines; `rect` = a block; `circle` = * round. Omit for the bare, class-driven block (size it with utility classes * yourself — the original low-level usage). */ variant?: SkeletonVariant; /** CSS width (a number is treated as px). With a `variant` and no width it * fills its container (responsive); for `circle` it is the diameter. */ width?: string | number; /** CSS height (a number is treated as px). Defaults per variant. */ height?: string | number; /** `text` only: how many lines to render (the last is shorter). Default 1. */ lines?: number; } const len = (v?: string | number) => (typeof v === 'number' ? `${v}px` : v); const rounding = (variant?: SkeletonVariant) => variant === 'circle' ? 'rounded-full' : variant === 'text' ? 'rounded' : 'rounded-md'; function Skeleton(props: SkeletonProps) { const [local, rest] = splitProps(props, ['class', 'variant', 'width', 'height', 'lines', 'style']); const hasWidth = () => local.width != null; const hasHeight = () => local.height != null; // The responsive default applies only to the variant API; bare class-driven // usage is left untouched so `` keeps working. const fills = () => !hasWidth() && local.variant != null && local.variant !== 'circle'; const blockStyle = (shortLast: boolean): JSX.CSSProperties => { const style: JSX.CSSProperties = typeof local.style === 'object' && local.style ? { ...local.style } : {}; if (local.variant === 'circle') { const d = len(local.width) ?? len(local.height) ?? '2.5rem'; style.width = d; style.height = d; return style; } if (shortLast) style.width = '70%'; else if (hasWidth()) style.width = len(local.width); if (hasHeight()) style.height = len(local.height); else if (local.variant === 'text') style.height = '0.75rem'; return style; }; const block = (shortLast = false) => (
); const lineCount = () => (local.variant === 'text' ? Math.max(1, local.lines ?? 1) : 1); return ( 1} fallback={block()}>
{(_, i) => block(i() === lineCount() - 1)}
); } export { Skeleton };