{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "inline-list",
  "title": "Inline List",
  "description": "A grouped list section for settings-style rows with flexible leading and trailing addons.",
  "registryDependencies": [],
  "files": [
    {
      "path": "ui/inline-list.tsx",
      "content": "import { cva, type VariantProps } from \"class-variance-authority\";\nimport {\n  Children,\n  cloneElement,\n  createContext,\n  isValidElement,\n  useContext,\n  useMemo,\n} from \"react\";\nimport { Pressable, View } from \"react-native\";\nimport { cn } from \"@/lib/utils\";\nimport { Text } from \"./text\";\n\n// Types\nexport type InlineListProps = React.ComponentProps<typeof View> & {\n  title?: string;\n  children: React.ReactNode;\n};\n\ntype InlineListItemVariant = \"default\" | \"destructive\";\n\nexport type InlineListItemProps = React.ComponentProps<typeof Pressable> & {\n  children: React.ReactNode;\n  showSeparator?: boolean;\n  variant?: InlineListItemVariant;\n};\n\nexport type InlineListItemTitleProps = React.ComponentProps<typeof Text>;\nexport type InlineListItemDescriptionProps = React.ComponentProps<typeof Text>;\n\nexport type InlineListItemAddonProps = React.ComponentProps<typeof View> &\n  VariantProps<typeof inlineListItemAddonVariants> & {\n    children: React.ReactNode;\n  };\n\ntype InlineListItemAddonIconProps = {\n  children: React.ReactNode;\n  className?: string;\n};\n\nexport type InlineListItemAddonChild =\n  | React.ReactElement<InlineListItemAddonProps>\n  | null\n  | false;\n\nexport type InlineListItemAddonChildren =\n  | InlineListItemAddonChild\n  | InlineListItemAddonChild[];\n\ntype InlineListItemAddonAlign = NonNullable<\n  VariantProps<typeof inlineListItemAddonVariants>[\"align\"]\n>;\n\n// Context\ntype InlineListSeparatorContextValue = {\n  showSeparator: boolean;\n};\n\nconst InlineListSeparatorContext =\n  createContext<InlineListSeparatorContextValue | null>(null);\n\nconst InlineListItemContext = createContext<InlineListItemVariant>(\"default\");\n\nconst useInlineListItemContext = () => useContext(InlineListItemContext);\n\nconst InlineListItemAddonContext =\n  createContext<InlineListItemAddonAlign>(\"inline-start\");\n\nconst useInlineListItemAddonContext = () =>\n  useContext(InlineListItemAddonContext);\n\n// Hooks\nexport const useInlineListItemAddons = (children?: React.ReactNode) => {\n  const startAddons: InlineListItemAddonChild[] = [];\n  const endAddons: InlineListItemAddonChild[] = [];\n\n  Children.forEach(children, (child) => {\n    if (isValidElement(child) && child.type === InlineListItemAddon) {\n      const typedChild = child as InlineListItemAddonChild;\n\n      if (typedChild) {\n        if (\n          typeof typedChild.props.align === \"undefined\" ||\n          typedChild.props.align === \"inline-start\"\n        ) {\n          startAddons.push(typedChild);\n        } else {\n          endAddons.push(typedChild);\n        }\n      }\n    }\n  });\n\n  return {\n    endAddons,\n    startAddons,\n  };\n};\n\nconst renderItemsWithSeparators = (children: React.ReactNode) => {\n  const childArray = Children.toArray(children);\n  const lastIndex = childArray.length - 1;\n\n  return childArray.map((child, index) => {\n    const key = isValidElement(child) && child.key !== null ? child.key : index;\n\n    return (\n      <InlineListSeparatorContext.Provider\n        key={key}\n        value={{ showSeparator: index !== lastIndex }}\n      >\n        {child}\n      </InlineListSeparatorContext.Provider>\n    );\n  });\n};\n\nconst parseInlineListItemContent = (children: React.ReactNode) => {\n  const content: React.ReactNode[] = [];\n  let contentIndex = 0;\n\n  Children.forEach(children, (child) => {\n    if (isValidElement(child) && child.type === InlineListItemAddon) {\n      return;\n    }\n\n    if (typeof child === \"string\") {\n      content.push(\n        <InlineListItemTitle key={`inline-list-item-title-${contentIndex}`}>\n          {child}\n        </InlineListItemTitle>\n      );\n      contentIndex += 1;\n      return;\n    }\n\n    if (isValidElement(child)) {\n      if (child.key === null) {\n        content.push(\n          cloneElement(child, {\n            key: `inline-list-item-content-${contentIndex}`,\n          })\n        );\n        contentIndex += 1;\n        return;\n      }\n\n      content.push(child);\n    }\n  });\n\n  return content;\n};\n\n// Components\nexport const InlineList = ({\n  title,\n  children,\n  className,\n  ...props\n}: InlineListProps) => {\n  const items = useMemo(() => renderItemsWithSeparators(children), [children]);\n\n  return (\n    <View className={cn(\"flex w-full flex-col gap-1\", className)} {...props}>\n      {title ? (\n        <Text className=\"px-4 text-muted-foreground text-xs uppercase tracking-wide\">\n          {title}\n        </Text>\n      ) : null}\n      <View\n        className=\"w-full overflow-hidden rounded-2xl bg-card\"\n        data-slot=\"inline-list\"\n      >\n        {items}\n      </View>\n    </View>\n  );\n};\n\nexport const InlineListItem = ({\n  children,\n  className,\n  showSeparator: showSeparatorProp,\n  onPress,\n  disabled,\n  variant = \"default\",\n  ...props\n}: InlineListItemProps) => {\n  const separatorContext = useContext(InlineListSeparatorContext);\n  const showSeparator =\n    showSeparatorProp ?? separatorContext?.showSeparator ?? false;\n  const { startAddons, endAddons } = useInlineListItemAddons(children);\n  const content = useMemo(\n    () => parseInlineListItemContent(children),\n    [children]\n  );\n\n  const rowClassName = cn(inlineListItemVariants({ variant }), className);\n\n  const rowContent = (\n    <>\n      {startAddons}\n      <View className=\"min-w-0 flex-1 flex-col justify-center gap-1\">\n        {content}\n      </View>\n      {endAddons}\n    </>\n  );\n\n  return (\n    <InlineListItemContext.Provider value={variant}>\n      <View className=\"w-full\" data-slot=\"inline-list-item\">\n        {onPress ? (\n          <Pressable\n            {...props}\n            accessibilityState={{\n              disabled: disabled ?? undefined,\n              ...props.accessibilityState,\n            }}\n            className={rowClassName}\n            disabled={disabled}\n            onPress={onPress}\n          >\n            {rowContent}\n          </Pressable>\n        ) : (\n          <View className={rowClassName}>{rowContent}</View>\n        )}\n\n        {showSeparator ? (\n          <View\n            className=\"mx-4 h-hairline bg-border\"\n            data-slot=\"inline-list-item-separator\"\n          />\n        ) : null}\n      </View>\n    </InlineListItemContext.Provider>\n  );\n};\n\nexport const InlineListItemTitle = ({\n  className,\n  ...props\n}: InlineListItemTitleProps) => {\n  const variant = useInlineListItemContext();\n  return (\n    <Text\n      className={cn(\n        \"font-medium text-base text-foreground\",\n        variant === \"destructive\" && \"font-normal text-destructive\",\n        className\n      )}\n      data-slot=\"inline-list-item-title\"\n      {...props}\n    />\n  );\n};\n\nexport const InlineListItemDescription = ({\n  className,\n  ...props\n}: InlineListItemDescriptionProps) => {\n  return (\n    <Text\n      className={cn(\"text-muted-foreground text-xs leading-none\", className)}\n      data-slot=\"inline-list-item-description\"\n      {...props}\n    />\n  );\n};\n\nexport const InlineListItemAddon = ({\n  align,\n  className,\n  children,\n  ...props\n}: InlineListItemAddonProps) => {\n  const resolvedAlign = align ?? \"inline-start\";\n\n  return (\n    <InlineListItemAddonContext.Provider value={resolvedAlign}>\n      <View\n        className={cn(inlineListItemAddonVariants({ align }), className)}\n        data-slot=\"inline-list-item-addon\"\n        {...props}\n      >\n        {children}\n      </View>\n    </InlineListItemAddonContext.Provider>\n  );\n};\n\nexport const InlineListItemAddonIcon = ({\n  children,\n  ...props\n}: InlineListItemAddonIconProps): React.ReactElement | null => {\n  const variant = useInlineListItemContext();\n  const align = useInlineListItemAddonContext();\n  const child = Children.only(children);\n\n  if (!child) {\n    if (__DEV__) {\n      throw new Error(\n        \"InlineListItemAddonIcon expects a single React element as children\"\n      );\n    }\n    return null;\n  }\n\n  return cloneElement(\n    child as React.ReactElement<InlineListItemAddonIconProps>,\n    {\n      ...props,\n      className: cn(\n        \"size-5\",\n        align === \"inline-start\"\n          ? variant === \"destructive\"\n            ? \"text-destructive\"\n            : \"text-foreground\"\n          : \"text-muted-foreground\",\n        props.className\n      ),\n    }\n  );\n};\n\n// Styles\nconst inlineListItemVariants = cva(\n  \"min-h-12 w-full flex-row items-center gap-3 px-4 py-2 disabled:opacity-50\",\n  {\n    defaultVariants: {\n      variant: \"default\",\n    },\n    variants: {\n      variant: {\n        default: \"active:bg-accent/90 dark:active:bg-accent/50\",\n        destructive: \"active:bg-destructive/5 dark:active:bg-destructive/10\",\n      },\n    },\n  }\n);\n\nconst inlineListItemAddonVariants = cva(\n  \"shrink-0 items-center justify-center\",\n  {\n    defaultVariants: {\n      align: \"inline-start\",\n    },\n    variants: {\n      align: {\n        \"inline-end\": \"\",\n        \"inline-start\": \"\",\n      },\n    },\n  }\n);\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}
