{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "primitives-radix-files",
  "title": "Files",
  "description": "A component that allows you to display a list of files and folders.",
  "dependencies": [
    "motion"
  ],
  "registryDependencies": [
    "@odysseyui/primitives-radix-accordion",
    "@odysseyui/primitives-effects-highlight",
    "@odysseyui/lib-get-strict-context",
    "@odysseyui/hooks-use-controlled-state"
  ],
  "files": [
    {
      "path": "registry/primitives/radix/files/index.tsx",
      "content": "'use client';\n\nimport * as React from 'react';\nimport { AnimatePresence, motion, type HTMLMotionProps } from 'motion/react';\n\nimport {\n  Highlight,\n  HighlightItem,\n  type HighlightItemProps,\n  type HighlightProps,\n} from '@/components/odyssey/primitives/effects/highlight';\nimport {\n  Accordion,\n  AccordionItem,\n  AccordionHeader,\n  AccordionTrigger,\n  AccordionContent,\n  type AccordionProps,\n  type AccordionItemProps,\n  type AccordionHeaderProps,\n  type AccordionTriggerProps,\n  type AccordionContentProps,\n} from '@/components/odyssey/primitives/radix/accordion';\nimport { getStrictContext } from '@/lib/get-strict-context';\nimport { useControlledState } from '@/hooks/use-controlled-state';\n\ntype FilesContextType = {\n  open: string[];\n};\n\ntype FolderContextType = {\n  isOpen: boolean;\n};\n\nconst [FilesProvider, useFiles] =\n  getStrictContext<FilesContextType>('FilesContext');\n\nconst [FolderProvider, useFolder] =\n  getStrictContext<FolderContextType>('FolderContext');\n\ntype BaseFilesProps = {\n  children: React.ReactNode;\n} & Omit<AccordionProps, 'type' | 'defaultValue' | 'value' | 'onValueChange'>;\n\ntype ControlledFilesProps = {\n  defaultOpen?: never;\n  open?: string[];\n  onOpenChange?: (open: string[]) => void;\n};\n\ntype UncontrolledFilesProps = {\n  defaultOpen: string[];\n  open?: never;\n  onOpenChange?: never;\n};\n\ntype FilesProps = BaseFilesProps &\n  (ControlledFilesProps | UncontrolledFilesProps);\n\nfunction Files({\n  children,\n  defaultOpen = [],\n  open,\n  onOpenChange,\n  style,\n  ...props\n}: FilesProps) {\n  const [openValue, setOpenValue] = useControlledState({\n    value: open,\n    defaultValue: defaultOpen,\n    onChange: onOpenChange,\n  });\n\n  return (\n    <FilesProvider value={{ open: openValue ?? [] }}>\n      <Accordion\n        data-slot=\"files\"\n        type=\"multiple\"\n        defaultValue={defaultOpen}\n        value={open}\n        onValueChange={setOpenValue}\n        style={{\n          position: 'relative',\n          overflow: 'auto',\n          ...style,\n        }}\n        {...props}\n      >\n        {children}\n      </Accordion>\n    </FilesProvider>\n  );\n}\n\ntype FilesHighlightProps = Omit<HighlightProps, 'controlledItems' | 'mode'>;\n\nfunction FilesHighlight({ hover = true, ...props }: FilesHighlightProps) {\n  return (\n    <Highlight\n      data-slot=\"files-highlight\"\n      controlledItems\n      mode=\"parent\"\n      hover={hover}\n      {...props}\n    />\n  );\n}\n\ntype FolderItemProps = AccordionItemProps;\n\nfunction FolderItem({ value, ...props }: FolderItemProps) {\n  const { open } = useFiles();\n\n  return (\n    <FolderProvider value={{ isOpen: open.includes(value) }}>\n      <AccordionItem data-slot=\"folder-item\" value={value} {...props} />\n    </FolderProvider>\n  );\n}\n\ntype FolderHeaderProps = AccordionHeaderProps;\n\nfunction FolderHeader(props: FolderHeaderProps) {\n  return <AccordionHeader data-slot=\"folder-header\" {...props} />;\n}\n\ntype FolderTriggerProps = AccordionTriggerProps;\n\nfunction FolderTrigger(props: FolderTriggerProps) {\n  return <AccordionTrigger data-slot=\"folder-trigger\" {...props} />;\n}\n\ntype FolderContentProps = AccordionContentProps;\n\nfunction FolderContent(props: FolderContentProps) {\n  return <AccordionContent data-slot=\"folder-content\" {...props} />;\n}\n\ntype FolderHighlightProps = HighlightItemProps;\n\nfunction FolderHighlight(props: FolderHighlightProps) {\n  return <HighlightItem data-slot=\"folder-highlight\" {...props} />;\n}\n\ntype FolderProps = React.ComponentProps<'div'>;\n\nfunction Folder(props: FolderProps) {\n  return <div data-slot=\"folder\" {...props} />;\n}\n\ntype FolderIconProps = HTMLMotionProps<'span'> & {\n  closeIcon: React.ReactNode;\n  openIcon: React.ReactNode;\n};\n\nfunction FolderIcon({\n  closeIcon,\n  openIcon,\n  transition = { duration: 0.15 },\n  ...props\n}: FolderIconProps) {\n  const { isOpen } = useFolder();\n\n  return (\n    <AnimatePresence mode=\"wait\">\n      <motion.span\n        key={isOpen ? 'open' : 'close'}\n        data-slot=\"folder-icon\"\n        initial={{ scale: 0.9 }}\n        animate={{ scale: 1 }}\n        exit={{ scale: 0.9 }}\n        transition={transition}\n        {...props}\n      >\n        {isOpen ? openIcon : closeIcon}\n      </motion.span>\n    </AnimatePresence>\n  );\n}\n\ntype FolderLabelProps = React.ComponentProps<'span'>;\n\nfunction FolderLabel(props: FolderLabelProps) {\n  return <span data-slot=\"folder-label\" {...props} />;\n}\n\ntype FileHighlightProps = HighlightItemProps;\n\nfunction FileHighlight(props: FileHighlightProps) {\n  return <HighlightItem data-slot=\"file-highlight\" {...props} />;\n}\n\ntype FileProps = React.ComponentProps<'div'>;\n\nfunction File(props: FileProps) {\n  return <div data-slot=\"file\" {...props} />;\n}\n\ntype FileIconProps = React.ComponentProps<'span'>;\n\nfunction FileIcon(props: FileIconProps) {\n  return <span data-slot=\"file-icon\" {...props} />;\n}\n\ntype FileLabelProps = React.ComponentProps<'span'>;\n\nfunction FileLabel(props: FileLabelProps) {\n  return <span data-slot=\"file-label\" {...props} />;\n}\n\nexport {\n  Files,\n  FilesHighlight,\n  FolderItem,\n  FolderHeader,\n  FolderTrigger,\n  FolderContent,\n  FileHighlight,\n  File,\n  FileIcon,\n  FileLabel,\n  FolderHighlight,\n  Folder,\n  FolderIcon,\n  FolderLabel,\n  useFiles,\n  useFolder,\n  type FilesProps,\n  type FilesHighlightProps,\n  type FolderItemProps,\n  type FolderHeaderProps,\n  type FolderTriggerProps,\n  type FolderContentProps,\n  type FileHighlightProps,\n  type FileProps,\n  type FileIconProps,\n  type FileLabelProps,\n  type FolderHighlightProps,\n  type FolderProps,\n  type FolderIconProps,\n  type FolderLabelProps,\n  type FilesContextType,\n  type FolderContextType,\n};\n",
      "type": "registry:ui",
      "target": "components/odysseyui/primitives/radix/files.tsx"
    }
  ],
  "type": "registry:ui"
}