asterui 0.12.59 → 0.12.61

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"Cascader.js","sources":["../../src/components/Cascader.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect, useCallback, useId, forwardRef, useMemo } from 'react'\n\n// DaisyUI classes\nconst dInput = 'input'\nconst dInputXs = 'input-xs'\nconst dInputSm = 'input-sm'\nconst dInputMd = 'input-md'\nconst dInputLg = 'input-lg'\nconst dInputDisabled = 'input-disabled'\nconst dInputPrimary = 'input-primary'\nconst dInputError = 'input-error'\nconst dInputWarning = 'input-warning'\nconst dBadge = 'badge'\nconst dBadgeSm = 'badge-sm'\nconst dBtn = 'btn'\nconst dBtnGhost = 'btn-ghost'\nconst dBtnXs = 'btn-xs'\nconst dBtnCircle = 'btn-circle'\nconst dLoading = 'loading'\nconst dLoadingSpinner = 'loading-spinner'\nconst dLoadingXs = 'loading-xs'\n\nexport interface CascaderOption {\n value: string\n label: React.ReactNode\n disabled?: boolean\n children?: CascaderOption[]\n isLeaf?: boolean\n}\n\nexport type CascaderColor = 'primary' | 'secondary' | 'accent' | 'info' | 'success' | 'warning' | 'error'\nexport type CascaderSize = 'xs' | 'sm' | 'md' | 'lg'\n\nexport interface CascaderProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> {\n /** Hierarchical options data */\n options: CascaderOption[]\n /** Controlled selected value path */\n value?: string[]\n /** Default selected value path (uncontrolled) */\n defaultValue?: string[]\n /** Callback when selection changes */\n onChange?: (value: string[], selectedOptions: CascaderOption[]) => void\n /** Placeholder text */\n placeholder?: string\n /** Disable the cascader */\n disabled?: boolean\n /** Show clear button */\n allowClear?: boolean\n /** How to expand sub-menus */\n expandTrigger?: 'click' | 'hover'\n /** Allow selection of any level, not just leaf nodes */\n changeOnSelect?: boolean\n /** Custom display render function */\n displayRender?: (labels: React.ReactNode[], selectedOptions: CascaderOption[]) => React.ReactNode\n /** Input size */\n size?: CascaderSize\n /** Focus ring color */\n color?: CascaderColor\n /** Validation status */\n status?: 'error' | 'warning'\n /** Enable search/filter functionality */\n showSearch?: boolean | {\n filter?: (inputValue: string, path: CascaderOption[]) => boolean\n render?: (inputValue: string, path: CascaderOption[]) => React.ReactNode\n matchInputWidth?: boolean\n }\n /** Content when no results found */\n notFoundContent?: React.ReactNode\n /** Async data loading function */\n loadData?: (selectedOptions: CascaderOption[]) => Promise<void>\n /** Custom field names for data mapping */\n fieldNames?: {\n label?: string\n value?: string\n children?: string\n }\n /** Controlled open state */\n open?: boolean\n /** Callback when dropdown visibility changes */\n onDropdownVisibleChange?: (open: boolean) => void\n /** Class name for dropdown */\n popupClassName?: string\n /** Custom dropdown render wrapper */\n dropdownRender?: (menu: React.ReactNode) => React.ReactNode\n /** Multiple selection mode */\n multiple?: boolean\n /** Max tags to show in multiple mode */\n maxTagCount?: number | 'responsive'\n /** Accessible label */\n 'aria-label'?: string\n /** Test ID for the component */\n 'data-testid'?: string\n}\n\n// Helper to get nested value using field names\nfunction getFieldValue<T>(option: Record<string, unknown>, field: string, fallback: string): T {\n return (option[field] ?? option[fallback]) as T\n}\n\nexport const Cascader = forwardRef<HTMLDivElement, CascaderProps>(({\n options,\n value,\n defaultValue,\n onChange,\n placeholder = 'Please select',\n disabled = false,\n allowClear = true,\n expandTrigger = 'click',\n changeOnSelect = false,\n displayRender,\n size = 'md',\n color,\n status,\n showSearch = false,\n notFoundContent = 'No results found',\n loadData,\n fieldNames,\n open: controlledOpen,\n onDropdownVisibleChange,\n popupClassName = '',\n dropdownRender,\n multiple = false,\n maxTagCount,\n className = '',\n 'aria-label': ariaLabel,\n 'data-testid': testId,\n ...rest\n}, ref) => {\n const baseTestId = testId ?? 'cascader'\n const isControlledOpen = controlledOpen !== undefined\n const [internalOpen, setInternalOpen] = useState(false)\n const isOpen = isControlledOpen ? controlledOpen : internalOpen\n\n const setIsOpen = useCallback((open: boolean) => {\n if (!isControlledOpen) {\n setInternalOpen(open)\n }\n onDropdownVisibleChange?.(open)\n }, [isControlledOpen, onDropdownVisibleChange])\n\n const [selectedPath, setSelectedPath] = useState<string[]>(value ?? defaultValue ?? [])\n const [selectedPaths, setSelectedPaths] = useState<string[][]>(\n value ? [value] : defaultValue ? [defaultValue] : []\n )\n const [hoveredPath, setHoveredPath] = useState<string[]>([])\n const [focusedIndex, setFocusedIndex] = useState<{ column: number; row: number }>({ column: 0, row: 0 })\n const [searchValue, setSearchValue] = useState('')\n const [loadingKeys, setLoadingKeys] = useState<Set<string>>(new Set())\n\n const containerRef = useRef<HTMLDivElement>(null)\n const inputRef = useRef<HTMLInputElement>(null)\n const dropdownRef = useRef<HTMLDivElement>(null)\n const baseId = useId()\n const inputId = `${baseId}-input`\n const listboxId = `${baseId}-listbox`\n\n // Field name mapping\n const labelField = fieldNames?.label ?? 'label'\n const valueField = fieldNames?.value ?? 'value'\n const childrenField = fieldNames?.children ?? 'children'\n\n // Normalize options with field names\n const normalizeOption = useCallback((opt: Record<string, unknown>): CascaderOption => ({\n value: getFieldValue<string>(opt, valueField, 'value'),\n label: getFieldValue<React.ReactNode>(opt, labelField, 'label'),\n disabled: opt.disabled as boolean | undefined,\n isLeaf: opt.isLeaf as boolean | undefined,\n children: opt[childrenField]\n ? (opt[childrenField] as Record<string, unknown>[]).map(normalizeOption)\n : undefined,\n }), [labelField, valueField, childrenField])\n\n const normalizedOptions = useMemo(() =>\n options.map(opt => normalizeOption(opt as unknown as Record<string, unknown>)),\n [options, normalizeOption]\n )\n\n // Sync with controlled value\n useEffect(() => {\n if (value !== undefined) {\n setSelectedPath(value)\n if (multiple) {\n setSelectedPaths([value])\n }\n }\n }, [value, multiple])\n\n // Close on outside click\n useEffect(() => {\n const handleClickOutside = (e: MouseEvent) => {\n if (containerRef.current && !containerRef.current.contains(e.target as Node)) {\n setIsOpen(false)\n setHoveredPath([])\n setSearchValue('')\n }\n }\n\n if (isOpen) {\n document.addEventListener('mousedown', handleClickOutside)\n return () => document.removeEventListener('mousedown', handleClickOutside)\n }\n }, [isOpen, setIsOpen])\n\n // Get options at each level based on path\n const getOptionsAtLevel = useCallback((level: number, path: string[]): CascaderOption[] => {\n if (level === 0) return normalizedOptions\n\n let currentOptions = normalizedOptions\n for (let i = 0; i < level; i++) {\n const selected = currentOptions.find(opt => opt.value === path[i])\n if (!selected?.children) return []\n currentOptions = selected.children\n }\n return currentOptions\n }, [normalizedOptions])\n\n // Get selected options objects from path\n const getSelectedOptions = useCallback((path: string[]): CascaderOption[] => {\n const result: CascaderOption[] = []\n let currentOptions = normalizedOptions\n\n for (const val of path) {\n const found = currentOptions.find(opt => opt.value === val)\n if (!found) break\n result.push(found)\n currentOptions = found.children || []\n }\n\n return result\n }, [normalizedOptions])\n\n // Get all paths for search\n const getAllPaths = useCallback((): { path: CascaderOption[]; values: string[] }[] => {\n const paths: { path: CascaderOption[]; values: string[] }[] = []\n\n const traverse = (opts: CascaderOption[], currentPath: CascaderOption[], currentValues: string[]) => {\n for (const opt of opts) {\n const newPath = [...currentPath, opt]\n const newValues = [...currentValues, opt.value]\n\n if (!opt.children || opt.children.length === 0) {\n paths.push({ path: newPath, values: newValues })\n } else {\n if (changeOnSelect) {\n paths.push({ path: newPath, values: newValues })\n }\n traverse(opt.children, newPath, newValues)\n }\n }\n }\n\n traverse(normalizedOptions, [], [])\n return paths\n }, [normalizedOptions, changeOnSelect])\n\n // Filter paths for search\n const filteredPaths = useMemo(() => {\n if (!showSearch || !searchValue.trim()) return null\n\n const allPaths = getAllPaths()\n const searchLower = searchValue.toLowerCase()\n\n const filterFn = typeof showSearch === 'object' && showSearch.filter\n ? showSearch.filter\n : (inputValue: string, path: CascaderOption[]) =>\n path.some(opt =>\n String(opt.label).toLowerCase().includes(inputValue.toLowerCase())\n )\n\n return allPaths.filter(({ path }) => filterFn(searchLower, path))\n }, [showSearch, searchValue, getAllPaths])\n\n // Determine which path to use for displaying columns\n const activePath = isOpen ? (hoveredPath.length > 0 ? hoveredPath : selectedPath) : selectedPath\n\n // Build columns to display (only when not searching)\n const columns: CascaderOption[][] = useMemo(() => {\n if (filteredPaths) return []\n\n const cols: CascaderOption[][] = []\n cols.push(normalizedOptions)\n\n for (let i = 0; i < activePath.length; i++) {\n const nextOptions = getOptionsAtLevel(i + 1, activePath)\n if (nextOptions.length > 0) {\n cols.push(nextOptions)\n }\n }\n return cols\n }, [filteredPaths, normalizedOptions, activePath, getOptionsAtLevel])\n\n const handleOptionClick = async (option: CascaderOption, level: number) => {\n if (option.disabled) return\n\n const newPath = [...activePath.slice(0, level), option.value]\n const selectedOpts = getSelectedOptions(newPath)\n\n // Handle async loading\n if (loadData && !option.children && !option.isLeaf) {\n const key = option.value\n if (!loadingKeys.has(key)) {\n setLoadingKeys(prev => new Set(prev).add(key))\n try {\n await loadData(selectedOpts)\n } finally {\n setLoadingKeys(prev => {\n const next = new Set(prev)\n next.delete(key)\n return next\n })\n }\n }\n setHoveredPath(newPath)\n return\n }\n\n if (option.children && option.children.length > 0) {\n // Has children - expand\n setHoveredPath(newPath)\n\n if (changeOnSelect) {\n // In changeOnSelect mode, also select this node\n setSelectedPath(newPath)\n onChange?.(newPath, selectedOpts)\n }\n } else {\n // Leaf node - select and close\n if (multiple) {\n const pathStr = newPath.join('/')\n const isSelected = selectedPaths.some(p => p.join('/') === pathStr)\n let newPaths: string[][]\n if (isSelected) {\n newPaths = selectedPaths.filter(p => p.join('/') !== pathStr)\n } else {\n newPaths = [...selectedPaths, newPath]\n }\n setSelectedPaths(newPaths)\n // Don't close in multiple mode\n } else {\n setSelectedPath(newPath)\n setIsOpen(false)\n setHoveredPath([])\n setSearchValue('')\n onChange?.(newPath, selectedOpts)\n }\n }\n }\n\n const handleSearchResultClick = (values: string[], path: CascaderOption[]) => {\n if (multiple) {\n const pathStr = values.join('/')\n const isSelected = selectedPaths.some(p => p.join('/') === pathStr)\n let newPaths: string[][]\n if (isSelected) {\n newPaths = selectedPaths.filter(p => p.join('/') !== pathStr)\n } else {\n newPaths = [...selectedPaths, values]\n }\n setSelectedPaths(newPaths)\n } else {\n setSelectedPath(values)\n setIsOpen(false)\n setSearchValue('')\n onChange?.(values, path)\n }\n }\n\n const handleOptionHover = (option: CascaderOption, level: number) => {\n if (expandTrigger !== 'hover' || option.disabled) return\n\n const newPath = [...activePath.slice(0, level), option.value]\n setHoveredPath(newPath)\n }\n\n const handleClear = (e: React.MouseEvent) => {\n e.stopPropagation()\n if (multiple) {\n setSelectedPaths([])\n onChange?.([], [])\n } else {\n setSelectedPath([])\n onChange?.([], [])\n }\n }\n\n const handleRemoveTag = (pathToRemove: string[], e: React.MouseEvent) => {\n e.stopPropagation()\n const pathStr = pathToRemove.join('/')\n const newPaths = selectedPaths.filter(p => p.join('/') !== pathStr)\n setSelectedPaths(newPaths)\n if (newPaths.length > 0) {\n onChange?.(newPaths[newPaths.length - 1], getSelectedOptions(newPaths[newPaths.length - 1]))\n } else {\n onChange?.([], [])\n }\n }\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (disabled) return\n\n switch (e.key) {\n case 'Enter':\n e.preventDefault()\n if (!isOpen) {\n setIsOpen(true)\n } else if (filteredPaths && filteredPaths.length > 0) {\n const { values, path } = filteredPaths[focusedIndex.row] || {}\n if (values) {\n handleSearchResultClick(values, path)\n }\n } else {\n const currentColumn = columns[focusedIndex.column]\n if (currentColumn) {\n const option = currentColumn[focusedIndex.row]\n if (option) {\n handleOptionClick(option, focusedIndex.column)\n }\n }\n }\n break\n case ' ':\n if (!showSearch) {\n e.preventDefault()\n setIsOpen(!isOpen)\n }\n break\n case 'Escape':\n e.preventDefault()\n setIsOpen(false)\n setHoveredPath([])\n setSearchValue('')\n break\n case 'ArrowDown':\n e.preventDefault()\n if (!isOpen) {\n setIsOpen(true)\n } else if (filteredPaths) {\n setFocusedIndex(prev => ({\n ...prev,\n row: Math.min(prev.row + 1, filteredPaths.length - 1)\n }))\n } else {\n const currentColumn = columns[focusedIndex.column]\n if (currentColumn) {\n setFocusedIndex(prev => ({\n ...prev,\n row: Math.min(prev.row + 1, currentColumn.length - 1)\n }))\n }\n }\n break\n case 'ArrowUp':\n e.preventDefault()\n if (filteredPaths) {\n setFocusedIndex(prev => ({\n ...prev,\n row: Math.max(prev.row - 1, 0)\n }))\n } else {\n setFocusedIndex(prev => ({\n ...prev,\n row: Math.max(prev.row - 1, 0)\n }))\n }\n break\n case 'ArrowRight':\n e.preventDefault()\n if (!filteredPaths && focusedIndex.column < columns.length - 1) {\n setFocusedIndex(prev => ({\n column: prev.column + 1,\n row: 0\n }))\n }\n break\n case 'ArrowLeft':\n e.preventDefault()\n if (!filteredPaths && focusedIndex.column > 0) {\n setFocusedIndex(prev => ({\n column: prev.column - 1,\n row: 0\n }))\n }\n break\n case 'Home':\n e.preventDefault()\n setFocusedIndex(prev => ({ ...prev, row: 0 }))\n break\n case 'End':\n e.preventDefault()\n if (filteredPaths) {\n setFocusedIndex(prev => ({ ...prev, row: filteredPaths.length - 1 }))\n } else {\n const currentColumn = columns[focusedIndex.column]\n if (currentColumn) {\n setFocusedIndex(prev => ({ ...prev, row: currentColumn.length - 1 }))\n }\n }\n break\n }\n }\n\n // Reset focus when dropdown opens/closes\n useEffect(() => {\n if (isOpen) {\n setFocusedIndex({ column: 0, row: 0 })\n }\n }, [isOpen])\n\n // Display value\n const selectedOptions = getSelectedOptions(selectedPath)\n const labels = selectedOptions.map(opt => opt.label)\n const displayValue = displayRender\n ? displayRender(labels, selectedOptions)\n : labels.join(' / ')\n\n // Size classes\n const sizeClasses: Record<CascaderSize, string> = {\n xs: `${dInputXs} text-xs min-h-6`,\n sm: `${dInputSm} text-sm min-h-8`,\n md: `${dInputMd} min-h-10`,\n lg: `${dInputLg} text-lg min-h-12`,\n }\n\n const dropdownSizeClasses: Record<CascaderSize, string> = {\n xs: 'text-xs',\n sm: 'text-sm',\n md: 'text-base',\n lg: 'text-lg',\n }\n\n // Color and status classes\n const colorClasses: Record<CascaderColor, string> = {\n primary: 'border-primary focus:border-primary',\n secondary: 'border-secondary focus:border-secondary',\n accent: 'border-accent focus:border-accent',\n info: 'border-info focus:border-info',\n success: 'border-success focus:border-success',\n warning: 'border-warning focus:border-warning',\n error: 'border-error focus:border-error',\n }\n\n const getColorClass = () => {\n if (status === 'error') return dInputError\n if (status === 'warning') return dInputWarning\n if (color && isOpen) return colorClasses[color]\n if (isOpen) return dInputPrimary\n return ''\n }\n\n const getOptionId = (colIndex: number, optIndex: number) =>\n `${baseId}-option-${colIndex}-${optIndex}`\n\n const getSearchOptionId = (index: number) =>\n `${baseId}-search-option-${index}`\n\n // Render tags for multiple mode\n const renderTags = () => {\n const paths = selectedPaths\n const displayPaths = maxTagCount === 'responsive' || typeof maxTagCount === 'number'\n ? paths.slice(0, typeof maxTagCount === 'number' ? maxTagCount : 3)\n : paths\n const hiddenCount = paths.length - displayPaths.length\n\n return (\n <div className=\"flex flex-wrap gap-1 flex-1\">\n {displayPaths.map((path) => {\n const opts = getSelectedOptions(path)\n const label = opts.map(o => o.label).join(' / ')\n return (\n <span\n key={path.join('/')}\n className={`${dBadge} ${dBadgeSm} gap-1`}\n >\n {label}\n <button\n type=\"button\"\n className={`${dBtn} ${dBtnGhost} ${dBtnXs} ${dBtnCircle} w-3 h-3 min-h-0`}\n onClick={(e) => handleRemoveTag(path, e)}\n aria-label={`Remove ${label}`}\n >\n <svg className=\"w-2 h-2\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </span>\n )\n })}\n {hiddenCount > 0 && (\n <span className={`${dBadge} ${dBadgeSm}`}>+{hiddenCount}</span>\n )}\n </div>\n )\n }\n\n // Render search results\n const renderSearchResults = () => {\n if (!filteredPaths) return null\n\n if (filteredPaths.length === 0) {\n return (\n <div className=\"p-4 text-center text-base-content/50\">\n {notFoundContent}\n </div>\n )\n }\n\n const renderFn = typeof showSearch === 'object' && showSearch.render\n ? showSearch.render\n : null\n\n return (\n <ul role=\"listbox\" className=\"max-h-[200px] overflow-y-auto py-1\">\n {filteredPaths.map(({ path, values }, index) => {\n const isSelected = multiple\n ? selectedPaths.some(p => p.join('/') === values.join('/'))\n : selectedPath.join('/') === values.join('/')\n const isFocused = focusedIndex.row === index\n\n return (\n <li\n key={values.join('/')}\n id={getSearchOptionId(index)}\n role=\"option\"\n aria-selected={isSelected}\n data-testid={`${baseTestId}-search-option-${values.join('-')}`}\n data-state={isSelected ? 'selected' : undefined}\n className={`px-3 py-2 cursor-pointer ${\n isSelected\n ? 'bg-primary text-primary-content'\n : isFocused\n ? 'bg-base-200'\n : 'hover:bg-base-200'\n }`}\n onClick={() => handleSearchResultClick(values, path)}\n >\n {renderFn\n ? renderFn(searchValue, path)\n : path.map(opt => opt.label).join(' / ')\n }\n </li>\n )\n })}\n </ul>\n )\n }\n\n // Render dropdown content\n const renderDropdownContent = () => {\n const content = filteredPaths ? renderSearchResults() : (\n <div className=\"flex\">\n {columns.map((columnOptions, colIndex) => (\n <ul\n key={colIndex}\n role=\"listbox\"\n aria-label={`Level ${colIndex + 1} options`}\n className={`min-w-[120px] max-h-[200px] overflow-y-auto py-1 ${\n colIndex > 0 ? 'border-l border-base-300' : ''\n }`}\n >\n {columnOptions.map((option, optIndex) => {\n const isSelected = selectedPath[colIndex] === option.value\n const isHovered = activePath[colIndex] === option.value\n const hasChildren = option.children && option.children.length > 0\n const isLoading = loadingKeys.has(option.value)\n const isFocused = focusedIndex.column === colIndex && focusedIndex.row === optIndex\n const optionId = getOptionId(colIndex, optIndex)\n\n return (\n <li\n key={option.value}\n id={optionId}\n role=\"option\"\n aria-selected={isSelected}\n aria-disabled={option.disabled}\n data-testid={`${baseTestId}-option-${option.value}`}\n data-state={isSelected ? 'selected' : isHovered ? 'hovered' : undefined}\n data-value={option.value}\n className={`px-3 py-2 cursor-pointer flex items-center justify-between gap-2 ${\n option.disabled\n ? 'text-base-content/30 cursor-not-allowed'\n : isSelected\n ? 'bg-primary text-primary-content'\n : isFocused\n ? 'bg-base-200'\n : isHovered\n ? 'bg-base-200'\n : 'hover:bg-base-200'\n }`}\n onClick={() => handleOptionClick(option, colIndex)}\n onMouseEnter={() => handleOptionHover(option, colIndex)}\n >\n <span>{option.label}</span>\n {isLoading ? (\n <span className={`${dLoading} ${dLoadingSpinner} ${dLoadingXs}`} />\n ) : hasChildren ? (\n <svg className=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M9 5l7 7-7 7\" />\n </svg>\n ) : null}\n </li>\n )\n })}\n </ul>\n ))}\n </div>\n )\n\n return dropdownRender ? dropdownRender(content) : content\n }\n\n // Get active descendant ID\n const getActiveDescendant = () => {\n if (!isOpen) return undefined\n if (filteredPaths) {\n return getSearchOptionId(focusedIndex.row)\n }\n return getOptionId(focusedIndex.column, focusedIndex.row)\n }\n\n const hasValue = multiple ? selectedPaths.length > 0 : selectedPath.length > 0\n\n return (\n <div\n ref={(node) => {\n containerRef.current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) ref.current = node\n }}\n className={`relative inline-block w-full ${className}`}\n data-testid={baseTestId}\n data-state={isOpen ? 'open' : 'closed'}\n {...rest}\n >\n {/* Input/Trigger */}\n <div\n id={inputId}\n role=\"combobox\"\n aria-expanded={isOpen}\n aria-haspopup=\"listbox\"\n aria-controls={listboxId}\n aria-activedescendant={getActiveDescendant()}\n aria-label={ariaLabel}\n aria-disabled={disabled}\n tabIndex={disabled ? -1 : 0}\n className={`${dInput} w-full flex items-center justify-between cursor-pointer gap-1 ${sizeClasses[size]} ${\n disabled ? `${dInputDisabled} cursor-not-allowed` : ''\n } ${getColorClass()}`}\n onClick={() => {\n if (!disabled) {\n setIsOpen(!isOpen)\n if (showSearch && !isOpen) {\n setTimeout(() => inputRef.current?.focus(), 0)\n }\n }\n }}\n onKeyDown={handleKeyDown}\n >\n {multiple && selectedPaths.length > 0 ? (\n renderTags()\n ) : showSearch && isOpen ? (\n <input\n ref={inputRef}\n type=\"text\"\n className=\"flex-1 bg-transparent outline-none min-w-[50px]\"\n value={searchValue}\n onChange={(e) => setSearchValue(e.target.value)}\n onClick={(e) => e.stopPropagation()}\n placeholder={hasValue ? String(displayValue) : placeholder}\n aria-label=\"Search options\"\n />\n ) : (\n <span className={`flex-1 truncate ${!hasValue ? 'text-base-content/50' : ''}`}>\n {hasValue ? displayValue : placeholder}\n </span>\n )}\n <div className=\"flex items-center gap-1 shrink-0\">\n {allowClear && hasValue && !disabled && (\n <button\n type=\"button\"\n className={`${dBtn} ${dBtnGhost} ${dBtnXs} ${dBtnCircle}`}\n onClick={handleClear}\n aria-label=\"Clear selection\"\n data-testid={`${baseTestId}-clear`}\n >\n <svg className=\"w-3 h-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n )}\n <svg\n className={`w-4 h-4 transition-transform ${isOpen ? 'rotate-180' : ''}`}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 9l-7 7-7-7\" />\n </svg>\n </div>\n </div>\n\n {/* Dropdown */}\n {isOpen && (\n <div\n ref={dropdownRef}\n id={listboxId}\n className={`absolute z-50 mt-1 bg-base-100 border border-base-300 rounded-lg shadow-lg ${dropdownSizeClasses[size]} ${popupClassName}`}\n data-testid={`${baseTestId}-dropdown`}\n >\n {renderDropdownContent()}\n </div>\n )}\n </div>\n )\n})\n\nCascader.displayName = 'Cascader'\n"],"names":["dInput","dInputXs","dInputSm","dInputMd","dInputLg","dInputDisabled","dInputPrimary","dInputError","dInputWarning","dBadge","dBadgeSm","dBtn","dBtnGhost","dBtnXs","dBtnCircle","dLoading","dLoadingSpinner","dLoadingXs","getFieldValue","option","field","fallback","Cascader","forwardRef","options","value","defaultValue","onChange","placeholder","disabled","allowClear","expandTrigger","changeOnSelect","displayRender","size","color","status","showSearch","notFoundContent","loadData","fieldNames","controlledOpen","onDropdownVisibleChange","popupClassName","dropdownRender","multiple","maxTagCount","className","ariaLabel","testId","rest","ref","baseTestId","isControlledOpen","internalOpen","setInternalOpen","useState","isOpen","setIsOpen","useCallback","open","selectedPath","setSelectedPath","selectedPaths","setSelectedPaths","hoveredPath","setHoveredPath","focusedIndex","setFocusedIndex","searchValue","setSearchValue","loadingKeys","setLoadingKeys","containerRef","useRef","inputRef","dropdownRef","baseId","useId","inputId","listboxId","labelField","valueField","childrenField","normalizeOption","opt","normalizedOptions","useMemo","useEffect","handleClickOutside","e","getOptionsAtLevel","level","path","currentOptions","i","selected","getSelectedOptions","result","val","found","getAllPaths","paths","traverse","opts","currentPath","currentValues","newPath","newValues","filteredPaths","allPaths","searchLower","filterFn","inputValue","activePath","columns","cols","nextOptions","handleOptionClick","selectedOpts","key","prev","next","pathStr","isSelected","p","newPaths","handleSearchResultClick","values","handleOptionHover","handleClear","handleRemoveTag","pathToRemove","handleKeyDown","currentColumn","selectedOptions","labels","displayValue","sizeClasses","dropdownSizeClasses","colorClasses","getColorClass","getOptionId","colIndex","optIndex","getSearchOptionId","index","renderTags","displayPaths","hiddenCount","jsxs","label","o","jsx","renderSearchResults","renderFn","isFocused","renderDropdownContent","content","columnOptions","isHovered","hasChildren","isLoading","optionId","getActiveDescendant","hasValue","node"],"mappings":"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"}
1
+ {"version":3,"file":"Cascader.js","sources":["../../src/components/Cascader.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect, useCallback, useId, forwardRef, useMemo } from 'react'\nimport { useConfig } from '../providers/ConfigProvider'\n\n// DaisyUI classes\nconst dInput = 'input'\nconst dInputXs = 'input-xs'\nconst dInputSm = 'input-sm'\nconst dInputMd = 'input-md'\nconst dInputLg = 'input-lg'\nconst dInputDisabled = 'input-disabled'\nconst dInputPrimary = 'input-primary'\nconst dInputError = 'input-error'\nconst dInputWarning = 'input-warning'\nconst dBadge = 'badge'\nconst dBadgeSm = 'badge-sm'\nconst dBtn = 'btn'\nconst dBtnGhost = 'btn-ghost'\nconst dBtnXs = 'btn-xs'\nconst dBtnCircle = 'btn-circle'\nconst dLoading = 'loading'\nconst dLoadingSpinner = 'loading-spinner'\nconst dLoadingXs = 'loading-xs'\n\nexport interface CascaderOption {\n value: string\n label: React.ReactNode\n disabled?: boolean\n children?: CascaderOption[]\n isLeaf?: boolean\n}\n\nexport type CascaderColor = 'primary' | 'secondary' | 'accent' | 'info' | 'success' | 'warning' | 'error'\nexport type CascaderSize = 'xs' | 'sm' | 'md' | 'lg'\n\nexport interface CascaderProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> {\n /** Hierarchical options data */\n options: CascaderOption[]\n /** Controlled selected value path */\n value?: string[]\n /** Default selected value path (uncontrolled) */\n defaultValue?: string[]\n /** Callback when selection changes */\n onChange?: (value: string[], selectedOptions: CascaderOption[]) => void\n /** Placeholder text */\n placeholder?: string\n /** Disable the cascader */\n disabled?: boolean\n /** Show clear button */\n allowClear?: boolean\n /** How to expand sub-menus */\n expandTrigger?: 'click' | 'hover'\n /** Allow selection of any level, not just leaf nodes */\n changeOnSelect?: boolean\n /** Custom display render function */\n displayRender?: (labels: React.ReactNode[], selectedOptions: CascaderOption[]) => React.ReactNode\n /** Input size */\n size?: CascaderSize\n /** Focus ring color */\n color?: CascaderColor\n /** Validation status */\n status?: 'error' | 'warning'\n /** Enable search/filter functionality */\n showSearch?: boolean | {\n filter?: (inputValue: string, path: CascaderOption[]) => boolean\n render?: (inputValue: string, path: CascaderOption[]) => React.ReactNode\n matchInputWidth?: boolean\n }\n /** Content when no results found */\n notFoundContent?: React.ReactNode\n /** Async data loading function */\n loadData?: (selectedOptions: CascaderOption[]) => Promise<void>\n /** Custom field names for data mapping */\n fieldNames?: {\n label?: string\n value?: string\n children?: string\n }\n /** Controlled open state */\n open?: boolean\n /** Callback when dropdown visibility changes */\n onDropdownVisibleChange?: (open: boolean) => void\n /** Class name for dropdown */\n popupClassName?: string\n /** Custom dropdown render wrapper */\n dropdownRender?: (menu: React.ReactNode) => React.ReactNode\n /** Multiple selection mode */\n multiple?: boolean\n /** Max tags to show in multiple mode */\n maxTagCount?: number | 'responsive'\n /** Accessible label */\n 'aria-label'?: string\n /** Test ID for the component */\n 'data-testid'?: string\n}\n\n// Helper to get nested value using field names\nfunction getFieldValue<T>(option: Record<string, unknown>, field: string, fallback: string): T {\n return (option[field] ?? option[fallback]) as T\n}\n\nexport const Cascader = forwardRef<HTMLDivElement, CascaderProps>(({\n options,\n value,\n defaultValue,\n onChange,\n placeholder = 'Please select',\n disabled,\n allowClear = true,\n expandTrigger = 'click',\n changeOnSelect = false,\n displayRender,\n size,\n color,\n status,\n showSearch = false,\n notFoundContent,\n loadData,\n fieldNames,\n open: controlledOpen,\n onDropdownVisibleChange,\n popupClassName = '',\n dropdownRender,\n multiple = false,\n maxTagCount,\n className = '',\n 'aria-label': ariaLabel,\n 'data-testid': testId,\n ...rest\n}, ref) => {\n const { componentSize, componentDisabled, renderEmpty } = useConfig()\n const effectiveSize = size ?? (componentSize === 'xl' ? 'lg' : componentSize as CascaderSize) ?? 'md'\n const effectiveDisabled = disabled ?? componentDisabled ?? false\n const effectiveNotFoundContent = notFoundContent ?? renderEmpty?.('Cascader') ?? 'No results found'\n\n const baseTestId = testId ?? 'cascader'\n const isControlledOpen = controlledOpen !== undefined\n const [internalOpen, setInternalOpen] = useState(false)\n const isOpen = isControlledOpen ? controlledOpen : internalOpen\n\n const setIsOpen = useCallback((open: boolean) => {\n if (!isControlledOpen) {\n setInternalOpen(open)\n }\n onDropdownVisibleChange?.(open)\n }, [isControlledOpen, onDropdownVisibleChange])\n\n const [selectedPath, setSelectedPath] = useState<string[]>(value ?? defaultValue ?? [])\n const [selectedPaths, setSelectedPaths] = useState<string[][]>(\n value ? [value] : defaultValue ? [defaultValue] : []\n )\n const [hoveredPath, setHoveredPath] = useState<string[]>([])\n const [focusedIndex, setFocusedIndex] = useState<{ column: number; row: number }>({ column: 0, row: 0 })\n const [searchValue, setSearchValue] = useState('')\n const [loadingKeys, setLoadingKeys] = useState<Set<string>>(new Set())\n\n const containerRef = useRef<HTMLDivElement>(null)\n const inputRef = useRef<HTMLInputElement>(null)\n const dropdownRef = useRef<HTMLDivElement>(null)\n const baseId = useId()\n const inputId = `${baseId}-input`\n const listboxId = `${baseId}-listbox`\n\n // Field name mapping\n const labelField = fieldNames?.label ?? 'label'\n const valueField = fieldNames?.value ?? 'value'\n const childrenField = fieldNames?.children ?? 'children'\n\n // Normalize options with field names\n const normalizeOption = useCallback((opt: Record<string, unknown>): CascaderOption => ({\n value: getFieldValue<string>(opt, valueField, 'value'),\n label: getFieldValue<React.ReactNode>(opt, labelField, 'label'),\n disabled: opt.disabled as boolean | undefined,\n isLeaf: opt.isLeaf as boolean | undefined,\n children: opt[childrenField]\n ? (opt[childrenField] as Record<string, unknown>[]).map(normalizeOption)\n : undefined,\n }), [labelField, valueField, childrenField])\n\n const normalizedOptions = useMemo(() =>\n options.map(opt => normalizeOption(opt as unknown as Record<string, unknown>)),\n [options, normalizeOption]\n )\n\n // Sync with controlled value\n useEffect(() => {\n if (value !== undefined) {\n setSelectedPath(value)\n if (multiple) {\n setSelectedPaths([value])\n }\n }\n }, [value, multiple])\n\n // Close on outside click\n useEffect(() => {\n const handleClickOutside = (e: MouseEvent) => {\n if (containerRef.current && !containerRef.current.contains(e.target as Node)) {\n setIsOpen(false)\n setHoveredPath([])\n setSearchValue('')\n }\n }\n\n if (isOpen) {\n document.addEventListener('mousedown', handleClickOutside)\n return () => document.removeEventListener('mousedown', handleClickOutside)\n }\n }, [isOpen, setIsOpen])\n\n // Get options at each level based on path\n const getOptionsAtLevel = useCallback((level: number, path: string[]): CascaderOption[] => {\n if (level === 0) return normalizedOptions\n\n let currentOptions = normalizedOptions\n for (let i = 0; i < level; i++) {\n const selected = currentOptions.find(opt => opt.value === path[i])\n if (!selected?.children) return []\n currentOptions = selected.children\n }\n return currentOptions\n }, [normalizedOptions])\n\n // Get selected options objects from path\n const getSelectedOptions = useCallback((path: string[]): CascaderOption[] => {\n const result: CascaderOption[] = []\n let currentOptions = normalizedOptions\n\n for (const val of path) {\n const found = currentOptions.find(opt => opt.value === val)\n if (!found) break\n result.push(found)\n currentOptions = found.children || []\n }\n\n return result\n }, [normalizedOptions])\n\n // Get all paths for search\n const getAllPaths = useCallback((): { path: CascaderOption[]; values: string[] }[] => {\n const paths: { path: CascaderOption[]; values: string[] }[] = []\n\n const traverse = (opts: CascaderOption[], currentPath: CascaderOption[], currentValues: string[]) => {\n for (const opt of opts) {\n const newPath = [...currentPath, opt]\n const newValues = [...currentValues, opt.value]\n\n if (!opt.children || opt.children.length === 0) {\n paths.push({ path: newPath, values: newValues })\n } else {\n if (changeOnSelect) {\n paths.push({ path: newPath, values: newValues })\n }\n traverse(opt.children, newPath, newValues)\n }\n }\n }\n\n traverse(normalizedOptions, [], [])\n return paths\n }, [normalizedOptions, changeOnSelect])\n\n // Filter paths for search\n const filteredPaths = useMemo(() => {\n if (!showSearch || !searchValue.trim()) return null\n\n const allPaths = getAllPaths()\n const searchLower = searchValue.toLowerCase()\n\n const filterFn = typeof showSearch === 'object' && showSearch.filter\n ? showSearch.filter\n : (inputValue: string, path: CascaderOption[]) =>\n path.some(opt =>\n String(opt.label).toLowerCase().includes(inputValue.toLowerCase())\n )\n\n return allPaths.filter(({ path }) => filterFn(searchLower, path))\n }, [showSearch, searchValue, getAllPaths])\n\n // Determine which path to use for displaying columns\n const activePath = isOpen ? (hoveredPath.length > 0 ? hoveredPath : selectedPath) : selectedPath\n\n // Build columns to display (only when not searching)\n const columns: CascaderOption[][] = useMemo(() => {\n if (filteredPaths) return []\n\n const cols: CascaderOption[][] = []\n cols.push(normalizedOptions)\n\n for (let i = 0; i < activePath.length; i++) {\n const nextOptions = getOptionsAtLevel(i + 1, activePath)\n if (nextOptions.length > 0) {\n cols.push(nextOptions)\n }\n }\n return cols\n }, [filteredPaths, normalizedOptions, activePath, getOptionsAtLevel])\n\n const handleOptionClick = async (option: CascaderOption, level: number) => {\n if (option.disabled) return\n\n const newPath = [...activePath.slice(0, level), option.value]\n const selectedOpts = getSelectedOptions(newPath)\n\n // Handle async loading\n if (loadData && !option.children && !option.isLeaf) {\n const key = option.value\n if (!loadingKeys.has(key)) {\n setLoadingKeys(prev => new Set(prev).add(key))\n try {\n await loadData(selectedOpts)\n } finally {\n setLoadingKeys(prev => {\n const next = new Set(prev)\n next.delete(key)\n return next\n })\n }\n }\n setHoveredPath(newPath)\n return\n }\n\n if (option.children && option.children.length > 0) {\n // Has children - expand\n setHoveredPath(newPath)\n\n if (changeOnSelect) {\n // In changeOnSelect mode, also select this node\n setSelectedPath(newPath)\n onChange?.(newPath, selectedOpts)\n }\n } else {\n // Leaf node - select and close\n if (multiple) {\n const pathStr = newPath.join('/')\n const isSelected = selectedPaths.some(p => p.join('/') === pathStr)\n let newPaths: string[][]\n if (isSelected) {\n newPaths = selectedPaths.filter(p => p.join('/') !== pathStr)\n } else {\n newPaths = [...selectedPaths, newPath]\n }\n setSelectedPaths(newPaths)\n // Don't close in multiple mode\n } else {\n setSelectedPath(newPath)\n setIsOpen(false)\n setHoveredPath([])\n setSearchValue('')\n onChange?.(newPath, selectedOpts)\n }\n }\n }\n\n const handleSearchResultClick = (values: string[], path: CascaderOption[]) => {\n if (multiple) {\n const pathStr = values.join('/')\n const isSelected = selectedPaths.some(p => p.join('/') === pathStr)\n let newPaths: string[][]\n if (isSelected) {\n newPaths = selectedPaths.filter(p => p.join('/') !== pathStr)\n } else {\n newPaths = [...selectedPaths, values]\n }\n setSelectedPaths(newPaths)\n } else {\n setSelectedPath(values)\n setIsOpen(false)\n setSearchValue('')\n onChange?.(values, path)\n }\n }\n\n const handleOptionHover = (option: CascaderOption, level: number) => {\n if (expandTrigger !== 'hover' || option.disabled) return\n\n const newPath = [...activePath.slice(0, level), option.value]\n setHoveredPath(newPath)\n }\n\n const handleClear = (e: React.MouseEvent) => {\n e.stopPropagation()\n if (multiple) {\n setSelectedPaths([])\n onChange?.([], [])\n } else {\n setSelectedPath([])\n onChange?.([], [])\n }\n }\n\n const handleRemoveTag = (pathToRemove: string[], e: React.MouseEvent) => {\n e.stopPropagation()\n const pathStr = pathToRemove.join('/')\n const newPaths = selectedPaths.filter(p => p.join('/') !== pathStr)\n setSelectedPaths(newPaths)\n if (newPaths.length > 0) {\n onChange?.(newPaths[newPaths.length - 1], getSelectedOptions(newPaths[newPaths.length - 1]))\n } else {\n onChange?.([], [])\n }\n }\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (effectiveDisabled) return\n\n switch (e.key) {\n case 'Enter':\n e.preventDefault()\n if (!isOpen) {\n setIsOpen(true)\n } else if (filteredPaths && filteredPaths.length > 0) {\n const { values, path } = filteredPaths[focusedIndex.row] || {}\n if (values) {\n handleSearchResultClick(values, path)\n }\n } else {\n const currentColumn = columns[focusedIndex.column]\n if (currentColumn) {\n const option = currentColumn[focusedIndex.row]\n if (option) {\n handleOptionClick(option, focusedIndex.column)\n }\n }\n }\n break\n case ' ':\n if (!showSearch) {\n e.preventDefault()\n setIsOpen(!isOpen)\n }\n break\n case 'Escape':\n e.preventDefault()\n setIsOpen(false)\n setHoveredPath([])\n setSearchValue('')\n break\n case 'ArrowDown':\n e.preventDefault()\n if (!isOpen) {\n setIsOpen(true)\n } else if (filteredPaths) {\n setFocusedIndex(prev => ({\n ...prev,\n row: Math.min(prev.row + 1, filteredPaths.length - 1)\n }))\n } else {\n const currentColumn = columns[focusedIndex.column]\n if (currentColumn) {\n setFocusedIndex(prev => ({\n ...prev,\n row: Math.min(prev.row + 1, currentColumn.length - 1)\n }))\n }\n }\n break\n case 'ArrowUp':\n e.preventDefault()\n if (filteredPaths) {\n setFocusedIndex(prev => ({\n ...prev,\n row: Math.max(prev.row - 1, 0)\n }))\n } else {\n setFocusedIndex(prev => ({\n ...prev,\n row: Math.max(prev.row - 1, 0)\n }))\n }\n break\n case 'ArrowRight':\n e.preventDefault()\n if (!filteredPaths && focusedIndex.column < columns.length - 1) {\n setFocusedIndex(prev => ({\n column: prev.column + 1,\n row: 0\n }))\n }\n break\n case 'ArrowLeft':\n e.preventDefault()\n if (!filteredPaths && focusedIndex.column > 0) {\n setFocusedIndex(prev => ({\n column: prev.column - 1,\n row: 0\n }))\n }\n break\n case 'Home':\n e.preventDefault()\n setFocusedIndex(prev => ({ ...prev, row: 0 }))\n break\n case 'End':\n e.preventDefault()\n if (filteredPaths) {\n setFocusedIndex(prev => ({ ...prev, row: filteredPaths.length - 1 }))\n } else {\n const currentColumn = columns[focusedIndex.column]\n if (currentColumn) {\n setFocusedIndex(prev => ({ ...prev, row: currentColumn.length - 1 }))\n }\n }\n break\n }\n }\n\n // Reset focus when dropdown opens/closes\n useEffect(() => {\n if (isOpen) {\n setFocusedIndex({ column: 0, row: 0 })\n }\n }, [isOpen])\n\n // Display value\n const selectedOptions = getSelectedOptions(selectedPath)\n const labels = selectedOptions.map(opt => opt.label)\n const displayValue = displayRender\n ? displayRender(labels, selectedOptions)\n : labels.join(' / ')\n\n // Size classes\n const sizeClasses: Record<CascaderSize, string> = {\n xs: `${dInputXs} text-xs min-h-6`,\n sm: `${dInputSm} text-sm min-h-8`,\n md: `${dInputMd} min-h-10`,\n lg: `${dInputLg} text-lg min-h-12`,\n }\n\n const dropdownSizeClasses: Record<CascaderSize, string> = {\n xs: 'text-xs',\n sm: 'text-sm',\n md: 'text-base',\n lg: 'text-lg',\n }\n\n const currentSize = effectiveSize\n\n // Color and status classes\n const colorClasses: Record<CascaderColor, string> = {\n primary: 'border-primary focus:border-primary',\n secondary: 'border-secondary focus:border-secondary',\n accent: 'border-accent focus:border-accent',\n info: 'border-info focus:border-info',\n success: 'border-success focus:border-success',\n warning: 'border-warning focus:border-warning',\n error: 'border-error focus:border-error',\n }\n\n const getColorClass = () => {\n if (status === 'error') return dInputError\n if (status === 'warning') return dInputWarning\n if (color && isOpen) return colorClasses[color]\n if (isOpen) return dInputPrimary\n return ''\n }\n\n const getOptionId = (colIndex: number, optIndex: number) =>\n `${baseId}-option-${colIndex}-${optIndex}`\n\n const getSearchOptionId = (index: number) =>\n `${baseId}-search-option-${index}`\n\n // Render tags for multiple mode\n const renderTags = () => {\n const paths = selectedPaths\n const displayPaths = maxTagCount === 'responsive' || typeof maxTagCount === 'number'\n ? paths.slice(0, typeof maxTagCount === 'number' ? maxTagCount : 3)\n : paths\n const hiddenCount = paths.length - displayPaths.length\n\n return (\n <div className=\"flex flex-wrap gap-1 flex-1\">\n {displayPaths.map((path) => {\n const opts = getSelectedOptions(path)\n const label = opts.map(o => o.label).join(' / ')\n return (\n <span\n key={path.join('/')}\n className={`${dBadge} ${dBadgeSm} gap-1`}\n >\n {label}\n <button\n type=\"button\"\n className={`${dBtn} ${dBtnGhost} ${dBtnXs} ${dBtnCircle} w-3 h-3 min-h-0`}\n onClick={(e) => handleRemoveTag(path, e)}\n aria-label={`Remove ${label}`}\n >\n <svg className=\"w-2 h-2\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </span>\n )\n })}\n {hiddenCount > 0 && (\n <span className={`${dBadge} ${dBadgeSm}`}>+{hiddenCount}</span>\n )}\n </div>\n )\n }\n\n // Render search results\n const renderSearchResults = () => {\n if (!filteredPaths) return null\n\n if (filteredPaths.length === 0) {\n return (\n <div className=\"p-4 text-center text-base-content/50\">\n {effectiveNotFoundContent}\n </div>\n )\n }\n\n const renderFn = typeof showSearch === 'object' && showSearch.render\n ? showSearch.render\n : null\n\n return (\n <ul role=\"listbox\" className=\"max-h-[200px] overflow-y-auto py-1\">\n {filteredPaths.map(({ path, values }, index) => {\n const isSelected = multiple\n ? selectedPaths.some(p => p.join('/') === values.join('/'))\n : selectedPath.join('/') === values.join('/')\n const isFocused = focusedIndex.row === index\n\n return (\n <li\n key={values.join('/')}\n id={getSearchOptionId(index)}\n role=\"option\"\n aria-selected={isSelected}\n data-testid={`${baseTestId}-search-option-${values.join('-')}`}\n data-state={isSelected ? 'selected' : undefined}\n className={`px-3 py-2 cursor-pointer ${\n isSelected\n ? 'bg-primary text-primary-content'\n : isFocused\n ? 'bg-base-200'\n : 'hover:bg-base-200'\n }`}\n onClick={() => handleSearchResultClick(values, path)}\n >\n {renderFn\n ? renderFn(searchValue, path)\n : path.map(opt => opt.label).join(' / ')\n }\n </li>\n )\n })}\n </ul>\n )\n }\n\n // Render dropdown content\n const renderDropdownContent = () => {\n const content = filteredPaths ? renderSearchResults() : (\n <div className=\"flex\">\n {columns.map((columnOptions, colIndex) => (\n <ul\n key={colIndex}\n role=\"listbox\"\n aria-label={`Level ${colIndex + 1} options`}\n className={`min-w-[120px] max-h-[200px] overflow-y-auto py-1 ${\n colIndex > 0 ? 'border-l border-base-300' : ''\n }`}\n >\n {columnOptions.map((option, optIndex) => {\n const isSelected = selectedPath[colIndex] === option.value\n const isHovered = activePath[colIndex] === option.value\n const hasChildren = option.children && option.children.length > 0\n const isLoading = loadingKeys.has(option.value)\n const isFocused = focusedIndex.column === colIndex && focusedIndex.row === optIndex\n const optionId = getOptionId(colIndex, optIndex)\n\n return (\n <li\n key={option.value}\n id={optionId}\n role=\"option\"\n aria-selected={isSelected}\n aria-disabled={option.disabled}\n data-testid={`${baseTestId}-option-${option.value}`}\n data-state={isSelected ? 'selected' : isHovered ? 'hovered' : undefined}\n data-value={option.value}\n className={`px-3 py-2 cursor-pointer flex items-center justify-between gap-2 ${\n option.disabled\n ? 'text-base-content/30 cursor-not-allowed'\n : isSelected\n ? 'bg-primary text-primary-content'\n : isFocused\n ? 'bg-base-200'\n : isHovered\n ? 'bg-base-200'\n : 'hover:bg-base-200'\n }`}\n onClick={() => handleOptionClick(option, colIndex)}\n onMouseEnter={() => handleOptionHover(option, colIndex)}\n >\n <span>{option.label}</span>\n {isLoading ? (\n <span className={`${dLoading} ${dLoadingSpinner} ${dLoadingXs}`} />\n ) : hasChildren ? (\n <svg className=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M9 5l7 7-7 7\" />\n </svg>\n ) : null}\n </li>\n )\n })}\n </ul>\n ))}\n </div>\n )\n\n return dropdownRender ? dropdownRender(content) : content\n }\n\n // Get active descendant ID\n const getActiveDescendant = () => {\n if (!isOpen) return undefined\n if (filteredPaths) {\n return getSearchOptionId(focusedIndex.row)\n }\n return getOptionId(focusedIndex.column, focusedIndex.row)\n }\n\n const hasValue = multiple ? selectedPaths.length > 0 : selectedPath.length > 0\n\n return (\n <div\n ref={(node) => {\n containerRef.current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) ref.current = node\n }}\n className={`relative inline-block w-full ${className}`}\n data-testid={baseTestId}\n data-state={isOpen ? 'open' : 'closed'}\n {...rest}\n >\n {/* Input/Trigger */}\n <div\n id={inputId}\n role=\"combobox\"\n aria-expanded={isOpen}\n aria-haspopup=\"listbox\"\n aria-controls={listboxId}\n aria-activedescendant={getActiveDescendant()}\n aria-label={ariaLabel}\n aria-disabled={effectiveDisabled}\n tabIndex={effectiveDisabled ? -1 : 0}\n className={`${dInput} w-full flex items-center justify-between cursor-pointer gap-1 ${sizeClasses[currentSize]} ${\n effectiveDisabled ? `${dInputDisabled} cursor-not-allowed` : ''\n } ${getColorClass()}`}\n onClick={() => {\n if (!effectiveDisabled) {\n setIsOpen(!isOpen)\n if (showSearch && !isOpen) {\n setTimeout(() => inputRef.current?.focus(), 0)\n }\n }\n }}\n onKeyDown={handleKeyDown}\n >\n {multiple && selectedPaths.length > 0 ? (\n renderTags()\n ) : showSearch && isOpen ? (\n <input\n ref={inputRef}\n type=\"text\"\n className=\"flex-1 bg-transparent outline-none min-w-[50px]\"\n value={searchValue}\n onChange={(e) => setSearchValue(e.target.value)}\n onClick={(e) => e.stopPropagation()}\n placeholder={hasValue ? String(displayValue) : placeholder}\n aria-label=\"Search options\"\n />\n ) : (\n <span className={`flex-1 truncate ${!hasValue ? 'text-base-content/50' : ''}`}>\n {hasValue ? displayValue : placeholder}\n </span>\n )}\n <div className=\"flex items-center gap-1 shrink-0\">\n {allowClear && hasValue && !effectiveDisabled && (\n <button\n type=\"button\"\n className={`${dBtn} ${dBtnGhost} ${dBtnXs} ${dBtnCircle}`}\n onClick={handleClear}\n aria-label=\"Clear selection\"\n data-testid={`${baseTestId}-clear`}\n >\n <svg className=\"w-3 h-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n )}\n <svg\n className={`w-4 h-4 transition-transform ${isOpen ? 'rotate-180' : ''}`}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 9l-7 7-7-7\" />\n </svg>\n </div>\n </div>\n\n {/* Dropdown */}\n {isOpen && (\n <div\n ref={dropdownRef}\n id={listboxId}\n className={`absolute z-50 mt-1 bg-base-100 border border-base-300 rounded-lg shadow-lg ${dropdownSizeClasses[currentSize]} ${popupClassName}`}\n data-testid={`${baseTestId}-dropdown`}\n >\n {renderDropdownContent()}\n </div>\n )}\n </div>\n )\n})\n\nCascader.displayName = 'Cascader'\n"],"names":["dInput","dInputXs","dInputSm","dInputMd","dInputLg","dInputDisabled","dInputPrimary","dInputError","dInputWarning","dBadge","dBadgeSm","dBtn","dBtnGhost","dBtnXs","dBtnCircle","dLoading","dLoadingSpinner","dLoadingXs","getFieldValue","option","field","fallback","Cascader","forwardRef","options","value","defaultValue","onChange","placeholder","disabled","allowClear","expandTrigger","changeOnSelect","displayRender","size","color","status","showSearch","notFoundContent","loadData","fieldNames","controlledOpen","onDropdownVisibleChange","popupClassName","dropdownRender","multiple","maxTagCount","className","ariaLabel","testId","rest","ref","componentSize","componentDisabled","renderEmpty","useConfig","effectiveSize","effectiveDisabled","effectiveNotFoundContent","baseTestId","isControlledOpen","internalOpen","setInternalOpen","useState","isOpen","setIsOpen","useCallback","open","selectedPath","setSelectedPath","selectedPaths","setSelectedPaths","hoveredPath","setHoveredPath","focusedIndex","setFocusedIndex","searchValue","setSearchValue","loadingKeys","setLoadingKeys","containerRef","useRef","inputRef","dropdownRef","baseId","useId","inputId","listboxId","labelField","valueField","childrenField","normalizeOption","opt","normalizedOptions","useMemo","useEffect","handleClickOutside","e","getOptionsAtLevel","level","path","currentOptions","i","selected","getSelectedOptions","result","val","found","getAllPaths","paths","traverse","opts","currentPath","currentValues","newPath","newValues","filteredPaths","allPaths","searchLower","filterFn","inputValue","activePath","columns","cols","nextOptions","handleOptionClick","selectedOpts","key","prev","next","pathStr","isSelected","p","newPaths","handleSearchResultClick","values","handleOptionHover","handleClear","handleRemoveTag","pathToRemove","handleKeyDown","currentColumn","selectedOptions","labels","displayValue","sizeClasses","dropdownSizeClasses","currentSize","colorClasses","getColorClass","getOptionId","colIndex","optIndex","getSearchOptionId","index","renderTags","displayPaths","hiddenCount","jsxs","label","o","jsx","renderSearchResults","renderFn","isFocused","renderDropdownContent","content","columnOptions","isHovered","hasChildren","isLoading","optionId","getActiveDescendant","hasValue","node"],"mappings":"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"}
@@ -1,57 +1,58 @@
1
- import { jsxs as b, Fragment as K, jsx as n } from "react/jsx-runtime";
2
- import C, { useState as g, useRef as y, useCallback as M, useEffect as L, createContext as V, useContext as A } from "react";
3
- import { createPortal as H } from "react-dom";
4
- const k = "menu", S = "divider", $ = V(null), O = () => {
5
- const e = A($);
1
+ import { jsxs as b, Fragment as V, jsx as n } from "react/jsx-runtime";
2
+ import C, { useState as g, useRef as y, useCallback as M, useEffect as L, createContext as A, useContext as H } from "react";
3
+ import { createPortal as O } from "react-dom";
4
+ import { useConfig as _ } from "../providers/ConfigProvider.js";
5
+ const k = "menu", S = "divider", $ = A(null), F = () => {
6
+ const e = H($);
6
7
  if (!e)
7
8
  throw new Error("ContextMenu compound components must be used within a ContextMenu");
8
9
  return e;
9
10
  }, R = ({
10
11
  children: e,
11
- icon: c,
12
+ icon: l,
12
13
  disabled: s = !1,
13
- danger: d = !1,
14
- className: h = "",
15
- _key: l
14
+ danger: h = !1,
15
+ className: m = "",
16
+ _key: i
16
17
  }) => {
17
- const { onSelect: m, onClose: o } = O();
18
- return /* @__PURE__ */ n("li", { className: h, children: /* @__PURE__ */ b(
18
+ const { onSelect: u, onClose: c } = F();
19
+ return /* @__PURE__ */ n("li", { className: m, children: /* @__PURE__ */ b(
19
20
  "button",
20
21
  {
21
22
  onClick: () => {
22
- s || !l || (m(l), o());
23
+ s || !i || (u(i), c());
23
24
  },
24
25
  disabled: s,
25
26
  className: `
26
27
  flex items-center gap-2 w-full px-4 py-2 text-left text-sm
27
28
  ${s ? "opacity-50 cursor-not-allowed" : "hover:bg-base-200"}
28
- ${d ? "text-error hover:bg-error/10" : ""}
29
+ ${h ? "text-error hover:bg-error/10" : ""}
29
30
  `,
30
31
  children: [
31
- c && /* @__PURE__ */ n("span", { className: "w-4 h-4", children: c }),
32
+ l && /* @__PURE__ */ n("span", { className: "w-4 h-4", children: l }),
32
33
  /* @__PURE__ */ n("span", { className: "flex-1", children: e })
33
34
  ]
34
35
  }
35
36
  ) });
36
- }, _ = ({ className: e = "" }) => /* @__PURE__ */ n("li", { className: `${S} my-1 ${e}` }), D = ({
37
+ }, X = ({ className: e = "" }) => /* @__PURE__ */ n("li", { className: `${S} my-1 ${e}` }), D = ({
37
38
  label: e,
38
- icon: c,
39
+ icon: l,
39
40
  disabled: s = !1,
40
- children: d,
41
- className: h = "",
42
- _key: l
41
+ children: h,
42
+ className: m = "",
43
+ _key: i
43
44
  }) => {
44
- const [m, o] = g(!1), a = y(null), u = () => {
45
- s || (a.current && clearTimeout(a.current), o(!0));
46
- }, f = () => {
47
- a.current = setTimeout(() => o(!1), 100);
45
+ const [u, c] = g(!1), r = y(null), f = () => {
46
+ s || (r.current && clearTimeout(r.current), c(!0));
47
+ }, a = () => {
48
+ r.current = setTimeout(() => c(!1), 100);
48
49
  };
49
50
  return /* @__PURE__ */ b(
50
51
  "li",
51
52
  {
52
- onMouseEnter: u,
53
- onMouseLeave: f,
54
- className: `relative ${h}`,
53
+ onMouseEnter: f,
54
+ onMouseLeave: a,
55
+ className: `relative ${m}`,
55
56
  children: [
56
57
  /* @__PURE__ */ b(
57
58
  "button",
@@ -62,46 +63,46 @@ const k = "menu", S = "divider", $ = V(null), O = () => {
62
63
  ${s ? "opacity-50 cursor-not-allowed" : "hover:bg-base-200"}
63
64
  `,
64
65
  children: [
65
- c && /* @__PURE__ */ n("span", { className: "w-4 h-4", children: c }),
66
+ l && /* @__PURE__ */ n("span", { className: "w-4 h-4", children: l }),
66
67
  /* @__PURE__ */ n("span", { className: "flex-1", children: e }),
67
68
  /* @__PURE__ */ n("svg", { className: "w-4 h-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ n("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" }) })
68
69
  ]
69
70
  }
70
71
  ),
71
- m && /* @__PURE__ */ n(
72
+ u && /* @__PURE__ */ n(
72
73
  "ul",
73
74
  {
74
75
  className: `${k} bg-base-100 rounded-box shadow-lg border border-base-300 absolute left-full top-0 min-w-[160px] z-50 p-1`,
75
- onMouseEnter: u,
76
- onMouseLeave: f,
77
- children: d
76
+ onMouseEnter: f,
77
+ onMouseLeave: a,
78
+ children: h
78
79
  }
79
80
  )
80
81
  ]
81
82
  }
82
83
  );
83
- }, j = ({ item: e, onSelect: c, onClose: s }) => {
84
- const [d, h] = g(!1), l = y(null);
84
+ }, j = ({ item: e, onSelect: l, onClose: s }) => {
85
+ const [h, m] = g(!1), i = y(null);
85
86
  if (e.divider)
86
87
  return /* @__PURE__ */ n("li", { className: `${S} my-1` });
87
- const m = () => {
88
- e.disabled || e.children && e.children.length > 0 || (c(e.key), s());
89
- }, o = e.children && e.children.length > 0, a = () => {
90
- o && (l.current && clearTimeout(l.current), h(!0));
91
- }, u = () => {
92
- o && (l.current = setTimeout(() => h(!1), 100));
88
+ const u = () => {
89
+ e.disabled || e.children && e.children.length > 0 || (l(e.key), s());
90
+ }, c = e.children && e.children.length > 0, r = () => {
91
+ c && (i.current && clearTimeout(i.current), m(!0));
92
+ }, f = () => {
93
+ c && (i.current = setTimeout(() => m(!1), 100));
93
94
  };
94
95
  return /* @__PURE__ */ b(
95
96
  "li",
96
97
  {
97
- onMouseEnter: a,
98
- onMouseLeave: u,
98
+ onMouseEnter: r,
99
+ onMouseLeave: f,
99
100
  className: "relative",
100
101
  children: [
101
102
  /* @__PURE__ */ b(
102
103
  "button",
103
104
  {
104
- onClick: m,
105
+ onClick: u,
105
106
  disabled: e.disabled,
106
107
  className: `
107
108
  flex items-center gap-2 w-full px-4 py-2 text-left text-sm
@@ -111,96 +112,96 @@ const k = "menu", S = "divider", $ = V(null), O = () => {
111
112
  children: [
112
113
  e.icon && /* @__PURE__ */ n("span", { className: "w-4 h-4", children: e.icon }),
113
114
  /* @__PURE__ */ n("span", { className: "flex-1", children: e.label }),
114
- o && /* @__PURE__ */ n("svg", { className: "w-4 h-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ n("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" }) })
115
+ c && /* @__PURE__ */ n("svg", { className: "w-4 h-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ n("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" }) })
115
116
  ]
116
117
  }
117
118
  ),
118
- o && d && /* @__PURE__ */ n(
119
+ c && h && /* @__PURE__ */ n(
119
120
  "ul",
120
121
  {
121
122
  className: `${k} bg-base-100 rounded-box shadow-lg border border-base-300 absolute left-full top-0 min-w-[160px] z-50 p-1`,
122
- onMouseEnter: a,
123
- onMouseLeave: u,
124
- children: e.children.map((f) => /* @__PURE__ */ n(j, { item: f, onSelect: c, onClose: s }, f.key))
123
+ onMouseEnter: r,
124
+ onMouseLeave: f,
125
+ children: e.children.map((a) => /* @__PURE__ */ n(j, { item: a, onSelect: l, onClose: s }, a.key))
125
126
  }
126
127
  )
127
128
  ]
128
129
  }
129
130
  );
130
- }, F = ({
131
+ }, Y = ({
131
132
  children: e,
132
- items: c,
133
+ items: l,
133
134
  onSelect: s,
134
- disabled: d = !1,
135
- className: h = ""
135
+ disabled: h = !1,
136
+ className: m = ""
136
137
  }) => {
137
- const [l, m] = g(!1), [o, a] = g({ x: 0, y: 0 }), u = y(null), f = y(null), W = M(
138
- (r) => {
139
- if (d) return;
140
- r.preventDefault(), r.stopPropagation();
141
- let t = r.clientX, i = r.clientY;
142
- a({ x: t, y: i }), m(!0);
138
+ const { getPopupContainer: i } = _(), [u, c] = g(!1), [r, f] = g({ x: 0, y: 0 }), a = y(null), P = y(null), W = M(
139
+ (o) => {
140
+ if (h) return;
141
+ o.preventDefault(), o.stopPropagation();
142
+ let t = o.clientX, d = o.clientY;
143
+ f({ x: t, y: d }), c(!0);
143
144
  },
144
- [d]
145
+ [h]
145
146
  ), p = M(() => {
146
- m(!1);
147
+ c(!1);
147
148
  }, []), N = M(
148
- (r) => {
149
- s?.(r);
149
+ (o) => {
150
+ s?.(o);
150
151
  },
151
152
  [s]
152
153
  );
153
154
  L(() => {
154
- if (l && u.current) {
155
- const t = u.current.getBoundingClientRect(), i = window.innerWidth, x = window.innerHeight;
156
- let { x: v, y: w } = o;
157
- v + t.width > i && (v = i - t.width - 8), w + t.height > x && (w = x - t.height - 8), (v !== o.x || w !== o.y) && a({ x: v, y: w });
155
+ if (u && a.current) {
156
+ const t = a.current.getBoundingClientRect(), d = window.innerWidth, x = window.innerHeight;
157
+ let { x: v, y: w } = r;
158
+ v + t.width > d && (v = d - t.width - 8), w + t.height > x && (w = x - t.height - 8), (v !== r.x || w !== r.y) && f({ x: v, y: w });
158
159
  }
159
- }, [l, o]), L(() => {
160
- if (!l) return;
161
- const r = (x) => {
162
- u.current && !u.current.contains(x.target) && p();
160
+ }, [u, r]), L(() => {
161
+ if (!u) return;
162
+ const o = (x) => {
163
+ a.current && !a.current.contains(x.target) && p();
163
164
  }, t = (x) => {
164
165
  x.key === "Escape" && p();
165
- }, i = () => {
166
+ }, d = () => {
166
167
  p();
167
168
  };
168
- return document.addEventListener("mousedown", r), document.addEventListener("keydown", t), document.addEventListener("scroll", i, !0), () => {
169
- document.removeEventListener("mousedown", r), document.removeEventListener("keydown", t), document.removeEventListener("scroll", i, !0);
169
+ return document.addEventListener("mousedown", o), document.addEventListener("keydown", t), document.addEventListener("scroll", d, !0), () => {
170
+ document.removeEventListener("mousedown", o), document.removeEventListener("keydown", t), document.removeEventListener("scroll", d, !0);
170
171
  };
171
- }, [l, p]);
172
- const P = (r) => C.Children.map(r, (t) => {
172
+ }, [u, p]);
173
+ const T = (o) => C.Children.map(o, (t) => {
173
174
  if (C.isValidElement(t)) {
174
- const i = t.key != null ? String(t.key) : void 0;
175
+ const d = t.key != null ? String(t.key) : void 0;
175
176
  if (t.type === R || t.type === D)
176
- return C.cloneElement(t, { _key: i });
177
+ return C.cloneElement(t, { _key: d });
177
178
  }
178
179
  return t;
179
- }), E = C.Children.toArray(e), T = E[0], z = P(E.slice(1)), B = c && c.length > 0, I = {
180
+ }), E = C.Children.toArray(e), z = E[0], B = T(E.slice(1)), I = l && l.length > 0, K = {
180
181
  onSelect: N,
181
182
  onClose: p
182
183
  };
183
- return /* @__PURE__ */ b(K, { children: [
184
- /* @__PURE__ */ n("div", { ref: f, onContextMenu: W, className: "inline-block", children: T }),
185
- l && H(
186
- /* @__PURE__ */ n($.Provider, { value: I, children: /* @__PURE__ */ n(
184
+ return /* @__PURE__ */ b(V, { children: [
185
+ /* @__PURE__ */ n("div", { ref: P, onContextMenu: W, className: "inline-block", children: z }),
186
+ u && O(
187
+ /* @__PURE__ */ n($.Provider, { value: K, children: /* @__PURE__ */ n(
187
188
  "ul",
188
189
  {
189
- ref: u,
190
- className: `${k} bg-base-100 rounded-box shadow-lg border border-base-300 min-w-[160px] p-1 fixed z-[9999] ${h}`,
191
- style: { left: o.x, top: o.y },
192
- children: B ? c.map((r) => /* @__PURE__ */ n(j, { item: r, onSelect: N, onClose: p }, r.key)) : z
190
+ ref: a,
191
+ className: `${k} bg-base-100 rounded-box shadow-lg border border-base-300 min-w-[160px] p-1 fixed z-[9999] ${m}`,
192
+ style: { left: r.x, top: r.y },
193
+ children: I ? l.map((o) => /* @__PURE__ */ n(j, { item: o, onSelect: N, onClose: p }, o.key)) : B
193
194
  }
194
195
  ) }),
195
- document.body
196
+ i ? i(document.body) : document.body
196
197
  )
197
198
  ] });
198
- }, G = Object.assign(F, {
199
+ }, U = Object.assign(Y, {
199
200
  Item: R,
200
- Divider: _,
201
+ Divider: X,
201
202
  SubMenu: D
202
203
  });
203
204
  export {
204
- G as ContextMenu
205
+ U as ContextMenu
205
206
  };
206
207
  //# sourceMappingURL=ContextMenu.js.map