@duskmoon-dev/el-cascader 0.5.0 → 0.6.0

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.
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../src/el-dm-cascader.ts"],
4
4
  "sourcesContent": [
5
- "/**\n * @duskmoon-dev/el-cascader\n *\n * A multi-panel cascading selection component following Ant Design patterns.\n */\n\nimport { BaseElement, css } from '@duskmoon-dev/el-core';\nimport type { Size, ValidationState } from '@duskmoon-dev/el-core';\n\n// Icons with explicit dimensions for proper rendering\nconst chevronDownIcon = `<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"m6 9 6 6 6-6\"/></svg>`;\nconst chevronRightIcon = `<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"m9 18 6-6-6-6\"/></svg>`;\nconst checkIcon = `<svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M20 6 9 17l-5-5\"/></svg>`;\nconst closeIcon = `<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M18 6 6 18\"/><path d=\"m6 6 12 12\"/></svg>`;\nconst searchIcon = `<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"11\" cy=\"11\" r=\"8\"/><path d=\"m21 21-4.3-4.3\"/></svg>`;\nconst loadingIcon = `<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"spinner\"><path d=\"M21 12a9 9 0 1 1-6.219-8.56\"/></svg>`;\n\n/**\n * Cascader option structure\n */\nexport interface CascaderOption {\n value: string;\n label: string;\n disabled?: boolean;\n children?: CascaderOption[];\n leaf?: boolean;\n loading?: boolean;\n}\n\n/**\n * Load data function type for async loading\n */\nexport type LoadDataFn = (option: CascaderOption) => Promise<CascaderOption[]>;\n\n/**\n * Event details\n */\nexport interface CascaderChangeEventDetail {\n value: string;\n selectedOptions: CascaderOption[];\n path: string[];\n}\n\nexport interface CascaderExpandEventDetail {\n option: CascaderOption;\n level: number;\n}\n\nexport interface CascaderSearchEventDetail {\n searchValue: string;\n}\n\n/**\n * Search result with full path\n */\ninterface SearchResult {\n path: CascaderOption[];\n pathLabels: string[];\n pathValues: string[];\n}\n\n// Styles\nconst styles = css`\n :host {\n display: inline-block;\n width: 100%;\n }\n\n .cascader {\n position: relative;\n width: 100%;\n }\n\n /* Trigger Button */\n .cascader-trigger {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n width: 100%;\n min-height: 2.75rem;\n padding: 0.5rem 0.75rem;\n font-size: var(--font-size-md, 1rem);\n line-height: 1.5;\n color: var(--color-on-surface);\n background-color: var(--color-surface);\n border: 1px solid var(--color-outline);\n border-radius: var(--radius-md, 0.5rem);\n cursor: pointer;\n transition: border-color 150ms ease, box-shadow 150ms ease;\n }\n\n .cascader-trigger:hover:not(:disabled) {\n border-color: var(--color-on-surface-variant);\n }\n\n .cascader-trigger:focus {\n outline: none;\n border-color: var(--color-primary);\n box-shadow: 0 0 0 3px color-mix(in oklch, var(--color-primary) 15%, transparent);\n }\n\n .cascader-trigger:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n background-color: var(--color-surface-container);\n }\n\n /* Value Display */\n .cascader-value {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n text-align: left;\n }\n\n .cascader-placeholder {\n color: var(--color-on-surface-variant);\n opacity: 0.7;\n }\n\n /* Tags Container (for multiple mode) */\n .cascader-tags {\n display: flex;\n flex-wrap: wrap;\n gap: 0.25rem;\n flex: 1;\n min-width: 0;\n }\n\n .cascader-tag {\n display: inline-flex;\n align-items: center;\n gap: 0.25rem;\n max-width: 100%;\n padding: 0.125rem 0.25rem 0.125rem 0.5rem;\n font-size: var(--font-size-sm, 0.875rem);\n line-height: 1.25rem;\n background-color: var(--color-surface-container-high, #e8e8e8);\n color: var(--color-on-surface);\n border-radius: 1rem;\n }\n\n .cascader-tag-text {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .cascader-tag-remove {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n padding: 0;\n color: inherit;\n background-color: transparent;\n border-radius: 50%;\n cursor: pointer;\n opacity: 0.7;\n transition: opacity 150ms ease, background-color 150ms ease;\n }\n\n .cascader-tag-remove svg {\n width: 10px;\n height: 10px;\n display: block;\n }\n\n .cascader-tag-remove:hover {\n opacity: 1;\n background-color: color-mix(in oklch, currentColor 15%, transparent);\n }\n\n .cascader-tag-overflow {\n padding: 0.125rem 0.5rem;\n background-color: var(--color-surface-container);\n color: var(--color-on-surface-variant);\n }\n\n /* Icons */\n .cascader-arrow {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n flex-shrink: 0;\n color: var(--color-on-surface-variant);\n transition: transform 150ms ease;\n }\n\n .cascader-arrow svg {\n width: 16px;\n height: 16px;\n display: block;\n }\n\n .cascader.open .cascader-arrow {\n transform: rotate(180deg);\n }\n\n .cascader-clear {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n padding: 0;\n color: var(--color-on-surface-variant);\n background-color: transparent;\n border-radius: 50%;\n cursor: pointer;\n flex-shrink: 0;\n transition: background-color 150ms ease;\n }\n\n .cascader-clear svg {\n width: 14px;\n height: 14px;\n display: block;\n }\n\n .cascader-clear:hover {\n background-color: var(--color-surface-container-high);\n }\n\n /* Dropdown - uses Popover API (top-layer requires position: fixed) */\n .cascader-dropdown {\n position: fixed;\n margin: 0;\n padding: 0;\n border: 1px solid var(--color-outline-variant);\n border-radius: var(--radius-md, 0.5rem);\n background-color: var(--color-surface);\n box-shadow: var(--shadow-md, 0 4px 6px -1px rgba(0, 0, 0, 0.1));\n overflow: hidden;\n display: none;\n flex-direction: column;\n z-index: 1000;\n }\n\n .cascader-dropdown:popover-open {\n display: flex;\n }\n\n /* Search */\n .cascader-search {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.5rem;\n border-bottom: 1px solid var(--color-outline-variant);\n }\n\n .cascader-search-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n color: var(--color-on-surface-variant);\n flex-shrink: 0;\n }\n\n .cascader-search-icon svg {\n width: 14px;\n height: 14px;\n display: block;\n }\n\n .cascader-search-input {\n flex: 1;\n padding: 0.375rem 0.5rem;\n font-size: var(--font-size-sm, 0.875rem);\n color: var(--color-on-surface);\n background-color: var(--color-surface-container);\n border: none;\n border-radius: var(--radius-sm, 0.25rem);\n outline: none;\n }\n\n .cascader-search-input:focus {\n background-color: var(--color-surface-container-high);\n }\n\n .cascader-search-input::placeholder {\n color: var(--color-on-surface-variant);\n opacity: 0.7;\n }\n\n /* Panels Container */\n .cascader-panels {\n display: flex;\n max-height: 18rem;\n }\n\n /* Panel */\n .cascader-panel {\n display: flex;\n flex-direction: column;\n min-width: 10rem;\n max-width: 14rem;\n max-height: 18rem;\n overflow-y: auto;\n border-right: 1px solid var(--color-outline-variant);\n }\n\n .cascader-panel:last-child {\n border-right: none;\n }\n\n .cascader-panel-options {\n padding: 0.25rem;\n }\n\n /* Option */\n .cascader-option {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n width: 100%;\n padding: 0.5rem 0.75rem;\n font-size: var(--font-size-sm, 0.875rem);\n color: var(--color-on-surface);\n background-color: transparent;\n border: none;\n border-radius: var(--radius-sm, 0.25rem);\n cursor: pointer;\n text-align: left;\n transition: background-color 150ms ease;\n }\n\n .cascader-option:hover:not(.disabled) {\n background-color: var(--color-surface-container);\n }\n\n .cascader-option.active {\n background-color: var(--color-surface-container-high);\n }\n\n .cascader-option.selected {\n background-color: var(--color-primary-container, #e8def8);\n color: var(--color-on-primary-container, #1d1b20);\n }\n\n .cascader-option.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n .cascader-option-checkbox {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 1rem;\n height: 1rem;\n background-color: transparent;\n border: 2px solid var(--color-on-surface-variant);\n border-radius: 0.125rem;\n flex-shrink: 0;\n }\n\n .cascader-option.selected .cascader-option-checkbox {\n background-color: var(--color-primary);\n border-color: var(--color-primary);\n color: var(--color-on-primary, white);\n }\n\n .cascader-option-label {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .cascader-option-arrow {\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--color-on-surface-variant);\n flex-shrink: 0;\n }\n\n .cascader-option-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n }\n\n .cascader-option-loading .spinner {\n animation: spin 1s linear infinite;\n }\n\n @keyframes spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n\n /* Search Results */\n .cascader-search-results {\n padding: 0.25rem;\n max-height: 18rem;\n overflow-y: auto;\n }\n\n .cascader-search-result {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n width: 100%;\n padding: 0.5rem 0.75rem;\n font-size: var(--font-size-sm, 0.875rem);\n color: var(--color-on-surface);\n background-color: transparent;\n border: none;\n border-radius: var(--radius-sm, 0.25rem);\n cursor: pointer;\n text-align: left;\n transition: background-color 150ms ease;\n }\n\n .cascader-search-result:hover {\n background-color: var(--color-surface-container);\n }\n\n .cascader-search-result.selected {\n background-color: var(--color-primary-container, #e8def8);\n color: var(--color-on-primary-container, #1d1b20);\n }\n\n .cascader-search-result-path {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .cascader-search-result-separator {\n color: var(--color-on-surface-variant);\n margin: 0 0.25rem;\n }\n\n /* Empty State */\n .cascader-empty {\n padding: 1.5rem;\n text-align: center;\n color: var(--color-on-surface-variant);\n font-size: var(--font-size-sm, 0.875rem);\n }\n\n /* Size Variants */\n :host([size=\"sm\"]) .cascader-trigger {\n min-height: 2.25rem;\n padding: 0.375rem 0.5rem;\n font-size: var(--font-size-sm, 0.875rem);\n border-radius: var(--radius-sm, 0.375rem);\n }\n\n :host([size=\"lg\"]) .cascader-trigger {\n min-height: 3.25rem;\n padding: 0.625rem 1rem;\n font-size: var(--font-size-lg, 1.125rem);\n border-radius: var(--radius-lg, 0.625rem);\n }\n\n /* Validation States */\n :host([validation-state=\"invalid\"]) .cascader-trigger {\n border-color: var(--color-error);\n }\n\n :host([validation-state=\"invalid\"]) .cascader-trigger:focus {\n border-color: var(--color-error);\n box-shadow: 0 0 0 3px color-mix(in oklch, var(--color-error) 15%, transparent);\n }\n\n :host([validation-state=\"valid\"]) .cascader-trigger {\n border-color: var(--color-success);\n }\n\n /* Disabled State */\n :host([disabled]) {\n pointer-events: none;\n }\n\n :host([disabled]) .cascader-trigger {\n cursor: not-allowed;\n opacity: 0.5;\n background-color: var(--color-surface-container);\n }\n`;\n\n/**\n * DuskMoon Cascader Element\n *\n * @element el-dm-cascader\n *\n * @attr {string} value - Selected path as JSON array: '[\"province\", \"city\", \"district\"]'\n * @attr {string} placeholder - Placeholder text when no selection.\n * @attr {boolean} disabled - Disable the cascader.\n * @attr {boolean} multiple - Enable multi-path selection.\n * @attr {boolean} searchable - Enable search functionality.\n * @attr {boolean} clearable - Show clear button.\n * @attr {boolean} change-on-select - Emit change on each level (vs only leaf).\n * @attr {string} expand-trigger - Expand trigger: 'click' (default) | 'hover'.\n * @attr {string} separator - Display separator (default: ' / ').\n * @attr {boolean} show-all-levels - Show full path or just leaf label.\n * @attr {string} show-checked-strategy - For multiple: 'all' | 'parent' | 'child'.\n * @attr {string} size - Size variant: 'sm' | 'md' | 'lg'.\n * @attr {string} validation-state - Validation state: 'valid' | 'invalid'.\n *\n * @fires change - Fired when selection changes.\n * @fires expand - Fired when panel expanded.\n * @fires search - Fired when search input changes.\n */\nexport class ElDmCascader extends BaseElement {\n static properties = {\n value: { type: String, reflect: true, default: '' },\n placeholder: { type: String, default: 'Select...' },\n disabled: { type: Boolean, reflect: true, default: false },\n multiple: { type: Boolean, reflect: true, default: false },\n searchable: { type: Boolean, reflect: true, default: false },\n clearable: { type: Boolean, reflect: true, default: false },\n changeOnSelect: { type: Boolean, reflect: true, attribute: 'change-on-select', default: false },\n expandTrigger: { type: String, attribute: 'expand-trigger', default: 'click' },\n separator: { type: String, default: ' / ' },\n showAllLevels: { type: Boolean, reflect: true, attribute: 'show-all-levels', default: true },\n showCheckedStrategy: { type: String, attribute: 'show-checked-strategy', default: 'all' },\n size: { type: String, reflect: true, default: 'md' },\n validationState: { type: String, reflect: true, attribute: 'validation-state' },\n options: { type: String, default: '' },\n };\n\n // Declared properties\n declare value: string;\n declare placeholder: string;\n declare disabled: boolean;\n declare multiple: boolean;\n declare searchable: boolean;\n declare clearable: boolean;\n declare changeOnSelect: boolean;\n declare expandTrigger: 'click' | 'hover';\n declare separator: string;\n declare showAllLevels: boolean;\n declare showCheckedStrategy: 'all' | 'parent' | 'child';\n declare size: Size;\n declare validationState: ValidationState;\n declare options: string;\n\n // Internal state\n private _isOpen = false;\n private _searchValue = '';\n private _activePath: string[] = [];\n private _selectedPaths: string[][] = [];\n private _loadingKeys = new Set<string>();\n private _options: CascaderOption[] = [];\n private _loadDataFn: LoadDataFn | null = null;\n\n // Bound handlers\n private _handleOutsideClick = this._onOutsideClick.bind(this);\n private _handleKeyDown = this._onKeyDown.bind(this);\n private _handleScroll = this._onScroll.bind(this);\n private _handleResize = this._onResize.bind(this);\n\n constructor() {\n super();\n this.attachStyles(styles);\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n document.addEventListener('click', this._handleOutsideClick);\n document.addEventListener('keydown', this._handleKeyDown);\n\n // Parse options from attribute (for static HTML/MDX usage)\n this._parseOptionsFromAttribute();\n\n this._parseValue();\n\n // Set up event delegation once\n this._setupEventDelegation();\n }\n\n /**\n * Parse options from JSON string attribute\n */\n private _parseOptionsFromAttribute(): void {\n if (this.options) {\n try {\n const parsed = JSON.parse(this.options);\n if (Array.isArray(parsed)) {\n this._options = parsed;\n }\n } catch {\n // Invalid JSON, ignore\n }\n }\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n document.removeEventListener('click', this._handleOutsideClick);\n document.removeEventListener('keydown', this._handleKeyDown);\n this._removeScrollListeners();\n }\n\n private _addScrollListeners(): void {\n window.addEventListener('scroll', this._handleScroll, true);\n window.addEventListener('resize', this._handleResize);\n }\n\n private _removeScrollListeners(): void {\n window.removeEventListener('scroll', this._handleScroll, true);\n window.removeEventListener('resize', this._handleResize);\n }\n\n private _onScroll(): void {\n if (this._isOpen) {\n const dropdown = this.shadowRoot?.querySelector('.cascader-dropdown') as HTMLElement;\n const trigger = this.shadowRoot?.querySelector('.cascader-trigger') as HTMLElement;\n if (dropdown && trigger) {\n this._positionDropdown(dropdown, trigger);\n }\n }\n }\n\n private _onResize(): void {\n if (this._isOpen) {\n this._close();\n }\n }\n\n /**\n * Set cascader options\n */\n setOptions(options: CascaderOption[]): void {\n this._options = options;\n this.update();\n }\n\n /**\n * Set async load data function\n */\n setLoadData(fn: LoadDataFn): void {\n this._loadDataFn = fn;\n }\n\n /**\n * Parse value into selected paths\n */\n private _parseValue(): void {\n if (!this.value) {\n this._selectedPaths = [];\n return;\n }\n\n try {\n const parsed = JSON.parse(this.value);\n if (this.multiple) {\n // Multiple mode: array of paths\n this._selectedPaths = Array.isArray(parsed[0]) ? parsed : [parsed];\n } else {\n // Single mode: single path\n this._selectedPaths = Array.isArray(parsed) ? [parsed] : [];\n }\n } catch {\n this._selectedPaths = [];\n }\n }\n\n /**\n * Get panels data based on active path\n */\n private _getPanels(): CascaderOption[][] {\n const panels: CascaderOption[][] = [this._options];\n\n let currentOptions = this._options;\n for (const value of this._activePath) {\n const option = currentOptions.find((o) => o.value === value);\n if (option?.children && option.children.length > 0) {\n panels.push(option.children);\n currentOptions = option.children;\n } else {\n break;\n }\n }\n\n return panels;\n }\n\n /**\n * Get display label for current selection\n */\n private _getDisplayLabel(): string {\n if (this._selectedPaths.length === 0) {\n return '';\n }\n\n const path = this._selectedPaths[0];\n const labels = this._getPathLabels(path);\n\n if (this.showAllLevels) {\n return labels.join(this.separator);\n }\n return labels[labels.length - 1] || '';\n }\n\n /**\n * Get labels for a path\n */\n private _getPathLabels(path: string[]): string[] {\n const labels: string[] = [];\n let currentOptions = this._options;\n\n for (const value of path) {\n const option = currentOptions.find((o) => o.value === value);\n if (option) {\n labels.push(option.label);\n currentOptions = option.children || [];\n }\n }\n\n return labels;\n }\n\n /**\n * Find option by path\n */\n private _findOptionByPath(path: string[]): CascaderOption | undefined {\n let currentOptions = this._options;\n let option: CascaderOption | undefined;\n\n for (const value of path) {\n option = currentOptions.find((o) => o.value === value);\n if (option?.children) {\n currentOptions = option.children;\n }\n }\n\n return option;\n }\n\n /**\n * Check if option is leaf (no children or marked as leaf)\n */\n private _isLeaf(option: CascaderOption): boolean {\n if (option.leaf === true) return true;\n if (option.leaf === false) return false;\n return !option.children || option.children.length === 0;\n }\n\n /**\n * Search options recursively\n */\n private _searchOptions(): SearchResult[] {\n const results: SearchResult[] = [];\n const search = this._searchValue.toLowerCase();\n\n const searchRecursive = (\n options: CascaderOption[],\n path: CascaderOption[],\n pathValues: string[]\n ): void => {\n for (const option of options) {\n const newPath = [...path, option];\n const newPathValues = [...pathValues, option.value];\n\n // Check if this option matches\n if (option.label.toLowerCase().includes(search)) {\n // Only add if it's a leaf or changeOnSelect is true\n if (this._isLeaf(option) || this.changeOnSelect) {\n results.push({\n path: newPath,\n pathLabels: newPath.map((o) => o.label),\n pathValues: newPathValues,\n });\n }\n }\n\n // Search children\n if (option.children) {\n searchRecursive(option.children, newPath, newPathValues);\n }\n }\n };\n\n searchRecursive(this._options, [], []);\n return results;\n }\n\n // Event handlers\n private _onOutsideClick(e: MouseEvent): void {\n if (!this.contains(e.target as Node)) {\n this._close();\n }\n }\n\n private _onKeyDown(e: KeyboardEvent): void {\n if (!this._isOpen) {\n if (e.key === 'Enter' || e.key === ' ' || e.key === 'ArrowDown') {\n if (document.activeElement === this || this.contains(document.activeElement)) {\n e.preventDefault();\n this._open();\n }\n }\n return;\n }\n\n switch (e.key) {\n case 'Escape':\n e.preventDefault();\n this._close();\n break;\n\n case 'ArrowLeft':\n e.preventDefault();\n if (this._activePath.length > 0) {\n this._activePath = this._activePath.slice(0, -1);\n this.update();\n }\n break;\n\n case 'ArrowRight':\n // Navigate into selected option if it has children\n break;\n }\n }\n\n private _open(): void {\n if (this.disabled) return;\n this._isOpen = true;\n this._activePath = this._selectedPaths[0] ? [...this._selectedPaths[0]] : [];\n this.update();\n\n // Add scroll/resize listeners to keep dropdown positioned\n this._addScrollListeners();\n\n // Show popover and position it\n requestAnimationFrame(() => {\n const dropdown = this.shadowRoot?.querySelector('.cascader-dropdown') as HTMLElement;\n const trigger = this.shadowRoot?.querySelector('.cascader-trigger') as HTMLElement;\n if (dropdown && trigger) {\n // Set initial position before showing (based on trigger only)\n const triggerRect = trigger.getBoundingClientRect();\n dropdown.style.top = `${triggerRect.bottom + 4}px`;\n dropdown.style.left = `${triggerRect.left}px`;\n dropdown.style.minWidth = `${triggerRect.width}px`;\n\n // Show the popover\n dropdown.showPopover();\n\n // Recalculate position after layout is complete\n requestAnimationFrame(() => {\n this._positionDropdown(dropdown, trigger);\n });\n }\n\n // Focus search input if searchable\n const searchInput = this.shadowRoot?.querySelector('.cascader-search-input') as HTMLInputElement;\n if (searchInput) {\n searchInput.focus();\n }\n });\n }\n\n private _close(): void {\n this._isOpen = false;\n this._searchValue = '';\n this._activePath = [];\n\n // Remove scroll/resize listeners\n this._removeScrollListeners();\n\n // Hide popover\n const dropdown = this.shadowRoot?.querySelector('.cascader-dropdown') as HTMLElement;\n if (dropdown) {\n try {\n dropdown.hidePopover();\n } catch {\n // Ignore if already hidden\n }\n }\n\n this.update();\n }\n\n private _positionDropdown(dropdown: HTMLElement, trigger: HTMLElement): void {\n const triggerRect = trigger.getBoundingClientRect();\n const viewportHeight = window.innerHeight;\n const viewportWidth = window.innerWidth;\n\n // Position below the trigger by default\n let top = triggerRect.bottom + 4;\n let left = triggerRect.left;\n\n // Get dropdown dimensions after it's visible\n const dropdownRect = dropdown.getBoundingClientRect();\n\n // If not enough space below, position above\n if (top + dropdownRect.height > viewportHeight && triggerRect.top > dropdownRect.height) {\n top = triggerRect.top - dropdownRect.height - 4;\n }\n\n // Ensure dropdown doesn't go off-screen horizontally\n if (left + dropdownRect.width > viewportWidth) {\n left = viewportWidth - dropdownRect.width - 8;\n }\n if (left < 8) {\n left = 8;\n }\n\n dropdown.style.top = `${top}px`;\n dropdown.style.left = `${left}px`;\n // Cascader may be wider than trigger due to panels\n dropdown.style.minWidth = `${triggerRect.width}px`;\n }\n\n private _toggle(): void {\n if (this._isOpen) {\n this._close();\n } else {\n this._open();\n }\n }\n\n private async _handleOptionClick(value: string, level: number): Promise<void> {\n // Update active path\n this._activePath = this._activePath.slice(0, level);\n this._activePath.push(value);\n\n const option = this._findOptionByPath(this._activePath);\n if (!option) {\n return;\n }\n\n // Check if we need to load children\n if (this._loadDataFn && !option.children && !option.leaf) {\n this._loadingKeys.add(value);\n this.update();\n\n try {\n const children = await this._loadDataFn(option);\n option.children = children;\n } finally {\n this._loadingKeys.delete(value);\n }\n }\n\n // Emit expand event\n this.emit<CascaderExpandEventDetail>('expand', { option, level });\n\n // Handle selection\n const isLeaf = this._isLeaf(option);\n if (isLeaf || this.changeOnSelect) {\n this._selectPath([...this._activePath]);\n\n if (isLeaf && !this.multiple) {\n this._close();\n }\n }\n\n this.update();\n }\n\n private _handleOptionHover(value: string, level: number): void {\n if (this.expandTrigger !== 'hover') return;\n\n this._activePath = this._activePath.slice(0, level);\n this._activePath.push(value);\n this.update();\n\n // Trigger async load if needed\n const option = this._findOptionByPath(this._activePath);\n if (option && this._loadDataFn && !option.children && !option.leaf) {\n this._handleOptionClick(value, level);\n }\n }\n\n private _selectPath(path: string[]): void {\n if (this.multiple) {\n // Toggle path in selected paths\n const pathStr = JSON.stringify(path);\n const index = this._selectedPaths.findIndex(\n (p) => JSON.stringify(p) === pathStr\n );\n\n if (index >= 0) {\n this._selectedPaths.splice(index, 1);\n } else {\n this._selectedPaths.push(path);\n }\n\n this.value = JSON.stringify(this._selectedPaths);\n } else {\n this._selectedPaths = [path];\n this.value = JSON.stringify(path);\n }\n\n this._emitChange();\n }\n\n private _selectSearchResult(result: SearchResult): void {\n this._selectPath(result.pathValues);\n if (!this.multiple) {\n this._close();\n }\n this.update();\n }\n\n private _removeTag(pathIndex: number): void {\n this._selectedPaths.splice(pathIndex, 1);\n this.value = this._selectedPaths.length > 0 ? JSON.stringify(this._selectedPaths) : '';\n this._emitChange();\n this.update();\n }\n\n private _handleSearch(e: Event): void {\n const input = e.target as HTMLInputElement;\n this._searchValue = input.value;\n this.emit<CascaderSearchEventDetail>('search', { searchValue: this._searchValue });\n this.update();\n }\n\n private _handleClear(e: Event): void {\n e.stopPropagation();\n this.value = '';\n this._selectedPaths = [];\n this.emit('clear', {});\n this._emitChange();\n this.update();\n }\n\n private _emitChange(): void {\n const selectedOptions = this._selectedPaths.map((path) =>\n this._findOptionByPath(path)\n ).filter((o): o is CascaderOption => o !== undefined);\n\n this.emit<CascaderChangeEventDetail>('change', {\n value: this.value,\n selectedOptions,\n path: this._selectedPaths[0] || [],\n });\n }\n\n // Rendering\n protected render(): string {\n return `\n <div class=\"cascader ${this._isOpen ? 'open' : ''}\">\n ${this._renderTrigger()}\n ${this._renderDropdown()}\n </div>\n `;\n }\n\n private _renderTrigger(): string {\n const hasValue = this._selectedPaths.length > 0;\n const showClear = this.clearable && hasValue && !this.disabled;\n\n return `\n <button\n type=\"button\"\n class=\"cascader-trigger\"\n aria-haspopup=\"listbox\"\n aria-expanded=\"${this._isOpen}\"\n ${this.disabled ? 'disabled' : ''}\n data-action=\"toggle\"\n >\n ${this.multiple && hasValue ? this._renderTags() : this._renderValue()}\n ${showClear ? `<span class=\"cascader-clear\" role=\"button\" tabindex=\"-1\" data-action=\"clear\">${closeIcon}</span>` : ''}\n <span class=\"cascader-arrow\">${chevronDownIcon}</span>\n </button>\n `;\n }\n\n private _renderValue(): string {\n const displayLabel = this._getDisplayLabel();\n if (!displayLabel) {\n return `<span class=\"cascader-value cascader-placeholder\">${this.placeholder}</span>`;\n }\n return `<span class=\"cascader-value\">${this._escapeHtml(displayLabel)}</span>`;\n }\n\n private _renderTags(): string {\n const tagsHtml = this._selectedPaths\n .map((path, index) => {\n const labels = this._getPathLabels(path);\n const displayLabel = this.showAllLevels\n ? labels.join(this.separator)\n : labels[labels.length - 1];\n\n return `\n <span class=\"cascader-tag\">\n <span class=\"cascader-tag-text\">${this._escapeHtml(displayLabel)}</span>\n <span class=\"cascader-tag-remove\" role=\"button\" tabindex=\"-1\" data-action=\"remove-tag\" data-index=\"${index}\">${closeIcon}</span>\n </span>\n `;\n })\n .join('');\n\n return `<div class=\"cascader-tags\">${tagsHtml || `<span class=\"cascader-placeholder\">${this.placeholder}</span>`}</div>`;\n }\n\n private _renderDropdown(): string {\n const showSearch = this.searchable && this._searchValue;\n\n return `\n <div class=\"cascader-dropdown\" role=\"listbox\" popover=\"manual\">\n ${this.searchable ? this._renderSearch() : ''}\n ${showSearch ? this._renderSearchResults() : this._renderPanels()}\n </div>\n `;\n }\n\n private _renderSearch(): string {\n return `\n <div class=\"cascader-search\">\n <span class=\"cascader-search-icon\">${searchIcon}</span>\n <input\n type=\"text\"\n class=\"cascader-search-input\"\n placeholder=\"Search...\"\n value=\"${this._escapeHtml(this._searchValue)}\"\n data-action=\"search\"\n />\n </div>\n `;\n }\n\n private _renderPanels(): string {\n const panels = this._getPanels();\n\n if (panels.length === 0 || panels[0].length === 0) {\n return `<div class=\"cascader-empty\">No options available</div>`;\n }\n\n return `\n <div class=\"cascader-panels\">\n ${panels.map((options, level) => this._renderPanel(options, level)).join('')}\n </div>\n `;\n }\n\n private _renderPanel(options: CascaderOption[], level: number): string {\n const selectedValue = this._activePath[level];\n const selectedPathValues = this._selectedPaths.flatMap((p) => p);\n\n const optionsHtml = options\n .map((option) => {\n const isActive = option.value === selectedValue;\n const isSelected = this.multiple\n ? selectedPathValues.includes(option.value)\n : JSON.stringify(this._selectedPaths[0]) === JSON.stringify([...this._activePath.slice(0, level), option.value]);\n const isLoading = this._loadingKeys.has(option.value);\n const hasChildren = !this._isLeaf(option);\n\n const classes = [\n 'cascader-option',\n isActive ? 'active' : '',\n isSelected ? 'selected' : '',\n option.disabled ? 'disabled' : '',\n ].filter(Boolean).join(' ');\n\n return `\n <button\n type=\"button\"\n class=\"${classes}\"\n data-action=\"option\"\n data-value=\"${this._escapeHtml(option.value)}\"\n data-level=\"${level}\"\n ${option.disabled ? 'disabled' : ''}\n >\n ${this.multiple ? `<span class=\"cascader-option-checkbox\">${isSelected ? checkIcon : ''}</span>` : ''}\n <span class=\"cascader-option-label\">${this._escapeHtml(option.label)}</span>\n ${isLoading ? `<span class=\"cascader-option-loading\">${loadingIcon}</span>` : ''}\n ${hasChildren && !isLoading ? `<span class=\"cascader-option-arrow\">${chevronRightIcon}</span>` : ''}\n </button>\n `;\n })\n .join('');\n\n return `\n <div class=\"cascader-panel\">\n <div class=\"cascader-panel-options\">${optionsHtml}</div>\n </div>\n `;\n }\n\n private _renderSearchResults(): string {\n const results = this._searchOptions();\n\n if (results.length === 0) {\n return `<div class=\"cascader-empty\">No results found</div>`;\n }\n\n const selectedPathStrs = this._selectedPaths.map((p) => JSON.stringify(p));\n\n const resultsHtml = results\n .map((result) => {\n const isSelected = selectedPathStrs.includes(JSON.stringify(result.pathValues));\n const classes = ['cascader-search-result', isSelected ? 'selected' : ''].filter(Boolean).join(' ');\n\n const pathHtml = result.pathLabels\n .map((label, i) => {\n const separator = i < result.pathLabels.length - 1\n ? `<span class=\"cascader-search-result-separator\">${this.separator}</span>`\n : '';\n return `<span>${this._escapeHtml(label)}</span>${separator}`;\n })\n .join('');\n\n return `\n <button\n type=\"button\"\n class=\"${classes}\"\n data-action=\"search-result\"\n data-path=\"${this._escapeHtml(JSON.stringify(result.pathValues))}\"\n >\n ${this.multiple ? `<span class=\"cascader-option-checkbox\">${isSelected ? checkIcon : ''}</span>` : ''}\n <span class=\"cascader-search-result-path\">${pathHtml}</span>\n </button>\n `;\n })\n .join('');\n\n return `<div class=\"cascader-search-results\">${resultsHtml}</div>`;\n }\n\n private _escapeHtml(str: string): string {\n const div = document.createElement('div');\n div.textContent = str;\n return div.innerHTML;\n }\n\n protected update(): void {\n // Preserve search input focus state before DOM replacement\n const searchInput = this.shadowRoot?.querySelector('.cascader-search-input') as HTMLInputElement;\n const hadFocus = searchInput && this.shadowRoot?.activeElement === searchInput;\n const cursorPosition = hadFocus ? searchInput.selectionStart : null;\n\n super.update();\n // Event delegation is set up once in connectedCallback\n\n // If dropdown is open, re-show the popover after DOM update\n // (since update() replaces the DOM, the new dropdown element needs showPopover())\n if (this._isOpen) {\n const dropdown = this.shadowRoot?.querySelector('.cascader-dropdown') as HTMLElement;\n const trigger = this.shadowRoot?.querySelector('.cascader-trigger') as HTMLElement;\n if (dropdown && trigger) {\n try {\n dropdown.showPopover();\n this._positionDropdown(dropdown, trigger);\n } catch {\n // Ignore if already shown or other errors\n }\n }\n\n // Restore search input focus if it had focus before update\n if (hadFocus) {\n const newSearchInput = this.shadowRoot?.querySelector('.cascader-search-input') as HTMLInputElement;\n if (newSearchInput) {\n newSearchInput.focus();\n // Restore cursor position\n if (cursorPosition !== null) {\n newSearchInput.setSelectionRange(cursorPosition, cursorPosition);\n }\n }\n }\n }\n }\n\n /**\n * Set up event delegation once (called in connectedCallback)\n */\n private _setupEventDelegation(): void {\n // Use event delegation on shadow root for all interactive elements\n this.shadowRoot?.addEventListener('click', (e) => {\n const target = e.target as HTMLElement;\n\n // Toggle trigger\n const trigger = target.closest('[data-action=\"toggle\"]');\n if (trigger && !target.closest('[data-action=\"clear\"]') && !target.closest('[data-action=\"remove-tag\"]')) {\n this._toggle();\n return;\n }\n\n // Clear button\n if (target.closest('[data-action=\"clear\"]')) {\n this._handleClear(e);\n return;\n }\n\n // Tag remove button\n const removeTag = target.closest('[data-action=\"remove-tag\"]');\n if (removeTag) {\n e.stopPropagation();\n const index = parseInt(removeTag.getAttribute('data-index') || '0', 10);\n this._removeTag(index);\n return;\n }\n\n // Panel option\n const option = target.closest('[data-action=\"option\"]');\n if (option) {\n const value = option.getAttribute('data-value');\n const level = parseInt(option.getAttribute('data-level') || '0', 10);\n if (value) {\n this._handleOptionClick(value, level);\n }\n return;\n }\n\n // Search result\n const searchResult = target.closest('[data-action=\"search-result\"]');\n if (searchResult) {\n const pathStr = searchResult.getAttribute('data-path');\n if (pathStr) {\n try {\n const pathValues = JSON.parse(pathStr) as string[];\n const result: SearchResult = {\n pathValues,\n path: [],\n pathLabels: this._getPathLabels(pathValues),\n };\n this._selectSearchResult(result);\n } catch {\n // Invalid path\n }\n }\n return;\n }\n });\n\n // Input event for search\n this.shadowRoot?.addEventListener('input', (e) => {\n const target = e.target as HTMLElement;\n if (target.matches('[data-action=\"search\"]')) {\n this._handleSearch(e);\n }\n });\n\n // Mouseenter for hover expand\n this.shadowRoot?.addEventListener('mouseenter', (e) => {\n if (this.expandTrigger !== 'hover') return;\n const target = e.target as HTMLElement;\n const option = target.closest('[data-action=\"option\"]');\n if (option) {\n const value = option.getAttribute('data-value');\n const level = parseInt(option.getAttribute('data-level') || '0', 10);\n if (value) {\n this._handleOptionHover(value, level);\n }\n }\n }, true); // Use capture for mouseenter\n }\n}\n\n/**\n * Register the custom element\n */\nexport function register(): void {\n if (!customElements.get('el-dm-cascader')) {\n customElements.define('el-dm-cascader', ElDmCascader);\n }\n}\n"
5
+ "/**\n * @duskmoon-dev/el-cascader\n *\n * A multi-panel cascading selection component following Ant Design patterns.\n */\n\nimport { BaseElement, css } from '@duskmoon-dev/el-base';\nimport type { Size, ValidationState } from '@duskmoon-dev/el-base';\nimport { css as cascaderCSS } from '@duskmoon-dev/core/components/cascader';\n\n// Icons with explicit dimensions for proper rendering\nconst chevronDownIcon = `<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"m6 9 6 6 6-6\"/></svg>`;\nconst chevronRightIcon = `<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"m9 18 6-6-6-6\"/></svg>`;\nconst checkIcon = `<svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M20 6 9 17l-5-5\"/></svg>`;\nconst closeIcon = `<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M18 6 6 18\"/><path d=\"m6 6 12 12\"/></svg>`;\nconst searchIcon = `<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"11\" cy=\"11\" r=\"8\"/><path d=\"m21 21-4.3-4.3\"/></svg>`;\nconst loadingIcon = `<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"spinner\"><path d=\"M21 12a9 9 0 1 1-6.219-8.56\"/></svg>`;\n\n/**\n * Cascader option structure\n */\nexport interface CascaderOption {\n value: string;\n label: string;\n disabled?: boolean;\n children?: CascaderOption[];\n leaf?: boolean;\n loading?: boolean;\n}\n\n/**\n * Load data function type for async loading\n */\nexport type LoadDataFn = (option: CascaderOption) => Promise<CascaderOption[]>;\n\n/**\n * Event details\n */\nexport interface CascaderChangeEventDetail {\n value: string;\n selectedOptions: CascaderOption[];\n path: string[];\n}\n\nexport interface CascaderExpandEventDetail {\n option: CascaderOption;\n level: number;\n}\n\nexport interface CascaderSearchEventDetail {\n searchValue: string;\n}\n\n/**\n * Search result with full path\n */\ninterface SearchResult {\n path: CascaderOption[];\n pathLabels: string[];\n pathValues: string[];\n}\n\n// Strip @layer wrapper from core CSS for Shadow DOM usage\nconst coreStyles = cascaderCSS.replace(/@layer\\s+components\\s*\\{/, '').replace(/\\}\\s*$/, '');\n\n// Styles: core CSS + element-specific overrides\nconst styles = css`\n :host {\n display: inline-block;\n width: 100%;\n }\n\n ${coreStyles}\n\n /* Override: block display for full-width behavior */\n .cascader {\n display: block;\n }\n\n /* Override: trigger sizing & gap */\n .cascader-trigger {\n gap: 0.5rem;\n min-height: 2.75rem;\n padding: 0.5rem 0.75rem;\n }\n\n /* Override: value display as block text */\n .cascader-value {\n display: block;\n text-align: left;\n }\n\n .cascader-placeholder {\n opacity: 0.7;\n }\n\n /* Tags (not in core) */\n .cascader-tags {\n display: flex;\n flex-wrap: wrap;\n gap: 0.25rem;\n flex: 1;\n min-width: 0;\n }\n\n .cascader-tag {\n display: inline-flex;\n align-items: center;\n gap: 0.25rem;\n max-width: 100%;\n padding: 0.125rem 0.25rem 0.125rem 0.5rem;\n font-size: var(--font-size-sm, 0.875rem);\n line-height: 1.25rem;\n background-color: var(--color-surface-container-high, #e8e8e8);\n color: var(--color-on-surface);\n border-radius: 1rem;\n }\n\n .cascader-tag-text {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .cascader-tag-remove {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n padding: 0;\n color: inherit;\n background-color: transparent;\n border-radius: 50%;\n cursor: pointer;\n opacity: 0.7;\n transition: opacity 150ms ease, background-color 150ms ease;\n }\n\n .cascader-tag-remove svg {\n width: 10px;\n height: 10px;\n display: block;\n }\n\n .cascader-tag-remove:hover {\n opacity: 1;\n background-color: color-mix(in oklch, currentColor 15%, transparent);\n }\n\n .cascader-tag-overflow {\n padding: 0.125rem 0.5rem;\n background-color: var(--color-surface-container);\n color: var(--color-on-surface-variant);\n }\n\n /* Override: arrow/clear SVG sizing */\n .cascader-arrow svg,\n .cascader-clear svg {\n display: block;\n }\n\n /* Override: dropdown uses Popover API (top-layer requires position: fixed) */\n .cascader-dropdown {\n position: fixed;\n flex-direction: column;\n z-index: 1000;\n }\n\n /* Search icon (not in core) */\n .cascader-search-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n color: var(--color-on-surface-variant);\n flex-shrink: 0;\n }\n\n .cascader-search-icon svg {\n width: 14px;\n height: 14px;\n display: block;\n }\n\n /* Override: panel max-height */\n .cascader-panels {\n max-height: 18rem;\n }\n\n .cascader-panel {\n max-height: 18rem;\n }\n\n /* Checkbox (not in core) */\n .cascader-option-checkbox {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 1rem;\n height: 1rem;\n background-color: transparent;\n border: 2px solid var(--color-on-surface-variant);\n border-radius: 0.125rem;\n flex-shrink: 0;\n }\n\n .cascader-option-selected .cascader-option-checkbox {\n background-color: var(--color-primary);\n border-color: var(--color-primary);\n color: var(--color-on-primary, white);\n }\n\n /* Loading spinner (not in core) */\n .cascader-option-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n }\n\n .cascader-option-loading .spinner {\n animation: spin 1s linear infinite;\n }\n\n @keyframes spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n\n /* Search results (not in core) */\n .cascader-search-results {\n padding: 0.25rem;\n max-height: 18rem;\n overflow-y: auto;\n }\n\n .cascader-search-result {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n width: 100%;\n padding: 0.5rem 0.75rem;\n font-size: var(--font-size-sm, 0.875rem);\n color: var(--color-on-surface);\n background-color: transparent;\n border: none;\n border-radius: var(--radius-sm, 0.25rem);\n cursor: pointer;\n text-align: left;\n transition: background-color 150ms ease;\n }\n\n .cascader-search-result:hover {\n background-color: var(--color-surface-container);\n }\n\n .cascader-search-result.selected {\n background-color: var(--color-primary-container, #e8def8);\n color: var(--color-on-primary-container, #1d1b20);\n }\n\n .cascader-search-result-path {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .cascader-search-result-separator {\n color: var(--color-on-surface-variant);\n margin: 0 0.25rem;\n }\n\n /* Size variants via :host (override core's container-class approach) */\n :host([size=\"sm\"]) .cascader-trigger {\n min-height: 2.25rem;\n padding: 0.375rem 0.5rem;\n font-size: var(--font-size-sm, 0.875rem);\n border-radius: var(--radius-sm, 0.375rem);\n }\n\n :host([size=\"lg\"]) .cascader-trigger {\n min-height: 3.25rem;\n padding: 0.625rem 1rem;\n font-size: var(--font-size-lg, 1.125rem);\n border-radius: var(--radius-lg, 0.625rem);\n }\n\n /* Validation states via :host (override core's container-class approach) */\n :host([validation-state=\"invalid\"]) .cascader-trigger {\n border-color: var(--color-error);\n }\n\n :host([validation-state=\"invalid\"]) .cascader-trigger:focus {\n border-color: var(--color-error);\n box-shadow: 0 0 0 3px color-mix(in oklch, var(--color-error) 15%, transparent);\n }\n\n :host([validation-state=\"valid\"]) .cascader-trigger {\n border-color: var(--color-success);\n }\n\n /* Disabled state via :host */\n :host([disabled]) {\n pointer-events: none;\n }\n\n :host([disabled]) .cascader-trigger {\n cursor: not-allowed;\n opacity: 0.5;\n background-color: var(--color-surface-container);\n }\n`;\n\n/**\n * DuskMoon Cascader Element\n *\n * @element el-dm-cascader\n *\n * @attr {string} value - Selected path as JSON array: '[\"province\", \"city\", \"district\"]'\n * @attr {string} placeholder - Placeholder text when no selection.\n * @attr {boolean} disabled - Disable the cascader.\n * @attr {boolean} multiple - Enable multi-path selection.\n * @attr {boolean} searchable - Enable search functionality.\n * @attr {boolean} clearable - Show clear button.\n * @attr {boolean} change-on-select - Emit change on each level (vs only leaf).\n * @attr {string} expand-trigger - Expand trigger: 'click' (default) | 'hover'.\n * @attr {string} separator - Display separator (default: ' / ').\n * @attr {boolean} show-all-levels - Show full path or just leaf label.\n * @attr {string} show-checked-strategy - For multiple: 'all' | 'parent' | 'child'.\n * @attr {string} size - Size variant: 'sm' | 'md' | 'lg'.\n * @attr {string} validation-state - Validation state: 'valid' | 'invalid'.\n *\n * @fires change - Fired when selection changes.\n * @fires expand - Fired when panel expanded.\n * @fires search - Fired when search input changes.\n */\nexport class ElDmCascader extends BaseElement {\n static properties = {\n value: { type: String, reflect: true, default: '' },\n placeholder: { type: String, default: 'Select...' },\n disabled: { type: Boolean, reflect: true, default: false },\n multiple: { type: Boolean, reflect: true, default: false },\n searchable: { type: Boolean, reflect: true, default: false },\n clearable: { type: Boolean, reflect: true, default: false },\n changeOnSelect: { type: Boolean, reflect: true, attribute: 'change-on-select', default: false },\n expandTrigger: { type: String, attribute: 'expand-trigger', default: 'click' },\n separator: { type: String, default: ' / ' },\n showAllLevels: { type: Boolean, reflect: true, attribute: 'show-all-levels', default: true },\n showCheckedStrategy: { type: String, attribute: 'show-checked-strategy', default: 'all' },\n size: { type: String, reflect: true, default: 'md' },\n validationState: { type: String, reflect: true, attribute: 'validation-state' },\n options: { type: String, default: '' },\n };\n\n // Declared properties\n declare value: string;\n declare placeholder: string;\n declare disabled: boolean;\n declare multiple: boolean;\n declare searchable: boolean;\n declare clearable: boolean;\n declare changeOnSelect: boolean;\n declare expandTrigger: 'click' | 'hover';\n declare separator: string;\n declare showAllLevels: boolean;\n declare showCheckedStrategy: 'all' | 'parent' | 'child';\n declare size: Size;\n declare validationState: ValidationState;\n declare options: string;\n\n // Internal state\n private _isOpen = false;\n private _searchValue = '';\n private _activePath: string[] = [];\n private _selectedPaths: string[][] = [];\n private _loadingKeys = new Set<string>();\n private _options: CascaderOption[] = [];\n private _loadDataFn: LoadDataFn | null = null;\n\n // Bound handlers\n private _handleOutsideClick = this._onOutsideClick.bind(this);\n private _handleKeyDown = this._onKeyDown.bind(this);\n private _handleScroll = this._onScroll.bind(this);\n private _handleResize = this._onResize.bind(this);\n\n constructor() {\n super();\n this.attachStyles(styles);\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n document.addEventListener('click', this._handleOutsideClick);\n document.addEventListener('keydown', this._handleKeyDown);\n\n // Parse options from attribute (for static HTML/MDX usage)\n this._parseOptionsFromAttribute();\n\n this._parseValue();\n\n // Set up event delegation once\n this._setupEventDelegation();\n }\n\n /**\n * Parse options from JSON string attribute\n */\n private _parseOptionsFromAttribute(): void {\n if (this.options) {\n try {\n const parsed = JSON.parse(this.options);\n if (Array.isArray(parsed)) {\n this._options = parsed;\n }\n } catch {\n // Invalid JSON, ignore\n }\n }\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n document.removeEventListener('click', this._handleOutsideClick);\n document.removeEventListener('keydown', this._handleKeyDown);\n this._removeScrollListeners();\n }\n\n private _addScrollListeners(): void {\n window.addEventListener('scroll', this._handleScroll, true);\n window.addEventListener('resize', this._handleResize);\n }\n\n private _removeScrollListeners(): void {\n window.removeEventListener('scroll', this._handleScroll, true);\n window.removeEventListener('resize', this._handleResize);\n }\n\n private _onScroll(): void {\n if (this._isOpen) {\n const dropdown = this.shadowRoot?.querySelector('.cascader-dropdown') as HTMLElement;\n const trigger = this.shadowRoot?.querySelector('.cascader-trigger') as HTMLElement;\n if (dropdown && trigger) {\n this._positionDropdown(dropdown, trigger);\n }\n }\n }\n\n private _onResize(): void {\n if (this._isOpen) {\n this._close();\n }\n }\n\n /**\n * Set cascader options\n */\n setOptions(options: CascaderOption[]): void {\n this._options = options;\n this.update();\n }\n\n /**\n * Set async load data function\n */\n setLoadData(fn: LoadDataFn): void {\n this._loadDataFn = fn;\n }\n\n /**\n * Parse value into selected paths\n */\n private _parseValue(): void {\n if (!this.value) {\n this._selectedPaths = [];\n return;\n }\n\n try {\n const parsed = JSON.parse(this.value);\n if (this.multiple) {\n // Multiple mode: array of paths\n this._selectedPaths = Array.isArray(parsed[0]) ? parsed : [parsed];\n } else {\n // Single mode: single path\n this._selectedPaths = Array.isArray(parsed) ? [parsed] : [];\n }\n } catch {\n this._selectedPaths = [];\n }\n }\n\n /**\n * Get panels data based on active path\n */\n private _getPanels(): CascaderOption[][] {\n const panels: CascaderOption[][] = [this._options];\n\n let currentOptions = this._options;\n for (const value of this._activePath) {\n const option = currentOptions.find((o) => o.value === value);\n if (option?.children && option.children.length > 0) {\n panels.push(option.children);\n currentOptions = option.children;\n } else {\n break;\n }\n }\n\n return panels;\n }\n\n /**\n * Get display label for current selection\n */\n private _getDisplayLabel(): string {\n if (this._selectedPaths.length === 0) {\n return '';\n }\n\n const path = this._selectedPaths[0];\n const labels = this._getPathLabels(path);\n\n if (this.showAllLevels) {\n return labels.join(this.separator);\n }\n return labels[labels.length - 1] || '';\n }\n\n /**\n * Get labels for a path\n */\n private _getPathLabels(path: string[]): string[] {\n const labels: string[] = [];\n let currentOptions = this._options;\n\n for (const value of path) {\n const option = currentOptions.find((o) => o.value === value);\n if (option) {\n labels.push(option.label);\n currentOptions = option.children || [];\n }\n }\n\n return labels;\n }\n\n /**\n * Find option by path\n */\n private _findOptionByPath(path: string[]): CascaderOption | undefined {\n let currentOptions = this._options;\n let option: CascaderOption | undefined;\n\n for (const value of path) {\n option = currentOptions.find((o) => o.value === value);\n if (option?.children) {\n currentOptions = option.children;\n }\n }\n\n return option;\n }\n\n /**\n * Check if option is leaf (no children or marked as leaf)\n */\n private _isLeaf(option: CascaderOption): boolean {\n if (option.leaf === true) return true;\n if (option.leaf === false) return false;\n return !option.children || option.children.length === 0;\n }\n\n /**\n * Search options recursively\n */\n private _searchOptions(): SearchResult[] {\n const results: SearchResult[] = [];\n const search = this._searchValue.toLowerCase();\n\n const searchRecursive = (\n options: CascaderOption[],\n path: CascaderOption[],\n pathValues: string[]\n ): void => {\n for (const option of options) {\n const newPath = [...path, option];\n const newPathValues = [...pathValues, option.value];\n\n // Check if this option matches\n if (option.label.toLowerCase().includes(search)) {\n // Only add if it's a leaf or changeOnSelect is true\n if (this._isLeaf(option) || this.changeOnSelect) {\n results.push({\n path: newPath,\n pathLabels: newPath.map((o) => o.label),\n pathValues: newPathValues,\n });\n }\n }\n\n // Search children\n if (option.children) {\n searchRecursive(option.children, newPath, newPathValues);\n }\n }\n };\n\n searchRecursive(this._options, [], []);\n return results;\n }\n\n // Event handlers\n private _onOutsideClick(e: MouseEvent): void {\n if (!this.contains(e.target as Node)) {\n this._close();\n }\n }\n\n private _onKeyDown(e: KeyboardEvent): void {\n if (!this._isOpen) {\n if (e.key === 'Enter' || e.key === ' ' || e.key === 'ArrowDown') {\n if (document.activeElement === this || this.contains(document.activeElement)) {\n e.preventDefault();\n this._open();\n }\n }\n return;\n }\n\n switch (e.key) {\n case 'Escape':\n e.preventDefault();\n this._close();\n break;\n\n case 'ArrowLeft':\n e.preventDefault();\n if (this._activePath.length > 0) {\n this._activePath = this._activePath.slice(0, -1);\n this.update();\n }\n break;\n\n case 'ArrowRight':\n // Navigate into selected option if it has children\n break;\n }\n }\n\n private _open(): void {\n if (this.disabled) return;\n this._isOpen = true;\n this._activePath = this._selectedPaths[0] ? [...this._selectedPaths[0]] : [];\n this.update();\n\n // Add scroll/resize listeners to keep dropdown positioned\n this._addScrollListeners();\n\n // Show popover and position it\n requestAnimationFrame(() => {\n const dropdown = this.shadowRoot?.querySelector('.cascader-dropdown') as HTMLElement;\n const trigger = this.shadowRoot?.querySelector('.cascader-trigger') as HTMLElement;\n if (dropdown && trigger) {\n // Set initial position before showing (based on trigger only)\n const triggerRect = trigger.getBoundingClientRect();\n dropdown.style.top = `${triggerRect.bottom + 4}px`;\n dropdown.style.left = `${triggerRect.left}px`;\n dropdown.style.minWidth = `${triggerRect.width}px`;\n\n // Show the popover\n dropdown.showPopover();\n\n // Recalculate position after layout is complete\n requestAnimationFrame(() => {\n this._positionDropdown(dropdown, trigger);\n });\n }\n\n // Focus search input if searchable\n const searchInput = this.shadowRoot?.querySelector('.cascader-search-input') as HTMLInputElement;\n if (searchInput) {\n searchInput.focus();\n }\n });\n }\n\n private _close(): void {\n this._isOpen = false;\n this._searchValue = '';\n this._activePath = [];\n\n // Remove scroll/resize listeners\n this._removeScrollListeners();\n\n // Hide popover\n const dropdown = this.shadowRoot?.querySelector('.cascader-dropdown') as HTMLElement;\n if (dropdown) {\n try {\n dropdown.hidePopover();\n } catch {\n // Ignore if already hidden\n }\n }\n\n this.update();\n }\n\n private _positionDropdown(dropdown: HTMLElement, trigger: HTMLElement): void {\n const triggerRect = trigger.getBoundingClientRect();\n const viewportHeight = window.innerHeight;\n const viewportWidth = window.innerWidth;\n\n // Position below the trigger by default\n let top = triggerRect.bottom + 4;\n let left = triggerRect.left;\n\n // Get dropdown dimensions after it's visible\n const dropdownRect = dropdown.getBoundingClientRect();\n\n // If not enough space below, position above\n if (top + dropdownRect.height > viewportHeight && triggerRect.top > dropdownRect.height) {\n top = triggerRect.top - dropdownRect.height - 4;\n }\n\n // Ensure dropdown doesn't go off-screen horizontally\n if (left + dropdownRect.width > viewportWidth) {\n left = viewportWidth - dropdownRect.width - 8;\n }\n if (left < 8) {\n left = 8;\n }\n\n dropdown.style.top = `${top}px`;\n dropdown.style.left = `${left}px`;\n // Cascader may be wider than trigger due to panels\n dropdown.style.minWidth = `${triggerRect.width}px`;\n }\n\n private _toggle(): void {\n if (this._isOpen) {\n this._close();\n } else {\n this._open();\n }\n }\n\n private async _handleOptionClick(value: string, level: number): Promise<void> {\n // Update active path\n this._activePath = this._activePath.slice(0, level);\n this._activePath.push(value);\n\n const option = this._findOptionByPath(this._activePath);\n if (!option) {\n return;\n }\n\n // Check if we need to load children\n if (this._loadDataFn && !option.children && !option.leaf) {\n this._loadingKeys.add(value);\n this.update();\n\n try {\n const children = await this._loadDataFn(option);\n option.children = children;\n } finally {\n this._loadingKeys.delete(value);\n }\n }\n\n // Emit expand event\n this.emit<CascaderExpandEventDetail>('expand', { option, level });\n\n // Handle selection\n const isLeaf = this._isLeaf(option);\n if (isLeaf || this.changeOnSelect) {\n this._selectPath([...this._activePath]);\n\n if (isLeaf && !this.multiple) {\n this._close();\n }\n }\n\n this.update();\n }\n\n private _handleOptionHover(value: string, level: number): void {\n if (this.expandTrigger !== 'hover') return;\n\n this._activePath = this._activePath.slice(0, level);\n this._activePath.push(value);\n this.update();\n\n // Trigger async load if needed\n const option = this._findOptionByPath(this._activePath);\n if (option && this._loadDataFn && !option.children && !option.leaf) {\n this._handleOptionClick(value, level);\n }\n }\n\n private _selectPath(path: string[]): void {\n if (this.multiple) {\n // Toggle path in selected paths\n const pathStr = JSON.stringify(path);\n const index = this._selectedPaths.findIndex(\n (p) => JSON.stringify(p) === pathStr\n );\n\n if (index >= 0) {\n this._selectedPaths.splice(index, 1);\n } else {\n this._selectedPaths.push(path);\n }\n\n this.value = JSON.stringify(this._selectedPaths);\n } else {\n this._selectedPaths = [path];\n this.value = JSON.stringify(path);\n }\n\n this._emitChange();\n }\n\n private _selectSearchResult(result: SearchResult): void {\n this._selectPath(result.pathValues);\n if (!this.multiple) {\n this._close();\n }\n this.update();\n }\n\n private _removeTag(pathIndex: number): void {\n this._selectedPaths.splice(pathIndex, 1);\n this.value = this._selectedPaths.length > 0 ? JSON.stringify(this._selectedPaths) : '';\n this._emitChange();\n this.update();\n }\n\n private _handleSearch(e: Event): void {\n const input = e.target as HTMLInputElement;\n this._searchValue = input.value;\n this.emit<CascaderSearchEventDetail>('search', { searchValue: this._searchValue });\n this.update();\n }\n\n private _handleClear(e: Event): void {\n e.stopPropagation();\n this.value = '';\n this._selectedPaths = [];\n this.emit('clear', {});\n this._emitChange();\n this.update();\n }\n\n private _emitChange(): void {\n const selectedOptions = this._selectedPaths.map((path) =>\n this._findOptionByPath(path)\n ).filter((o): o is CascaderOption => o !== undefined);\n\n this.emit<CascaderChangeEventDetail>('change', {\n value: this.value,\n selectedOptions,\n path: this._selectedPaths[0] || [],\n });\n }\n\n // Rendering\n protected render(): string {\n return `\n <div class=\"cascader ${this._isOpen ? 'cascader-open' : ''}\">\n ${this._renderTrigger()}\n ${this._renderDropdown()}\n </div>\n `;\n }\n\n private _renderTrigger(): string {\n const hasValue = this._selectedPaths.length > 0;\n const showClear = this.clearable && hasValue && !this.disabled;\n\n return `\n <button\n type=\"button\"\n class=\"cascader-trigger\"\n aria-haspopup=\"listbox\"\n aria-expanded=\"${this._isOpen}\"\n ${this.disabled ? 'disabled' : ''}\n data-action=\"toggle\"\n >\n ${this.multiple && hasValue ? this._renderTags() : this._renderValue()}\n ${showClear ? `<span class=\"cascader-clear\" role=\"button\" tabindex=\"-1\" data-action=\"clear\">${closeIcon}</span>` : ''}\n <span class=\"cascader-arrow\">${chevronDownIcon}</span>\n </button>\n `;\n }\n\n private _renderValue(): string {\n const displayLabel = this._getDisplayLabel();\n if (!displayLabel) {\n return `<span class=\"cascader-value cascader-placeholder\">${this.placeholder}</span>`;\n }\n return `<span class=\"cascader-value\">${this._escapeHtml(displayLabel)}</span>`;\n }\n\n private _renderTags(): string {\n const tagsHtml = this._selectedPaths\n .map((path, index) => {\n const labels = this._getPathLabels(path);\n const displayLabel = this.showAllLevels\n ? labels.join(this.separator)\n : labels[labels.length - 1];\n\n return `\n <span class=\"cascader-tag\">\n <span class=\"cascader-tag-text\">${this._escapeHtml(displayLabel)}</span>\n <span class=\"cascader-tag-remove\" role=\"button\" tabindex=\"-1\" data-action=\"remove-tag\" data-index=\"${index}\">${closeIcon}</span>\n </span>\n `;\n })\n .join('');\n\n return `<div class=\"cascader-tags\">${tagsHtml || `<span class=\"cascader-placeholder\">${this.placeholder}</span>`}</div>`;\n }\n\n private _renderDropdown(): string {\n const showSearch = this.searchable && this._searchValue;\n\n return `\n <div class=\"cascader-dropdown\" role=\"listbox\" popover=\"manual\">\n ${this.searchable ? this._renderSearch() : ''}\n ${showSearch ? this._renderSearchResults() : this._renderPanels()}\n </div>\n `;\n }\n\n private _renderSearch(): string {\n return `\n <div class=\"cascader-search\">\n <span class=\"cascader-search-icon\">${searchIcon}</span>\n <input\n type=\"text\"\n class=\"cascader-search-input\"\n placeholder=\"Search...\"\n value=\"${this._escapeHtml(this._searchValue)}\"\n data-action=\"search\"\n />\n </div>\n `;\n }\n\n private _renderPanels(): string {\n const panels = this._getPanels();\n\n if (panels.length === 0 || panels[0].length === 0) {\n return `<div class=\"cascader-empty\">No options available</div>`;\n }\n\n return `\n <div class=\"cascader-panels\">\n ${panels.map((options, level) => this._renderPanel(options, level)).join('')}\n </div>\n `;\n }\n\n private _renderPanel(options: CascaderOption[], level: number): string {\n const selectedValue = this._activePath[level];\n const selectedPathValues = this._selectedPaths.flatMap((p) => p);\n\n const optionsHtml = options\n .map((option) => {\n const isActive = option.value === selectedValue;\n const isSelected = this.multiple\n ? selectedPathValues.includes(option.value)\n : JSON.stringify(this._selectedPaths[0]) === JSON.stringify([...this._activePath.slice(0, level), option.value]);\n const isLoading = this._loadingKeys.has(option.value);\n const hasChildren = !this._isLeaf(option);\n\n const classes = [\n 'cascader-option',\n isActive ? 'cascader-option-active' : '',\n isSelected ? 'cascader-option-selected' : '',\n option.disabled ? 'cascader-option-disabled' : '',\n ].filter(Boolean).join(' ');\n\n return `\n <button\n type=\"button\"\n class=\"${classes}\"\n data-action=\"option\"\n data-value=\"${this._escapeHtml(option.value)}\"\n data-level=\"${level}\"\n ${option.disabled ? 'disabled' : ''}\n >\n ${this.multiple ? `<span class=\"cascader-option-checkbox\">${isSelected ? checkIcon : ''}</span>` : ''}\n <span class=\"cascader-option-label\">${this._escapeHtml(option.label)}</span>\n ${isLoading ? `<span class=\"cascader-option-loading\">${loadingIcon}</span>` : ''}\n ${hasChildren && !isLoading ? `<span class=\"cascader-option-arrow\">${chevronRightIcon}</span>` : ''}\n </button>\n `;\n })\n .join('');\n\n return `\n <div class=\"cascader-panel\">\n <div class=\"cascader-options\">${optionsHtml}</div>\n </div>\n `;\n }\n\n private _renderSearchResults(): string {\n const results = this._searchOptions();\n\n if (results.length === 0) {\n return `<div class=\"cascader-empty\">No results found</div>`;\n }\n\n const selectedPathStrs = this._selectedPaths.map((p) => JSON.stringify(p));\n\n const resultsHtml = results\n .map((result) => {\n const isSelected = selectedPathStrs.includes(JSON.stringify(result.pathValues));\n const classes = ['cascader-search-result', isSelected ? 'selected' : ''].filter(Boolean).join(' ');\n\n const pathHtml = result.pathLabels\n .map((label, i) => {\n const separator = i < result.pathLabels.length - 1\n ? `<span class=\"cascader-search-result-separator\">${this.separator}</span>`\n : '';\n return `<span>${this._escapeHtml(label)}</span>${separator}`;\n })\n .join('');\n\n return `\n <button\n type=\"button\"\n class=\"${classes}\"\n data-action=\"search-result\"\n data-path=\"${this._escapeHtml(JSON.stringify(result.pathValues))}\"\n >\n ${this.multiple ? `<span class=\"cascader-option-checkbox\">${isSelected ? checkIcon : ''}</span>` : ''}\n <span class=\"cascader-search-result-path\">${pathHtml}</span>\n </button>\n `;\n })\n .join('');\n\n return `<div class=\"cascader-search-results\">${resultsHtml}</div>`;\n }\n\n private _escapeHtml(str: string): string {\n const div = document.createElement('div');\n div.textContent = str;\n return div.innerHTML;\n }\n\n protected update(): void {\n // Preserve search input focus state before DOM replacement\n const searchInput = this.shadowRoot?.querySelector('.cascader-search-input') as HTMLInputElement;\n const hadFocus = searchInput && this.shadowRoot?.activeElement === searchInput;\n const cursorPosition = hadFocus ? searchInput.selectionStart : null;\n\n super.update();\n // Event delegation is set up once in connectedCallback\n\n // If dropdown is open, re-show the popover after DOM update\n // (since update() replaces the DOM, the new dropdown element needs showPopover())\n if (this._isOpen) {\n const dropdown = this.shadowRoot?.querySelector('.cascader-dropdown') as HTMLElement;\n const trigger = this.shadowRoot?.querySelector('.cascader-trigger') as HTMLElement;\n if (dropdown && trigger) {\n try {\n dropdown.showPopover();\n this._positionDropdown(dropdown, trigger);\n } catch {\n // Ignore if already shown or other errors\n }\n }\n\n // Restore search input focus if it had focus before update\n if (hadFocus) {\n const newSearchInput = this.shadowRoot?.querySelector('.cascader-search-input') as HTMLInputElement;\n if (newSearchInput) {\n newSearchInput.focus();\n // Restore cursor position\n if (cursorPosition !== null) {\n newSearchInput.setSelectionRange(cursorPosition, cursorPosition);\n }\n }\n }\n }\n }\n\n /**\n * Set up event delegation once (called in connectedCallback)\n */\n private _setupEventDelegation(): void {\n // Use event delegation on shadow root for all interactive elements\n this.shadowRoot?.addEventListener('click', (e) => {\n const target = e.target as HTMLElement;\n\n // Toggle trigger\n const trigger = target.closest('[data-action=\"toggle\"]');\n if (trigger && !target.closest('[data-action=\"clear\"]') && !target.closest('[data-action=\"remove-tag\"]')) {\n this._toggle();\n return;\n }\n\n // Clear button\n if (target.closest('[data-action=\"clear\"]')) {\n this._handleClear(e);\n return;\n }\n\n // Tag remove button\n const removeTag = target.closest('[data-action=\"remove-tag\"]');\n if (removeTag) {\n e.stopPropagation();\n const index = parseInt(removeTag.getAttribute('data-index') || '0', 10);\n this._removeTag(index);\n return;\n }\n\n // Panel option\n const option = target.closest('[data-action=\"option\"]');\n if (option) {\n const value = option.getAttribute('data-value');\n const level = parseInt(option.getAttribute('data-level') || '0', 10);\n if (value) {\n this._handleOptionClick(value, level);\n }\n return;\n }\n\n // Search result\n const searchResult = target.closest('[data-action=\"search-result\"]');\n if (searchResult) {\n const pathStr = searchResult.getAttribute('data-path');\n if (pathStr) {\n try {\n const pathValues = JSON.parse(pathStr) as string[];\n const result: SearchResult = {\n pathValues,\n path: [],\n pathLabels: this._getPathLabels(pathValues),\n };\n this._selectSearchResult(result);\n } catch {\n // Invalid path\n }\n }\n return;\n }\n });\n\n // Input event for search\n this.shadowRoot?.addEventListener('input', (e) => {\n const target = e.target as HTMLElement;\n if (target.matches('[data-action=\"search\"]')) {\n this._handleSearch(e);\n }\n });\n\n // Mouseenter for hover expand\n this.shadowRoot?.addEventListener('mouseenter', (e) => {\n if (this.expandTrigger !== 'hover') return;\n const target = e.target as HTMLElement;\n const option = target.closest('[data-action=\"option\"]');\n if (option) {\n const value = option.getAttribute('data-value');\n const level = parseInt(option.getAttribute('data-level') || '0', 10);\n if (value) {\n this._handleOptionHover(value, level);\n }\n }\n }, true); // Use capture for mouseenter\n }\n}\n\n/**\n * Register the custom element\n */\nexport function register(): void {\n if (!customElements.get('el-dm-cascader')) {\n customElements.define('el-dm-cascader', ElDmCascader);\n }\n}\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "14A82928B562098464756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "ED3416414C36397464756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -1,71 +1,44 @@
1
1
  // src/el-dm-cascader.ts
2
- import { BaseElement, css } from "@duskmoon-dev/el-core";
2
+ import { BaseElement, css } from "@duskmoon-dev/el-base";
3
+ import { css as cascaderCSS } from "@duskmoon-dev/core/components/cascader";
3
4
  var chevronDownIcon = `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg>`;
4
5
  var chevronRightIcon = `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg>`;
5
6
  var checkIcon = `<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg>`;
6
7
  var closeIcon = `<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>`;
7
8
  var searchIcon = `<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>`;
8
9
  var loadingIcon = `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="spinner"><path d="M21 12a9 9 0 1 1-6.219-8.56"/></svg>`;
10
+ var coreStyles = cascaderCSS.replace(/@layer\s+components\s*\{/, "").replace(/\}\s*$/, "");
9
11
  var styles = css`
10
12
  :host {
11
13
  display: inline-block;
12
14
  width: 100%;
13
15
  }
14
16
 
17
+ ${coreStyles}
18
+
19
+ /* Override: block display for full-width behavior */
15
20
  .cascader {
16
- position: relative;
17
- width: 100%;
21
+ display: block;
18
22
  }
19
23
 
20
- /* Trigger Button */
24
+ /* Override: trigger sizing & gap */
21
25
  .cascader-trigger {
22
- display: flex;
23
- align-items: center;
24
26
  gap: 0.5rem;
25
- width: 100%;
26
27
  min-height: 2.75rem;
27
28
  padding: 0.5rem 0.75rem;
28
- font-size: var(--font-size-md, 1rem);
29
- line-height: 1.5;
30
- color: var(--color-on-surface);
31
- background-color: var(--color-surface);
32
- border: 1px solid var(--color-outline);
33
- border-radius: var(--radius-md, 0.5rem);
34
- cursor: pointer;
35
- transition: border-color 150ms ease, box-shadow 150ms ease;
36
- }
37
-
38
- .cascader-trigger:hover:not(:disabled) {
39
- border-color: var(--color-on-surface-variant);
40
- }
41
-
42
- .cascader-trigger:focus {
43
- outline: none;
44
- border-color: var(--color-primary);
45
- box-shadow: 0 0 0 3px color-mix(in oklch, var(--color-primary) 15%, transparent);
46
- }
47
-
48
- .cascader-trigger:disabled {
49
- cursor: not-allowed;
50
- opacity: 0.5;
51
- background-color: var(--color-surface-container);
52
29
  }
53
30
 
54
- /* Value Display */
31
+ /* Override: value display as block text */
55
32
  .cascader-value {
56
- flex: 1;
57
- overflow: hidden;
58
- text-overflow: ellipsis;
59
- white-space: nowrap;
33
+ display: block;
60
34
  text-align: left;
61
35
  }
62
36
 
63
37
  .cascader-placeholder {
64
- color: var(--color-on-surface-variant);
65
38
  opacity: 0.7;
66
39
  }
67
40
 
68
- /* Tags Container (for multiple mode) */
41
+ /* Tags (not in core) */
69
42
  .cascader-tags {
70
43
  display: flex;
71
44
  flex-wrap: wrap;
@@ -125,81 +98,20 @@ var styles = css`
125
98
  color: var(--color-on-surface-variant);
126
99
  }
