{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"bar-chart","type":"registry:ui","title":"Bar chart","description":"A compact bar series with an accessible label.","dependencies":["clsx","tailwind-merge"],"registryDependencies":["https://caliperui.site/r/styles.json"],"files":[{"path":"ui/bar-chart.tsx","type":"registry:ui","target":"components/ui/bar-chart.tsx","content":"import type { ComponentProps, CSSProperties } from \"react\";\nimport { cn } from \"./lib/cn\";\nimport \"./shared/bar-chart.css\";\nimport \"./bar-chart.css\";\n\nexport type BarChartProps = Omit<ComponentProps<\"div\">, \"children\"> & {\n  values: readonly number[];\n  label: string;\n  /** One short label per bar, drawn under the baseline. */\n  labels?: readonly string[];\n};\n\nexport function BarChart({\n  values,\n  label,\n  labels,\n  className,\n  ...props\n}: BarChartProps) {\n  const peak = Math.max(...values, 1);\n  return (\n    <div data-slot=\"bar-chart\" role=\"img\" aria-label={label} className={cn(\"grid gap-2\", className)} {...props}>\n      <div className=\"flex h-28 items-end gap-[clamp(2px,2%,10px)] border-b border-border\">\n        {values.map((value, index) => (\n          <div\n            key={index}\n            data-slot=\"bar\"\n            className={cn(\n              \"min-h-1 flex-1 rounded-t-[min(6px,30%)]\",\n              // Data colour, not ink: the latest bar in full, the rest as a quiet run of the same series.\n              index === values.length - 1\n                ? \"bg-[var(--chart-1)]\"\n                : \"bg-[color-mix(in_srgb,var(--chart-1)_32%,transparent)] hover:bg-[color-mix(in_srgb,var(--chart-1)_55%,transparent)]\",\n            )}\n            style={{ height: `${Math.max(8, (value / peak) * 100)}%`, \"--i\": index } as CSSProperties}\n          />\n        ))}\n      </div>\n      {labels && (\n        <div aria-hidden=\"true\" className=\"flex gap-[clamp(2px,2%,10px)] text-[11px] text-muted-foreground\">\n          {values.map((_, index) => (\n            <span key={index} className={cn(\"min-w-0 flex-1 truncate text-center\", index === values.length - 1 && \"text-foreground\")}>\n              {labels[index]}\n            </span>\n          ))}\n        </div>\n      )}\n    </div>\n  );\n}\n"},{"path":"ui/lib/cn.ts","type":"registry:ui","target":"components/ui/lib/cn.ts","content":"import { clsx, type ClassValue } from \"clsx\";\nimport { extendTailwindMerge } from \"tailwind-merge\";\n\nconst twMerge = extendTailwindMerge({\n  extend: { theme: { radius: [\"control\", \"surface\", \"overlay\"], shadow: [\"overlay\"] } },\n});\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs));\n}\n"},{"path":"ui/shared/bar-chart.css","type":"registry:file","target":"components/ui/shared/bar-chart.css","content":"/* Shared by bar-chart.tsx, range-histogram.tsx; each imports it. Edit freely. */\n@layer theme, base, components, utilities;\n\n@layer components {\n  @media (prefers-reduced-motion: no-preference) {\n    :is([data-slot=\"bar-chart\"] [data-slot=\"bar\"], [data-slot=\"range-histogram-bars\"] > span) {\n      transform-origin: 50% 100%;\n      animation: caliper-chart-rise var(--duration-showcase) var(--ease-showcase) backwards;\n      animation-delay: calc(var(--i, 0) * 28ms);\n    }\n  }\n}\n"},{"path":"ui/bar-chart.css","type":"registry:file","target":"components/ui/bar-chart.css","content":"/* bar-chart.tsx's styles; it imports this file. Edit freely. */\n@layer theme, base, components, utilities;\n\n@layer components {\n  [data-slot=\"bar\"] {\n    /* A new dataset moves the bars to their new heights instead of jumping. */\n    transition: background-color var(--duration-fast) var(--ease-out), height var(--duration-travel) var(--ease-out);\n  }\n\n  @media (prefers-reduced-motion: reduce) {\n    [data-slot=\"bar\"] {\n      transition: none;\n    }\n  }\n}\n"}],"categories":["data"],"meta":{"tier":"free","license":"MIT","family":"blocks","docs":"/docs/components/bar-chart"}}