{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "code-accordion",
  "title": "Code Accordion",
  "description": "A code window that springs a range of lines closed and replaces them with a \"N lines collapsed\" placeholder.",
  "dependencies": [
    "remotion"
  ],
  "files": [
    {
      "path": "registry/bases/editframe/components/code-accordion/index.tsx",
      "content": "\"use client\";\n\nimport { Timegroup } from \"@editframe/react\";\nimport type { CSSProperties } from \"react\";\n\nconst FONT_MONO =\n  \"var(--font-geist-mono), ui-monospace, SFMono-Regular, monospace\";\n\nconst DEFAULT_LINES = [\n  \"export function processOrders(orders) {\",\n  \"  const valid = [];\",\n  \"  for (const order of orders) {\",\n  \"    if (!order.id) continue;\",\n  \"    if (!order.customer) continue;\",\n  \"    if (!order.items?.length) continue;\",\n  \"    if (order.total <= 0) continue;\",\n  \"    if (order.status === 'cancelled') continue;\",\n  \"    if (order.status === 'refunded') continue;\",\n  \"    const enriched = enrich(order);\",\n  \"    const validated = validate(enriched);\",\n  \"    if (!validated.ok) continue;\",\n  \"    const priced = price(validated.value);\",\n  \"    const taxed = applyTax(priced);\",\n  \"    const shipped = applyShipping(taxed);\",\n  \"    valid.push(shipped);\",\n  \"  }\",\n  \"  return valid;\",\n  \"}\",\n];\n\nexport interface CodeAccordionProps {\n  lines?: string[];\n  collapseRange?: [number, number];\n  collapseAt?: number;\n  title?: string;\n  fontSize?: number;\n  width?: number;\n  background?: string;\n  cardColor?: string;\n  textColor?: string;\n  mutedColor?: string;\n  speed?: number;\n  fps?: number;\n  durationInFrames?: number;\n  height?: number;\n  className?: string;\n}\n\nconst Light = ({ color }: { color: string }) => (\n  <div\n    style={{\n      background: color,\n      borderRadius: \"50%\",\n      height: 11,\n      opacity: 0.6,\n      width: 11,\n    }}\n  />\n);\n\nconst Line = ({\n  line,\n  index,\n  lineHeight,\n  textColor,\n  mutedColor,\n}: {\n  line: string;\n  index: number;\n  lineHeight: number;\n  textColor: string;\n  mutedColor: string;\n}) => (\n  <div\n    style={{\n      alignItems: \"center\",\n      color: textColor,\n      display: \"flex\",\n      height: lineHeight,\n      whiteSpace: \"pre\",\n    }}\n  >\n    <span\n      style={{\n        color: mutedColor,\n        paddingRight: 16,\n        textAlign: \"right\",\n        userSelect: \"none\",\n        width: 56,\n      }}\n    >\n      {index + 1}\n    </span>\n    <span>{line}</span>\n  </div>\n);\n\nexport const CodeAccordion = ({\n  lines = DEFAULT_LINES,\n  collapseRange = [3, 14],\n  collapseAt = 30,\n  title = \"process-orders.ts\",\n  fontSize = 16,\n  width = 720,\n  background = \"#050505\",\n  cardColor = \"#0a0a0a\",\n  textColor = \"#e4e4e7\",\n  mutedColor = \"#52525b\",\n  speed = 1,\n  fps = 30,\n  durationInFrames = 150,\n  height = 720,\n  className,\n}: CodeAccordionProps) => {\n  const safeSpeed = Math.max(0.01, speed);\n  const durationMs = (durationInFrames / fps) * 1000;\n  const frameMs = 1000 / fps;\n  const collapseStartMs = collapseAt * frameMs;\n  const collapseDurationMs = (durationInFrames * 0.6 * frameMs) / safeSpeed;\n\n  const lineHeight = Math.round(fontSize * 1.55);\n  const [start, end] = collapseRange;\n  const collapsedCount = Math.max(0, end - start + 1);\n\n  const before = lines.slice(0, start);\n  const collapsed = lines.slice(start, end + 1);\n  const after = lines.slice(end + 1);\n\n  const containerStyle: CSSProperties = {\n    alignItems: \"center\",\n    background,\n    display: \"flex\",\n    fontFamily: FONT_MONO,\n    height,\n    justifyContent: \"center\",\n    overflow: \"hidden\",\n    position: \"relative\",\n    width,\n  };\n\n  return (\n    <Timegroup\n      className={className}\n      duration={`${durationMs}ms`}\n      mode=\"fixed\"\n      style={containerStyle}\n    >\n      <>\n        <style>{`\n          @keyframes framecn-accordion-collapse {\n            from { height: ${collapsedCount * lineHeight}px; }\n            to { height: ${lineHeight}px; }\n          }\n          @keyframes framecn-accordion-fade-out {\n            to { opacity: 0; }\n          }\n          @keyframes framecn-accordion-fade-in {\n            from { opacity: 0; }\n            to { opacity: 1; }\n          }\n        `}</style>\n        <div\n          style={{\n            background: cardColor,\n            border: \"1px solid rgba(255,255,255,0.06)\",\n            borderRadius: 14,\n            boxShadow:\n              \"0 30px 80px rgba(0,0,0,0.55), inset 0 1px 0 rgba(255,255,255,0.05)\",\n            overflow: \"hidden\",\n            width,\n          }}\n        >\n          {/* Chrome */}\n          <div\n            style={{\n              alignItems: \"center\",\n              borderBottom: \"1px solid rgba(255,255,255,0.05)\",\n              display: \"flex\",\n              gap: 8,\n              height: 38,\n              padding: \"0 14px\",\n            }}\n          >\n            <Light color=\"#ff5f57\" />\n            <Light color=\"#febc2e\" />\n            <Light color=\"#28c840\" />\n            <div\n              style={{\n                color: mutedColor,\n                flex: 1,\n                fontSize: 12,\n                textAlign: \"center\",\n              }}\n            >\n              {title}\n            </div>\n          </div>\n\n          {/* Code body */}\n          <div style={{ fontSize, lineHeight: 1.55, padding: \"16px 0\" }}>\n            {before.map((line, i) => (\n              <Line\n                key={`b-${i}`}\n                line={line}\n                index={i}\n                lineHeight={lineHeight}\n                textColor={textColor}\n                mutedColor={mutedColor}\n              />\n            ))}\n\n            {/* Collapsing region */}\n            <div\n              style={{\n                animation: `framecn-accordion-collapse ${collapseDurationMs}ms cubic-bezier(0.16, 1, 0.3, 1) ${collapseStartMs}ms backwards`,\n                overflow: \"hidden\",\n                position: \"relative\",\n              }}\n            >\n              <div\n                style={{\n                  animation: `framecn-accordion-fade-out ${collapseDurationMs * 0.6}ms ease-out ${collapseStartMs}ms backwards`,\n                }}\n              >\n                {collapsed.map((line, i) => (\n                  <Line\n                    key={`c-${i}`}\n                    line={line}\n                    index={start + i}\n                    lineHeight={lineHeight}\n                    textColor={textColor}\n                    mutedColor={mutedColor}\n                  />\n                ))}\n              </div>\n\n              {/* Placeholder bar */}\n              <div\n                style={{\n                  alignItems: \"center\",\n                  animation: `framecn-accordion-fade-in ${collapseDurationMs * 0.4}ms ease-in ${collapseStartMs + collapseDurationMs * 0.6}ms backwards`,\n                  bottom: 0,\n                  color: mutedColor,\n                  display: \"flex\",\n                  fontStyle: \"italic\",\n                  height: lineHeight,\n                  left: 0,\n                  paddingLeft: 56,\n                  position: \"absolute\",\n                  right: 0,\n                }}\n              >\n                ⋯ {collapsedCount} lines collapsed\n              </div>\n            </div>\n\n            {after.map((line, i) => (\n              <Line\n                key={`a-${i}`}\n                line={line}\n                index={end + 1 + i}\n                lineHeight={lineHeight}\n                textColor={textColor}\n                mutedColor={mutedColor}\n              />\n            ))}\n          </div>\n        </div>\n      </>\n    </Timegroup>\n  );\n};\n",
      "type": "registry:component",
      "target": "components/framecn/code-accordion.tsx"
    }
  ],
  "type": "registry:component"
}