127
100
 
128
- /* Icons */
129
- .cascader-arrow {
130
- display: inline-flex;
131
- align-items: center;
132
- justify-content: center;
133
- width: 20px;
134
- height: 20px;
135
- flex-shrink: 0;
136
- color: var(--color-on-surface-variant);
137
- transition: transform 150ms ease;
138
- }
139
-
140
- .cascader-arrow svg {
141
- width: 16px;
142
- height: 16px;
143
- display: block;
144
- }
145
-
146
- .cascader.open .cascader-arrow {
147
- transform: rotate(180deg);
148
- }
149
-
150
- .cascader-clear {
151
- display: inline-flex;
152
- align-items: center;
153
- justify-content: center;
154
- width: 20px;
155
- height: 20px;
156
- padding: 0;
157
- color: var(--color-on-surface-variant);
158
- background-color: transparent;
159
- border-radius: 50%;
160
- cursor: pointer;
161
- flex-shrink: 0;
162
- transition: background-color 150ms ease;
163
- }
164
-
101
+ /* Override: arrow/clear SVG sizing */
102
+ .cascader-arrow svg,
165
103
  .cascader-clear svg {
166
- width: 14px;
167
- height: 14px;
168
104
  display: block;
169
105
  }
170
106
 
171
- .cascader-clear:hover {
172
- background-color: var(--color-surface-container-high);
173
- }
174
-
175
- /* Dropdown - uses Popover API (top-layer requires position: fixed) */
107
+ /* Override: dropdown uses Popover API (top-layer requires position: fixed) */
176
108
  .cascader-dropdown {
177
109
  position: fixed;
178
- margin: 0;
179
- padding: 0;
180
- border: 1px solid var(--color-outline-variant);
181
- border-radius: var(--radius-md, 0.5rem);
182
- background-color: var(--color-surface);
183
- box-shadow: var(--shadow-md, 0 4px 6px -1px rgba(0, 0, 0, 0.1));
184
- overflow: hidden;
185
- display: none;
186
110
  flex-direction: column;
187
111
  z-index: 1000;
188
112
  }
