asterui 0.12.49 → 0.12.51
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.
- package/dist/components/Alert.js +18 -18
- package/dist/components/Alert.js.map +1 -1
- package/dist/components/Autocomplete.js +115 -114
- package/dist/components/Autocomplete.js.map +1 -1
- package/dist/components/Avatar.js +33 -32
- package/dist/components/Avatar.js.map +1 -1
- package/dist/components/Badge.js +99 -99
- package/dist/components/Badge.js.map +1 -1
- package/dist/components/Breadcrumb.js +12 -11
- package/dist/components/Breadcrumb.js.map +1 -1
- package/dist/components/Browser.js +10 -10
- package/dist/components/Browser.js.map +1 -1
- package/dist/components/Button.js +80 -79
- package/dist/components/Button.js.map +1 -1
- package/dist/components/Card.d.ts +2 -0
- package/dist/components/Card.js +111 -110
- package/dist/components/Card.js.map +1 -1
- package/dist/components/Carousel.js +59 -59
- package/dist/components/Carousel.js.map +1 -1
- package/dist/components/Cascader.js +175 -174
- package/dist/components/Cascader.js.map +1 -1
- package/dist/components/Chat.js +27 -27
- package/dist/components/Chat.js.map +1 -1
- package/dist/components/Checkbox.js +98 -97
- package/dist/components/Checkbox.js.map +1 -1
- package/dist/components/Code.js +11 -11
- package/dist/components/Code.js.map +1 -1
- package/dist/components/Collapse.js +46 -46
- package/dist/components/Collapse.js.map +1 -1
- package/dist/components/ColorPicker.d.ts +1 -1
- package/dist/components/ColorPicker.js +93 -91
- package/dist/components/ColorPicker.js.map +1 -1
- package/dist/components/Command.js +120 -120
- package/dist/components/Command.js.map +1 -1
- package/dist/components/ConfigProvider.d.ts +1 -1
- package/dist/components/ConfigProvider.js +9 -9
- package/dist/components/ConfigProvider.js.map +1 -1
- package/dist/components/ContextMenu.js +33 -33
- package/dist/components/ContextMenu.js.map +1 -1
- package/dist/components/CopyButton.js +74 -73
- package/dist/components/CopyButton.js.map +1 -1
- package/dist/components/Countdown.js +60 -59
- package/dist/components/Countdown.js.map +1 -1
- package/dist/components/DatePicker.d.ts +1 -1
- package/dist/components/DatePicker.js +54 -53
- package/dist/components/DatePicker.js.map +1 -1
- package/dist/components/Diff.js +10 -10
- package/dist/components/Diff.js.map +1 -1
- package/dist/components/Divider.js +21 -20
- package/dist/components/Divider.js.map +1 -1
- package/dist/components/Dock.js +28 -27
- package/dist/components/Dock.js.map +1 -1
- package/dist/components/Drawer.js +43 -43
- package/dist/components/Drawer.js.map +1 -1
- package/dist/components/Dropdown.js +127 -127
- package/dist/components/Dropdown.js.map +1 -1
- package/dist/components/Empty.js +16 -15
- package/dist/components/Empty.js.map +1 -1
- package/dist/components/Fieldset.js +11 -10
- package/dist/components/Fieldset.js.map +1 -1
- package/dist/components/FileInput.js +30 -29
- package/dist/components/FileInput.js.map +1 -1
- package/dist/components/Filter.d.ts +1 -1
- package/dist/components/Filter.js +32 -30
- package/dist/components/Filter.js.map +1 -1
- package/dist/components/FloatButton.js +83 -83
- package/dist/components/FloatButton.js.map +1 -1
- package/dist/components/Footer.js +14 -13
- package/dist/components/Footer.js.map +1 -1
- package/dist/components/Form.js +133 -132
- package/dist/components/Form.js.map +1 -1
- package/dist/components/Hero.js +12 -11
- package/dist/components/Hero.js.map +1 -1
- package/dist/components/HoverGallery.js +7 -7
- package/dist/components/HoverGallery.js.map +1 -1
- package/dist/components/Image.js +40 -40
- package/dist/components/Image.js.map +1 -1
- package/dist/components/Input.js +171 -169
- package/dist/components/Input.js.map +1 -1
- package/dist/components/InputNumber.js +84 -83
- package/dist/components/InputNumber.js.map +1 -1
- package/dist/components/Join.js +11 -10
- package/dist/components/Join.js.map +1 -1
- package/dist/components/Kbd.js +15 -15
- package/dist/components/Kbd.js.map +1 -1
- package/dist/components/List.d.ts +1 -1
- package/dist/components/List.js +75 -72
- package/dist/components/List.js.map +1 -1
- package/dist/components/Loading.d.ts +1 -1
- package/dist/components/Loading.js +31 -29
- package/dist/components/Loading.js.map +1 -1
- package/dist/components/Mask.js +31 -31
- package/dist/components/Mask.js.map +1 -1
- package/dist/components/Mention.js +61 -61
- package/dist/components/Mention.js.map +1 -1
- package/dist/components/Menu.js +84 -84
- package/dist/components/Menu.js.map +1 -1
- package/dist/components/Message.js +30 -29
- package/dist/components/Message.js.map +1 -1
- package/dist/components/Modal.js +117 -116
- package/dist/components/Modal.js.map +1 -1
- package/dist/components/MonthCalendar.d.ts +31 -0
- package/dist/components/MonthCalendar.js +205 -0
- package/dist/components/MonthCalendar.js.map +1 -0
- package/dist/components/Navbar.js +25 -25
- package/dist/components/Navbar.js.map +1 -1
- package/dist/components/Notification.js +56 -55
- package/dist/components/Notification.js.map +1 -1
- package/dist/components/OTPInput.js +69 -68
- package/dist/components/OTPInput.js.map +1 -1
- package/dist/components/Pagination.d.ts +1 -1
- package/dist/components/Pagination.js +60 -58
- package/dist/components/Pagination.js.map +1 -1
- package/dist/components/Phone.js +10 -10
- package/dist/components/Phone.js.map +1 -1
- package/dist/components/Popconfirm.js +60 -60
- package/dist/components/Popconfirm.js.map +1 -1
- package/dist/components/Progress.js +17 -17
- package/dist/components/Progress.js.map +1 -1
- package/dist/components/QRCode.js +23 -23
- package/dist/components/QRCode.js.map +1 -1
- package/dist/components/RadialProgress.js +17 -17
- package/dist/components/RadialProgress.js.map +1 -1
- package/dist/components/Radio.js +41 -40
- package/dist/components/Radio.js.map +1 -1
- package/dist/components/Range.d.ts +1 -1
- package/dist/components/Range.js +39 -37
- package/dist/components/Range.js.map +1 -1
- package/dist/components/Rating.js +79 -78
- package/dist/components/Rating.js.map +1 -1
- package/dist/components/ResponsiveDrawer.js +27 -27
- package/dist/components/ResponsiveDrawer.js.map +1 -1
- package/dist/components/RichTextEditor.d.ts +32 -0
- package/dist/components/RichTextEditor.js +335 -0
- package/dist/components/RichTextEditor.js.map +1 -0
- package/dist/components/Segmented.d.ts +1 -1
- package/dist/components/Segmented.js +48 -46
- package/dist/components/Segmented.js.map +1 -1
- package/dist/components/Select.js +55 -54
- package/dist/components/Select.js.map +1 -1
- package/dist/components/Skeleton.js +9 -9
- package/dist/components/Skeleton.js.map +1 -1
- package/dist/components/Splitter.js +1 -3
- package/dist/components/Splitter.js.map +1 -1
- package/dist/components/Stat.js +17 -16
- package/dist/components/Stat.js.map +1 -1
- package/dist/components/Status.js +29 -29
- package/dist/components/Status.js.map +1 -1
- package/dist/components/Steps.js +61 -61
- package/dist/components/Steps.js.map +1 -1
- package/dist/components/Table.js +256 -256
- package/dist/components/Table.js.map +1 -1
- package/dist/components/Tabs.js +65 -65
- package/dist/components/Tabs.js.map +1 -1
- package/dist/components/Tag.js +147 -147
- package/dist/components/Tag.js.map +1 -1
- package/dist/components/TextRotate.js +6 -6
- package/dist/components/TextRotate.js.map +1 -1
- package/dist/components/Textarea.js +35 -34
- package/dist/components/Textarea.js.map +1 -1
- package/dist/components/ThemeController.d.ts +1 -1
- package/dist/components/ThemeController.js +71 -68
- package/dist/components/ThemeController.js.map +1 -1
- package/dist/components/TimePicker.d.ts +1 -1
- package/dist/components/TimePicker.js +133 -129
- package/dist/components/TimePicker.js.map +1 -1
- package/dist/components/Timeline.js +79 -79
- package/dist/components/Timeline.js.map +1 -1
- package/dist/components/Toggle.js +33 -32
- package/dist/components/Toggle.js.map +1 -1
- package/dist/components/Tooltip.js +25 -25
- package/dist/components/Tooltip.js.map +1 -1
- package/dist/components/Tour.js +126 -126
- package/dist/components/Tour.js.map +1 -1
- package/dist/components/Transfer.js +93 -92
- package/dist/components/Transfer.js.map +1 -1
- package/dist/components/Tree.js +200 -200
- package/dist/components/Tree.js.map +1 -1
- package/dist/components/TreeSelect.js +255 -254
- package/dist/components/TreeSelect.js.map +1 -1
- package/dist/components/Typography.js +71 -70
- package/dist/components/Typography.js.map +1 -1
- package/dist/components/Upload.js +81 -81
- package/dist/components/Upload.js.map +1 -1
- package/dist/components/WeekCalendar.d.ts +35 -0
- package/dist/components/WeekCalendar.js +204 -0
- package/dist/components/WeekCalendar.js.map +1 -0
- package/dist/components/Window.js +7 -7
- package/dist/components/Window.js.map +1 -1
- package/dist/editor.d.ts +1 -0
- package/dist/editor.js +5 -0
- package/dist/editor.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +211 -207
- package/dist/index.js.map +1 -1
- package/package.json +30 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Command.js","sources":["../../src/components/Command.tsx"],"sourcesContent":["import React, {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react'\n\n// Types\nexport interface CommandItemConfig {\n key: string\n label: React.ReactNode\n group?: string\n keywords?: string[]\n disabled?: boolean\n onSelect?: () => void\n icon?: React.ReactNode\n}\n\nexport interface CommandProps extends Omit<React.HTMLAttributes<HTMLDialogElement>, 'children'> {\n children?: React.ReactNode\n open?: boolean\n onOpenChange?: (open: boolean) => void\n defaultOpen?: boolean\n items?: CommandItemConfig[]\n filter?: (value: string, search: string, keywords?: string[]) => boolean\n loop?: boolean\n shortcut?: string[]\n placeholder?: string\n emptyMessage?: React.ReactNode\n}\n\ninterface CommandContextValue {\n searchValue: string\n setSearchValue: (value: string) => void\n highlightedIndex: number\n setHighlightedIndex: (index: number) => void\n registerItem: (id: string, value: string, keywords: string[], disabled: boolean) => void\n unregisterItem: (id: string) => void\n filteredItems: FilteredItem[]\n selectItem: (id: string) => void\n loop: boolean\n baseId: string\n currentPage: string\n setPage: (pageId: string) => void\n goBack: () => void\n pageStack: string[]\n}\n\ninterface FilteredItem {\n id: string\n value: string\n keywords: string[]\n disabled: boolean\n}\n\ninterface ItemRegistration {\n id: string\n value: string\n keywords: string[]\n disabled: boolean\n onSelect?: () => void\n}\n\nconst CommandContext = createContext<CommandContextValue | null>(null)\n\nfunction useCommandContext() {\n const context = useContext(CommandContext)\n if (!context) {\n throw new Error('Command compound components must be used within a Command')\n }\n return context\n}\n\n// Default filter function\nconst defaultFilter = (value: string, search: string, keywords: string[] = []): boolean => {\n const searchLower = search.toLowerCase()\n const valueLower = value.toLowerCase()\n if (valueLower.includes(searchLower)) return true\n return keywords.some((k) => k.toLowerCase().includes(searchLower))\n}\n\n// Root Command component\nconst CommandRoot = forwardRef<HTMLDialogElement, CommandProps>(\n (\n {\n children,\n open: controlledOpen,\n onOpenChange,\n defaultOpen = false,\n items,\n filter = defaultFilter,\n loop = true,\n shortcut = ['k'],\n placeholder = 'Type a command or search...',\n emptyMessage = 'No results found.',\n className = '',\n ...rest\n },\n ref\n ) => {\n const dialogRef = useRef<HTMLDialogElement>(null)\n const inputRef = useRef<HTMLInputElement>(null)\n const listRef = useRef<HTMLDivElement>(null)\n const previousActiveElement = useRef<HTMLElement | null>(null)\n const baseId = useId()\n\n // Controlled/uncontrolled open state\n const [internalOpen, setInternalOpen] = useState(defaultOpen)\n const isControlled = controlledOpen !== undefined\n const isOpen = isControlled ? controlledOpen : internalOpen\n\n const setIsOpen = useCallback(\n (newOpen: boolean) => {\n if (!isControlled) {\n setInternalOpen(newOpen)\n }\n onOpenChange?.(newOpen)\n },\n [isControlled, onOpenChange]\n )\n\n // State\n const [searchValue, setSearchValue] = useState('')\n const [highlightedIndex, setHighlightedIndex] = useState(0)\n const [registeredItems, setRegisteredItems] = useState<Map<string, ItemRegistration>>(new Map())\n const [pageStack, setPageStack] = useState<string[]>(['root'])\n const currentPage = pageStack[pageStack.length - 1]\n\n // Page navigation\n const setPage = useCallback((pageId: string) => {\n setPageStack((prev) => [...prev, pageId])\n setSearchValue('')\n setHighlightedIndex(0)\n }, [])\n\n const goBack = useCallback(() => {\n if (pageStack.length > 1) {\n setPageStack((prev) => prev.slice(0, -1))\n setSearchValue('')\n setHighlightedIndex(0)\n }\n }, [pageStack.length])\n\n // Item registration for compound components\n const registerItem = useCallback(\n (id: string, value: string, keywords: string[], disabled: boolean, onSelect?: () => void) => {\n setRegisteredItems((prev) => {\n const next = new Map(prev)\n next.set(id, { id, value, keywords, disabled, onSelect })\n return next\n })\n },\n []\n )\n\n const unregisterItem = useCallback((id: string) => {\n setRegisteredItems((prev) => {\n const next = new Map(prev)\n next.delete(id)\n return next\n })\n }, [])\n\n // Compute filtered items\n const filteredItems = useMemo((): FilteredItem[] => {\n // Use data-driven items if provided\n if (items) {\n return items\n .filter((item) => {\n if (!searchValue) return true\n const label = typeof item.label === 'string' ? item.label : ''\n return filter(label, searchValue, item.keywords)\n })\n .map((item) => ({\n id: item.key,\n value: typeof item.label === 'string' ? item.label : item.key,\n keywords: item.keywords || [],\n disabled: item.disabled || false,\n }))\n }\n\n // Use registered compound items\n const itemsArray = Array.from(registeredItems.values())\n return itemsArray.filter((item) => {\n if (!searchValue) return true\n return filter(item.value, searchValue, item.keywords)\n })\n }, [items, registeredItems, searchValue, filter])\n\n // Get enabled items for navigation\n const enabledItems = useMemo(\n () => filteredItems.filter((item) => !item.disabled),\n [filteredItems]\n )\n\n // Select item\n const selectItem = useCallback(\n (id: string) => {\n if (items) {\n const item = items.find((i) => i.key === id)\n if (item && !item.disabled) {\n item.onSelect?.()\n setIsOpen(false)\n }\n } else {\n const reg = registeredItems.get(id)\n if (reg && !reg.disabled) {\n reg.onSelect?.()\n setIsOpen(false)\n }\n }\n },\n [items, registeredItems, setIsOpen]\n )\n\n // Reset state when opening\n useEffect(() => {\n if (isOpen) {\n setSearchValue('')\n setHighlightedIndex(0)\n setPageStack(['root'])\n }\n }, [isOpen])\n\n // Handle dialog open/close\n useEffect(() => {\n const dialog = dialogRef.current\n if (!dialog) return\n\n if (isOpen) {\n if (!dialog.open) {\n previousActiveElement.current = document.activeElement as HTMLElement\n dialog.showModal()\n setTimeout(() => inputRef.current?.focus(), 0)\n }\n } else {\n if (dialog.open) {\n dialog.close()\n previousActiveElement.current?.focus()\n }\n }\n }, [isOpen])\n\n // Handle dialog close event\n useEffect(() => {\n const dialog = dialogRef.current\n if (!dialog) return\n\n const onDialogClose = () => {\n setIsOpen(false)\n }\n\n dialog.addEventListener('close', onDialogClose)\n return () => dialog.removeEventListener('close', onDialogClose)\n }, [setIsOpen])\n\n // Global keyboard shortcut\n useEffect(() => {\n const handleGlobalKeyDown = (e: KeyboardEvent) => {\n const key = shortcut[0]?.toLowerCase()\n if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === key) {\n e.preventDefault()\n setIsOpen(!isOpen)\n }\n }\n\n document.addEventListener('keydown', handleGlobalKeyDown)\n return () => document.removeEventListener('keydown', handleGlobalKeyDown)\n }, [shortcut, isOpen, setIsOpen])\n\n // Keyboard navigation\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n switch (e.key) {\n case 'ArrowDown': {\n e.preventDefault()\n if (enabledItems.length === 0) return\n setHighlightedIndex((prev) => {\n const next = prev + 1\n if (next >= enabledItems.length) {\n return loop ? 0 : prev\n }\n return next\n })\n break\n }\n case 'ArrowUp': {\n e.preventDefault()\n if (enabledItems.length === 0) return\n setHighlightedIndex((prev) => {\n const next = prev - 1\n if (next < 0) {\n return loop ? enabledItems.length - 1 : 0\n }\n return next\n })\n break\n }\n case 'Enter': {\n e.preventDefault()\n const item = enabledItems[highlightedIndex]\n if (item) {\n selectItem(item.id)\n }\n break\n }\n case 'Escape': {\n e.preventDefault()\n if (pageStack.length > 1) {\n goBack()\n } else {\n setIsOpen(false)\n }\n break\n }\n case 'Backspace': {\n if (searchValue === '' && pageStack.length > 1) {\n e.preventDefault()\n goBack()\n }\n break\n }\n }\n },\n [enabledItems, highlightedIndex, loop, selectItem, pageStack, goBack, searchValue, setIsOpen]\n )\n\n // Scroll highlighted item into view\n useEffect(() => {\n if (highlightedIndex >= 0 && listRef.current) {\n const items = listRef.current.querySelectorAll('[data-command-item]')\n const highlightedEl = items[highlightedIndex] as HTMLElement\n highlightedEl?.scrollIntoView({ block: 'nearest' })\n }\n }, [highlightedIndex])\n\n // Handle mask click\n const handleBackdropClick = (e: React.MouseEvent) => {\n if (e.target === dialogRef.current) {\n setIsOpen(false)\n }\n }\n\n const contextValue: CommandContextValue = {\n searchValue,\n setSearchValue,\n highlightedIndex,\n setHighlightedIndex,\n registerItem: (id, value, keywords, disabled) => registerItem(id, value, keywords, disabled),\n unregisterItem,\n filteredItems,\n selectItem,\n loop,\n baseId,\n currentPage,\n setPage,\n goBack,\n pageStack,\n }\n\n // Render data-driven items\n const renderDataDrivenItems = () => {\n if (!items) return null\n\n // Group items\n const groups = new Map<string, CommandItemConfig[]>()\n const ungrouped: CommandItemConfig[] = []\n\n filteredItems.forEach((fi) => {\n const item = items.find((i) => i.key === fi.id)\n if (!item) return\n if (item.group) {\n const group = groups.get(item.group) || []\n group.push(item)\n groups.set(item.group, group)\n } else {\n ungrouped.push(item)\n }\n })\n\n let globalIndex = 0\n\n return (\n <>\n {Array.from(groups.entries()).map(([groupName, groupItems]) => (\n <div key={groupName} role=\"group\" aria-label={groupName}>\n <div className=\"px-3 py-2 text-xs font-semibold text-base-content/60 uppercase tracking-wider\">\n {groupName}\n </div>\n {groupItems.map((item) => {\n const itemIndex = globalIndex++\n const isHighlighted = itemIndex === highlightedIndex\n return (\n <div\n key={item.key}\n role=\"option\"\n aria-selected={isHighlighted}\n aria-disabled={item.disabled}\n data-command-item\n data-highlighted={isHighlighted}\n className={[\n 'px-3 py-2 cursor-pointer flex items-center gap-3',\n isHighlighted && 'bg-primary text-primary-content',\n !isHighlighted && 'hover:bg-base-200',\n item.disabled && 'opacity-50 cursor-not-allowed',\n ]\n .filter(Boolean)\n .join(' ')}\n onClick={() => !item.disabled && selectItem(item.key)}\n onMouseEnter={() => !item.disabled && setHighlightedIndex(itemIndex)}\n >\n {item.icon && <span className=\"w-5 h-5\">{item.icon}</span>}\n <span>{item.label}</span>\n </div>\n )\n })}\n </div>\n ))}\n {ungrouped.length > 0 && (\n <div role=\"group\">\n {ungrouped.map((item) => {\n const itemIndex = globalIndex++\n const isHighlighted = itemIndex === highlightedIndex\n return (\n <div\n key={item.key}\n role=\"option\"\n aria-selected={isHighlighted}\n aria-disabled={item.disabled}\n data-command-item\n data-highlighted={isHighlighted}\n className={[\n 'px-3 py-2 cursor-pointer flex items-center gap-3',\n isHighlighted && 'bg-primary text-primary-content',\n !isHighlighted && 'hover:bg-base-200',\n item.disabled && 'opacity-50 cursor-not-allowed',\n ]\n .filter(Boolean)\n .join(' ')}\n onClick={() => !item.disabled && selectItem(item.key)}\n onMouseEnter={() => !item.disabled && setHighlightedIndex(itemIndex)}\n >\n {item.icon && <span className=\"w-5 h-5\">{item.icon}</span>}\n <span>{item.label}</span>\n </div>\n )\n })}\n </div>\n )}\n </>\n )\n }\n\n return (\n <dialog\n ref={(node) => {\n ;(dialogRef as React.MutableRefObject<HTMLDialogElement | null>).current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) ref.current = node\n }}\n className={`modal ${className}`}\n onClick={handleBackdropClick}\n {...rest}\n >\n <div\n className=\"modal-box p-0 max-w-lg w-full overflow-hidden\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Command palette\"\n >\n <CommandContext.Provider value={contextValue}>\n {/* Breadcrumb for nested pages */}\n {pageStack.length > 1 && (\n <div className=\"px-3 py-2 border-b border-base-content/10 flex items-center gap-2 text-sm\">\n <button\n onClick={goBack}\n className=\"hover:bg-base-200 rounded p-1\"\n aria-label=\"Go back\"\n >\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=\"M15 19l-7-7 7-7\" />\n </svg>\n </button>\n <span className=\"text-base-content/60\">{currentPage}</span>\n </div>\n )}\n\n {/* Search input */}\n <div className=\"px-3 py-3 border-b border-base-content/10\">\n <div className=\"flex items-center gap-3\">\n <svg\n className=\"w-5 h-5 text-base-content/50\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\"\n />\n </svg>\n <input\n ref={inputRef}\n type=\"text\"\n className=\"flex-1 bg-transparent border-none outline-none text-base placeholder:text-base-content/50\"\n placeholder={placeholder}\n value={searchValue}\n onChange={(e) => {\n setSearchValue(e.target.value)\n setHighlightedIndex(0)\n }}\n onKeyDown={handleKeyDown}\n role=\"combobox\"\n aria-expanded=\"true\"\n aria-controls={`${baseId}-listbox`}\n aria-activedescendant={\n enabledItems[highlightedIndex]\n ? `${baseId}-item-${enabledItems[highlightedIndex].id}`\n : undefined\n }\n />\n </div>\n </div>\n\n {/* List */}\n <div\n ref={listRef}\n className=\"max-h-80 overflow-y-auto py-2\"\n role=\"listbox\"\n id={`${baseId}-listbox`}\n >\n {items ? (\n filteredItems.length > 0 ? (\n renderDataDrivenItems()\n ) : (\n <div className=\"px-3 py-8 text-center text-base-content/60\">{emptyMessage}</div>\n )\n ) : (\n children\n )}\n </div>\n\n {/* Footer with shortcut hint */}\n <div className=\"px-3 py-2 border-t border-base-content/10 flex items-center justify-between text-xs text-base-content/50\">\n <div className=\"flex items-center gap-4\">\n <span className=\"flex items-center gap-1\">\n <kbd className=\"kbd kbd-xs\">↑↓</kbd> navigate\n </span>\n <span className=\"flex items-center gap-1\">\n <kbd className=\"kbd kbd-xs\">↵</kbd> select\n </span>\n <span className=\"flex items-center gap-1\">\n <kbd className=\"kbd kbd-xs\">esc</kbd> close\n </span>\n </div>\n </div>\n </CommandContext.Provider>\n </div>\n </dialog>\n )\n }\n)\n\nCommandRoot.displayName = 'Command'\n\n// Command.Input - for compound pattern customization\ninterface CommandInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'value' | 'onChange'> {\n value?: string\n onValueChange?: (value: string) => void\n}\n\nfunction CommandInput({ placeholder, value, onValueChange, ...rest }: CommandInputProps) {\n const { searchValue, setSearchValue } = useCommandContext()\n const controlledValue = value !== undefined ? value : searchValue\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = e.target.value\n if (onValueChange) {\n onValueChange(newValue)\n } else {\n setSearchValue(newValue)\n }\n }\n\n return (\n <input\n type=\"text\"\n className=\"flex-1 bg-transparent border-none outline-none text-base placeholder:text-base-content/50\"\n placeholder={placeholder}\n value={controlledValue}\n onChange={handleChange}\n {...rest}\n />\n )\n}\n\n// Command.List\ninterface CommandListProps {\n children: React.ReactNode\n}\n\nfunction CommandList({ children }: CommandListProps) {\n const { baseId, currentPage } = useCommandContext()\n\n // Filter children to only show items for current page\n const filteredChildren = React.Children.toArray(children).filter((child) => {\n if (!React.isValidElement(child)) return false\n // Show Command.Page only if it matches currentPage\n if (child.type === CommandPage) {\n return (child.props as CommandPageProps).id === currentPage\n }\n // Show groups/items only on root page\n return currentPage === 'root'\n })\n\n return (\n <div role=\"listbox\" id={`${baseId}-listbox`} className=\"py-2\">\n {filteredChildren}\n </div>\n )\n}\n\n// Command.Group\ninterface CommandGroupProps {\n heading?: React.ReactNode\n children: React.ReactNode\n}\n\nfunction CommandGroup({ heading, children }: CommandGroupProps) {\n const { searchValue, filteredItems } = useCommandContext()\n\n // Check if any children match the filter\n const childArray = React.Children.toArray(children)\n const hasVisibleChildren = childArray.some((child) => {\n if (!React.isValidElement(child)) return false\n const childProps = child.props as CommandItemProps\n const childValue = childProps.value || ''\n if (!searchValue) return true\n return filteredItems.some((fi) => fi.value === childValue || fi.id === childProps.value)\n })\n\n if (searchValue && !hasVisibleChildren) {\n return null\n }\n\n return (\n <div role=\"group\" aria-label={typeof heading === 'string' ? heading : undefined}>\n {heading && (\n <div className=\"px-3 py-2 text-xs font-semibold text-base-content/60 uppercase tracking-wider\">\n {heading}\n </div>\n )}\n {children}\n </div>\n )\n}\n\n// Command.Item\ninterface CommandItemProps {\n children: React.ReactNode\n value?: string\n onSelect?: () => void\n disabled?: boolean\n keywords?: string[]\n icon?: React.ReactNode\n}\n\nfunction CommandItem({\n children,\n value,\n onSelect,\n disabled = false,\n keywords = [],\n icon,\n}: CommandItemProps) {\n const {\n registerItem,\n unregisterItem,\n filteredItems,\n highlightedIndex,\n setHighlightedIndex,\n baseId,\n } = useCommandContext()\n\n const itemId = useId()\n const itemValue = value || (typeof children === 'string' ? children : '')\n\n // Register item\n useEffect(() => {\n registerItem(itemId, itemValue, keywords, disabled)\n return () => unregisterItem(itemId)\n }, [itemId, itemValue, keywords, disabled, registerItem, unregisterItem])\n\n // Store onSelect in a ref so we can access it from selectItem\n const onSelectRef = useRef(onSelect)\n onSelectRef.current = onSelect\n\n // Check if this item is visible after filtering\n const isVisible = filteredItems.some((fi) => fi.id === itemId)\n if (!isVisible) return null\n\n // Find index in filtered items\n const enabledItems = filteredItems.filter((fi) => !fi.disabled)\n const itemIndex = enabledItems.findIndex((fi) => fi.id === itemId)\n const isHighlighted = itemIndex === highlightedIndex\n\n const handleClick = () => {\n if (!disabled && onSelect) {\n onSelect()\n }\n }\n\n return (\n <div\n id={`${baseId}-item-${itemId}`}\n role=\"option\"\n aria-selected={isHighlighted}\n aria-disabled={disabled}\n data-command-item\n data-highlighted={isHighlighted}\n className={[\n 'px-3 py-2 cursor-pointer flex items-center gap-3',\n isHighlighted && 'bg-primary text-primary-content',\n !isHighlighted && 'hover:bg-base-200',\n disabled && 'opacity-50 cursor-not-allowed',\n ]\n .filter(Boolean)\n .join(' ')}\n onClick={handleClick}\n onMouseEnter={() => !disabled && setHighlightedIndex(itemIndex)}\n >\n {icon && <span className=\"w-5 h-5\">{icon}</span>}\n <span>{children}</span>\n </div>\n )\n}\n\n// Command.Empty\ninterface CommandEmptyProps {\n children?: React.ReactNode\n}\n\nfunction CommandEmpty({ children = 'No results found.' }: CommandEmptyProps) {\n const { filteredItems, searchValue } = useCommandContext()\n\n if (filteredItems.length > 0 || !searchValue) {\n return null\n }\n\n return <div className=\"px-3 py-8 text-center text-base-content/60\">{children}</div>\n}\n\n// Command.Page - for nested navigation\ninterface CommandPageProps {\n id: string\n children: React.ReactNode\n}\n\nfunction CommandPage({ id, children }: CommandPageProps) {\n const { currentPage } = useCommandContext()\n\n if (currentPage !== id) {\n return null\n }\n\n return <>{children}</>\n}\n\n// Command.Separator\nfunction CommandSeparator() {\n return <div className=\"my-2 border-t border-base-content/10\" role=\"separator\" />\n}\n\n// Export compound component\nexport const Command = Object.assign(CommandRoot, {\n Input: CommandInput,\n List: CommandList,\n Group: CommandGroup,\n Item: CommandItem,\n Empty: CommandEmpty,\n Page: CommandPage,\n Separator: CommandSeparator,\n})\n\nexport default Command\n"],"names":["CommandContext","createContext","useCommandContext","context","useContext","defaultFilter","value","search","keywords","searchLower","k","CommandRoot","forwardRef","children","controlledOpen","onOpenChange","defaultOpen","items","filter","loop","shortcut","placeholder","emptyMessage","className","rest","ref","dialogRef","useRef","inputRef","listRef","previousActiveElement","baseId","useId","internalOpen","setInternalOpen","useState","isControlled","isOpen","setIsOpen","useCallback","newOpen","searchValue","setSearchValue","highlightedIndex","setHighlightedIndex","registeredItems","setRegisteredItems","pageStack","setPageStack","currentPage","setPage","pageId","prev","goBack","registerItem","id","disabled","onSelect","next","unregisterItem","filteredItems","useMemo","item","label","enabledItems","selectItem","i","reg","useEffect","dialog","onDialogClose","handleGlobalKeyDown","e","key","handleKeyDown","handleBackdropClick","contextValue","renderDataDrivenItems","groups","ungrouped","fi","group","globalIndex","jsxs","Fragment","groupName","groupItems","jsx","itemIndex","isHighlighted","node","CommandInput","onValueChange","newValue","CommandList","filteredChildren","React","child","CommandPage","CommandGroup","heading","hasVisibleChildren","childProps","childValue","CommandItem","icon","itemId","itemValue","onSelectRef","handleClick","CommandEmpty","CommandSeparator","Command"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Command.js","sources":["../../src/components/Command.tsx"],"sourcesContent":["import React, {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react'\n\n// DaisyUI classes\nconst dModal = 'modal'\nconst dModalBox = 'modal-box'\nconst dKbd = 'kbd'\nconst dKbdXs = 'kbd-xs'\n\n// Types\nexport interface CommandItemConfig {\n key: string\n label: React.ReactNode\n group?: string\n keywords?: string[]\n disabled?: boolean\n onSelect?: () => void\n icon?: React.ReactNode\n}\n\nexport interface CommandProps extends Omit<React.HTMLAttributes<HTMLDialogElement>, 'children'> {\n children?: React.ReactNode\n open?: boolean\n onOpenChange?: (open: boolean) => void\n defaultOpen?: boolean\n items?: CommandItemConfig[]\n filter?: (value: string, search: string, keywords?: string[]) => boolean\n loop?: boolean\n shortcut?: string[]\n placeholder?: string\n emptyMessage?: React.ReactNode\n}\n\ninterface CommandContextValue {\n searchValue: string\n setSearchValue: (value: string) => void\n highlightedIndex: number\n setHighlightedIndex: (index: number) => void\n registerItem: (id: string, value: string, keywords: string[], disabled: boolean) => void\n unregisterItem: (id: string) => void\n filteredItems: FilteredItem[]\n selectItem: (id: string) => void\n loop: boolean\n baseId: string\n currentPage: string\n setPage: (pageId: string) => void\n goBack: () => void\n pageStack: string[]\n}\n\ninterface FilteredItem {\n id: string\n value: string\n keywords: string[]\n disabled: boolean\n}\n\ninterface ItemRegistration {\n id: string\n value: string\n keywords: string[]\n disabled: boolean\n onSelect?: () => void\n}\n\nconst CommandContext = createContext<CommandContextValue | null>(null)\n\nfunction useCommandContext() {\n const context = useContext(CommandContext)\n if (!context) {\n throw new Error('Command compound components must be used within a Command')\n }\n return context\n}\n\n// Default filter function\nconst defaultFilter = (value: string, search: string, keywords: string[] = []): boolean => {\n const searchLower = search.toLowerCase()\n const valueLower = value.toLowerCase()\n if (valueLower.includes(searchLower)) return true\n return keywords.some((k) => k.toLowerCase().includes(searchLower))\n}\n\n// Root Command component\nconst CommandRoot = forwardRef<HTMLDialogElement, CommandProps>(\n (\n {\n children,\n open: controlledOpen,\n onOpenChange,\n defaultOpen = false,\n items,\n filter = defaultFilter,\n loop = true,\n shortcut = ['k'],\n placeholder = 'Type a command or search...',\n emptyMessage = 'No results found.',\n className = '',\n ...rest\n },\n ref\n ) => {\n const dialogRef = useRef<HTMLDialogElement>(null)\n const inputRef = useRef<HTMLInputElement>(null)\n const listRef = useRef<HTMLDivElement>(null)\n const previousActiveElement = useRef<HTMLElement | null>(null)\n const baseId = useId()\n\n // Controlled/uncontrolled open state\n const [internalOpen, setInternalOpen] = useState(defaultOpen)\n const isControlled = controlledOpen !== undefined\n const isOpen = isControlled ? controlledOpen : internalOpen\n\n const setIsOpen = useCallback(\n (newOpen: boolean) => {\n if (!isControlled) {\n setInternalOpen(newOpen)\n }\n onOpenChange?.(newOpen)\n },\n [isControlled, onOpenChange]\n )\n\n // State\n const [searchValue, setSearchValue] = useState('')\n const [highlightedIndex, setHighlightedIndex] = useState(0)\n const [registeredItems, setRegisteredItems] = useState<Map<string, ItemRegistration>>(new Map())\n const [pageStack, setPageStack] = useState<string[]>(['root'])\n const currentPage = pageStack[pageStack.length - 1]\n\n // Page navigation\n const setPage = useCallback((pageId: string) => {\n setPageStack((prev) => [...prev, pageId])\n setSearchValue('')\n setHighlightedIndex(0)\n }, [])\n\n const goBack = useCallback(() => {\n if (pageStack.length > 1) {\n setPageStack((prev) => prev.slice(0, -1))\n setSearchValue('')\n setHighlightedIndex(0)\n }\n }, [pageStack.length])\n\n // Item registration for compound components\n const registerItem = useCallback(\n (id: string, value: string, keywords: string[], disabled: boolean, onSelect?: () => void) => {\n setRegisteredItems((prev) => {\n const next = new Map(prev)\n next.set(id, { id, value, keywords, disabled, onSelect })\n return next\n })\n },\n []\n )\n\n const unregisterItem = useCallback((id: string) => {\n setRegisteredItems((prev) => {\n const next = new Map(prev)\n next.delete(id)\n return next\n })\n }, [])\n\n // Compute filtered items\n const filteredItems = useMemo((): FilteredItem[] => {\n // Use data-driven items if provided\n if (items) {\n return items\n .filter((item) => {\n if (!searchValue) return true\n const label = typeof item.label === 'string' ? item.label : ''\n return filter(label, searchValue, item.keywords)\n })\n .map((item) => ({\n id: item.key,\n value: typeof item.label === 'string' ? item.label : item.key,\n keywords: item.keywords || [],\n disabled: item.disabled || false,\n }))\n }\n\n // Use registered compound items\n const itemsArray = Array.from(registeredItems.values())\n return itemsArray.filter((item) => {\n if (!searchValue) return true\n return filter(item.value, searchValue, item.keywords)\n })\n }, [items, registeredItems, searchValue, filter])\n\n // Get enabled items for navigation\n const enabledItems = useMemo(\n () => filteredItems.filter((item) => !item.disabled),\n [filteredItems]\n )\n\n // Select item\n const selectItem = useCallback(\n (id: string) => {\n if (items) {\n const item = items.find((i) => i.key === id)\n if (item && !item.disabled) {\n item.onSelect?.()\n setIsOpen(false)\n }\n } else {\n const reg = registeredItems.get(id)\n if (reg && !reg.disabled) {\n reg.onSelect?.()\n setIsOpen(false)\n }\n }\n },\n [items, registeredItems, setIsOpen]\n )\n\n // Reset state when opening\n useEffect(() => {\n if (isOpen) {\n setSearchValue('')\n setHighlightedIndex(0)\n setPageStack(['root'])\n }\n }, [isOpen])\n\n // Handle dialog open/close\n useEffect(() => {\n const dialog = dialogRef.current\n if (!dialog) return\n\n if (isOpen) {\n if (!dialog.open) {\n previousActiveElement.current = document.activeElement as HTMLElement\n dialog.showModal()\n setTimeout(() => inputRef.current?.focus(), 0)\n }\n } else {\n if (dialog.open) {\n dialog.close()\n previousActiveElement.current?.focus()\n }\n }\n }, [isOpen])\n\n // Handle dialog close event\n useEffect(() => {\n const dialog = dialogRef.current\n if (!dialog) return\n\n const onDialogClose = () => {\n setIsOpen(false)\n }\n\n dialog.addEventListener('close', onDialogClose)\n return () => dialog.removeEventListener('close', onDialogClose)\n }, [setIsOpen])\n\n // Global keyboard shortcut\n useEffect(() => {\n const handleGlobalKeyDown = (e: KeyboardEvent) => {\n const key = shortcut[0]?.toLowerCase()\n if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === key) {\n e.preventDefault()\n setIsOpen(!isOpen)\n }\n }\n\n document.addEventListener('keydown', handleGlobalKeyDown)\n return () => document.removeEventListener('keydown', handleGlobalKeyDown)\n }, [shortcut, isOpen, setIsOpen])\n\n // Keyboard navigation\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n switch (e.key) {\n case 'ArrowDown': {\n e.preventDefault()\n if (enabledItems.length === 0) return\n setHighlightedIndex((prev) => {\n const next = prev + 1\n if (next >= enabledItems.length) {\n return loop ? 0 : prev\n }\n return next\n })\n break\n }\n case 'ArrowUp': {\n e.preventDefault()\n if (enabledItems.length === 0) return\n setHighlightedIndex((prev) => {\n const next = prev - 1\n if (next < 0) {\n return loop ? enabledItems.length - 1 : 0\n }\n return next\n })\n break\n }\n case 'Enter': {\n e.preventDefault()\n const item = enabledItems[highlightedIndex]\n if (item) {\n selectItem(item.id)\n }\n break\n }\n case 'Escape': {\n e.preventDefault()\n if (pageStack.length > 1) {\n goBack()\n } else {\n setIsOpen(false)\n }\n break\n }\n case 'Backspace': {\n if (searchValue === '' && pageStack.length > 1) {\n e.preventDefault()\n goBack()\n }\n break\n }\n }\n },\n [enabledItems, highlightedIndex, loop, selectItem, pageStack, goBack, searchValue, setIsOpen]\n )\n\n // Scroll highlighted item into view\n useEffect(() => {\n if (highlightedIndex >= 0 && listRef.current) {\n const items = listRef.current.querySelectorAll('[data-command-item]')\n const highlightedEl = items[highlightedIndex] as HTMLElement\n highlightedEl?.scrollIntoView({ block: 'nearest' })\n }\n }, [highlightedIndex])\n\n // Handle mask click\n const handleBackdropClick = (e: React.MouseEvent) => {\n if (e.target === dialogRef.current) {\n setIsOpen(false)\n }\n }\n\n const contextValue: CommandContextValue = {\n searchValue,\n setSearchValue,\n highlightedIndex,\n setHighlightedIndex,\n registerItem: (id, value, keywords, disabled) => registerItem(id, value, keywords, disabled),\n unregisterItem,\n filteredItems,\n selectItem,\n loop,\n baseId,\n currentPage,\n setPage,\n goBack,\n pageStack,\n }\n\n // Render data-driven items\n const renderDataDrivenItems = () => {\n if (!items) return null\n\n // Group items\n const groups = new Map<string, CommandItemConfig[]>()\n const ungrouped: CommandItemConfig[] = []\n\n filteredItems.forEach((fi) => {\n const item = items.find((i) => i.key === fi.id)\n if (!item) return\n if (item.group) {\n const group = groups.get(item.group) || []\n group.push(item)\n groups.set(item.group, group)\n } else {\n ungrouped.push(item)\n }\n })\n\n let globalIndex = 0\n\n return (\n <>\n {Array.from(groups.entries()).map(([groupName, groupItems]) => (\n <div key={groupName} role=\"group\" aria-label={groupName}>\n <div className=\"px-3 py-2 text-xs font-semibold text-base-content/60 uppercase tracking-wider\">\n {groupName}\n </div>\n {groupItems.map((item) => {\n const itemIndex = globalIndex++\n const isHighlighted = itemIndex === highlightedIndex\n return (\n <div\n key={item.key}\n role=\"option\"\n aria-selected={isHighlighted}\n aria-disabled={item.disabled}\n data-command-item\n data-highlighted={isHighlighted}\n className={[\n 'px-3 py-2 cursor-pointer flex items-center gap-3',\n isHighlighted && 'bg-primary text-primary-content',\n !isHighlighted && 'hover:bg-base-200',\n item.disabled && 'opacity-50 cursor-not-allowed',\n ]\n .filter(Boolean)\n .join(' ')}\n onClick={() => !item.disabled && selectItem(item.key)}\n onMouseEnter={() => !item.disabled && setHighlightedIndex(itemIndex)}\n >\n {item.icon && <span className=\"w-5 h-5\">{item.icon}</span>}\n <span>{item.label}</span>\n </div>\n )\n })}\n </div>\n ))}\n {ungrouped.length > 0 && (\n <div role=\"group\">\n {ungrouped.map((item) => {\n const itemIndex = globalIndex++\n const isHighlighted = itemIndex === highlightedIndex\n return (\n <div\n key={item.key}\n role=\"option\"\n aria-selected={isHighlighted}\n aria-disabled={item.disabled}\n data-command-item\n data-highlighted={isHighlighted}\n className={[\n 'px-3 py-2 cursor-pointer flex items-center gap-3',\n isHighlighted && 'bg-primary text-primary-content',\n !isHighlighted && 'hover:bg-base-200',\n item.disabled && 'opacity-50 cursor-not-allowed',\n ]\n .filter(Boolean)\n .join(' ')}\n onClick={() => !item.disabled && selectItem(item.key)}\n onMouseEnter={() => !item.disabled && setHighlightedIndex(itemIndex)}\n >\n {item.icon && <span className=\"w-5 h-5\">{item.icon}</span>}\n <span>{item.label}</span>\n </div>\n )\n })}\n </div>\n )}\n </>\n )\n }\n\n return (\n <dialog\n ref={(node) => {\n ;(dialogRef as React.MutableRefObject<HTMLDialogElement | null>).current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) ref.current = node\n }}\n className={`${dModal} ${className}`}\n onClick={handleBackdropClick}\n {...rest}\n >\n <div\n className={`${dModalBox} p-0 max-w-lg w-full overflow-hidden`}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Command palette\"\n >\n <CommandContext.Provider value={contextValue}>\n {/* Breadcrumb for nested pages */}\n {pageStack.length > 1 && (\n <div className=\"px-3 py-2 border-b border-base-content/10 flex items-center gap-2 text-sm\">\n <button\n onClick={goBack}\n className=\"hover:bg-base-200 rounded p-1\"\n aria-label=\"Go back\"\n >\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=\"M15 19l-7-7 7-7\" />\n </svg>\n </button>\n <span className=\"text-base-content/60\">{currentPage}</span>\n </div>\n )}\n\n {/* Search input */}\n <div className=\"px-3 py-3 border-b border-base-content/10\">\n <div className=\"flex items-center gap-3\">\n <svg\n className=\"w-5 h-5 text-base-content/50\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\"\n />\n </svg>\n <input\n ref={inputRef}\n type=\"text\"\n className=\"flex-1 bg-transparent border-none outline-none text-base placeholder:text-base-content/50\"\n placeholder={placeholder}\n value={searchValue}\n onChange={(e) => {\n setSearchValue(e.target.value)\n setHighlightedIndex(0)\n }}\n onKeyDown={handleKeyDown}\n role=\"combobox\"\n aria-expanded=\"true\"\n aria-controls={`${baseId}-listbox`}\n aria-activedescendant={\n enabledItems[highlightedIndex]\n ? `${baseId}-item-${enabledItems[highlightedIndex].id}`\n : undefined\n }\n />\n </div>\n </div>\n\n {/* List */}\n <div\n ref={listRef}\n className=\"max-h-80 overflow-y-auto py-2\"\n role=\"listbox\"\n id={`${baseId}-listbox`}\n >\n {items ? (\n filteredItems.length > 0 ? (\n renderDataDrivenItems()\n ) : (\n <div className=\"px-3 py-8 text-center text-base-content/60\">{emptyMessage}</div>\n )\n ) : (\n children\n )}\n </div>\n\n {/* Footer with shortcut hint */}\n <div className=\"px-3 py-2 border-t border-base-content/10 flex items-center justify-between text-xs text-base-content/50\">\n <div className=\"flex items-center gap-4\">\n <span className=\"flex items-center gap-1\">\n <kbd className={`${dKbd} ${dKbdXs}`}>↑↓</kbd> navigate\n </span>\n <span className=\"flex items-center gap-1\">\n <kbd className={`${dKbd} ${dKbdXs}`}>↵</kbd> select\n </span>\n <span className=\"flex items-center gap-1\">\n <kbd className={`${dKbd} ${dKbdXs}`}>esc</kbd> close\n </span>\n </div>\n </div>\n </CommandContext.Provider>\n </div>\n </dialog>\n )\n }\n)\n\nCommandRoot.displayName = 'Command'\n\n// Command.Input - for compound pattern customization\ninterface CommandInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'value' | 'onChange'> {\n value?: string\n onValueChange?: (value: string) => void\n}\n\nfunction CommandInput({ placeholder, value, onValueChange, ...rest }: CommandInputProps) {\n const { searchValue, setSearchValue } = useCommandContext()\n const controlledValue = value !== undefined ? value : searchValue\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = e.target.value\n if (onValueChange) {\n onValueChange(newValue)\n } else {\n setSearchValue(newValue)\n }\n }\n\n return (\n <input\n type=\"text\"\n className=\"flex-1 bg-transparent border-none outline-none text-base placeholder:text-base-content/50\"\n placeholder={placeholder}\n value={controlledValue}\n onChange={handleChange}\n {...rest}\n />\n )\n}\n\n// Command.List\ninterface CommandListProps {\n children: React.ReactNode\n}\n\nfunction CommandList({ children }: CommandListProps) {\n const { baseId, currentPage } = useCommandContext()\n\n // Filter children to only show items for current page\n const filteredChildren = React.Children.toArray(children).filter((child) => {\n if (!React.isValidElement(child)) return false\n // Show Command.Page only if it matches currentPage\n if (child.type === CommandPage) {\n return (child.props as CommandPageProps).id === currentPage\n }\n // Show groups/items only on root page\n return currentPage === 'root'\n })\n\n return (\n <div role=\"listbox\" id={`${baseId}-listbox`} className=\"py-2\">\n {filteredChildren}\n </div>\n )\n}\n\n// Command.Group\ninterface CommandGroupProps {\n heading?: React.ReactNode\n children: React.ReactNode\n}\n\nfunction CommandGroup({ heading, children }: CommandGroupProps) {\n const { searchValue, filteredItems } = useCommandContext()\n\n // Check if any children match the filter\n const childArray = React.Children.toArray(children)\n const hasVisibleChildren = childArray.some((child) => {\n if (!React.isValidElement(child)) return false\n const childProps = child.props as CommandItemProps\n const childValue = childProps.value || ''\n if (!searchValue) return true\n return filteredItems.some((fi) => fi.value === childValue || fi.id === childProps.value)\n })\n\n if (searchValue && !hasVisibleChildren) {\n return null\n }\n\n return (\n <div role=\"group\" aria-label={typeof heading === 'string' ? heading : undefined}>\n {heading && (\n <div className=\"px-3 py-2 text-xs font-semibold text-base-content/60 uppercase tracking-wider\">\n {heading}\n </div>\n )}\n {children}\n </div>\n )\n}\n\n// Command.Item\ninterface CommandItemProps {\n children: React.ReactNode\n value?: string\n onSelect?: () => void\n disabled?: boolean\n keywords?: string[]\n icon?: React.ReactNode\n}\n\nfunction CommandItem({\n children,\n value,\n onSelect,\n disabled = false,\n keywords = [],\n icon,\n}: CommandItemProps) {\n const {\n registerItem,\n unregisterItem,\n filteredItems,\n highlightedIndex,\n setHighlightedIndex,\n baseId,\n } = useCommandContext()\n\n const itemId = useId()\n const itemValue = value || (typeof children === 'string' ? children : '')\n\n // Register item\n useEffect(() => {\n registerItem(itemId, itemValue, keywords, disabled)\n return () => unregisterItem(itemId)\n }, [itemId, itemValue, keywords, disabled, registerItem, unregisterItem])\n\n // Store onSelect in a ref so we can access it from selectItem\n const onSelectRef = useRef(onSelect)\n onSelectRef.current = onSelect\n\n // Check if this item is visible after filtering\n const isVisible = filteredItems.some((fi) => fi.id === itemId)\n if (!isVisible) return null\n\n // Find index in filtered items\n const enabledItems = filteredItems.filter((fi) => !fi.disabled)\n const itemIndex = enabledItems.findIndex((fi) => fi.id === itemId)\n const isHighlighted = itemIndex === highlightedIndex\n\n const handleClick = () => {\n if (!disabled && onSelect) {\n onSelect()\n }\n }\n\n return (\n <div\n id={`${baseId}-item-${itemId}`}\n role=\"option\"\n aria-selected={isHighlighted}\n aria-disabled={disabled}\n data-command-item\n data-highlighted={isHighlighted}\n className={[\n 'px-3 py-2 cursor-pointer flex items-center gap-3',\n isHighlighted && 'bg-primary text-primary-content',\n !isHighlighted && 'hover:bg-base-200',\n disabled && 'opacity-50 cursor-not-allowed',\n ]\n .filter(Boolean)\n .join(' ')}\n onClick={handleClick}\n onMouseEnter={() => !disabled && setHighlightedIndex(itemIndex)}\n >\n {icon && <span className=\"w-5 h-5\">{icon}</span>}\n <span>{children}</span>\n </div>\n )\n}\n\n// Command.Empty\ninterface CommandEmptyProps {\n children?: React.ReactNode\n}\n\nfunction CommandEmpty({ children = 'No results found.' }: CommandEmptyProps) {\n const { filteredItems, searchValue } = useCommandContext()\n\n if (filteredItems.length > 0 || !searchValue) {\n return null\n }\n\n return <div className=\"px-3 py-8 text-center text-base-content/60\">{children}</div>\n}\n\n// Command.Page - for nested navigation\ninterface CommandPageProps {\n id: string\n children: React.ReactNode\n}\n\nfunction CommandPage({ id, children }: CommandPageProps) {\n const { currentPage } = useCommandContext()\n\n if (currentPage !== id) {\n return null\n }\n\n return <>{children}</>\n}\n\n// Command.Separator\nfunction CommandSeparator() {\n return <div className=\"my-2 border-t border-base-content/10\" role=\"separator\" />\n}\n\n// Export compound component\nexport const Command = Object.assign(CommandRoot, {\n Input: CommandInput,\n List: CommandList,\n Group: CommandGroup,\n Item: CommandItem,\n Empty: CommandEmpty,\n Page: CommandPage,\n Separator: CommandSeparator,\n})\n\nexport default Command\n"],"names":["dModal","dModalBox","dKbd","dKbdXs","CommandContext","createContext","useCommandContext","context","useContext","defaultFilter","value","search","keywords","searchLower","k","CommandRoot","forwardRef","children","controlledOpen","onOpenChange","defaultOpen","items","filter","loop","shortcut","placeholder","emptyMessage","className","rest","ref","dialogRef","useRef","inputRef","listRef","previousActiveElement","baseId","useId","internalOpen","setInternalOpen","useState","isControlled","isOpen","setIsOpen","useCallback","newOpen","searchValue","setSearchValue","highlightedIndex","setHighlightedIndex","registeredItems","setRegisteredItems","pageStack","setPageStack","currentPage","setPage","pageId","prev","goBack","registerItem","id","disabled","onSelect","next","unregisterItem","filteredItems","useMemo","item","label","enabledItems","selectItem","i","reg","useEffect","dialog","onDialogClose","handleGlobalKeyDown","e","key","handleKeyDown","handleBackdropClick","contextValue","renderDataDrivenItems","groups","ungrouped","fi","group","globalIndex","jsxs","Fragment","groupName","groupItems","jsx","itemIndex","isHighlighted","node","CommandInput","onValueChange","newValue","CommandList","filteredChildren","React","child","CommandPage","CommandGroup","heading","hasVisibleChildren","childProps","childValue","CommandItem","icon","itemId","itemValue","onSelectRef","handleClick","CommandEmpty","CommandSeparator","Command"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
2
|
import { Locale } from '../locale';
|
|
3
|
-
export type ComponentSize = '
|
|
3
|
+
export type ComponentSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
4
4
|
export type Direction = 'ltr' | 'rtl';
|
|
5
5
|
export interface ConfigContextValue {
|
|
6
6
|
/** Current locale */
|
|
@@ -3,24 +3,24 @@ import { createContext as C, useContext as r, useMemo as p } from "react";
|
|
|
3
3
|
import u from "../locale/en-US.js";
|
|
4
4
|
const m = {
|
|
5
5
|
locale: u,
|
|
6
|
-
componentSize: "
|
|
6
|
+
componentSize: "md",
|
|
7
7
|
direction: "ltr"
|
|
8
8
|
}, n = C(m);
|
|
9
9
|
function P() {
|
|
10
10
|
return r(n);
|
|
11
11
|
}
|
|
12
|
-
function
|
|
12
|
+
function g() {
|
|
13
13
|
const { locale: o } = r(n);
|
|
14
14
|
return o;
|
|
15
15
|
}
|
|
16
16
|
function S(o) {
|
|
17
|
-
return
|
|
17
|
+
return g()[o] ?? u[o] ?? {};
|
|
18
18
|
}
|
|
19
19
|
const z = ({
|
|
20
20
|
locale: o,
|
|
21
21
|
componentSize: t,
|
|
22
|
-
direction:
|
|
23
|
-
prefixCls:
|
|
22
|
+
direction: c,
|
|
23
|
+
prefixCls: i,
|
|
24
24
|
getPopupContainer: l,
|
|
25
25
|
children: f
|
|
26
26
|
}) => {
|
|
@@ -28,11 +28,11 @@ const z = ({
|
|
|
28
28
|
() => ({
|
|
29
29
|
locale: o ?? e.locale,
|
|
30
30
|
componentSize: t ?? e.componentSize,
|
|
31
|
-
direction:
|
|
32
|
-
prefixCls:
|
|
31
|
+
direction: c ?? e.direction,
|
|
32
|
+
prefixCls: i ?? e.prefixCls,
|
|
33
33
|
getPopupContainer: l ?? e.getPopupContainer
|
|
34
34
|
}),
|
|
35
|
-
[o, t,
|
|
35
|
+
[o, t, c, i, l, e]
|
|
36
36
|
);
|
|
37
37
|
return /* @__PURE__ */ a(n.Provider, { value: s, children: f });
|
|
38
38
|
};
|
|
@@ -41,6 +41,6 @@ export {
|
|
|
41
41
|
z as ConfigProvider,
|
|
42
42
|
S as useComponentLocale,
|
|
43
43
|
P as useConfig,
|
|
44
|
-
|
|
44
|
+
g as useLocale
|
|
45
45
|
};
|
|
46
46
|
//# sourceMappingURL=ConfigProvider.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConfigProvider.js","sources":["../../src/components/ConfigProvider.tsx"],"sourcesContent":["import React, { createContext, useContext, useMemo } from 'react'\nimport type { Locale } from '../locale'\nimport enUS from '../locale/en-US'\n\nexport type ComponentSize = '
|
|
1
|
+
{"version":3,"file":"ConfigProvider.js","sources":["../../src/components/ConfigProvider.tsx"],"sourcesContent":["import React, { createContext, useContext, useMemo } from 'react'\nimport type { Locale } from '../locale'\nimport enUS from '../locale/en-US'\n\nexport type ComponentSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl'\nexport type Direction = 'ltr' | 'rtl'\n\nexport interface ConfigContextValue {\n /** Current locale */\n locale: Locale\n /** Component size */\n componentSize?: ComponentSize\n /** Layout direction */\n direction?: Direction\n /** Prefix for CSS classes */\n prefixCls?: string\n /** Default container for portals (modals, dropdowns, etc.) */\n getPopupContainer?: (triggerNode?: HTMLElement) => HTMLElement\n}\n\nexport interface ConfigProviderProps {\n /** Locale configuration */\n locale?: Locale\n /** Component size for all child components */\n componentSize?: ComponentSize\n /** Layout direction (ltr or rtl) */\n direction?: Direction\n /** Prefix for CSS classes */\n prefixCls?: string\n /** Default container for portals */\n getPopupContainer?: (triggerNode?: HTMLElement) => HTMLElement\n /** Child components */\n children?: React.ReactNode\n}\n\nconst defaultConfig: ConfigContextValue = {\n locale: enUS,\n componentSize: 'md',\n direction: 'ltr',\n}\n\nconst ConfigContext = createContext<ConfigContextValue>(defaultConfig)\n\n/**\n * Hook to access the current configuration\n */\nexport function useConfig(): ConfigContextValue {\n return useContext(ConfigContext)\n}\n\n/**\n * Hook to access the current locale\n */\nexport function useLocale(): Locale {\n const { locale } = useContext(ConfigContext)\n return locale\n}\n\n/**\n * Hook to get locale strings for a specific component\n */\nexport function useComponentLocale<K extends keyof Locale>(\n componentName: K\n): NonNullable<Locale[K]> {\n const locale = useLocale()\n return (locale[componentName] ?? enUS[componentName] ?? {}) as NonNullable<Locale[K]>\n}\n\n/**\n * ConfigProvider component for global configuration\n *\n * Provides locale, component size, direction, and other settings to all child components.\n *\n * @example\n * ```tsx\n * import { ConfigProvider, zhCN } from 'asterui'\n *\n * <ConfigProvider locale={zhCN} componentSize=\"small\">\n * <App />\n * </ConfigProvider>\n * ```\n */\nexport const ConfigProvider: React.FC<ConfigProviderProps> = ({\n locale,\n componentSize,\n direction,\n prefixCls,\n getPopupContainer,\n children,\n}) => {\n // Get parent config if nested\n const parentConfig = useContext(ConfigContext)\n\n const config = useMemo<ConfigContextValue>(\n () => ({\n locale: locale ?? parentConfig.locale,\n componentSize: componentSize ?? parentConfig.componentSize,\n direction: direction ?? parentConfig.direction,\n prefixCls: prefixCls ?? parentConfig.prefixCls,\n getPopupContainer: getPopupContainer ?? parentConfig.getPopupContainer,\n }),\n [locale, componentSize, direction, prefixCls, getPopupContainer, parentConfig]\n )\n\n return <ConfigContext.Provider value={config}>{children}</ConfigContext.Provider>\n}\n\n// Also export the context for advanced use cases\nexport { ConfigContext }\n"],"names":["defaultConfig","enUS","ConfigContext","createContext","useConfig","useContext","useLocale","locale","useComponentLocale","componentName","ConfigProvider","componentSize","direction","prefixCls","getPopupContainer","children","parentConfig","config","useMemo"],"mappings":";;;AAmCA,MAAMA,IAAoC;AAAA,EACxC,QAAQC;AAAA,EACR,eAAe;AAAA,EACf,WAAW;AACb,GAEMC,IAAgBC,EAAkCH,CAAa;AAK9D,SAASI,IAAgC;AAC9C,SAAOC,EAAWH,CAAa;AACjC;AAKO,SAASI,IAAoB;AAClC,QAAM,EAAE,QAAAC,EAAA,IAAWF,EAAWH,CAAa;AAC3C,SAAOK;AACT;AAKO,SAASC,EACdC,GACwB;AAExB,SADeH,EAAA,EACAG,CAAa,KAAKR,EAAKQ,CAAa,KAAK,CAAA;AAC1D;AAgBO,MAAMC,IAAgD,CAAC;AAAA,EAC5D,QAAAH;AAAA,EACA,eAAAI;AAAA,EACA,WAAAC;AAAA,EACA,WAAAC;AAAA,EACA,mBAAAC;AAAA,EACA,UAAAC;AACF,MAAM;AAEJ,QAAMC,IAAeX,EAAWH,CAAa,GAEvCe,IAASC;AAAA,IACb,OAAO;AAAA,MACL,QAAQX,KAAUS,EAAa;AAAA,MAC/B,eAAeL,KAAiBK,EAAa;AAAA,MAC7C,WAAWJ,KAAaI,EAAa;AAAA,MACrC,WAAWH,KAAaG,EAAa;AAAA,MACrC,mBAAmBF,KAAqBE,EAAa;AAAA,IAAA;AAAA,IAEvD,CAACT,GAAQI,GAAeC,GAAWC,GAAWC,GAAmBE,CAAY;AAAA,EAAA;AAG/E,2BAAQd,EAAc,UAAd,EAAuB,OAAOe,GAAS,UAAAF,GAAS;AAC1D;"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { jsxs as b, Fragment as
|
|
2
|
-
import C, { useState as g, useRef as y, useCallback as M, useEffect as
|
|
3
|
-
import { createPortal as
|
|
4
|
-
const
|
|
5
|
-
const e =
|
|
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($);
|
|
6
6
|
if (!e)
|
|
7
7
|
throw new Error("ContextMenu compound components must be used within a ContextMenu");
|
|
8
8
|
return e;
|
|
9
|
-
},
|
|
9
|
+
}, R = ({
|
|
10
10
|
children: e,
|
|
11
11
|
icon: c,
|
|
12
12
|
disabled: s = !1,
|
|
@@ -14,7 +14,7 @@ const L = I(null), A = () => {
|
|
|
14
14
|
className: h = "",
|
|
15
15
|
_key: l
|
|
16
16
|
}) => {
|
|
17
|
-
const { onSelect: m, onClose: o } =
|
|
17
|
+
const { onSelect: m, onClose: o } = O();
|
|
18
18
|
return /* @__PURE__ */ n("li", { className: h, children: /* @__PURE__ */ b(
|
|
19
19
|
"button",
|
|
20
20
|
{
|
|
@@ -33,7 +33,7 @@ const L = I(null), A = () => {
|
|
|
33
33
|
]
|
|
34
34
|
}
|
|
35
35
|
) });
|
|
36
|
-
},
|
|
36
|
+
}, _ = ({ className: e = "" }) => /* @__PURE__ */ n("li", { className: `${S} my-1 ${e}` }), D = ({
|
|
37
37
|
label: e,
|
|
38
38
|
icon: c,
|
|
39
39
|
disabled: s = !1,
|
|
@@ -71,7 +71,7 @@ const L = I(null), A = () => {
|
|
|
71
71
|
m && /* @__PURE__ */ n(
|
|
72
72
|
"ul",
|
|
73
73
|
{
|
|
74
|
-
className:
|
|
74
|
+
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
75
|
onMouseEnter: u,
|
|
76
76
|
onMouseLeave: f,
|
|
77
77
|
children: d
|
|
@@ -80,10 +80,10 @@ const L = I(null), A = () => {
|
|
|
80
80
|
]
|
|
81
81
|
}
|
|
82
82
|
);
|
|
83
|
-
},
|
|
83
|
+
}, j = ({ item: e, onSelect: c, onClose: s }) => {
|
|
84
84
|
const [d, h] = g(!1), l = y(null);
|
|
85
85
|
if (e.divider)
|
|
86
|
-
return /* @__PURE__ */ n("li", { className:
|
|
86
|
+
return /* @__PURE__ */ n("li", { className: `${S} my-1` });
|
|
87
87
|
const m = () => {
|
|
88
88
|
e.disabled || e.children && e.children.length > 0 || (c(e.key), s());
|
|
89
89
|
}, o = e.children && e.children.length > 0, a = () => {
|
|
@@ -118,23 +118,23 @@ const L = I(null), A = () => {
|
|
|
118
118
|
o && d && /* @__PURE__ */ n(
|
|
119
119
|
"ul",
|
|
120
120
|
{
|
|
121
|
-
className:
|
|
121
|
+
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
122
|
onMouseEnter: a,
|
|
123
123
|
onMouseLeave: u,
|
|
124
|
-
children: e.children.map((f) => /* @__PURE__ */ n(
|
|
124
|
+
children: e.children.map((f) => /* @__PURE__ */ n(j, { item: f, onSelect: c, onClose: s }, f.key))
|
|
125
125
|
}
|
|
126
126
|
)
|
|
127
127
|
]
|
|
128
128
|
}
|
|
129
129
|
);
|
|
130
|
-
},
|
|
130
|
+
}, F = ({
|
|
131
131
|
children: e,
|
|
132
132
|
items: c,
|
|
133
133
|
onSelect: s,
|
|
134
134
|
disabled: d = !1,
|
|
135
135
|
className: h = ""
|
|
136
136
|
}) => {
|
|
137
|
-
const [l, m] = g(!1), [o, a] = g({ x: 0, y: 0 }), u = y(null), f = y(null),
|
|
137
|
+
const [l, m] = g(!1), [o, a] = g({ x: 0, y: 0 }), u = y(null), f = y(null), W = M(
|
|
138
138
|
(r) => {
|
|
139
139
|
if (d) return;
|
|
140
140
|
r.preventDefault(), r.stopPropagation();
|
|
@@ -144,19 +144,19 @@ const L = I(null), A = () => {
|
|
|
144
144
|
[d]
|
|
145
145
|
), p = M(() => {
|
|
146
146
|
m(!1);
|
|
147
|
-
}, []),
|
|
147
|
+
}, []), N = M(
|
|
148
148
|
(r) => {
|
|
149
149
|
s?.(r);
|
|
150
150
|
},
|
|
151
151
|
[s]
|
|
152
152
|
);
|
|
153
|
-
|
|
153
|
+
L(() => {
|
|
154
154
|
if (l && u.current) {
|
|
155
155
|
const t = u.current.getBoundingClientRect(), i = window.innerWidth, x = window.innerHeight;
|
|
156
156
|
let { x: v, y: w } = o;
|
|
157
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 });
|
|
158
158
|
}
|
|
159
|
-
}, [l, o]),
|
|
159
|
+
}, [l, o]), L(() => {
|
|
160
160
|
if (!l) return;
|
|
161
161
|
const r = (x) => {
|
|
162
162
|
u.current && !u.current.contains(x.target) && p();
|
|
@@ -169,38 +169,38 @@ const L = I(null), A = () => {
|
|
|
169
169
|
document.removeEventListener("mousedown", r), document.removeEventListener("keydown", t), document.removeEventListener("scroll", i, !0);
|
|
170
170
|
};
|
|
171
171
|
}, [l, p]);
|
|
172
|
-
const
|
|
172
|
+
const P = (r) => C.Children.map(r, (t) => {
|
|
173
173
|
if (C.isValidElement(t)) {
|
|
174
174
|
const i = t.key != null ? String(t.key) : void 0;
|
|
175
|
-
if (t.type ===
|
|
175
|
+
if (t.type === R || t.type === D)
|
|
176
176
|
return C.cloneElement(t, { _key: i });
|
|
177
177
|
}
|
|
178
178
|
return t;
|
|
179
|
-
}),
|
|
180
|
-
onSelect:
|
|
179
|
+
}), E = C.Children.toArray(e), T = E[0], z = P(E.slice(1)), B = c && c.length > 0, I = {
|
|
180
|
+
onSelect: N,
|
|
181
181
|
onClose: p
|
|
182
182
|
};
|
|
183
|
-
return /* @__PURE__ */ b(
|
|
184
|
-
/* @__PURE__ */ n("div", { ref: f, onContextMenu:
|
|
185
|
-
l &&
|
|
186
|
-
/* @__PURE__ */ n(
|
|
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(
|
|
187
187
|
"ul",
|
|
188
188
|
{
|
|
189
189
|
ref: u,
|
|
190
|
-
className:
|
|
190
|
+
className: `${k} bg-base-100 rounded-box shadow-lg border border-base-300 min-w-[160px] p-1 fixed z-[9999] ${h}`,
|
|
191
191
|
style: { left: o.x, top: o.y },
|
|
192
|
-
children:
|
|
192
|
+
children: B ? c.map((r) => /* @__PURE__ */ n(j, { item: r, onSelect: N, onClose: p }, r.key)) : z
|
|
193
193
|
}
|
|
194
194
|
) }),
|
|
195
195
|
document.body
|
|
196
196
|
)
|
|
197
197
|
] });
|
|
198
|
-
},
|
|
199
|
-
Item:
|
|
200
|
-
Divider:
|
|
201
|
-
SubMenu:
|
|
198
|
+
}, G = Object.assign(F, {
|
|
199
|
+
Item: R,
|
|
200
|
+
Divider: _,
|
|
201
|
+
SubMenu: D
|
|
202
202
|
});
|
|
203
203
|
export {
|
|
204
|
-
|
|
204
|
+
G as ContextMenu
|
|
205
205
|
};
|
|
206
206
|
//# sourceMappingURL=ContextMenu.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContextMenu.js","sources":["../../src/components/ContextMenu.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect, useCallback, createContext, useContext } from 'react'\nimport { createPortal } from 'react-dom'\n\nexport interface ContextMenuItem {\n key: string\n label: React.ReactNode\n icon?: React.ReactNode\n disabled?: boolean\n danger?: boolean\n divider?: boolean\n children?: ContextMenuItem[]\n}\n\nexport interface ContextMenuProps {\n /** Element that triggers the context menu on right-click */\n children: React.ReactNode\n /** Menu items (data-driven pattern) */\n items?: ContextMenuItem[]\n /** Callback when an item is selected */\n onSelect?: (key: string) => void\n /** Whether the context menu is disabled */\n disabled?: boolean\n /** Additional CSS classes for the menu */\n className?: string\n}\n\nexport interface ContextMenuItemProps {\n /** Item content */\n children: React.ReactNode\n /** Icon to display before label */\n icon?: React.ReactNode\n /** Whether the item is disabled */\n disabled?: boolean\n /** Show as danger/destructive action */\n danger?: boolean\n /** Additional CSS classes */\n className?: string\n /** @internal */\n _key?: string\n}\n\nexport interface ContextMenuDividerProps {\n /** Additional CSS classes */\n className?: string\n}\n\nexport interface ContextMenuSubMenuProps {\n /** Submenu label */\n label: React.ReactNode\n /** Icon to display before label */\n icon?: React.ReactNode\n /** Whether the submenu is disabled */\n disabled?: boolean\n /** Submenu items */\n children: React.ReactNode\n /** Additional CSS classes */\n className?: string\n /** @internal */\n _key?: string\n}\n\ninterface ContextMenuContextValue {\n onSelect: (key: string) => void\n onClose: () => void\n}\n\ninterface MenuPosition {\n x: number\n y: number\n}\n\nconst ContextMenuContext = createContext<ContextMenuContextValue | null>(null)\n\nconst useContextMenuContext = () => {\n const context = useContext(ContextMenuContext)\n if (!context) {\n throw new Error('ContextMenu compound components must be used within a ContextMenu')\n }\n return context\n}\n\n// Compound pattern components\nconst ContextMenuItemComponent: React.FC<ContextMenuItemProps> = ({\n children,\n icon,\n disabled = false,\n danger = false,\n className = '',\n _key,\n}) => {\n const { onSelect, onClose } = useContextMenuContext()\n\n const handleClick = () => {\n if (disabled || !_key) return\n onSelect(_key)\n onClose()\n }\n\n return (\n <li className={className}>\n <button\n onClick={handleClick}\n disabled={disabled}\n className={`\n flex items-center gap-2 w-full px-4 py-2 text-left text-sm\n ${disabled ? 'opacity-50 cursor-not-allowed' : 'hover:bg-base-200'}\n ${danger ? 'text-error hover:bg-error/10' : ''}\n `}\n >\n {icon && <span className=\"w-4 h-4\">{icon}</span>}\n <span className=\"flex-1\">{children}</span>\n </button>\n </li>\n )\n}\n\nconst ContextMenuDividerComponent: React.FC<ContextMenuDividerProps> = ({ className = '' }) => {\n return <li className={`divider my-1 ${className}`}></li>\n}\n\nconst ContextMenuSubMenuComponent: React.FC<ContextMenuSubMenuProps> = ({\n label,\n icon,\n disabled = false,\n children,\n className = '',\n _key: _unusedKey,\n}) => {\n const [showSubmenu, setShowSubmenu] = useState(false)\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n\n const handleMouseEnter = () => {\n if (disabled) return\n if (timeoutRef.current) clearTimeout(timeoutRef.current)\n setShowSubmenu(true)\n }\n\n const handleMouseLeave = () => {\n timeoutRef.current = setTimeout(() => setShowSubmenu(false), 100)\n }\n\n return (\n <li\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n className={`relative ${className}`}\n >\n <button\n disabled={disabled}\n className={`\n flex items-center gap-2 w-full px-4 py-2 text-left text-sm\n ${disabled ? 'opacity-50 cursor-not-allowed' : 'hover:bg-base-200'}\n `}\n >\n {icon && <span className=\"w-4 h-4\">{icon}</span>}\n <span className=\"flex-1\">{label}</span>\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 </button>\n {showSubmenu && (\n <ul\n className=\"menu bg-base-100 rounded-box shadow-lg border border-base-300 absolute left-full top-0 min-w-[160px] z-50 p-1\"\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n >\n {children}\n </ul>\n )}\n </li>\n )\n}\n\n// Data-driven pattern internal component\nconst MenuItem: React.FC<{\n item: ContextMenuItem\n onSelect: (key: string) => void\n onClose: () => void\n}> = ({ item, onSelect, onClose }) => {\n const [showSubmenu, setShowSubmenu] = useState(false)\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n\n if (item.divider) {\n return <li className=\"divider my-1\"></li>\n }\n\n const handleClick = () => {\n if (item.disabled) return\n if (item.children && item.children.length > 0) return\n onSelect(item.key)\n onClose()\n }\n\n const hasSubmenu = item.children && item.children.length > 0\n\n const handleMouseEnter = () => {\n if (!hasSubmenu) return\n if (timeoutRef.current) clearTimeout(timeoutRef.current)\n setShowSubmenu(true)\n }\n\n const handleMouseLeave = () => {\n if (!hasSubmenu) return\n timeoutRef.current = setTimeout(() => setShowSubmenu(false), 100)\n }\n\n return (\n <li\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n className=\"relative\"\n >\n <button\n onClick={handleClick}\n disabled={item.disabled}\n className={`\n flex items-center gap-2 w-full px-4 py-2 text-left text-sm\n ${item.disabled ? 'opacity-50 cursor-not-allowed' : 'hover:bg-base-200'}\n ${item.danger ? 'text-error hover:bg-error/10' : ''}\n `}\n >\n {item.icon && <span className=\"w-4 h-4\">{item.icon}</span>}\n <span className=\"flex-1\">{item.label}</span>\n {hasSubmenu && (\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 )}\n </button>\n {hasSubmenu && showSubmenu && (\n <ul\n className=\"menu bg-base-100 rounded-box shadow-lg border border-base-300 absolute left-full top-0 min-w-[160px] z-50 p-1\"\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n >\n {item.children!.map((child) => (\n <MenuItem key={child.key} item={child} onSelect={onSelect} onClose={onClose} />\n ))}\n </ul>\n )}\n </li>\n )\n}\n\nconst ContextMenuRoot: React.FC<ContextMenuProps> = ({\n children,\n items,\n onSelect,\n disabled = false,\n className = '',\n}) => {\n const [visible, setVisible] = useState(false)\n const [position, setPosition] = useState<MenuPosition>({ x: 0, y: 0 })\n const menuRef = useRef<HTMLUListElement>(null)\n const triggerRef = useRef<HTMLDivElement>(null)\n\n const handleContextMenu = useCallback(\n (e: React.MouseEvent) => {\n if (disabled) return\n e.preventDefault()\n e.stopPropagation()\n\n // Calculate position, ensuring menu stays within viewport\n let x = e.clientX\n let y = e.clientY\n\n // We'll adjust after render when we know menu dimensions\n setPosition({ x, y })\n setVisible(true)\n },\n [disabled]\n )\n\n const handleClose = useCallback(() => {\n setVisible(false)\n }, [])\n\n const handleSelect = useCallback(\n (key: string) => {\n onSelect?.(key)\n },\n [onSelect]\n )\n\n // Adjust position after menu renders to keep it in viewport\n useEffect(() => {\n if (visible && menuRef.current) {\n const menu = menuRef.current\n const rect = menu.getBoundingClientRect()\n const viewportWidth = window.innerWidth\n const viewportHeight = window.innerHeight\n\n let { x, y } = position\n\n if (x + rect.width > viewportWidth) {\n x = viewportWidth - rect.width - 8\n }\n if (y + rect.height > viewportHeight) {\n y = viewportHeight - rect.height - 8\n }\n\n if (x !== position.x || y !== position.y) {\n setPosition({ x, y })\n }\n }\n }, [visible, position])\n\n // Close on click outside or escape\n useEffect(() => {\n if (!visible) return\n\n const handleClickOutside = (e: MouseEvent) => {\n if (menuRef.current && !menuRef.current.contains(e.target as Node)) {\n handleClose()\n }\n }\n\n const handleEscape = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n handleClose()\n }\n }\n\n const handleScroll = () => {\n handleClose()\n }\n\n document.addEventListener('mousedown', handleClickOutside)\n document.addEventListener('keydown', handleEscape)\n document.addEventListener('scroll', handleScroll, true)\n\n return () => {\n document.removeEventListener('mousedown', handleClickOutside)\n document.removeEventListener('keydown', handleEscape)\n document.removeEventListener('scroll', handleScroll, true)\n }\n }, [visible, handleClose])\n\n // Clone children to extract keys\n const cloneChildrenWithKeys = (children: React.ReactNode): React.ReactNode => {\n return React.Children.map(children, (child) => {\n if (React.isValidElement(child)) {\n const childKey = child.key != null ? String(child.key) : undefined\n if (child.type === ContextMenuItemComponent || child.type === ContextMenuSubMenuComponent) {\n return React.cloneElement(child as React.ReactElement<any>, { _key: childKey })\n }\n }\n return child\n })\n }\n\n // Determine if using data-driven or compound pattern\n // Find menu content children (not the trigger element)\n const childArray = React.Children.toArray(children)\n const triggerChild = childArray[0]\n const menuChildren = cloneChildrenWithKeys(childArray.slice(1))\n const useDataDriven = items && items.length > 0\n\n const contextValue: ContextMenuContextValue = {\n onSelect: handleSelect,\n onClose: handleClose,\n }\n\n return (\n <>\n <div ref={triggerRef} onContextMenu={handleContextMenu} className=\"inline-block\">\n {triggerChild}\n </div>\n {visible &&\n createPortal(\n <ContextMenuContext.Provider value={contextValue}>\n <ul\n ref={menuRef}\n className={`menu bg-base-100 rounded-box shadow-lg border border-base-300 min-w-[160px] p-1 fixed z-[9999] ${className}`}\n style={{ left: position.x, top: position.y }}\n >\n {useDataDriven\n ? items!.map((item) => (\n <MenuItem key={item.key} item={item} onSelect={handleSelect} onClose={handleClose} />\n ))\n : menuChildren}\n </ul>\n </ContextMenuContext.Provider>,\n document.body\n )}\n </>\n )\n}\n\n// Assign compound components\nexport const ContextMenu = Object.assign(ContextMenuRoot, {\n Item: ContextMenuItemComponent,\n Divider: ContextMenuDividerComponent,\n SubMenu: ContextMenuSubMenuComponent,\n})\n"],"names":["ContextMenuContext","createContext","useContextMenuContext","context","useContext","ContextMenuItemComponent","children","icon","disabled","danger","className","_key","onSelect","onClose","jsx","jsxs","ContextMenuDividerComponent","ContextMenuSubMenuComponent","label","_unusedKey","showSubmenu","setShowSubmenu","useState","timeoutRef","useRef","handleMouseEnter","handleMouseLeave","MenuItem","item","handleClick","hasSubmenu","child","ContextMenuRoot","items","visible","setVisible","position","setPosition","menuRef","triggerRef","handleContextMenu","useCallback","e","x","y","handleClose","handleSelect","key","useEffect","rect","viewportWidth","viewportHeight","handleClickOutside","handleEscape","handleScroll","cloneChildrenWithKeys","React","childKey","childArray","triggerChild","menuChildren","useDataDriven","contextValue","Fragment","createPortal","ContextMenu"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ContextMenu.js","sources":["../../src/components/ContextMenu.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect, useCallback, createContext, useContext } from 'react'\nimport { createPortal } from 'react-dom'\n\n// DaisyUI classes\nconst dMenu = 'menu'\nconst dDivider = 'divider'\n\nexport interface ContextMenuItem {\n key: string\n label: React.ReactNode\n icon?: React.ReactNode\n disabled?: boolean\n danger?: boolean\n divider?: boolean\n children?: ContextMenuItem[]\n}\n\nexport interface ContextMenuProps {\n /** Element that triggers the context menu on right-click */\n children: React.ReactNode\n /** Menu items (data-driven pattern) */\n items?: ContextMenuItem[]\n /** Callback when an item is selected */\n onSelect?: (key: string) => void\n /** Whether the context menu is disabled */\n disabled?: boolean\n /** Additional CSS classes for the menu */\n className?: string\n}\n\nexport interface ContextMenuItemProps {\n /** Item content */\n children: React.ReactNode\n /** Icon to display before label */\n icon?: React.ReactNode\n /** Whether the item is disabled */\n disabled?: boolean\n /** Show as danger/destructive action */\n danger?: boolean\n /** Additional CSS classes */\n className?: string\n /** @internal */\n _key?: string\n}\n\nexport interface ContextMenuDividerProps {\n /** Additional CSS classes */\n className?: string\n}\n\nexport interface ContextMenuSubMenuProps {\n /** Submenu label */\n label: React.ReactNode\n /** Icon to display before label */\n icon?: React.ReactNode\n /** Whether the submenu is disabled */\n disabled?: boolean\n /** Submenu items */\n children: React.ReactNode\n /** Additional CSS classes */\n className?: string\n /** @internal */\n _key?: string\n}\n\ninterface ContextMenuContextValue {\n onSelect: (key: string) => void\n onClose: () => void\n}\n\ninterface MenuPosition {\n x: number\n y: number\n}\n\nconst ContextMenuContext = createContext<ContextMenuContextValue | null>(null)\n\nconst useContextMenuContext = () => {\n const context = useContext(ContextMenuContext)\n if (!context) {\n throw new Error('ContextMenu compound components must be used within a ContextMenu')\n }\n return context\n}\n\n// Compound pattern components\nconst ContextMenuItemComponent: React.FC<ContextMenuItemProps> = ({\n children,\n icon,\n disabled = false,\n danger = false,\n className = '',\n _key,\n}) => {\n const { onSelect, onClose } = useContextMenuContext()\n\n const handleClick = () => {\n if (disabled || !_key) return\n onSelect(_key)\n onClose()\n }\n\n return (\n <li className={className}>\n <button\n onClick={handleClick}\n disabled={disabled}\n className={`\n flex items-center gap-2 w-full px-4 py-2 text-left text-sm\n ${disabled ? 'opacity-50 cursor-not-allowed' : 'hover:bg-base-200'}\n ${danger ? 'text-error hover:bg-error/10' : ''}\n `}\n >\n {icon && <span className=\"w-4 h-4\">{icon}</span>}\n <span className=\"flex-1\">{children}</span>\n </button>\n </li>\n )\n}\n\nconst ContextMenuDividerComponent: React.FC<ContextMenuDividerProps> = ({ className = '' }) => {\n return <li className={`${dDivider} my-1 ${className}`}></li>\n}\n\nconst ContextMenuSubMenuComponent: React.FC<ContextMenuSubMenuProps> = ({\n label,\n icon,\n disabled = false,\n children,\n className = '',\n _key: _unusedKey,\n}) => {\n const [showSubmenu, setShowSubmenu] = useState(false)\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n\n const handleMouseEnter = () => {\n if (disabled) return\n if (timeoutRef.current) clearTimeout(timeoutRef.current)\n setShowSubmenu(true)\n }\n\n const handleMouseLeave = () => {\n timeoutRef.current = setTimeout(() => setShowSubmenu(false), 100)\n }\n\n return (\n <li\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n className={`relative ${className}`}\n >\n <button\n disabled={disabled}\n className={`\n flex items-center gap-2 w-full px-4 py-2 text-left text-sm\n ${disabled ? 'opacity-50 cursor-not-allowed' : 'hover:bg-base-200'}\n `}\n >\n {icon && <span className=\"w-4 h-4\">{icon}</span>}\n <span className=\"flex-1\">{label}</span>\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 </button>\n {showSubmenu && (\n <ul\n className={`${dMenu} bg-base-100 rounded-box shadow-lg border border-base-300 absolute left-full top-0 min-w-[160px] z-50 p-1`}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n >\n {children}\n </ul>\n )}\n </li>\n )\n}\n\n// Data-driven pattern internal component\nconst MenuItem: React.FC<{\n item: ContextMenuItem\n onSelect: (key: string) => void\n onClose: () => void\n}> = ({ item, onSelect, onClose }) => {\n const [showSubmenu, setShowSubmenu] = useState(false)\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n\n if (item.divider) {\n return <li className={`${dDivider} my-1`}></li>\n }\n\n const handleClick = () => {\n if (item.disabled) return\n if (item.children && item.children.length > 0) return\n onSelect(item.key)\n onClose()\n }\n\n const hasSubmenu = item.children && item.children.length > 0\n\n const handleMouseEnter = () => {\n if (!hasSubmenu) return\n if (timeoutRef.current) clearTimeout(timeoutRef.current)\n setShowSubmenu(true)\n }\n\n const handleMouseLeave = () => {\n if (!hasSubmenu) return\n timeoutRef.current = setTimeout(() => setShowSubmenu(false), 100)\n }\n\n return (\n <li\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n className=\"relative\"\n >\n <button\n onClick={handleClick}\n disabled={item.disabled}\n className={`\n flex items-center gap-2 w-full px-4 py-2 text-left text-sm\n ${item.disabled ? 'opacity-50 cursor-not-allowed' : 'hover:bg-base-200'}\n ${item.danger ? 'text-error hover:bg-error/10' : ''}\n `}\n >\n {item.icon && <span className=\"w-4 h-4\">{item.icon}</span>}\n <span className=\"flex-1\">{item.label}</span>\n {hasSubmenu && (\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 )}\n </button>\n {hasSubmenu && showSubmenu && (\n <ul\n className={`${dMenu} bg-base-100 rounded-box shadow-lg border border-base-300 absolute left-full top-0 min-w-[160px] z-50 p-1`}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n >\n {item.children!.map((child) => (\n <MenuItem key={child.key} item={child} onSelect={onSelect} onClose={onClose} />\n ))}\n </ul>\n )}\n </li>\n )\n}\n\nconst ContextMenuRoot: React.FC<ContextMenuProps> = ({\n children,\n items,\n onSelect,\n disabled = false,\n className = '',\n}) => {\n const [visible, setVisible] = useState(false)\n const [position, setPosition] = useState<MenuPosition>({ x: 0, y: 0 })\n const menuRef = useRef<HTMLUListElement>(null)\n const triggerRef = useRef<HTMLDivElement>(null)\n\n const handleContextMenu = useCallback(\n (e: React.MouseEvent) => {\n if (disabled) return\n e.preventDefault()\n e.stopPropagation()\n\n // Calculate position, ensuring menu stays within viewport\n let x = e.clientX\n let y = e.clientY\n\n // We'll adjust after render when we know menu dimensions\n setPosition({ x, y })\n setVisible(true)\n },\n [disabled]\n )\n\n const handleClose = useCallback(() => {\n setVisible(false)\n }, [])\n\n const handleSelect = useCallback(\n (key: string) => {\n onSelect?.(key)\n },\n [onSelect]\n )\n\n // Adjust position after menu renders to keep it in viewport\n useEffect(() => {\n if (visible && menuRef.current) {\n const menu = menuRef.current\n const rect = menu.getBoundingClientRect()\n const viewportWidth = window.innerWidth\n const viewportHeight = window.innerHeight\n\n let { x, y } = position\n\n if (x + rect.width > viewportWidth) {\n x = viewportWidth - rect.width - 8\n }\n if (y + rect.height > viewportHeight) {\n y = viewportHeight - rect.height - 8\n }\n\n if (x !== position.x || y !== position.y) {\n setPosition({ x, y })\n }\n }\n }, [visible, position])\n\n // Close on click outside or escape\n useEffect(() => {\n if (!visible) return\n\n const handleClickOutside = (e: MouseEvent) => {\n if (menuRef.current && !menuRef.current.contains(e.target as Node)) {\n handleClose()\n }\n }\n\n const handleEscape = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n handleClose()\n }\n }\n\n const handleScroll = () => {\n handleClose()\n }\n\n document.addEventListener('mousedown', handleClickOutside)\n document.addEventListener('keydown', handleEscape)\n document.addEventListener('scroll', handleScroll, true)\n\n return () => {\n document.removeEventListener('mousedown', handleClickOutside)\n document.removeEventListener('keydown', handleEscape)\n document.removeEventListener('scroll', handleScroll, true)\n }\n }, [visible, handleClose])\n\n // Clone children to extract keys\n const cloneChildrenWithKeys = (children: React.ReactNode): React.ReactNode => {\n return React.Children.map(children, (child) => {\n if (React.isValidElement(child)) {\n const childKey = child.key != null ? String(child.key) : undefined\n if (child.type === ContextMenuItemComponent || child.type === ContextMenuSubMenuComponent) {\n return React.cloneElement(child as React.ReactElement<any>, { _key: childKey })\n }\n }\n return child\n })\n }\n\n // Determine if using data-driven or compound pattern\n // Find menu content children (not the trigger element)\n const childArray = React.Children.toArray(children)\n const triggerChild = childArray[0]\n const menuChildren = cloneChildrenWithKeys(childArray.slice(1))\n const useDataDriven = items && items.length > 0\n\n const contextValue: ContextMenuContextValue = {\n onSelect: handleSelect,\n onClose: handleClose,\n }\n\n return (\n <>\n <div ref={triggerRef} onContextMenu={handleContextMenu} className=\"inline-block\">\n {triggerChild}\n </div>\n {visible &&\n createPortal(\n <ContextMenuContext.Provider value={contextValue}>\n <ul\n ref={menuRef}\n className={`${dMenu} bg-base-100 rounded-box shadow-lg border border-base-300 min-w-[160px] p-1 fixed z-[9999] ${className}`}\n style={{ left: position.x, top: position.y }}\n >\n {useDataDriven\n ? items!.map((item) => (\n <MenuItem key={item.key} item={item} onSelect={handleSelect} onClose={handleClose} />\n ))\n : menuChildren}\n </ul>\n </ContextMenuContext.Provider>,\n document.body\n )}\n </>\n )\n}\n\n// Assign compound components\nexport const ContextMenu = Object.assign(ContextMenuRoot, {\n Item: ContextMenuItemComponent,\n Divider: ContextMenuDividerComponent,\n SubMenu: ContextMenuSubMenuComponent,\n})\n"],"names":["dMenu","dDivider","ContextMenuContext","createContext","useContextMenuContext","context","useContext","ContextMenuItemComponent","children","icon","disabled","danger","className","_key","onSelect","onClose","jsx","jsxs","ContextMenuDividerComponent","ContextMenuSubMenuComponent","label","_unusedKey","showSubmenu","setShowSubmenu","useState","timeoutRef","useRef","handleMouseEnter","handleMouseLeave","MenuItem","item","handleClick","hasSubmenu","child","ContextMenuRoot","items","visible","setVisible","position","setPosition","menuRef","triggerRef","handleContextMenu","useCallback","e","x","y","handleClose","handleSelect","key","useEffect","rect","viewportWidth","viewportHeight","handleClickOutside","handleEscape","handleScroll","cloneChildrenWithKeys","React","childKey","childArray","triggerChild","menuChildren","useDataDriven","contextValue","Fragment","createPortal","ContextMenu"],"mappings":";;;AAIA,MAAMA,IAAQ,QACRC,IAAW,WAsEXC,IAAqBC,EAA8C,IAAI,GAEvEC,IAAwB,MAAM;AAClC,QAAMC,IAAUC,EAAWJ,CAAkB;AAC7C,MAAI,CAACG;AACH,UAAM,IAAI,MAAM,mEAAmE;AAErF,SAAOA;AACT,GAGME,IAA2D,CAAC;AAAA,EAChE,UAAAC;AAAA,EACA,MAAAC;AAAA,EACA,UAAAC,IAAW;AAAA,EACX,QAAAC,IAAS;AAAA,EACT,WAAAC,IAAY;AAAA,EACZ,MAAAC;AACF,MAAM;AACJ,QAAM,EAAE,UAAAC,GAAU,SAAAC,EAAA,IAAYX,EAAA;AAQ9B,SACE,gBAAAY,EAAC,QAAG,WAAAJ,GACF,UAAA,gBAAAK;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,SATc,MAAM;AACxB,QAAIP,KAAY,CAACG,MACjBC,EAASD,CAAI,GACbE,EAAA;AAAA,MACF;AAAA,MAMM,UAAAL;AAAA,MACA,WAAW;AAAA;AAAA,YAEPA,IAAW,kCAAkC,mBAAmB;AAAA,YAChEC,IAAS,iCAAiC,EAAE;AAAA;AAAA,MAG/C,UAAA;AAAA,QAAAF,KAAQ,gBAAAO,EAAC,QAAA,EAAK,WAAU,WAAW,UAAAP,GAAK;AAAA,QACzC,gBAAAO,EAAC,QAAA,EAAK,WAAU,UAAU,UAAAR,EAAA,CAAS;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA,GAEvC;AAEJ,GAEMU,IAAiE,CAAC,EAAE,WAAAN,IAAY,2BAC5E,MAAA,EAAG,WAAW,GAAGX,CAAQ,SAASW,CAAS,IAAI,GAGnDO,IAAiE,CAAC;AAAA,EACtE,OAAAC;AAAA,EACA,MAAAX;AAAA,EACA,UAAAC,IAAW;AAAA,EACX,UAAAF;AAAA,EACA,WAAAI,IAAY;AAAA,EACZ,MAAMS;AACR,MAAM;AACJ,QAAM,CAACC,GAAaC,CAAc,IAAIC,EAAS,EAAK,GAC9CC,IAAaC,EAA6C,IAAI,GAE9DC,IAAmB,MAAM;AAC7B,IAAIjB,MACAe,EAAW,WAAS,aAAaA,EAAW,OAAO,GACvDF,EAAe,EAAI;AAAA,EACrB,GAEMK,IAAmB,MAAM;AAC7B,IAAAH,EAAW,UAAU,WAAW,MAAMF,EAAe,EAAK,GAAG,GAAG;AAAA,EAClE;AAEA,SACE,gBAAAN;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,cAAcU;AAAA,MACd,cAAcC;AAAA,MACd,WAAW,YAAYhB,CAAS;AAAA,MAEhC,UAAA;AAAA,QAAA,gBAAAK;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,UAAAP;AAAA,YACA,WAAW;AAAA;AAAA,YAEPA,IAAW,kCAAkC,mBAAmB;AAAA;AAAA,YAGnE,UAAA;AAAA,cAAAD,KAAQ,gBAAAO,EAAC,QAAA,EAAK,WAAU,WAAW,UAAAP,GAAK;AAAA,cACzC,gBAAAO,EAAC,QAAA,EAAK,WAAU,UAAU,UAAAI,GAAM;AAAA,cAChC,gBAAAJ,EAAC,SAAI,WAAU,WAAU,MAAK,QAAO,SAAQ,aAAY,QAAO,gBAC9D,4BAAC,QAAA,EAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,gBAAe,EAAA,CACtF;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAEDM,KACC,gBAAAN;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAW,GAAGhB,CAAK;AAAA,YACnB,cAAc2B;AAAA,YACd,cAAcC;AAAA,YAEb,UAAApB;AAAA,UAAA;AAAA,QAAA;AAAA,MACH;AAAA,IAAA;AAAA,EAAA;AAIR,GAGMqB,IAID,CAAC,EAAE,MAAAC,GAAM,UAAAhB,GAAU,SAAAC,QAAc;AACpC,QAAM,CAACO,GAAaC,CAAc,IAAIC,EAAS,EAAK,GAC9CC,IAAaC,EAA6C,IAAI;AAEpE,MAAII,EAAK;AACP,WAAO,gBAAAd,EAAC,MAAA,EAAG,WAAW,GAAGf,CAAQ,SAAS;AAG5C,QAAM8B,IAAc,MAAM;AACxB,IAAID,EAAK,YACLA,EAAK,YAAYA,EAAK,SAAS,SAAS,MAC5ChB,EAASgB,EAAK,GAAG,GACjBf,EAAA;AAAA,EACF,GAEMiB,IAAaF,EAAK,YAAYA,EAAK,SAAS,SAAS,GAErDH,IAAmB,MAAM;AAC7B,IAAKK,MACDP,EAAW,WAAS,aAAaA,EAAW,OAAO,GACvDF,EAAe,EAAI;AAAA,EACrB,GAEMK,IAAmB,MAAM;AAC7B,IAAKI,MACLP,EAAW,UAAU,WAAW,MAAMF,EAAe,EAAK,GAAG,GAAG;AAAA,EAClE;AAEA,SACE,gBAAAN;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,cAAcU;AAAA,MACd,cAAcC;AAAA,MACd,WAAU;AAAA,MAEV,UAAA;AAAA,QAAA,gBAAAX;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAASc;AAAA,YACT,UAAUD,EAAK;AAAA,YACf,WAAW;AAAA;AAAA,YAEPA,EAAK,WAAW,kCAAkC,mBAAmB;AAAA,YACrEA,EAAK,SAAS,iCAAiC,EAAE;AAAA;AAAA,YAGpD,UAAA;AAAA,cAAAA,EAAK,QAAQ,gBAAAd,EAAC,QAAA,EAAK,WAAU,WAAW,YAAK,MAAK;AAAA,cACnD,gBAAAA,EAAC,QAAA,EAAK,WAAU,UAAU,YAAK,OAAM;AAAA,cACpCgB,uBACE,OAAA,EAAI,WAAU,WAAU,MAAK,QAAO,SAAQ,aAAY,QAAO,gBAC9D,UAAA,gBAAAhB,EAAC,QAAA,EAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,eAAA,CAAe,EAAA,CACtF;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAGHgB,KAAcV,KACb,gBAAAN;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAW,GAAGhB,CAAK;AAAA,YACnB,cAAc2B;AAAA,YACd,cAAcC;AAAA,YAEb,UAAAE,EAAK,SAAU,IAAI,CAACG,MACnB,gBAAAjB,EAACa,GAAA,EAAyB,MAAMI,GAAO,UAAAnB,GAAoB,SAAAC,EAAA,GAA5CkB,EAAM,GAAwD,CAC9E;AAAA,UAAA;AAAA,QAAA;AAAA,MACH;AAAA,IAAA;AAAA,EAAA;AAIR,GAEMC,IAA8C,CAAC;AAAA,EACnD,UAAA1B;AAAA,EACA,OAAA2B;AAAA,EACA,UAAArB;AAAA,EACA,UAAAJ,IAAW;AAAA,EACX,WAAAE,IAAY;AACd,MAAM;AACJ,QAAM,CAACwB,GAASC,CAAU,IAAIb,EAAS,EAAK,GACtC,CAACc,GAAUC,CAAW,IAAIf,EAAuB,EAAE,GAAG,GAAG,GAAG,GAAG,GAC/DgB,IAAUd,EAAyB,IAAI,GACvCe,IAAaf,EAAuB,IAAI,GAExCgB,IAAoBC;AAAA,IACxB,CAACC,MAAwB;AACvB,UAAIlC,EAAU;AACd,MAAAkC,EAAE,eAAA,GACFA,EAAE,gBAAA;AAGF,UAAIC,IAAID,EAAE,SACNE,IAAIF,EAAE;AAGV,MAAAL,EAAY,EAAE,GAAAM,GAAG,GAAAC,GAAG,GACpBT,EAAW,EAAI;AAAA,IACjB;AAAA,IACA,CAAC3B,CAAQ;AAAA,EAAA,GAGLqC,IAAcJ,EAAY,MAAM;AACpC,IAAAN,EAAW,EAAK;AAAA,EAClB,GAAG,CAAA,CAAE,GAECW,IAAeL;AAAA,IACnB,CAACM,MAAgB;AACf,MAAAnC,IAAWmC,CAAG;AAAA,IAChB;AAAA,IACA,CAACnC,CAAQ;AAAA,EAAA;AAIX,EAAAoC,EAAU,MAAM;AACd,QAAId,KAAWI,EAAQ,SAAS;AAE9B,YAAMW,IADOX,EAAQ,QACH,sBAAA,GACZY,IAAgB,OAAO,YACvBC,IAAiB,OAAO;AAE9B,UAAI,EAAE,GAAAR,GAAG,GAAAC,EAAA,IAAMR;AAEf,MAAIO,IAAIM,EAAK,QAAQC,MACnBP,IAAIO,IAAgBD,EAAK,QAAQ,IAE/BL,IAAIK,EAAK,SAASE,MACpBP,IAAIO,IAAiBF,EAAK,SAAS,KAGjCN,MAAMP,EAAS,KAAKQ,MAAMR,EAAS,MACrCC,EAAY,EAAE,GAAAM,GAAG,GAAAC,GAAG;AAAA,IAExB;AAAA,EACF,GAAG,CAACV,GAASE,CAAQ,CAAC,GAGtBY,EAAU,MAAM;AACd,QAAI,CAACd,EAAS;AAEd,UAAMkB,IAAqB,CAACV,MAAkB;AAC5C,MAAIJ,EAAQ,WAAW,CAACA,EAAQ,QAAQ,SAASI,EAAE,MAAc,KAC/DG,EAAA;AAAA,IAEJ,GAEMQ,IAAe,CAACX,MAAqB;AACzC,MAAIA,EAAE,QAAQ,YACZG,EAAA;AAAA,IAEJ,GAEMS,IAAe,MAAM;AACzB,MAAAT,EAAA;AAAA,IACF;AAEA,oBAAS,iBAAiB,aAAaO,CAAkB,GACzD,SAAS,iBAAiB,WAAWC,CAAY,GACjD,SAAS,iBAAiB,UAAUC,GAAc,EAAI,GAE/C,MAAM;AACX,eAAS,oBAAoB,aAAaF,CAAkB,GAC5D,SAAS,oBAAoB,WAAWC,CAAY,GACpD,SAAS,oBAAoB,UAAUC,GAAc,EAAI;AAAA,IAC3D;AAAA,EACF,GAAG,CAACpB,GAASW,CAAW,CAAC;AAGzB,QAAMU,IAAwB,CAACjD,MACtBkD,EAAM,SAAS,IAAIlD,GAAU,CAACyB,MAAU;AAC7C,QAAIyB,EAAM,eAAezB,CAAK,GAAG;AAC/B,YAAM0B,IAAW1B,EAAM,OAAO,OAAO,OAAOA,EAAM,GAAG,IAAI;AACzD,UAAIA,EAAM,SAAS1B,KAA4B0B,EAAM,SAASd;AAC5D,eAAOuC,EAAM,aAAazB,GAAkC,EAAE,MAAM0B,GAAU;AAAA,IAElF;AACA,WAAO1B;AAAA,EACT,CAAC,GAKG2B,IAAaF,EAAM,SAAS,QAAQlD,CAAQ,GAC5CqD,IAAeD,EAAW,CAAC,GAC3BE,IAAeL,EAAsBG,EAAW,MAAM,CAAC,CAAC,GACxDG,IAAgB5B,KAASA,EAAM,SAAS,GAExC6B,IAAwC;AAAA,IAC5C,UAAUhB;AAAA,IACV,SAASD;AAAA,EAAA;AAGX,SACE,gBAAA9B,EAAAgD,GAAA,EACE,UAAA;AAAA,IAAA,gBAAAjD,EAAC,SAAI,KAAKyB,GAAY,eAAeC,GAAmB,WAAU,gBAC/D,UAAAmB,EAAA,CACH;AAAA,IACCzB,KACC8B;AAAA,MACE,gBAAAlD,EAACd,EAAmB,UAAnB,EAA4B,OAAO8D,GAClC,UAAA,gBAAAhD;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,KAAKwB;AAAA,UACL,WAAW,GAAGxC,CAAK,8FAA8FY,CAAS;AAAA,UAC1H,OAAO,EAAE,MAAM0B,EAAS,GAAG,KAAKA,EAAS,EAAA;AAAA,UAExC,UAAAyB,IACG5B,EAAO,IAAI,CAACL,MACV,gBAAAd,EAACa,GAAA,EAAwB,MAAAC,GAAY,UAAUkB,GAAc,SAASD,EAAA,GAAvDjB,EAAK,GAA+D,CACpF,IACDgC;AAAA,QAAA;AAAA,MAAA,GAER;AAAA,MACA,SAAS;AAAA,IAAA;AAAA,EACX,GACJ;AAEJ,GAGaK,IAAc,OAAO,OAAOjC,GAAiB;AAAA,EACxD,MAAM3B;AAAA,EACN,SAASW;AAAA,EACT,SAASC;AACX,CAAC;"}
|