{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "primitives-base-files",
  "title": "Files",
  "description": "A component that allows you to display a list of files and folders.",
  "dependencies": [
    "motion"
  ],
  "registryDependencies": [
    "@odysseyui/primitives-base-accordion",
    "@odysseyui/primitives-effects-highlight",
    "@odysseyui/lib-get-strict-context",
    "@odysseyui/hooks-use-controlled-state"
  ],
  "files": [
    {
      "path": "registry/primitives/base/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  AccordionPanel,\n  type AccordionProps,\n  type AccordionItemProps,\n  type AccordionHeaderProps,\n  type AccordionTriggerProps,\n  type AccordionPanelProps,\n} from '@/components/odyssey/primitives/base/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 FilesProps = {\n  children: React.ReactNode;\n  defaultOpen?: string[];\n  open?: string[];\n  onOpenChange?: (open: string[]) => void;\n} & Omit<AccordionProps, 'type' | 'defaultValue' | 'value' | 'onValueChange'>;\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        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 FolderPanelProps = AccordionPanelProps;\n\nfunction FolderPanel(props: FolderPanelProps) {\n  return <AccordionPanel data-slot=\"folder-panel\" {...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\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\nexport {\n  Files,\n  FilesHighlight,\n  FolderItem,\n  FolderHeader,\n  FolderTrigger,\n  FolderPanel,\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 FolderPanelProps,\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/base/files.tsx"
    }
  ],
  "type": "registry:ui"
}