{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "meter",
  "title": "Meter",
  "description": "A meter component.",
  "dependencies": [
    "class-variance-authority"
  ],
  "files": [
    {
      "path": "registry/default/meter/meter.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { Meter as BaseMeter } from \"@base-ui/react/meter\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"@/lib/utils\";\n\nconst meterRootVariants = cva(\"max-w-[300px] w-full flex flex-col\", {\n  variants: {\n    size: {\n      sm: \"gap-2\",\n      md: \"gap-2\",\n      lg: \"gap-2\",\n    },\n  },\n  defaultVariants: {\n    size: \"md\",\n  },\n});\n\ninterface MeterRootProps\n  extends React.ComponentProps<typeof BaseMeter.Root>,\n    VariantProps<typeof meterRootVariants> {\n  animated?: boolean;\n  low?: number;\n  high?: number;\n  optimumMin?: number;\n  optimumMax?: number;\n  showOptimumMarkers?: boolean;\n  showThresholdColors?: boolean;\n}\n\nfunction MeterRoot({\n  className,\n  children,\n  size = \"md\",\n  animated = false,\n  value = 0,\n  min = 0,\n  max = 100,\n  low,\n  high,\n  optimumMin,\n  optimumMax,\n  showOptimumMarkers = true,\n  showThresholdColors = true,\n  ...props\n}: MeterRootProps) {\n  const optimumStyles =\n    optimumMin !== undefined && optimumMax !== undefined\n      ? {\n          \"--meter-optimum-min-percent\": `${((optimumMin - min) / (max - min)) * 100}%`,\n          \"--meter-optimum-max-percent\": `${((optimumMax - min) / (max - min)) * 100}%`,\n          \"--meter-optimum-width-percent\": `${((optimumMax - optimumMin) / (max - min)) * 100}%`,\n        }\n      : {};\n\n  // Status from thresholds, most-specific config first:\n  const getStatus = () => {\n    // Range (optimumMin + optimumMax): in-range is optimal, low/high mark danger\n    if (optimumMin !== undefined && optimumMax !== undefined) {\n      if (low !== undefined && value < low) return \"danger\";\n      if (high !== undefined && value > high) return \"danger\";\n      if (value >= optimumMin && value <= optimumMax) return \"optimal\";\n      return \"suboptimal\";\n    }\n\n    // Directional three-tier, higher is better (e.g. battery: low=15, optimumMin=75)\n    if (optimumMin !== undefined && low !== undefined) {\n      if (value < low) return \"danger\";\n      if (value >= optimumMin) return \"optimal\";\n      return \"suboptimal\";\n    }\n\n    // Directional three-tier, lower is better (e.g. temp: optimumMax=60, high=80)\n    if (optimumMax !== undefined && high !== undefined) {\n      if (value > high) return \"danger\";\n      if (value <= optimumMax) return \"optimal\";\n      return \"suboptimal\";\n    }\n\n    // Two-tier: low only (higher is better)\n    if (low !== undefined && high === undefined) {\n      if (value < low) return \"danger\";\n      return \"optimal\";\n    }\n\n    // Two-tier: high only (lower is better)\n    if (high !== undefined && low === undefined) {\n      if (value > high) return \"danger\";\n      return \"optimal\";\n    }\n\n    // Two-tier: both (middle is best)\n    if (low !== undefined && high !== undefined) {\n      if (value < low || value > high) return \"danger\";\n      return \"optimal\";\n    }\n\n    return \"normal\";\n  };\n\n  return (\n    <BaseMeter.Root\n      value={value}\n      min={min}\n      max={max}\n      data-slot=\"meter\"\n      data-size={size}\n      data-animated={animated}\n      data-low={low}\n      data-high={high}\n      data-optimum-min={showOptimumMarkers ? optimumMin : undefined}\n      data-optimum-max={showOptimumMarkers ? optimumMax : undefined}\n      data-status={showThresholdColors ? getStatus() : \"normal\"}\n      className={cn(\"group/meter\", meterRootVariants({ size }), className)}\n      style={optimumStyles as React.CSSProperties}\n      {...props}\n    >\n      {children}\n    </BaseMeter.Root>\n  );\n}\n\ninterface MeterTrackProps extends React.ComponentProps<typeof BaseMeter.Track> {\n  segments?: number;\n  striped?: boolean;\n  gradient?: boolean;\n}\n\nfunction MeterTrack({\n  className,\n  children,\n  segments,\n  striped,\n  gradient,\n  ...props\n}: MeterTrackProps) {\n  return (\n    <div className=\"relative\">\n      <BaseMeter.Track\n        data-slot=\"meter-track\"\n        data-segments={segments}\n        data-striped={striped}\n        data-gradient={gradient}\n        className={cn(\n          \"bg-primary/20 relative w-full overflow-hidden rounded-md\",\n          \"group-data-[size=lg]/meter:h-3 group-data-[size=md]/meter:h-2 group-data-[size=sm]/meter:h-1.5\",\n          striped &&\n            \"from-primary/20 to-primary/30 bg-gradient-to-r bg-[length:1rem_1rem]\",\n          gradient &&\n            \"from-primary/10 via-primary/20 to-primary/10 bg-gradient-to-r\",\n          className,\n        )}\n        {...props}\n      >\n        {children}\n        {segments && segments > 1 && <MeterSegments segments={segments} />}\n        <MeterOptimumTicks />\n      </BaseMeter.Track>\n      <MeterOptimumRangeLine />\n    </div>\n  );\n}\n\nfunction MeterSegments({ segments }: { segments: number }) {\n  return (\n    <div className=\"absolute inset-0\">\n      {Array.from({ length: segments - 1 }).map((_, i) => (\n        <div\n          key={i}\n          className=\"bg-background/50 absolute top-0 bottom-0 w-px\"\n          style={{ left: `${((i + 1) / segments) * 100}%` }}\n        />\n      ))}\n    </div>\n  );\n}\n\n// Vertical tick markers above the track. Shown only when both optimumMin and\n// optimumMax are set (the doubled group-data selector).\nfunction MeterOptimumTicks() {\n  return (\n    <div className=\"pointer-events-none absolute inset-0 hidden group-data-[optimum-min]/meter:group-data-[optimum-max]/meter:block\">\n      {/* Start marker */}\n      <div\n        className=\"absolute -top-2 h-3 w-px\"\n        style={{ left: \"calc(var(--meter-optimum-min-percent) - 0.5px)\" }}\n      >\n        <div className=\"bg-foreground ring-background h-full w-full rounded-full ring-1\" />\n      </div>\n      {/* End marker */}\n      <div\n        className=\"absolute -top-2 h-3 w-px\"\n        style={{ left: \"calc(var(--meter-optimum-max-percent) - 0.5px)\" }}\n      >\n        <div className=\"bg-foreground ring-background h-full w-full rounded-full ring-1\" />\n      </div>\n    </div>\n  );\n}\n\n// Horizontal range line below the track. Same dual-optimum visibility gate.\nfunction MeterOptimumRangeLine() {\n  return (\n    <div className=\"pointer-events-none absolute inset-x-0 top-full hidden group-data-[optimum-min]/meter:group-data-[optimum-max]/meter:block\">\n      <div\n        className=\"absolute top-0.5 h-0.5\"\n        style={{\n          left: \"calc(var(--meter-optimum-min-percent) - 0.25px)\",\n          width: \"calc(var(--meter-optimum-width-percent) + 0.5px)\",\n        }}\n      >\n        <div className=\"bg-foreground/70 ring-background h-full w-full rounded-full ring-1\" />\n      </div>\n    </div>\n  );\n}\n\nfunction MeterIndicator({\n  className,\n  ...props\n}: React.ComponentProps<typeof BaseMeter.Indicator>) {\n  return (\n    <BaseMeter.Indicator\n      data-slot=\"meter-indicator\"\n      className={cn(\n        \"h-full\",\n        \"group-data-[animated=true]/meter:transition-all group-data-[animated=true]/meter:duration-300 group-data-[animated=true]/meter:ease-out\",\n        // Status-based colors using semantic theme colors\n        \"group-data-[status=normal]/meter:bg-primary\",\n        \"group-data-[status=optimal]/meter:bg-success\",\n        \"group-data-[status=suboptimal]/meter:bg-warning\",\n        \"group-data-[status=danger]/meter:bg-danger\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction MeterLabel({\n  className,\n  ...props\n}: React.ComponentProps<typeof BaseMeter.Label>) {\n  return (\n    <BaseMeter.Label\n      data-slot=\"meter-label\"\n      className={cn(\n        \"font-medium\",\n        \"group-data-[size=lg]/meter:text-base group-data-[size=md]/meter:text-sm group-data-[size=sm]/meter:text-xs\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction MeterValue({\n  className,\n  ...props\n}: React.ComponentProps<typeof BaseMeter.Value>) {\n  return (\n    <BaseMeter.Value\n      data-slot=\"meter-value\"\n      className={cn(\n        \"text-muted-foreground\",\n        \"group-data-[size=lg]/meter:text-base group-data-[size=md]/meter:text-sm group-data-[size=sm]/meter:text-xs\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\n// Legacy default export for backward compatibility\nfunction Meter({\n  className,\n  children,\n  low,\n  high,\n  optimumMin,\n  optimumMax,\n  ...props\n}: MeterRootProps) {\n  return (\n    <MeterRoot\n      className={className}\n      low={low}\n      high={high}\n      optimumMin={optimumMin}\n      optimumMax={optimumMax}\n      {...props}\n    >\n      {children}\n      <MeterTrack>\n        <MeterIndicator />\n      </MeterTrack>\n    </MeterRoot>\n  );\n}\n\nexport {\n  Meter,\n  MeterRoot,\n  MeterTrack,\n  MeterIndicator,\n  MeterLabel,\n  MeterValue,\n  type MeterRootProps,\n  type MeterTrackProps,\n};\n",
      "type": "registry:ui",
      "target": "components/ui/cubby-ui/meter.tsx"
    }
  ],
  "type": "registry:ui"
}