{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "channel-strip",
  "type": "registry:ui",
  "title": "ChannelStrip",
  "description": "Console mixer strips — title, fader, level meter with dB scale, value, and controls — whose rows line up across a Mixer even when a strip leaves a part out.",
  "dependencies": [],
  "registryDependencies": [
    "https://control-ui.dev/r/core.json"
  ],
  "files": [
    {
      "path": "src/registry/knob-contracts/channel-strip-knobs.ts",
      "target": "@components/control-ui/knob-contracts/channel-strip-knobs.ts",
      "type": "registry:component",
      "content": "// Generated from src/registry/sources/control-ui/recipes/channel-strip.css by scripts/gen-knob-contracts.ts — run `bun run sync:knobs`.\nexport const channelStripKnobs = [\n  \"--cui-channel-strip-size\",\n  \"--cui-channel-strip-body-height\",\n  \"--cui-channel-strip-separator-color\",\n  \"--cui-channel-strip-value-foreground\",\n] as const;\nexport type ChannelStripKnobStyle = Partial<Record<(typeof channelStripKnobs)[number], string>>;\n"
    },
    {
      "path": "src/registry/sources/control-ui/recipes/channel-strip.css",
      "target": "@components/control-ui/styles/recipes/channel-strip.css",
      "type": "registry:file",
      "content": "@layer components {\n  :where([data-control-family=\"channel-strip\"][data-slot=\"mixer\"]) {\n    display: grid;\n    grid-auto-columns: max-content;\n    grid-auto-flow: column;\n    grid-template-rows: repeat(4, auto);\n    gap: calc(var(--spacing) * 2);\n    overflow-x: auto;\n  }\n\n  :where([data-control-family=\"channel-strip\"][data-slot=\"root\"]) {\n    --cui-channel-strip-size: calc(var(--spacing) * 24);\n    --cui-channel-strip-body-height: calc(var(--spacing) * 40);\n    --cui-channel-strip-separator-color: var(--border);\n    --cui-channel-strip-value-foreground: var(--muted-foreground);\n    inline-size: var(--cui-channel-strip-size);\n    display: grid;\n    grid-row: span 4;\n    grid-template-rows: subgrid;\n    row-gap: calc(var(--spacing) * 2);\n  }\n\n  :where([data-control-family=\"channel-strip\"][data-slot=\"root\"][data-variant=\"master\"]) {\n    border-inline-start: 1px solid var(--cui-channel-strip-separator-color);\n    padding-inline-start: calc(var(--spacing) * 2);\n  }\n\n  :where([data-control-family=\"channel-strip\"][data-slot=\"header\"]) {\n    grid-row: 1;\n    gap: var(--spacing);\n    min-block-size: calc(var(--spacing) * 6);\n  }\n\n  :where([data-control-family=\"channel-strip\"][data-slot=\"body\"]) {\n    grid-row: 2;\n    gap: calc(var(--spacing) * 2);\n    block-size: var(--cui-channel-strip-body-height);\n    padding-block: calc(var(--spacing) * 2);\n  }\n\n  :where([data-control-family=\"channel-strip\"][data-slot=\"value\"]) {\n    grid-row: 3;\n    color: var(--cui-channel-strip-value-foreground);\n    text-align: center;\n  }\n\n  :where([data-control-family=\"channel-strip\"][data-slot=\"controls\"]) {\n    grid-row: 4;\n    gap: var(--spacing);\n  }\n}\n\n@property --cui-channel-strip-size {\n  syntax: \"<length-percentage>\";\n  inherits: true;\n  initial-value: 0px;\n}\n\n@property --cui-channel-strip-body-height {\n  syntax: \"<length-percentage>\";\n  inherits: true;\n  initial-value: 0px;\n}\n\n@property --cui-channel-strip-separator-color {\n  syntax: \"<color>\";\n  inherits: true;\n  initial-value: transparent;\n}\n\n@property --cui-channel-strip-value-foreground {\n  syntax: \"<color>\";\n  inherits: true;\n  initial-value: transparent;\n}\n"
    },
    {
      "path": "src/registry/sources/control-ui/ui/channel-strip.tsx",
      "target": "@components/control-ui/ui/channel-strip.tsx",
      "type": "registry:ui",
      "content": "\"use client\";\n\nimport type { ComponentProps, CSSProperties } from \"react\";\nimport { createContext, use, useId } from \"react\";\nimport type { ChannelStripKnobStyle } from \"@/components/control-ui/knob-contracts/channel-strip-knobs\";\nimport { cn } from \"@/components/control-ui/lib/cn\";\n\nexport type ChannelStripVariant = \"default\" | \"master\";\n\ntype ChannelStripPartProps = Omit<ComponentProps<\"div\">, \"style\"> & { style?: CSSProperties & ChannelStripKnobStyle };\n\nexport type MixerProps = ChannelStripPartProps;\n\nexport type ChannelStripProps = ChannelStripPartProps & { variant?: ChannelStripVariant };\n\nexport type ChannelStripHeaderProps = ChannelStripPartProps;\n\nexport type ChannelStripTitleProps = ComponentProps<\"span\">;\n\nexport type ChannelStripActionsProps = ChannelStripPartProps;\n\nexport type ChannelStripBodyProps = ChannelStripPartProps;\n\nexport type ChannelStripValueProps = ChannelStripPartProps;\n\nexport type ChannelStripControlsProps = ChannelStripPartProps;\n\nconst ChannelStripTitleIdContext = createContext<string | null>(null);\n\nexport function Mixer({ className, ...props }: MixerProps) {\n  return (\n    // biome-ignore lint/a11y/useSemanticElements: a mixer is a named group of channel strips, not a fieldset form group.\n    <div\n      role=\"group\"\n      data-control-ui=\"channel-strip\"\n      data-control-family=\"channel-strip\"\n      data-slot=\"mixer\"\n      className={className}\n      {...props}\n    />\n  );\n}\n\nexport function ChannelStrip({ variant = \"default\", className, ...props }: ChannelStripProps) {\n  const titleId = useId();\n  return (\n    <ChannelStripTitleIdContext value={titleId}>\n      {/* biome-ignore lint/a11y/useSemanticElements: a channel strip is a labelled group of controls, not a fieldset form group. */}\n      <div\n        role=\"group\"\n        aria-labelledby={titleId}\n        data-control-ui=\"channel-strip\"\n        data-control-family=\"channel-strip\"\n        data-slot=\"root\"\n        data-variant={variant}\n        className={cn(\"min-w-0\", className)}\n        {...props}\n      />\n    </ChannelStripTitleIdContext>\n  );\n}\n\nexport function ChannelStripHeader({ className, ...props }: ChannelStripHeaderProps) {\n  return (\n    <div\n      data-control-ui=\"channel-strip\"\n      data-control-family=\"channel-strip\"\n      data-slot=\"header\"\n      className={cn(\"flex min-w-0 items-center\", className)}\n      {...props}\n    />\n  );\n}\n\nexport function ChannelStripTitle({ className, ...props }: ChannelStripTitleProps) {\n  const titleId = use(ChannelStripTitleIdContext);\n  return (\n    <span\n      data-control-ui=\"channel-strip\"\n      data-control-family=\"channel-strip\"\n      data-slot=\"title\"\n      className={cn(\"min-w-0 flex-1 truncate text-caption\", className)}\n      {...props}\n      id={titleId ?? undefined}\n    />\n  );\n}\n\nexport function ChannelStripActions({ className, ...props }: ChannelStripActionsProps) {\n  return (\n    <div\n      data-control-ui=\"channel-strip\"\n      data-control-family=\"channel-strip\"\n      data-slot=\"actions\"\n      className={cn(\"flex shrink-0 items-center\", className)}\n      {...props}\n    />\n  );\n}\n\nexport function ChannelStripBody({ className, ...props }: ChannelStripBodyProps) {\n  return (\n    <div\n      data-control-ui=\"channel-strip\"\n      data-control-family=\"channel-strip\"\n      data-slot=\"body\"\n      className={cn(\"flex items-stretch justify-center\", className)}\n      {...props}\n    />\n  );\n}\n\nexport function ChannelStripValue({ className, ...props }: ChannelStripValueProps) {\n  return (\n    <div\n      data-control-ui=\"channel-strip\"\n      data-control-family=\"channel-strip\"\n      data-slot=\"value\"\n      className={cn(\"text-caption tabular-nums\", className)}\n      {...props}\n    />\n  );\n}\n\nexport function ChannelStripControls({ className, ...props }: ChannelStripControlsProps) {\n  return (\n    <div\n      data-control-ui=\"channel-strip\"\n      data-control-family=\"channel-strip\"\n      data-slot=\"controls\"\n      className={cn(\"flex flex-wrap content-start items-center justify-center\", className)}\n      {...props}\n    />\n  );\n}\n"
    }
  ],
  "css": {
    "@import \"../components/control-ui/styles/recipes/channel-strip.css\"": {}
  }
}
