{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "description": "A star rating that reads and writes a numeric value.",
  "docs": "Two steps after installing: import the copied stylesheet once at your app entry — it lands at `styles/liquefy-ui.css` — or `@import` it from your global CSS *before* `tailwindcss`, so Tailwind utilities keep winning over component styles. Then wrap the tree in `<LiquefyProvider>`, which is where every component reads its tokens from. Every copied file already carries its own 'use client' directive. Full documentation: https://liquefy-ui.com/#/docs/installation",
  "files": [
    {
      "content": "'use client'\n\nimport { forwardRef, useRef, useState, type HTMLAttributes } from 'react'\nimport { StarGlyph } from '@/lib/internal-glyphs'\nimport { useLiquefyConfig } from '@/lib/provider'\nimport { useLiquidStyles, type LiquidStyleProps } from '@/lib/styles-prop'\n\nexport type LiquidRatingProps = Omit<HTMLAttributes<HTMLDivElement>, 'defaultValue' | 'onChange'> & LiquidStyleProps & {\n  defaultValue?: number\n  label?: string\n  max?: number\n  onValueChange?: (value: number) => void\n  readOnly?: boolean\n  size?: 'sm' | 'md' | 'lg'\n  value?: number\n}\n\nconst starSizes = { lg: 26, md: 21, sm: 16 } as const\n\nexport const LiquidRating = forwardRef<HTMLDivElement, LiquidRatingProps>(({\n  className,\n  defaultValue = 0,\n  label = 'Rating',\n  max = 5,\n  onValueChange,\n  readOnly = false,\n  size = 'md',\n  style,\n  styles,\n  value,\n  ...props\n}, ref) => {\n  const config = useLiquefyConfig()\n  const starRefs = useRef<(HTMLButtonElement | null)[]>([])\n  const [internalValue, setInternalValue] = useState(defaultValue)\n  const [hovered, setHovered] = useState<number | null>(null)\n  const resolvedValue = value ?? internalValue\n  const displayValue = hovered ?? resolvedValue\n\n  const handleSelect = (starValue: number) => {\n    const nextValue = starValue === resolvedValue ? 0 : starValue\n    if (value === undefined) setInternalValue(nextValue)\n    onValueChange?.(nextValue)\n\n    if (config.motion === false) return\n    // Ripple a springy pop across every lit star so the rating fills with life.\n    if (nextValue === 0) {\n      starRefs.current[starValue - 1]?.animate(\n        [{ scale: '1' }, { scale: '0.7' }, { scale: '1' }],\n        { duration: 420, easing: 'cubic-bezier(0.2, 0.9, 0.25, 1)' },\n      )\n      return\n    }\n    for (let index = 0; index < nextValue; index += 1) {\n      starRefs.current[index]?.animate(\n        [{ scale: '1' }, { scale: '1.42' }, { scale: '0.88' }, { scale: '1.06' }, { scale: '1' }],\n        { delay: index * 45, duration: 520, easing: 'cubic-bezier(0.2, 0.9, 0.25, 1)' },\n      )\n    }\n  }\n\n  const root = useLiquidStyles('lq-rating', { className, style, styles })\n\n  return (\n    <div\n      aria-label={`${label}: ${resolvedValue} of ${max}`}\n      className={root.className}\n      data-liquid-size={size}\n      data-read-only={readOnly}\n      onPointerLeave={() => setHovered(null)}\n      ref={ref}\n      role={readOnly ? 'img' : undefined}\n      style={root.style}\n      {...props}\n    >\n      {Array.from({ length: max }, (_, index) => {\n        const starValue = index + 1\n        const active = starValue <= displayValue\n        if (readOnly) {\n          return (\n            <span className=\"lq-rating__star\" data-active={active} key={starValue}>\n              <StarGlyph size={starSizes[size]} />\n            </span>\n          )\n        }\n\n        return (\n          <button\n            aria-label={`${label}: ${starValue} of ${max}`}\n            aria-pressed={starValue === resolvedValue}\n            className=\"lq-rating__star\"\n            data-active={active}\n            key={starValue}\n            onClick={() => handleSelect(starValue)}\n            onPointerEnter={() => setHovered(starValue)}\n            ref={(node) => { starRefs.current[index] = node }}\n            type=\"button\"\n          >\n            <StarGlyph size={starSizes[size]} />\n          </button>\n        )\n      })}\n    </div>\n  )\n})\n\nLiquidRating.displayName = 'LiquidRating'\n",
      "path": "registry/liquid-rating.tsx",
      "type": "registry:ui"
    }
  ],
  "name": "liquid-rating",
  "registryDependencies": [
    "https://liquefy-ui.com/r/liquefy-ui.json",
    "https://liquefy-ui.com/r/internal-glyphs.json",
    "https://liquefy-ui.com/r/provider.json",
    "https://liquefy-ui.com/r/styles-prop.json"
  ],
  "title": "LiquidRating",
  "type": "registry:ui"
}