189
113
 
190
- .cascader-dropdown:popover-open {
191
- display: flex;
192
- }
193
-
194
- /* Search */
195
- .cascader-search {
196
- display: flex;
197
- align-items: center;
198
- gap: 0.5rem;
199
- padding: 0.5rem;
200
- border-bottom: 1px solid var(--color-outline-variant);
201
- }
202
-
114
+ /* Search icon (not in core) */
203
115
  .cascader-search-icon {
204
116
  display: inline-flex;
205
117
  align-items: center;
@@ -216,86 +128,16 @@ var styles = css`
216
128
  display: block;
217
129
  }
218
130
 
219
- .cascader-search-input {
220
- flex: 1;
221
- padding: 0.375rem 0.5rem;
222
- font-size: var(--font-size-sm, 0.875rem);
223
- color: var(--color-on-surface);
224
- background-color: var(--color-surface-container);
225
- border: none;
226
- border-radius: var(--radius-sm, 0.25rem);
227
- outline: none;
228
- }
229
-
230
- .cascader-search-input:focus {
231
- background-color: var(--color-surface-container-high);
232
- }
233
-
234
- .cascader-search-input::placeholder {
235
- color: var(--color-on-surface-variant);
236
- opacity: 0.7;
237
- }
238
-
239
- /* Panels Container */
131
+ /* Override: panel max-height */
240
132
  .cascader-panels {
241
- display: flex;
242
133
  max-height: 18rem;
243
134
  }
244
135
 
245
- /* Panel */
246
136
  .cascader-panel {
247
- display: flex;
248
- flex-direction: column;
249
- min-width: 10rem;
250
- max-width: 14rem;
251
137
  max-height: 18rem;
252
- overflow-y: auto;
253
- border-right: 1px solid var(--color-outline-variant);
254
- }
255
-
256
- .cascader-panel:last-child {
257
- border-right: none;
258
- }
259
-
260
- .cascader-panel-options {
261
- padding: 0.25rem;
262
- }
263
-
264
- /* Option */
265
- .cascader-option {
266
- display: flex;
267
- align-items: center;
268
- gap: 0.5rem;
269
- width: 100%;
270
- padding: 0.5rem 0.75rem;
271
- font-size: var(--font-size-sm, 0.875rem);
272
- color: var(--color-on-surface);
273
- background-color: transparent;
274
- border: none;
275
- border-radius: var(--radius-sm, 0.25rem);
276
- cursor: pointer;
277
- text-align: left;
278
- transition: background-color 150ms ease;
279
- }
280
-
281
- .cascader-option:hover:not(.disabled) {
282
- background-color: var(--color-surface-container);
283
- }
284
-
285
- .cascader-option.active {
286
- background-color: var(--color-surface-container-high);
287
- }
288
-
289
- .cascader-option.selected {
290
- background-color: var(--color-primary-container, #e8def8);
291
- color: var(--color-on-primary-container, #1d1b20);
292
- }
293
-
294
- .cascader-option.disabled {
295
- opacity: 0.5;
296
- cursor: not-allowed;
297
138
  }
298
139
 
140
+ /* Checkbox (not in core) */
299
141
  .cascader-option-checkbox {
300
142
  display: flex;
301
143
  align-items: center;
@@ -308,27 +150,13 @@ var styles = css`
308
150
  flex-shrink: 0;
309
151
  }
