{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "animated-bar-chart",
  "title": "Animated Bar Chart",
  "description": "Bars spring up from the baseline in a staggered cascade.",
  "dependencies": [
    "remotion"
  ],
  "files": [
    {
      "path": "registry/bases/editframe/components/animated-bar-chart/index.tsx",
      "content": "\"use client\";\n\nimport { Timegroup } from \"@editframe/react\";\nimport type { CSSProperties } from \"react\";\n\nexport interface AnimatedBarChartProps {\n  data?: number[];\n  labels?: string[];\n  width?: number;\n  height?: number;\n  barColor?: string;\n  background?: string;\n  gap?: number;\n  staggerFrames?: number;\n  speed?: number;\n  fps?: number;\n  durationInFrames?: number;\n  className?: string;\n}\n\nconst clampProgressValue = (value: number) => Math.max(0, value);\n\nexport const AnimatedBarChart = ({\n  data = [35, 60, 45, 80, 55, 70, 90, 65],\n  labels,\n  width = 1000,\n  height = 500,\n  barColor = \"#0ea5e9\",\n  background = \"#0a0a0a\",\n  gap = 16,\n  staggerFrames = 6,\n  speed = 1,\n  fps = 30,\n  durationInFrames = 90,\n  className,\n}: AnimatedBarChartProps) => {\n  const chartData = data.length > 0 ? data.map(clampProgressValue) : [0];\n  const max = Math.max(1, ...chartData);\n  const safeSpeed = Math.max(0.01, speed);\n  const padding = 60;\n  const labelSpace = labels ? 40 : 0;\n  const innerWidth = width - padding * 2;\n  const innerHeight = height - padding * 2 - labelSpace;\n  const safeGap = Math.max(0, gap);\n  const barWidth =\n    (innerWidth - safeGap * (chartData.length - 1)) / chartData.length;\n  const baseY = padding + innerHeight;\n  const frameMs = 1000 / fps;\n  const growDurationMs = 900 / safeSpeed;\n  const staggerMs = (staggerFrames * frameMs) / safeSpeed;\n  const durationMs = (durationInFrames / fps) * 1000;\n  const chartStyle = {\n    \"--animated-bar-chart-color\": barColor,\n    \"--animated-bar-chart-shadow\": `${barColor}55`,\n    background,\n    display: \"block\",\n    fontFamily:\n      \"var(--font-geist-sans), -apple-system, BlinkMacSystemFont, sans-serif\",\n    height,\n    overflow: \"hidden\",\n    position: \"relative\",\n    width,\n  } as CSSProperties;\n\n  return (\n    <Timegroup\n      className={className}\n      duration={`${durationMs}ms`}\n      mode=\"fixed\"\n      style={chartStyle}\n    >\n      <>\n        <style>{`\n        @keyframes framecn-animated-bar-grow {\n          from {\n            opacity: 0.5;\n            transform: scaleY(0);\n          }\n          to {\n            opacity: 1;\n            transform: scaleY(1);\n          }\n        }\n\n        @keyframes framecn-animated-bar-label {\n          from {\n            opacity: 0;\n            transform: translateY(8px);\n          }\n          to {\n            opacity: 1;\n            transform: translateY(0);\n          }\n        }\n      `}</style>\n        <svg\n          aria-label=\"Animated bar chart\"\n          height={height}\n          role=\"img\"\n          viewBox={`0 0 ${width} ${height}`}\n          width={width}\n        >\n          <line\n            stroke=\"#27272a\"\n            strokeWidth={2}\n            x1={padding}\n            x2={padding + innerWidth}\n            y1={baseY}\n            y2={baseY}\n          />\n\n          {chartData.map((value, index) => {\n            const targetHeight = (value / max) * innerHeight;\n            const x = padding + index * (barWidth + safeGap);\n            const y = baseY - targetHeight;\n            const animationDelay = index * staggerMs;\n\n            return (\n              <g key={`${value}-${index}`}>\n                <rect\n                  fill=\"var(--animated-bar-chart-color)\"\n                  height={targetHeight}\n                  rx={6}\n                  style={{\n                    animation: `framecn-animated-bar-grow ${growDurationMs}ms cubic-bezier(0.16, 1, 0.3, 1) ${animationDelay}ms backwards`,\n                    filter:\n                      \"drop-shadow(0 4px 16px var(--animated-bar-chart-shadow))\",\n                    transformBox: \"fill-box\",\n                    transformOrigin: `${x + barWidth / 2}px ${baseY}px`,\n                  }}\n                  width={barWidth}\n                  x={x}\n                  y={y}\n                />\n                {labels?.[index] && (\n                  <text\n                    fill=\"#a1a1aa\"\n                    fontSize={16}\n                    style={{\n                      animation: `framecn-animated-bar-label ${growDurationMs}ms ease-out ${animationDelay}ms backwards`,\n                      fontFamily:\n                        \"var(--font-geist-sans), -apple-system, BlinkMacSystemFont, sans-serif\",\n                    }}\n                    textAnchor=\"middle\"\n                    x={x + barWidth / 2}\n                    y={baseY + 28}\n                  >\n                    {labels[index]}\n                  </text>\n                )}\n              </g>\n            );\n          })}\n        </svg>\n      </>\n    </Timegroup>\n  );\n};\n",
      "type": "registry:component",
      "target": "components/framecn/animated-bar-chart.tsx"
    }
  ],
  "type": "registry:component"
}