{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "box", "title": "Box Widget", "description": "AdminLTE box/card widget with header, body, footer, tools. Supports 6 color variants, solid fill, collapsible, removable, and loading overlay.", "dependencies": [ "lucide-react" ], "registryDependencies": [ "https://raw.githubusercontent.com/dnachavez/adminlte-next/master/public/r/adminlte-theme.json", "https://raw.githubusercontent.com/dnachavez/adminlte-next/master/public/r/adminlte-button.json", "https://raw.githubusercontent.com/dnachavez/adminlte-next/master/public/r/use-collapsible.json", "https://raw.githubusercontent.com/dnachavez/adminlte-next/master/public/r/use-removable.json", "https://raw.githubusercontent.com/dnachavez/adminlte-next/master/public/r/use-box-loading.json" ], "files": [ { "path": "registry/new-york/box/components/box.tsx", "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { useState, useRef, useEffect, useCallback } from \"react\"\nimport { cn } from \"@/registry/new-york/adminlte-theme/lib/cn\"\nimport { type BoxVariant, boxVariantColors } from \"@/registry/new-york/adminlte-theme/lib/colors\"\n\n/* -------------------------------------------------------------------------- */\n/* BoxTools */\n/* -------------------------------------------------------------------------- */\n\ninterface BoxToolsProps extends React.HTMLAttributes {\n children?: React.ReactNode\n}\n\nconst BoxTools = React.forwardRef(\n ({ className, children, ...props }, ref) => (\n \n {children}\n \n )\n)\nBoxTools.displayName = \"BoxTools\"\n\n/* -------------------------------------------------------------------------- */\n/* BoxHeader */\n/* -------------------------------------------------------------------------- */\n\ninterface BoxHeaderProps extends React.HTMLAttributes {\n title?: string\n children?: React.ReactNode\n}\n\nconst BoxHeader = React.forwardRef(\n ({ className, title, children, ...props }, ref) => (\n \n {title && (\n

{title}

\n )}\n {children}\n \n )\n)\nBoxHeader.displayName = \"BoxHeader\"\n\n/* -------------------------------------------------------------------------- */\n/* BoxBody */\n/* -------------------------------------------------------------------------- */\n\ninterface BoxBodyProps extends React.HTMLAttributes {\n children?: React.ReactNode\n}\n\nconst BoxBody = React.forwardRef(\n ({ className, children, ...props }, ref) => (\n \n {children}\n \n )\n)\nBoxBody.displayName = \"BoxBody\"\n\n/* -------------------------------------------------------------------------- */\n/* BoxFooter */\n/* -------------------------------------------------------------------------- */\n\ninterface BoxFooterProps extends React.HTMLAttributes {\n children?: React.ReactNode\n}\n\nconst BoxFooter = React.forwardRef(\n ({ className, children, ...props }, ref) => (\n \n {children}\n \n )\n)\nBoxFooter.displayName = \"BoxFooter\"\n\n/* -------------------------------------------------------------------------- */\n/* Loading overlay spinner */\n/* -------------------------------------------------------------------------- */\n\nfunction BoxLoadingOverlay() {\n return (\n
\n \n \n \n \n
\n )\n}\n\n/* -------------------------------------------------------------------------- */\n/* Tool buttons (collapse / remove) */\n/* -------------------------------------------------------------------------- */\n\nfunction CollapseButton({\n isCollapsed,\n onClick,\n solid,\n}: {\n isCollapsed: boolean\n onClick: () => void\n solid?: boolean\n}) {\n return (\n \n \n {isCollapsed ? (\n \n ) : (\n \n )}\n \n \n )\n}\n\nfunction RemoveButton({\n onClick,\n solid,\n}: {\n onClick: () => void\n solid?: boolean\n}) {\n return (\n \n \n \n \n \n \n )\n}\n\n/* -------------------------------------------------------------------------- */\n/* Box */\n/* -------------------------------------------------------------------------- */\n\nconst solidVariantBg: Record = {\n default: \"bg-[#d2d6de]\",\n primary: \"bg-[#3c8dbc]\",\n info: \"bg-[#00c0ef]\",\n success: \"bg-[#00a65a]\",\n warning: \"bg-[#f39c12]\",\n danger: \"bg-[#dd4b39]\",\n}\n\ninterface BoxProps extends React.HTMLAttributes {\n variant?: BoxVariant\n solid?: boolean\n collapsible?: boolean\n removable?: boolean\n loading?: boolean\n defaultCollapsed?: boolean\n title?: string\n tools?: React.ReactNode\n footer?: React.ReactNode\n children?: React.ReactNode\n}\n\nconst Box = React.forwardRef(\n (\n {\n className,\n variant = \"default\",\n solid = false,\n collapsible = false,\n removable = false,\n loading = false,\n defaultCollapsed = false,\n title,\n tools,\n footer,\n children,\n ...props\n },\n ref\n ) => {\n const [isCollapsed, setIsCollapsed] = useState(defaultCollapsed)\n const [isRemoving, setIsRemoving] = useState(false)\n const [isRemoved, setIsRemoved] = useState(false)\n const contentRef = useRef(null)\n const [contentHeight, setContentHeight] = useState(\n undefined\n )\n\n const toggleCollapse = useCallback(() => {\n setIsCollapsed((prev) => !prev)\n }, [])\n\n const handleRemove = useCallback(() => {\n setIsRemoving(true)\n setTimeout(() => {\n setIsRemoved(true)\n }, 500)\n }, [])\n\n useEffect(() => {\n if (contentRef.current) {\n setContentHeight(contentRef.current.scrollHeight)\n }\n }, [children, footer])\n\n if (isRemoved) return null\n\n const borderColor = boxVariantColors[variant]\n const hasHeader = title || tools || collapsible || removable\n const showToolbar = collapsible || removable || tools\n\n return (\n \n {/* Loading overlay */}\n {loading && }\n\n {/* Header */}\n {hasHeader && (\n \n {showToolbar && (\n \n {tools}\n {collapsible && (\n \n )}\n {removable && (\n \n )}\n \n )}\n \n )}\n\n {/* Collapsible wrapper */}\n \n {/* Body */}\n {children && {children}}\n\n {/* Footer */}\n {footer && {footer}}\n \n \n )\n }\n)\nBox.displayName = \"Box\"\n\nexport { Box, BoxHeader, BoxBody, BoxFooter, BoxTools }\nexport type { BoxProps, BoxHeaderProps, BoxBodyProps, BoxFooterProps, BoxToolsProps }\n", "type": "registry:component" } ], "type": "registry:component" }