{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "choicebox",
  "title": "Choicebox",
  "description": "Card-sized options for a choice that needs a sentence each.",
  "registryDependencies": [
    "https://creance.pages.dev/r/creance-base.json"
  ],
  "files": [
    {
      "path": "choicebox/Choicebox.css",
      "content": ".cr-choicebox {\n  margin: 0;\n  padding: 0;\n  border: 0;\n  color: var(--cr-color-text-default);\n  font-family: var(--cr-font-family-sans);\n}\n\n.cr-choicebox__legend {\n  margin-bottom: var(--cr-space-3);\n  padding: 0;\n  font-size: var(--cr-font-size-sm);\n  font-weight: var(--cr-font-weight-semibold);\n}\n\n.cr-choicebox__options {\n  display: grid;\n  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n  gap: var(--cr-space-3);\n}\n\n.cr-choicebox__card {\n  display: flex;\n  gap: var(--cr-space-3);\n  padding: var(--cr-space-4);\n  border-radius: var(--cr-radius-lg);\n  background: var(--cr-color-glass-tile);\n  cursor: pointer;\n  transition: background-color var(--cr-motion-duration-fast) var(--cr-motion-easing-standard),\n    box-shadow var(--cr-motion-duration-fast) var(--cr-motion-easing-standard);\n}\n\n.cr-choicebox__card:has(:checked) {\n  background: var(--cr-color-glass-popover);\n  box-shadow: 0 0 0 1.5px var(--cr-color-ink-bg);\n}\n\n.cr-choicebox__card:has(:disabled) {\n  cursor: not-allowed;\n  opacity: 0.55;\n}\n\n.cr-choicebox__card:has(:focus-visible) {\n  outline: var(--cr-focus-width) solid var(--cr-color-focus);\n  outline-offset: var(--cr-focus-offset);\n}\n\n.cr-choicebox__input {\n  flex: none;\n  width: 20px;\n  height: 20px;\n  margin: 2px 0 0;\n  accent-color: var(--cr-color-ink-bg);\n  cursor: inherit;\n}\n\n.cr-choicebox__input:focus-visible {\n  outline: none;\n}\n\n.cr-choicebox__text {\n  display: grid;\n  gap: var(--cr-space-1);\n}\n\n.cr-choicebox__title {\n  font-size: var(--cr-font-size-md);\n  font-weight: var(--cr-font-weight-semibold);\n}\n\n.cr-choicebox__description {\n  color: var(--cr-color-text-muted);\n  font-size: var(--cr-font-size-sm);\n}\n",
      "type": "registry:file",
      "target": "@components/creance/choicebox/Choicebox.css"
    },
    {
      "path": "choicebox/Choicebox.tsx",
      "content": "'use client';\n\nimport { useId, useState, type ReactNode } from 'react';\nimport { cx } from '@/lib/creance/cx';\nimport './Choicebox.css';\n\nexport interface ChoiceboxOption {\n  value: string;\n  title: ReactNode;\n  description?: ReactNode;\n  disabled?: boolean;\n}\n\ninterface Base {\n  /** The question the cards answer. */\n  legend: ReactNode;\n  options: ChoiceboxOption[];\n  name?: string;\n  className?: string;\n}\n\nexport type ChoiceboxProps = Base &\n  (\n    | { type?: 'radio'; value?: string; defaultValue?: string; onValueChange?: (value: string) => void }\n    | { type: 'checkbox'; value?: string[]; defaultValue?: string[]; onValueChange?: (value: string[]) => void }\n  );\n\n/** Large cards for a choice that needs a sentence of explanation each. Native radios or checkboxes inside. */\nexport function Choicebox(props: ChoiceboxProps) {\n  const { legend, options, name, className } = props;\n  const auto = useId();\n  const multiple = props.type === 'checkbox';\n  const [own, setOwn] = useState<string[]>(() =>\n    multiple ? (props.defaultValue ?? []) : props.defaultValue ? [props.defaultValue] : [],\n  );\n  const selected: string[] =\n    props.value === undefined ? own : multiple ? (props.value as string[]) : [props.value as string];\n\n  const change = (value: string, checked: boolean) => {\n    const next = multiple ? (checked ? [...selected, value] : selected.filter((v) => v !== value)) : [value];\n    if (props.value === undefined) setOwn(next);\n    if (props.type === 'checkbox') props.onValueChange?.(next);\n    else props.onValueChange?.(value);\n  };\n\n  return (\n    <fieldset className={cx('cr-choicebox', className)}>\n      <legend className=\"cr-choicebox__legend\">{legend}</legend>\n      <div className=\"cr-choicebox__options\">\n        {options.map((o) => (\n          <label key={o.value} className=\"cr-choicebox__card\">\n            <input\n              type={multiple ? 'checkbox' : 'radio'}\n              className=\"cr-choicebox__input\"\n              name={name ?? auto}\n              value={o.value}\n              disabled={o.disabled}\n              checked={selected.includes(o.value)}\n              onChange={(e) => change(o.value, e.currentTarget.checked)}\n            />\n            <span className=\"cr-choicebox__text\">\n              <span className=\"cr-choicebox__title\">{o.title}</span>\n              {o.description && <span className=\"cr-choicebox__description\">{o.description}</span>}\n            </span>\n          </label>\n        ))}\n      </div>\n    </fieldset>\n  );\n}\n",
      "type": "registry:ui",
      "target": "@components/creance/choicebox/Choicebox.tsx"
    }
  ],
  "categories": [
    "molecule",
    "forms"
  ],
  "type": "registry:ui"
}