{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "collapsible",
  "title": "Collapsible",
  "description": "접기/펼치기 — open/defaultOpen/onOpenChange + trigger(aria-expanded)·content 3종 구성. 무스타일 패스스루(shadcn 원본 계약).",
  "dependencies": [
    "@unikit-bridge/ui",
    "clsx",
    "tailwind-merge",
    "tailwindcss"
  ],
  "registryDependencies": [],
  "files": [
    {
      "path": "registry/ui/collapsible.tsx",
      "content": "// Collapsible — shadcn/ui（new-york-v4） collapsible.tsx 유니버설 포팅 （사이클 30, T-3b）.\n// 원본: shadcn-ref/ui/collapsible.tsx — radix Collapsible을 그대로\n// 재노출하는 무스타일 래퍼라 이식 결과에도 스타일 토큰이 없다. radix 의존 제거의\n// 가장 단순한 예로, 전개 상태（open）를 React state + context로 직접 관리한다.\n// （accordion.tsx가 같은 구조의 다중 항목 확장이다.）\n//\n// 포팅 판단（원본 대비 차이）:\n// - 애니메이션（radix data-state 기반 CSS 전이） 미지원 — 열림/닫힘 즉시 전환.\n// - 콘텐츠는 open 시에만 마운트한다（마운트/언마운트 방식）.\n// - Trigger는 Pressable（웹 button） — 네이티브 Pressable（View 기반）에 문자열\n//   children을 직접 두면 RN 런타임이 크래시하므로（\"Text strings must be\n//   rendered within a <Text> component\"） children을 내부 Text로 감싼다（B-1）.\n//   문자열 라벨 children 권장（AccordionTrigger와 동일 구조）.\nimport {\n  createContext,\n  forwardRef,\n  useCallback,\n  useContext,\n  useMemo,\n  useRef,\n  useState,\n  type ReactNode,\n} from \"react\";\nimport {\n  animateLayout,\n  Pressable,\n  Text,\n  View,\n  type BridgePressableRef,\n  type BridgeViewRef,\n  type PressableProps,\n  type ViewProps,\n} from \"@unikit-bridge/ui/primitives\";\n\ntype CollapsibleContextValue = {\n  open: boolean;\n  toggle: () => void;\n};\n\nconst CollapsibleContext = createContext<CollapsibleContextValue | null>(null);\n\nfunction useCollapsibleContext(component: string): CollapsibleContextValue {\n  const ctx = useContext(CollapsibleContext);\n  if (!ctx) {\n    throw new Error(`<${component}>는 <Collapsible> 안에서 사용해야 합니다.`);\n  }\n  return ctx;\n}\n\nexport type CollapsibleProps = ViewProps & {\n  open?: boolean;\n  defaultOpen?: boolean;\n  onOpenChange?: (open: boolean) => void;\n};\n\nconst Collapsible = forwardRef<BridgeViewRef, CollapsibleProps>(\n  ({ open, defaultOpen = false, onOpenChange, children, ...props }, ref) => {\n    // 비제어 상태 — 제어（open 지정）면 무시된다.\n    const [internalOpen, setInternalOpen] = useState(defaultOpen);\n    const isOpen = open ?? internalOpen;\n    const isOpenRef = useRef(isOpen);\n    isOpenRef.current = isOpen;\n    const toggle = useCallback(() => {\n      animateLayout();\n      const next = !isOpenRef.current;\n      if (open === undefined) setInternalOpen(next);\n      onOpenChange?.(next);\n    }, [open, onOpenChange]);\n    const contextValue = useMemo(\n      () => ({ open: isOpen, toggle }),\n      [isOpen, toggle],\n    );\n    return (\n      <CollapsibleContext.Provider value={contextValue}>\n        <View ref={ref} {...props}>\n          {children}\n        </View>\n      </CollapsibleContext.Provider>\n    );\n  },\n);\nCollapsible.displayName = \"Collapsible\";\n\nexport type CollapsibleTriggerProps = PressableProps & {\n  // 함수형 children은 내부 Text 래핑 구조와 양립하지 않아 문자열 children 권장.\n  children?: ReactNode;\n};\n\nconst CollapsibleTrigger = forwardRef<\n  BridgePressableRef,\n  CollapsibleTriggerProps\n>(({ children, onPress, ...props }, ref) => {\n  const { open, toggle } = useCollapsibleContext(\"CollapsibleTrigger\");\n  return (\n    <Pressable\n      ref={ref}\n      accessibilityRole=\"button\"\n      aria-expanded={open}\n      onPress={() => {\n        toggle();\n        onPress?.();\n      }}\n      {...props}\n    >\n      {/* 이중 지정: 전경색·타이포그래피는 내부 Text에（네이티브 색 상속 불가） */}\n      <Text className=\"font-sans text-sm font-medium text-foreground\">\n        {children}\n      </Text>\n    </Pressable>\n  );\n});\nCollapsibleTrigger.displayName = \"CollapsibleTrigger\";\n\nexport type CollapsibleContentProps = ViewProps;\n\nconst CollapsibleContent = forwardRef<BridgeViewRef, CollapsibleContentProps>(\n  ({ children, ...props }, ref) => {\n    const { open } = useCollapsibleContext(\"CollapsibleContent\");\n    // open 시에만 렌더 — 마운트/언마운트 방식（애니메이션 없음）.\n    if (!open) return null;\n    return (\n      <View ref={ref} {...props}>\n        {children}\n      </View>\n    );\n  },\n);\nCollapsibleContent.displayName = \"CollapsibleContent\";\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent };\n",
      "type": "registry:ui",
      "target": "components/unikit/collapsible.tsx"
    }
  ],
  "type": "registry:ui"
}
