{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "meter",
  "title": "Meter",
  "description": "The bar springs to its value, changes colour at thresholds and the digits roll.",
  "dependencies": [
    "@ui-sdk/core@0.1.0-beta.2",
    "@ui-sdk/react@0.1.0-beta.2"
  ],
  "registryDependencies": [
    "@keyframery/motion"
  ],
  "files": [
    {
      "path": "registry/components/keyframery/primitives/meter.tsx",
      "content": "\"use client\"\n\n/* Animated drop-in for `@ui-sdk/react/meter`: same parts, same props. Swap the import and keep your code.\n   This file adds motion only. Colours, radii, shadows and spacing stay yours. */\n\nimport {\n  MeterIndicator as MeterIndicatorPart,\n  MeterTrack as MeterTrackPart,\n  MeterValue as MeterValuePart,\n} from \"@ui-sdk/react/meter\"\nimport * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nexport * from \"@ui-sdk/react/meter\"\n\n/* Roll: every digit is a column of 0 to 9 that slides to its value on a spring; other characters\n   (the decimal point, units) stay put. Positions are keyed from the right, so a new leading\n   digit is added instead of everything shifting. Exported for other numbers. */\nfunction Roll({ text, className }: { text: string; className?: string }) {\n  const chars = text.split(\"\")\n  /* Screen readers get the plain value; the digit columns are only for the eye. */\n  return (\n    <>\n    <span className=\"sr-only\">{text}</span>\n    <span data-slot=\"roll\" aria-hidden className={cn(\"inline-flex h-[1lh] overflow-hidden whitespace-pre tabular-nums\", className)}>\n      {chars.map((c, i) => {\n        const key = chars.length - i\n        return /\\d/.test(c) ? (\n          <span\n            key={key}\n            style={{ \"--d\": Number(c) } as React.CSSProperties}\n            className=\"flex flex-col transition-[translate] duration-[calc(500ms*var(--kf-speed,1))] ease-spring [translate:0_calc(var(--d)*-1lh)] motion-reduce:transition-none!\"\n          >\n            {Array.from({ length: 10 }, (_, d) => (\n              <span key={d} className=\"h-[1lh]\">\n                {d}\n              </span>\n            ))}\n          </span>\n        ) : (\n          <span key={key}>{c}</span>\n        )\n      })}\n    </span>\n    </>\n  )\n}\n\n/* The value rolls to each new reading. Pass children to render your own. */\nfunction MeterValue({ children, ...props }: React.ComponentProps<typeof MeterValuePart>) {\n  return <MeterValuePart {...props}>{children ?? ((state) => <Roll text={state.text} />)}</MeterValuePart>\n}\n\n/* The track clips the fill, so its spring overshoot never shows outside. */\nfunction MeterTrack({ className, ...props }: React.ComponentProps<typeof MeterTrackPart>) {\n  return <MeterTrackPart className={cn(\"overflow-hidden\", className)} {...props} />\n}\n\n/* The fill moves to each new reading on a spring: it overshoots a little and settles. */\nfunction MeterIndicator({ className, ...props }: React.ComponentProps<typeof MeterIndicatorPart>) {\n  return (\n    <MeterIndicatorPart\n      className={cn(\n        \"block h-full [transition:width_calc(700ms*var(--kf-speed,1))_var(--ease-spring),background-color_calc(300ms*var(--kf-speed,1))_var(--ease-house)] motion-reduce:transition-none!\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { MeterIndicator, MeterTrack, MeterValue, Roll }\n",
      "type": "registry:component",
      "target": "components/keyframery/primitives/meter.tsx"
    },
    {
      "path": "registry/components/keyframery/meter.tsx",
      "content": "\"use client\"\n\n/* Styled meter: the animated primitive plus the Keyframery look. */\n\nimport {\n  Meter as MeterRoot,\n  MeterIndicator as MeterIndicatorPart,\n  MeterLabel as MeterLabelPart,\n  MeterTrack as MeterTrackPart,\n  MeterValue as MeterValuePart,\n} from \"@/components/keyframery/primitives/meter\"\nimport * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\n/* Label and value share the first row; the track spans the row below.\n   `high` works like the native meter's: a reading above it is the bad range,\n   and only then does the meter use the destructive colour. */\nfunction Meter({\n  className,\n  high,\n  ...props\n}: React.ComponentProps<typeof MeterRoot> & { high?: number }) {\n  const over = high !== undefined && props.value > high\n  return (\n    <MeterRoot\n      data-high={over ? \"\" : undefined}\n      className={cn(\n        \"group/meter grid w-full grid-cols-[minmax(0,1fr)_auto] items-baseline gap-x-3 gap-y-2\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction MeterLabel({ className, ...props }: React.ComponentProps<typeof MeterLabelPart>) {\n  return (\n    <MeterLabelPart\n      className={cn(\"truncate text-[13px] leading-5 font-medium text-foreground\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction MeterValue({ className, ...props }: React.ComponentProps<typeof MeterValuePart>) {\n  return (\n    <MeterValuePart\n      className={cn(\n        \"col-start-2 text-[13px] leading-5 text-muted-foreground tabular-nums\",\n        \"transition-colors duration-[calc(150ms*var(--kf-speed,1))] group-data-high/meter:text-destructive motion-reduce:transition-none!\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\n/* The track is a thin pill well. */\nfunction MeterTrack({ className, ...props }: React.ComponentProps<typeof MeterTrackPart>) {\n  return (\n    <MeterTrackPart\n      className={cn(\n        \"relative col-span-full h-1.5 w-full rounded-full bg-muted\",\n        \"shadow-[inset_0_1px_2px_rgb(0_0_0/0.07),inset_0_0_0_1px_rgb(0_0_0/0.035)]\",\n        \"dark:shadow-[inset_0_1px_2px_rgb(0_0_0/0.5),inset_0_0_0_1px_rgb(255_255_255/0.04)]\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\n/* The fill springs to each new reading (from the primitive) and turns destructive only above `high`. */\nfunction MeterIndicator({ className, ...props }: React.ComponentProps<typeof MeterIndicatorPart>) {\n  return (\n    <MeterIndicatorPart\n      className={cn(\n        \"rounded-full bg-primary\",\n        \"shadow-[inset_0_1px_0_rgb(255_255_255/0.14)]\",\n        \"group-data-high/meter:bg-destructive\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Meter, MeterIndicator, MeterLabel, MeterTrack, MeterValue }\n",
      "type": "registry:component",
      "target": "components/keyframery/meter.tsx"
    }
  ],
  "type": "registry:component"
}