import React from 'react'; import clsx from 'clsx'; type SpinnerSize = 'xs' | 'sm' | 'lg'; export interface SpinnerProps extends React.HTMLAttributes { size?: SpinnerSize | number | string; label?: string | null; isDecorative?: boolean; } function toSpinnerSize(size: SpinnerProps['size']) { if (size === undefined) return { dataSize: 'sm' }; if (size === 'xs' || size === 'sm' || size === 'lg') { return { dataSize: size }; } if (typeof size === 'number') return { customSize: `${size}px` }; return { customSize: size }; } export function Spinner({ size = 'sm', label = null, isDecorative = false, className, style, 'aria-label': ariaLabelProp, ...props }: SpinnerProps) { const sizeProps = toSpinnerSize(size); const hasLabel = !isDecorative && typeof label === 'string' && label.length > 0; const ariaLabel = isDecorative ? undefined : ariaLabelProp ?? (typeof label === 'string' && label.length > 0 ? label : 'Loading'); const mergedStyle = { ...style, ...(sizeProps.customSize ? ({ '--spinner-size': sizeProps.customSize } as React.CSSProperties) : {}), }; return (
{hasLabel && {label}}
); }