{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "rating",
  "title": "Rating",
  "description": "stars · display (half stars, `showValue`, `count`) or input with `onChange` (44pt radio stars)",
  "dependencies": [
    "lucide-react-native@^1.21.0"
  ],
  "registryDependencies": [
    "@kit-native/icon",
    "@kit-native/lib-haptics",
    "@kit-native/lib-palette-context",
    "@kit-native/lib-utils",
    "@kit-native/text"
  ],
  "files": [
    {
      "path": "components/kit/rating.tsx",
      "content": "import { Icon } from '@/components/ui/icon';\nimport { Text } from '@/components/ui/text';\nimport { haptic } from '@/lib/haptics';\nimport { usePalette } from '@/lib/palette-context';\nimport { cn } from '@/lib/utils';\nimport { StarIcon } from 'lucide-react-native';\nimport { Pressable, View } from 'react-native';\n\ntype Props = {\n  /** 0 to `max`. Shown to the nearest half star. */\n  value: number;\n  /** Makes it an input: each star is a radio button, tapping one sets the rating. Omit to display. */\n  onChange?: (value: number) => void;\n  max?: number;\n  /** Display only: the number beside the stars, and how many reviews (`4.6 · 120 reviews`). */\n  showValue?: boolean;\n  count?: number;\n  size?: 'sm' | 'md' | 'lg';\n  /** What is being rated, for screen readers (\"Rate your order\"). Default \"Rating\". */\n  accessibilityLabel?: string;\n  className?: string;\n};\n\nconst PX = { sm: 14, md: 18, lg: 28 } as const;\n\nfunction Star({ px, fraction }: { px: number; fraction: number }) {\n  const filled = usePalette().warning;\n  return (\n    <View style={{ width: px, height: px }}>\n      <Icon as={StarIcon} size={px} className=\"text-muted-foreground\" strokeWidth={1.75} />\n      {fraction > 0 ? (\n        <View className=\"absolute top-0 left-0 h-full overflow-hidden\" style={{ width: px * fraction }}>\n          <Icon as={StarIcon} size={px} className=\"text-warning\" fill={filled} strokeWidth={1.75} />\n        </View>\n      ) : null}\n    </View>\n  );\n}\n\n/**\n * Stars. Without `onChange` it shows a score (half stars, optional number and review count); with\n * `onChange` it is an input whose stars are 44pt radio buttons.\n */\nexport function Rating({ value, onChange, max = 5, showValue, count, size, accessibilityLabel = 'Rating', className }: Props) {\n  const stars = Array.from({ length: max }, (_, i) => i + 1);\n  const half = Math.round(value * 2) / 2;\n\n  if (onChange) {\n    const px = PX[size ?? 'lg'];\n    return (\n      <View role=\"radiogroup\" aria-label={accessibilityLabel} className={cn('flex-row', className)}>\n        {stars.map((n) => (\n          <Pressable\n            key={n}\n            role=\"radio\"\n            aria-checked={value === n}\n            aria-label={`${n} ${n === 1 ? 'star' : 'stars'}`}\n            accessibilityState={{ checked: value === n }}\n            onPress={() => {\n              haptic('selection');\n              onChange(n);\n            }}\n            hitSlop={4}\n            className=\"size-11 items-center justify-center active:opacity-70\">\n            <Star px={px} fraction={n <= value ? 1 : 0} />\n          </Pressable>\n        ))}\n      </View>\n    );\n  }\n\n  const px = PX[size ?? 'sm'];\n  const label = `Rated ${value} out of ${max}${count ? `, ${count} reviews` : ''}`;\n  return (\n    <View role=\"img\" aria-label={label} accessible className={cn('flex-row items-center gap-1.5', className)}>\n      <View className=\"flex-row gap-0.5\">\n        {stars.map((n) => (\n          <Star key={n} px={px} fraction={Math.max(0, Math.min(1, half - (n - 1)))} />\n        ))}\n      </View>\n      {showValue || count ? (\n        <Text className={cn('text-muted-foreground', size === 'md' || size === 'lg' ? 'text-sm' : 'text-xs')}>\n          {[showValue ? value.toFixed(1) : null, count ? `${count} reviews` : null].filter(Boolean).join(' · ')}\n        </Text>\n      ) : null}\n    </View>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/kit/rating.tsx"
    }
  ],
  "meta": {
    "exports": [
      "Rating"
    ],
    "api": "<Rating value onChange? showValue? count? size? accessibilityLabel? />"
  },
  "docs": "Run `npx expo install --fix` afterwards so Expo SDK packages match your SDK. Needs the kit theme (`@kit-native/theme`) and `KitThemeProvider` from `@kit-native/lib-theme-context` at the root.",
  "categories": [
    "inputs"
  ],
  "type": "registry:component"
}