310
152
 
311
- .cascader-option.selected .cascader-option-checkbox {
153
+ .cascader-option-selected .cascader-option-checkbox {
312
154
  background-color: var(--color-primary);
313
155
  border-color: var(--color-primary);
314
156
  color: var(--color-on-primary, white);
315
157
  }
316
158
 
317
- .cascader-option-label {
318
- flex: 1;
319
- overflow: hidden;
320
- text-overflow: ellipsis;
321
- white-space: nowrap;
322
- }
323
-
324
- .cascader-option-arrow {
325
- display: flex;
326
- align-items: center;
327
- justify-content: center;
328
- color: var(--color-on-surface-variant);
329
- flex-shrink: 0;
330
- }
331
-
159
+ /* Loading spinner (not in core) */
332
160
  .cascader-option-loading {
333
161
  display: flex;
334
162
  align-items: center;
@@ -345,7 +173,7 @@ var styles = css`
345
173
  to { transform: rotate(360deg); }
346
174
  }
347
175
 
348
- /* Search Results */
176
+ /* Search results (not in core) */
349
177
  .cascader-search-results {
350
178
  padding: 0.25rem;
351
179
  max-height: 18rem;
@@ -389,15 +217,7 @@ var styles = css`
389
217
  margin: 0 0.25rem;
390
218
  }
391
219
 
392
- /* Empty State */
393
- .cascader-empty {
394
- padding: 1.5rem;
395
- text-align: center;
396
- color: var(--color-on-surface-variant);
397
- font-size: var(--font-size-sm, 0.875rem);
398
- }
399
-
400
- /* Size Variants */
220
+ /* Size variants via :host (override core's container-class approach) */
401
221
  :host([size="sm"]) .cascader-trigger {
402
222
  min-height: 2.25rem;
403
223
  padding: 0.375rem 0.5rem;
@@ -412,7 +232,7 @@ var styles = css`
412
232
  border-radius: var(--radius-lg, 0.625rem);
413
233
  }
414
234
 
415
- /* Validation States */
235
+ /* Validation states via :host (override core's container-class approach) */
416
236
  :host([validation-state="invalid"]) .cascader-trigger {
417
237
  border-color: var(--color-error);
418
238
  }
@@ -426,7 +246,7 @@ var styles = css`
426
246
  border-color: var(--color-success);
427
247
  }
428
248
 
429
- /* Disabled State */
249
+ /* Disabled state via :host */
430
250
  :host([disabled]) {
431
251
  pointer-events: none;
432
252
  }
@@ -806,7 +626,7 @@ class ElDmCascader extends BaseElement {
806
626
  }
807
627
  render() {
808
628
  return `
809
- <div class="cascader ${this._isOpen ? "open" : ""}">
629
+ <div class="cascader ${this._isOpen ? "cascader-open" : ""}">
810
630
  ${this._renderTrigger()}
811
631
  ${this._renderDropdown()}
812
632
  </div>
@@ -894,9 +714,9 @@ class ElDmCascader extends BaseElement {
894
714
  const hasChildren = !this._isLeaf(option);
895
715
  const classes = [
896
716
  "cascader-option",
897
- isActive ? "active" : "",
898
- isSelected ? "selected" : "",
899
- option.disabled ? "disabled" : ""
717
+ isActive ? "cascader-option-active" : "",
718
+ isSelected ? "cascader-option-selected" : "",
719
+ option.disabled ? "cascader-option-disabled" : ""
900
720
  ].filter(Boolean).join(" ");
901
721
  return `
902
722
  <button
@@ -916,7 +736,7 @@ class ElDmCascader extends BaseElement {
916
736
  }).join("");
917
737
  return `
918
738
  <div class="cascader-panel">
919
- <div class="cascader-panel-options">${optionsHtml}</div>
739
+ <div class="cascader-options">${optionsHtml}</div>
920
740
  </div>
921
741
  `;
922
742
  }
@@ -1052,5 +872,5 @@ function register() {
1052
872
  // src/register.ts
1053
873
  register();
1054
874
 
1055
- //# debugId=B49288E17D9672F264756E2164756E21
875
+ //# debugId=04FCE6719A151FF064756E2164756E21
1056
876
  //# sourceMappingURL=register.js.map