{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "toggle-group",
  "title": "ToggleGroup",
  "description": "토글 그룹 — single/multiple 선택 모드(shadcn API 준수), context로 Toggle 재사용, 그룹 disabled 일괄 전파.",
  "dependencies": [
    "@unikit-bridge/ui",
    "class-variance-authority",
    "clsx",
    "tailwind-merge",
    "tailwindcss"
  ],
  "registryDependencies": [
    "utils",
    "toggle"
  ],
  "files": [
    {
      "path": "registry/ui/toggle-group.tsx",
      "content": "// ToggleGroup — shadcn/ui new-york-v4 toggle-group을 UniKit UI 브리지로 이식.\n// 포팅 판단:\n// - radix ToggleGroup（Root/Item） 제거 — 선택 상태는 React context로 관리하고\n//   하위 항목은 Toggle（./toggle）에 pressed를 주입해 재사용한다.\n// - spacing prop · --gap CSS 변수 · data-spacing/first:/last: 셀렉터 제거 —\n//   의사 클래스·CSS 변수는 네이티브에서 재현 불가라 연접 대신 고정 gap-1 간격의\n//   독립 항목 배치로 단순화（항목의 rounded-md·테두리가 그대로 살아있다）.\n// - single은 이미 선택된 항목 재선택 시 onValueChange（\"\"）（radix 원본 동작 준수）,\n//   multiple은 배열 토글. 그룹 disabled는 항목에 일괄 전파.\nimport {\n  createContext,\n  forwardRef,\n  useCallback,\n  useContext,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\";\nimport {\n  View,\n  type BridgePressableRef,\n  type BridgeViewRef,\n  type ViewProps,\n} from \"@unikit-bridge/ui/primitives\";\nimport type { VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"@/lib/utils\";\n\nimport { Toggle, toggleVariants, type ToggleProps } from \"./toggle\";\n\n// 그룹 상태 — ToggleGroup이 공급하고 ToggleGroupItem이 소비.\ntype ToggleGroupContextValue = {\n  type: \"single\" | \"multiple\";\n  isSelected: (value: string) => boolean;\n  onItemPress: (value: string) => void;\n  variant: VariantProps<typeof toggleVariants>[\"variant\"];\n  size: VariantProps<typeof toggleVariants>[\"size\"];\n  disabled: boolean;\n};\n\n// 그룹 밖에서 Item을 쓴 경우의 폴백 — 눌림 없는 정적 항목으로 렌더（비권장）.\nconst ToggleGroupContext = createContext<ToggleGroupContextValue>({\n  type: \"single\",\n  isSelected: () => false,\n  onItemPress: () => {},\n  variant: \"default\",\n  size: \"default\",\n  disabled: false,\n});\n\n// shadcn 원본 API 준수 — type에 따라 value/onValueChange 시그니처가 갈린다.\ntype ToggleGroupBaseProps = ViewProps &\n  VariantProps<typeof toggleVariants> & {\n    /** 단일/다중 선택 — 기본 single */\n    type?: \"single\" | \"multiple\";\n    /** 비제어형 초기값（single: 문자열, multiple: 배열） */\n    defaultValue?: string | string[];\n    /** 그룹 전체 차단 — 항목에 일괄 전파 */\n    disabled?: boolean;\n  };\n\nexport type ToggleGroupProps = ToggleGroupBaseProps &\n  (\n    | {\n        type?: \"single\";\n        value?: string;\n        onValueChange?: (value: string) => void;\n      }\n    | {\n        type: \"multiple\";\n        value?: string[];\n        onValueChange?: (value: string[]) => void;\n      }\n  );\n\n// 내부 상태는 string［］로 통합（single은 길이 0~1 배열） — \"\"·undefined는 선택 없음.\nconst toArray = (v: string | string[] | undefined): string[] =>\n  v === undefined || v === \"\" ? [] : Array.isArray(v) ? v : [v];\n\nconst ToggleGroup = forwardRef<BridgeViewRef, ToggleGroupProps>(\n  (\n    {\n      className,\n      variant,\n      size,\n      type = \"single\",\n      value,\n      defaultValue,\n      onValueChange,\n      disabled = false,\n      children,\n      ...props\n    },\n    ref,\n  ) => {\n    const [uncontrolled, setUncontrolled] = useState(() =>\n      toArray(defaultValue),\n    );\n    const isControlled = value !== undefined;\n    const selected = useMemo(\n      () => (isControlled ? toArray(value) : uncontrolled),\n      [isControlled, value, uncontrolled],\n    );\n    const selectedRef = useRef(selected);\n    selectedRef.current = selected;\n\n    const isSelected = useCallback(\n      (itemValue: string) => selected.includes(itemValue),\n      [selected],\n    );\n\n    const handleItemPress = useCallback(\n      (itemValue: string) => {\n        const current = selectedRef.current;\n        if (type === \"multiple\") {\n          const next = current.includes(itemValue)\n            ? current.filter((v) => v !== itemValue)\n            : [...current, itemValue];\n          if (!isControlled) setUncontrolled(next);\n          if (onValueChange) {\n            // type 브랜치가 보장하는 시그니처로 좁힌다（any 아님）.\n            (onValueChange as (value: string[]) => void)(next);\n          }\n          return;\n        }\n        // single — 이미 선택된 항목 재선택 시 해제（radix 동작: 빈 문자열 방출）\n        const next = current[0] === itemValue ? [] : [itemValue];\n        if (!isControlled) setUncontrolled(next);\n        if (onValueChange) {\n          (onValueChange as (value: string) => void)(next[0] ?? \"\");\n        }\n      },\n      [type, isControlled, onValueChange],\n    );\n\n    const contextValue = useMemo(\n      () => ({\n        type,\n        isSelected,\n        onItemPress: handleItemPress,\n        variant,\n        size,\n        disabled,\n      }),\n      [type, isSelected, handleItemPress, variant, size, disabled],\n    );\n\n    return (\n      <View\n        ref={ref}\n        className={cn(\n          // w-fit은 uniwind 미지원 — self-start 치환으로 양쪽 플랫폼 내용 폭（M-2）.\n          \"flex self-start flex-row items-center gap-1 rounded-md\",\n          className,\n        )}\n        {...props}\n      >\n        <ToggleGroupContext.Provider value={contextValue}>\n          {children}\n        </ToggleGroupContext.Provider>\n      </View>\n    );\n  },\n);\nToggleGroup.displayName = \"ToggleGroup\";\n\nexport type ToggleGroupItemProps = Omit<\n  ToggleProps,\n  \"pressed\" | \"defaultPressed\" | \"onPressedChange\"\n> & {\n  /** 이 항목의 값 */\n  value: string;\n};\n\nconst ToggleGroupItem = forwardRef<BridgePressableRef, ToggleGroupItemProps>(\n  (\n    { className, variant, size, disabled, value, children, ...props },\n    ref,\n  ) => {\n    const group = useContext(ToggleGroupContext);\n    const isPressed = group.isSelected(value);\n    const isDisabled = disabled || group.disabled;\n    const onItemPress = group.onItemPress;\n    const handlePressedChange = useCallback(\n      () => onItemPress(value),\n      [onItemPress, value],\n    );\n\n    return (\n      <Toggle\n        ref={ref}\n        variant={group.variant ?? variant}\n        size={group.size ?? size}\n        pressed={isPressed}\n        onPressedChange={handlePressedChange}\n        disabled={isDisabled}\n        className={cn(\n          // 원본 항목 오버라이드: min-w-9 → min-w-0, px-2 → px-3. z-index는 웹 전용.\n          \"w-auto min-w-0 shrink-0 px-3 web:focus:z-10 web:focus-visible:z-10\",\n          className,\n        )}\n        {...props}\n      >\n        {children}\n      </Toggle>\n    );\n  },\n);\nToggleGroupItem.displayName = \"ToggleGroupItem\";\n\nexport { ToggleGroup, ToggleGroupItem };\n",
      "type": "registry:ui",
      "target": "components/unikit/toggle-group.tsx"
    }
  ],
  "type": "registry:ui"
}
