@duskmoon-dev/el-popover 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.
- package/README.md +152 -0
- package/dist/cjs/index.js +35 -63
- package/dist/cjs/index.js.map +3 -3
- package/dist/cjs/register.js +35 -63
- package/dist/cjs/register.js.map +3 -3
- package/dist/esm/index.js +33 -61
- package/dist/esm/index.js.map +3 -3
- package/dist/esm/register.js +33 -61
- package/dist/esm/register.js.map +3 -3
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/el-dm-popover.d.ts +1 -1
- package/dist/types/el-dm-popover.d.ts.map +1 -1
- package/package.json +6 -5
package/dist/esm/index.js.map
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/el-dm-popover.ts", "../../src/index.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"/**\n * DuskMoon Popover Element\n *\n * A contextual overlay/popup component that appears relative to a trigger element.\n * Supports multiple trigger modes, placements, and auto-flip when near viewport edges.\n *\n * @element el-dm-popover\n *\n * @attr {boolean} open - Whether the popover is visible\n * @attr {string} trigger - Trigger mode: click, hover, focus, manual\n * @attr {string} placement - Popover position relative to trigger\n * @attr {number} offset - Distance from trigger element in pixels\n * @attr {boolean} arrow - Whether to show arrow pointing to trigger\n *\n * @slot trigger - The element that triggers the popover\n * @slot - Default slot for popover content\n *\n * @fires open - Fired when popover opens\n * @fires close - Fired when popover closes\n *\n * @csspart popover - The popover container\n * @csspart content - The popover content area\n * @csspart arrow - The popover arrow\n */\n\nimport { BaseElement, css } from '@duskmoon-dev/el-core';\n\nexport type PopoverPlacement =\n | 'top'\n | 'top-start'\n | 'top-end'\n | 'bottom'\n | 'bottom-start'\n | 'bottom-end'\n | 'left'\n | 'left-start'\n | 'left-end'\n | 'right'\n | 'right-start'\n | 'right-end';\n\nexport type PopoverTrigger = 'click' | 'hover' | 'focus' | 'manual';\n\nconst styles = css`\n :host {\n display: inline-block;\n position: relative;\n }\n\n :host([hidden]) {\n display: none !important;\n }\n\n .popover-trigger {\n display: inline-flex;\n }\n\n .popover-panel {\n position: fixed;\n z-index: 1000;\n min-width: 8rem;\n max-width: 20rem;\n padding: 0.75rem 1rem;\n background-color: var(--color-surface, #ffffff);\n border: 1px solid var(--color-outline, #e0e0e0);\n border-radius: 0.5rem;\n box-shadow:\n 0 4px 6px -1px rgb(0 0 0 / 0.1),\n 0 2px 4px -2px rgb(0 0 0 / 0.1);\n opacity: 0;\n visibility: hidden;\n transform: scale(0.95);\n transition:\n opacity 150ms ease,\n visibility 150ms ease,\n transform 150ms ease;\n pointer-events: none;\n font-family: inherit;\n }\n\n .popover-panel.visible {\n opacity: 1;\n visibility: visible;\n transform: scale(1);\n pointer-events: auto;\n }\n\n .popover-arrow {\n position: absolute;\n width: 0.75rem;\n height: 0.75rem;\n background-color: var(--color-surface, #ffffff);\n border: 1px solid var(--color-outline, #e0e0e0);\n transform: rotate(45deg);\n }\n\n /* Arrow positioning based on popover placement */\n .popover-panel[data-placement^='top'] .popover-arrow {\n bottom: -0.4375rem;\n border-top: none;\n border-left: none;\n }\n\n .popover-panel[data-placement^='bottom'] .popover-arrow {\n top: -0.4375rem;\n border-bottom: none;\n border-right: none;\n }\n\n .popover-panel[data-placement^='left'] .popover-arrow {\n right: -0.4375rem;\n border-top: none;\n border-left: none;\n }\n\n .popover-panel[data-placement^='right'] .popover-arrow {\n left: -0.4375rem;\n border-bottom: none;\n border-right: none;\n }\n\n /* Center aligned arrows */\n .popover-panel[data-placement='top'] .popover-arrow,\n .popover-panel[data-placement='bottom'] .popover-arrow {\n left: 50%;\n transform: translateX(-50%) rotate(45deg);\n }\n\n .popover-panel[data-placement='left'] .popover-arrow,\n .popover-panel[data-placement='right'] .popover-arrow {\n top: 50%;\n transform: translateY(-50%) rotate(45deg);\n }\n\n /* Start aligned arrows */\n .popover-panel[data-placement='top-start'] .popover-arrow,\n .popover-panel[data-placement='bottom-start'] .popover-arrow {\n left: 1rem;\n }\n\n .popover-panel[data-placement='left-start'] .popover-arrow,\n .popover-panel[data-placement='right-start'] .popover-arrow {\n top: 1rem;\n }\n\n /* End aligned arrows */\n .popover-panel[data-placement='top-end'] .popover-arrow,\n .popover-panel[data-placement='bottom-end'] .popover-arrow {\n right: 1rem;\n left: auto;\n }\n\n .popover-panel[data-placement='left-end'] .popover-arrow,\n .popover-panel[data-placement='right-end'] .popover-arrow {\n bottom: 1rem;\n top: auto;\n }\n\n .popover-content {\n color: var(--color-on-surface, #1f1f1f);\n font-size: 0.875rem;\n line-height: 1.5;\n }\n`;\n\nexport class ElDmPopover extends BaseElement {\n static properties = {\n open: { type: Boolean, reflect: true, default: false },\n trigger: { type: String, reflect: true, default: 'click' },\n placement: { type: String, reflect: true, default: 'bottom' },\n offset: { type: Number, reflect: true, default: 8 },\n arrow: { type: Boolean, reflect: true, default: true },\n };\n\n declare open: boolean;\n declare trigger: PopoverTrigger;\n declare placement: PopoverPlacement;\n declare offset: number;\n declare arrow: boolean;\n\n private _boundHandleClickOutside: (e: MouseEvent) => void;\n private _boundHandleKeyDown: (e: KeyboardEvent) => void;\n private _boundHandleScroll: () => void;\n private _boundUpdatePosition: () => void;\n private _hoverTimeout: number | null = null;\n private _currentPlacement: PopoverPlacement = 'bottom';\n\n constructor() {\n super();\n this.attachStyles(styles);\n this._boundHandleClickOutside = this._handleClickOutside.bind(this);\n this._boundHandleKeyDown = this._handleKeyDown.bind(this);\n this._boundHandleScroll = this._handleScroll.bind(this);\n this._boundUpdatePosition = this._updatePosition.bind(this);\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n this._setupTriggerListeners();\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback?.();\n this._removeTriggerListeners();\n this._removeGlobalListeners();\n }\n\n /**\n * Show the popover\n */\n show(): void {\n if (this.open) return;\n this.open = true;\n this._currentPlacement = this.placement;\n this._addGlobalListeners();\n this._updatePosition();\n this._setVisible(true);\n this.emit('open');\n }\n\n /**\n * Hide the popover\n */\n hide(): void {\n if (!this.open) return;\n this.open = false;\n this._removeGlobalListeners();\n this._setVisible(false);\n this.emit('close');\n }\n\n /**\n * Toggle the popover visibility\n */\n toggle(): void {\n if (this.open) {\n this.hide();\n } else {\n this.show();\n }\n }\n\n private _setVisible(visible: boolean): void {\n const panel = this.shadowRoot?.querySelector('.popover-panel');\n if (panel) {\n panel.classList.toggle('visible', visible);\n }\n }\n\n private _setupTriggerListeners(): void {\n const triggerSlot = this.shadowRoot?.querySelector(\n 'slot[name=\"trigger\"]',\n ) as HTMLSlotElement | null;\n\n if (!triggerSlot) return;\n\n triggerSlot.addEventListener('slotchange', () => {\n this._attachTriggerEvents();\n });\n\n // Initial attachment\n this._attachTriggerEvents();\n }\n\n private _attachTriggerEvents(): void {\n const triggerEl = this._getTriggerElement();\n if (!triggerEl) return;\n\n // Remove any existing listeners first\n this._detachTriggerEvents(triggerEl);\n\n if (this.trigger === 'click') {\n triggerEl.addEventListener('click', this._handleTriggerClick);\n } else if (this.trigger === 'hover') {\n triggerEl.addEventListener('mouseenter', this._handleTriggerMouseEnter);\n triggerEl.addEventListener('mouseleave', this._handleTriggerMouseLeave);\n // Also track hover on the popover panel\n this.addEventListener('mouseenter', this._handlePopoverMouseEnter);\n this.addEventListener('mouseleave', this._handlePopoverMouseLeave);\n } else if (this.trigger === 'focus') {\n triggerEl.addEventListener('focusin', this._handleTriggerFocus);\n triggerEl.addEventListener('focusout', this._handleTriggerBlur);\n }\n }\n\n private _detachTriggerEvents(triggerEl: Element): void {\n triggerEl.removeEventListener('click', this._handleTriggerClick);\n triggerEl.removeEventListener('mouseenter', this._handleTriggerMouseEnter);\n triggerEl.removeEventListener('mouseleave', this._handleTriggerMouseLeave);\n triggerEl.removeEventListener('focusin', this._handleTriggerFocus);\n triggerEl.removeEventListener('focusout', this._handleTriggerBlur);\n this.removeEventListener('mouseenter', this._handlePopoverMouseEnter);\n this.removeEventListener('mouseleave', this._handlePopoverMouseLeave);\n }\n\n private _removeTriggerListeners(): void {\n const triggerEl = this._getTriggerElement();\n if (triggerEl) {\n this._detachTriggerEvents(triggerEl);\n }\n }\n\n private _getTriggerElement(): Element | null {\n const triggerSlot = this.shadowRoot?.querySelector(\n 'slot[name=\"trigger\"]',\n ) as HTMLSlotElement | null;\n if (!triggerSlot) return null;\n const assigned = triggerSlot.assignedElements();\n return assigned[0] || null;\n }\n\n private _handleTriggerClick = (): void => {\n this.toggle();\n };\n\n private _handleTriggerMouseEnter = (): void => {\n if (this._hoverTimeout) {\n clearTimeout(this._hoverTimeout);\n this._hoverTimeout = null;\n }\n this.show();\n };\n\n private _handleTriggerMouseLeave = (): void => {\n this._hoverTimeout = window.setTimeout(() => {\n this.hide();\n }, 100);\n };\n\n private _handlePopoverMouseEnter = (): void => {\n if (this._hoverTimeout) {\n clearTimeout(this._hoverTimeout);\n this._hoverTimeout = null;\n }\n };\n\n private _handlePopoverMouseLeave = (): void => {\n this._hoverTimeout = window.setTimeout(() => {\n this.hide();\n }, 100);\n };\n\n private _handleTriggerFocus = (): void => {\n this.show();\n };\n\n private _handleTriggerBlur = (): void => {\n // Delay to allow focus to move to popover content\n setTimeout(() => {\n if (!this.contains(document.activeElement)) {\n this.hide();\n }\n }, 0);\n };\n\n private _addGlobalListeners(): void {\n document.addEventListener('click', this._boundHandleClickOutside, true);\n document.addEventListener('keydown', this._boundHandleKeyDown);\n window.addEventListener('scroll', this._boundHandleScroll, true);\n window.addEventListener('resize', this._boundUpdatePosition);\n }\n\n private _removeGlobalListeners(): void {\n document.removeEventListener('click', this._boundHandleClickOutside, true);\n document.removeEventListener('keydown', this._boundHandleKeyDown);\n window.removeEventListener('scroll', this._boundHandleScroll, true);\n window.removeEventListener('resize', this._boundUpdatePosition);\n }\n\n private _handleClickOutside(e: MouseEvent): void {\n if (this.trigger !== 'click') return;\n\n const path = e.composedPath();\n if (!path.includes(this)) {\n this.hide();\n }\n }\n\n private _handleKeyDown(e: KeyboardEvent): void {\n if (e.key === 'Escape') {\n this.hide();\n // Return focus to trigger element\n const triggerEl = this._getTriggerElement() as HTMLElement | null;\n triggerEl?.focus?.();\n }\n }\n\n private _handleScroll(): void {\n if (this.open) {\n this._updatePosition();\n }\n }\n\n private _updatePosition(): void {\n const triggerEl = this._getTriggerElement();\n const panel = this.shadowRoot?.querySelector('.popover-panel') as HTMLElement | null;\n\n if (!triggerEl || !panel) return;\n\n const triggerRect = triggerEl.getBoundingClientRect();\n const panelRect = panel.getBoundingClientRect();\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n\n // Determine the best placement with auto-flip\n const effectivePlacement = this._getEffectivePlacement(\n triggerRect,\n panelRect,\n viewportWidth,\n viewportHeight,\n );\n\n this._currentPlacement = effectivePlacement;\n\n // Calculate position based on placement\n const position = this._calculatePosition(triggerRect, panelRect, effectivePlacement);\n\n // Apply position\n panel.style.left = `${position.x}px`;\n panel.style.top = `${position.y}px`;\n panel.setAttribute('data-placement', effectivePlacement);\n }\n\n private _getEffectivePlacement(\n triggerRect: DOMRect,\n panelRect: DOMRect,\n viewportWidth: number,\n viewportHeight: number,\n ): PopoverPlacement {\n const [mainAxis, alignment] = this.placement.split('-') as [\n 'top' | 'bottom' | 'left' | 'right',\n 'start' | 'end' | undefined,\n ];\n\n // Check if there's enough space in the preferred direction\n const spaceTop = triggerRect.top;\n const spaceBottom = viewportHeight - triggerRect.bottom;\n const spaceLeft = triggerRect.left;\n const spaceRight = viewportWidth - triggerRect.right;\n\n let effectiveMainAxis = mainAxis;\n\n // Flip main axis if needed\n if (mainAxis === 'top' && spaceTop < panelRect.height + this.offset) {\n if (spaceBottom >= panelRect.height + this.offset) {\n effectiveMainAxis = 'bottom';\n }\n } else if (mainAxis === 'bottom' && spaceBottom < panelRect.height + this.offset) {\n if (spaceTop >= panelRect.height + this.offset) {\n effectiveMainAxis = 'top';\n }\n } else if (mainAxis === 'left' && spaceLeft < panelRect.width + this.offset) {\n if (spaceRight >= panelRect.width + this.offset) {\n effectiveMainAxis = 'right';\n }\n } else if (mainAxis === 'right' && spaceRight < panelRect.width + this.offset) {\n if (spaceLeft >= panelRect.width + this.offset) {\n effectiveMainAxis = 'left';\n }\n }\n\n return alignment\n ? (`${effectiveMainAxis}-${alignment}` as PopoverPlacement)\n : effectiveMainAxis;\n }\n\n private _calculatePosition(\n triggerRect: DOMRect,\n panelRect: DOMRect,\n placement: PopoverPlacement,\n ): { x: number; y: number } {\n const [mainAxis, alignment] = placement.split('-') as [\n 'top' | 'bottom' | 'left' | 'right',\n 'start' | 'end' | undefined,\n ];\n\n let x = 0;\n let y = 0;\n\n // Calculate main axis position\n switch (mainAxis) {\n case 'top':\n y = triggerRect.top - panelRect.height - this.offset;\n break;\n case 'bottom':\n y = triggerRect.bottom + this.offset;\n break;\n case 'left':\n x = triggerRect.left - panelRect.width - this.offset;\n break;\n case 'right':\n x = triggerRect.right + this.offset;\n break;\n }\n\n // Calculate cross axis position based on alignment\n if (mainAxis === 'top' || mainAxis === 'bottom') {\n switch (alignment) {\n case 'start':\n x = triggerRect.left;\n break;\n case 'end':\n x = triggerRect.right - panelRect.width;\n break;\n default:\n x = triggerRect.left + (triggerRect.width - panelRect.width) / 2;\n }\n } else {\n switch (alignment) {\n case 'start':\n y = triggerRect.top;\n break;\n case 'end':\n y = triggerRect.bottom - panelRect.height;\n break;\n default:\n y = triggerRect.top + (triggerRect.height - panelRect.height) / 2;\n }\n }\n\n // Constrain to viewport\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n const padding = 8;\n\n x = Math.max(padding, Math.min(x, viewportWidth - panelRect.width - padding));\n y = Math.max(padding, Math.min(y, viewportHeight - panelRect.height - padding));\n\n return { x, y };\n }\n\n update(): void {\n super.update();\n if (this.open) {\n // Defer position update to allow DOM to render\n requestAnimationFrame(() => {\n this._updatePosition();\n this._setVisible(true);\n });\n }\n }\n\n render(): string {\n return `\n <div class=\"popover-trigger\">\n <slot name=\"trigger\"></slot>\n </div>\n <div\n class=\"popover-panel\"\n part=\"popover\"\n role=\"dialog\"\n aria-modal=\"false\"\n data-placement=\"${this.placement}\"\n >\n ${this.arrow ? '<div class=\"popover-arrow\" part=\"arrow\"></div>' : ''}\n <div class=\"popover-content\" part=\"content\">\n <slot></slot>\n </div>\n </div>\n `;\n }\n}\n",
|
|
5
|
+
"/**\n * DuskMoon Popover Element\n *\n * A contextual overlay/popup component that appears relative to a trigger element.\n * Supports multiple trigger modes, placements, and auto-flip when near viewport edges.\n *\n * @element el-dm-popover\n *\n * @attr {boolean} open - Whether the popover is visible\n * @attr {string} trigger - Trigger mode: click, hover, focus, manual\n * @attr {string} placement - Popover position relative to trigger\n * @attr {number} offset - Distance from trigger element in pixels\n * @attr {boolean} arrow - Whether to show arrow pointing to trigger\n *\n * @slot trigger - The element that triggers the popover\n * @slot - Default slot for popover content\n *\n * @fires open - Fired when popover opens\n * @fires close - Fired when popover closes\n *\n * @csspart popover - The popover container\n * @csspart content - The popover content area\n * @csspart arrow - The popover arrow\n */\n\nimport { BaseElement, css, animationStyles } from '@duskmoon-dev/el-base';\nimport { css as popoverCSS } from '@duskmoon-dev/core/components/popover';\n\nexport type PopoverPlacement =\n | 'top'\n | 'top-start'\n | 'top-end'\n | 'bottom'\n | 'bottom-start'\n | 'bottom-end'\n | 'left'\n | 'left-start'\n | 'left-end'\n | 'right'\n | 'right-start'\n | 'right-end';\n\nexport type PopoverTrigger = 'click' | 'hover' | 'focus' | 'manual';\n\n// Strip @layer wrapper for Shadow DOM compatibility\nconst coreStyles = popoverCSS.replace(/@layer\\s+components\\s*\\{/, '').replace(/\\}\\s*$/, '');\n\nconst styles = css`\n :host {\n display: inline-block;\n position: relative;\n }\n\n :host([hidden]) {\n display: none !important;\n }\n\n /* Import core popover styles */\n ${coreStyles}\n\n .popover-trigger {\n display: inline-flex;\n }\n\n /* Override core's position: absolute for JS-based positioning */\n .popover-content {\n position: fixed;\n min-width: 8rem;\n pointer-events: none;\n font-family: inherit;\n }\n\n .popover-content.show {\n pointer-events: auto;\n }\n\n /* Arrow positioning based on popover placement (data-attribute based) */\n .popover-content[data-placement^='top'] .popover-arrow {\n bottom: -0.4375rem;\n border-top: none;\n border-left: none;\n }\n\n .popover-content[data-placement^='bottom'] .popover-arrow {\n top: -0.4375rem;\n border-bottom: none;\n border-right: none;\n }\n\n .popover-content[data-placement^='left'] .popover-arrow {\n right: -0.4375rem;\n border-top: none;\n border-left: none;\n }\n\n .popover-content[data-placement^='right'] .popover-arrow {\n left: -0.4375rem;\n border-bottom: none;\n border-right: none;\n }\n\n /* Center aligned arrows */\n .popover-content[data-placement='top'] .popover-arrow,\n .popover-content[data-placement='bottom'] .popover-arrow {\n left: 50%;\n transform: translateX(-50%) rotate(45deg);\n }\n\n .popover-content[data-placement='left'] .popover-arrow,\n .popover-content[data-placement='right'] .popover-arrow {\n top: 50%;\n transform: translateY(-50%) rotate(45deg);\n }\n\n /* Start aligned arrows */\n .popover-content[data-placement='top-start'] .popover-arrow,\n .popover-content[data-placement='bottom-start'] .popover-arrow {\n left: 1rem;\n }\n\n .popover-content[data-placement='left-start'] .popover-arrow,\n .popover-content[data-placement='right-start'] .popover-arrow {\n top: 1rem;\n }\n\n /* End aligned arrows */\n .popover-content[data-placement='top-end'] .popover-arrow,\n .popover-content[data-placement='bottom-end'] .popover-arrow {\n right: 1rem;\n left: auto;\n }\n\n .popover-content[data-placement='left-end'] .popover-arrow,\n .popover-content[data-placement='right-end'] .popover-arrow {\n bottom: 1rem;\n top: auto;\n }\n`;\n\nexport class ElDmPopover extends BaseElement {\n static properties = {\n open: { type: Boolean, reflect: true, default: false },\n trigger: { type: String, reflect: true, default: 'click' },\n placement: { type: String, reflect: true, default: 'bottom' },\n offset: { type: Number, reflect: true, default: 8 },\n arrow: { type: Boolean, reflect: true, default: true },\n };\n\n declare open: boolean;\n declare trigger: PopoverTrigger;\n declare placement: PopoverPlacement;\n declare offset: number;\n declare arrow: boolean;\n\n private _boundHandleClickOutside: (e: MouseEvent) => void;\n private _boundHandleKeyDown: (e: KeyboardEvent) => void;\n private _boundHandleScroll: () => void;\n private _boundUpdatePosition: () => void;\n private _hoverTimeout: number | null = null;\n private _currentPlacement: PopoverPlacement = 'bottom';\n\n constructor() {\n super();\n this.attachStyles([styles, animationStyles]);\n this._boundHandleClickOutside = this._handleClickOutside.bind(this);\n this._boundHandleKeyDown = this._handleKeyDown.bind(this);\n this._boundHandleScroll = this._handleScroll.bind(this);\n this._boundUpdatePosition = this._updatePosition.bind(this);\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n this._setupTriggerListeners();\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback?.();\n this._removeTriggerListeners();\n this._removeGlobalListeners();\n }\n\n /**\n * Show the popover\n */\n show(): void {\n if (this.open) return;\n this.open = true;\n this._currentPlacement = this.placement;\n this._addGlobalListeners();\n this._updatePosition();\n this._setVisible(true);\n this.emit('open');\n }\n\n /**\n * Hide the popover\n */\n hide(): void {\n if (!this.open) return;\n this.open = false;\n this._removeGlobalListeners();\n this._setVisible(false);\n this.emit('close');\n }\n\n /**\n * Toggle the popover visibility\n */\n toggle(): void {\n if (this.open) {\n this.hide();\n } else {\n this.show();\n }\n }\n\n private _setVisible(visible: boolean): void {\n const panel = this.shadowRoot?.querySelector('.popover-content');\n if (panel) {\n panel.classList.toggle('show', visible);\n }\n }\n\n private _setupTriggerListeners(): void {\n const triggerSlot = this.shadowRoot?.querySelector(\n 'slot[name=\"trigger\"]',\n ) as HTMLSlotElement | null;\n\n if (!triggerSlot) return;\n\n triggerSlot.addEventListener('slotchange', () => {\n this._attachTriggerEvents();\n });\n\n // Initial attachment\n this._attachTriggerEvents();\n }\n\n private _attachTriggerEvents(): void {\n const triggerEl = this._getTriggerElement();\n if (!triggerEl) return;\n\n // Remove any existing listeners first\n this._detachTriggerEvents(triggerEl);\n\n if (this.trigger === 'click') {\n triggerEl.addEventListener('click', this._handleTriggerClick);\n } else if (this.trigger === 'hover') {\n triggerEl.addEventListener('mouseenter', this._handleTriggerMouseEnter);\n triggerEl.addEventListener('mouseleave', this._handleTriggerMouseLeave);\n // Also track hover on the popover panel\n this.addEventListener('mouseenter', this._handlePopoverMouseEnter);\n this.addEventListener('mouseleave', this._handlePopoverMouseLeave);\n } else if (this.trigger === 'focus') {\n triggerEl.addEventListener('focusin', this._handleTriggerFocus);\n triggerEl.addEventListener('focusout', this._handleTriggerBlur);\n }\n }\n\n private _detachTriggerEvents(triggerEl: Element): void {\n triggerEl.removeEventListener('click', this._handleTriggerClick);\n triggerEl.removeEventListener('mouseenter', this._handleTriggerMouseEnter);\n triggerEl.removeEventListener('mouseleave', this._handleTriggerMouseLeave);\n triggerEl.removeEventListener('focusin', this._handleTriggerFocus);\n triggerEl.removeEventListener('focusout', this._handleTriggerBlur);\n this.removeEventListener('mouseenter', this._handlePopoverMouseEnter);\n this.removeEventListener('mouseleave', this._handlePopoverMouseLeave);\n }\n\n private _removeTriggerListeners(): void {\n const triggerEl = this._getTriggerElement();\n if (triggerEl) {\n this._detachTriggerEvents(triggerEl);\n }\n }\n\n private _getTriggerElement(): Element | null {\n const triggerSlot = this.shadowRoot?.querySelector(\n 'slot[name=\"trigger\"]',\n ) as HTMLSlotElement | null;\n if (!triggerSlot) return null;\n const assigned = triggerSlot.assignedElements();\n return assigned[0] || null;\n }\n\n private _handleTriggerClick = (): void => {\n this.toggle();\n };\n\n private _handleTriggerMouseEnter = (): void => {\n if (this._hoverTimeout) {\n clearTimeout(this._hoverTimeout);\n this._hoverTimeout = null;\n }\n this.show();\n };\n\n private _handleTriggerMouseLeave = (): void => {\n this._hoverTimeout = window.setTimeout(() => {\n this.hide();\n }, 100);\n };\n\n private _handlePopoverMouseEnter = (): void => {\n if (this._hoverTimeout) {\n clearTimeout(this._hoverTimeout);\n this._hoverTimeout = null;\n }\n };\n\n private _handlePopoverMouseLeave = (): void => {\n this._hoverTimeout = window.setTimeout(() => {\n this.hide();\n }, 100);\n };\n\n private _handleTriggerFocus = (): void => {\n this.show();\n };\n\n private _handleTriggerBlur = (): void => {\n // Delay to allow focus to move to popover content\n setTimeout(() => {\n if (!this.contains(document.activeElement)) {\n this.hide();\n }\n }, 0);\n };\n\n private _addGlobalListeners(): void {\n document.addEventListener('click', this._boundHandleClickOutside, true);\n document.addEventListener('keydown', this._boundHandleKeyDown);\n window.addEventListener('scroll', this._boundHandleScroll, true);\n window.addEventListener('resize', this._boundUpdatePosition);\n }\n\n private _removeGlobalListeners(): void {\n document.removeEventListener('click', this._boundHandleClickOutside, true);\n document.removeEventListener('keydown', this._boundHandleKeyDown);\n window.removeEventListener('scroll', this._boundHandleScroll, true);\n window.removeEventListener('resize', this._boundUpdatePosition);\n }\n\n private _handleClickOutside(e: MouseEvent): void {\n if (this.trigger !== 'click') return;\n\n const path = e.composedPath();\n if (!path.includes(this)) {\n this.hide();\n }\n }\n\n private _handleKeyDown(e: KeyboardEvent): void {\n if (e.key === 'Escape') {\n this.hide();\n // Return focus to trigger element\n const triggerEl = this._getTriggerElement() as HTMLElement | null;\n triggerEl?.focus?.();\n }\n }\n\n private _handleScroll(): void {\n if (this.open) {\n this._updatePosition();\n }\n }\n\n private _updatePosition(): void {\n const triggerEl = this._getTriggerElement();\n const panel = this.shadowRoot?.querySelector('.popover-content') as HTMLElement | null;\n\n if (!triggerEl || !panel) return;\n\n const triggerRect = triggerEl.getBoundingClientRect();\n const panelRect = panel.getBoundingClientRect();\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n\n // Determine the best placement with auto-flip\n const effectivePlacement = this._getEffectivePlacement(\n triggerRect,\n panelRect,\n viewportWidth,\n viewportHeight,\n );\n\n this._currentPlacement = effectivePlacement;\n\n // Calculate position based on placement\n const position = this._calculatePosition(triggerRect, panelRect, effectivePlacement);\n\n // Apply position\n panel.style.left = `${position.x}px`;\n panel.style.top = `${position.y}px`;\n panel.setAttribute('data-placement', effectivePlacement);\n }\n\n private _getEffectivePlacement(\n triggerRect: DOMRect,\n panelRect: DOMRect,\n viewportWidth: number,\n viewportHeight: number,\n ): PopoverPlacement {\n const [mainAxis, alignment] = this.placement.split('-') as [\n 'top' | 'bottom' | 'left' | 'right',\n 'start' | 'end' | undefined,\n ];\n\n // Check if there's enough space in the preferred direction\n const spaceTop = triggerRect.top;\n const spaceBottom = viewportHeight - triggerRect.bottom;\n const spaceLeft = triggerRect.left;\n const spaceRight = viewportWidth - triggerRect.right;\n\n let effectiveMainAxis = mainAxis;\n\n // Flip main axis if needed\n if (mainAxis === 'top' && spaceTop < panelRect.height + this.offset) {\n if (spaceBottom >= panelRect.height + this.offset) {\n effectiveMainAxis = 'bottom';\n }\n } else if (mainAxis === 'bottom' && spaceBottom < panelRect.height + this.offset) {\n if (spaceTop >= panelRect.height + this.offset) {\n effectiveMainAxis = 'top';\n }\n } else if (mainAxis === 'left' && spaceLeft < panelRect.width + this.offset) {\n if (spaceRight >= panelRect.width + this.offset) {\n effectiveMainAxis = 'right';\n }\n } else if (mainAxis === 'right' && spaceRight < panelRect.width + this.offset) {\n if (spaceLeft >= panelRect.width + this.offset) {\n effectiveMainAxis = 'left';\n }\n }\n\n return alignment\n ? (`${effectiveMainAxis}-${alignment}` as PopoverPlacement)\n : effectiveMainAxis;\n }\n\n private _calculatePosition(\n triggerRect: DOMRect,\n panelRect: DOMRect,\n placement: PopoverPlacement,\n ): { x: number; y: number } {\n const [mainAxis, alignment] = placement.split('-') as [\n 'top' | 'bottom' | 'left' | 'right',\n 'start' | 'end' | undefined,\n ];\n\n let x = 0;\n let y = 0;\n\n // Calculate main axis position\n switch (mainAxis) {\n case 'top':\n y = triggerRect.top - panelRect.height - this.offset;\n break;\n case 'bottom':\n y = triggerRect.bottom + this.offset;\n break;\n case 'left':\n x = triggerRect.left - panelRect.width - this.offset;\n break;\n case 'right':\n x = triggerRect.right + this.offset;\n break;\n }\n\n // Calculate cross axis position based on alignment\n if (mainAxis === 'top' || mainAxis === 'bottom') {\n switch (alignment) {\n case 'start':\n x = triggerRect.left;\n break;\n case 'end':\n x = triggerRect.right - panelRect.width;\n break;\n default:\n x = triggerRect.left + (triggerRect.width - panelRect.width) / 2;\n }\n } else {\n switch (alignment) {\n case 'start':\n y = triggerRect.top;\n break;\n case 'end':\n y = triggerRect.bottom - panelRect.height;\n break;\n default:\n y = triggerRect.top + (triggerRect.height - panelRect.height) / 2;\n }\n }\n\n // Constrain to viewport\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n const padding = 8;\n\n x = Math.max(padding, Math.min(x, viewportWidth - panelRect.width - padding));\n y = Math.max(padding, Math.min(y, viewportHeight - panelRect.height - padding));\n\n return { x, y };\n }\n\n update(): void {\n super.update();\n if (this.open) {\n // Defer position update to allow DOM to render\n requestAnimationFrame(() => {\n this._updatePosition();\n this._setVisible(true);\n });\n }\n }\n\n render(): string {\n return `\n <div class=\"popover-trigger\">\n <slot name=\"trigger\"></slot>\n </div>\n <div\n class=\"popover-content\"\n part=\"popover\"\n role=\"dialog\"\n aria-modal=\"false\"\n data-placement=\"${this.placement}\"\n >\n ${this.arrow ? '<div class=\"popover-arrow\" part=\"arrow\"></div>' : ''}\n <div class=\"popover-body\" part=\"content\">\n <slot></slot>\n </div>\n </div>\n `;\n }\n}\n",
|
|
6
6
|
"/**\n * @duskmoon-dev/el-popover\n *\n * DuskMoon Popover custom element\n */\n\nimport { ElDmPopover } from './el-dm-popover.js';\n\nexport { ElDmPopover };\nexport type { PopoverPlacement, PopoverTrigger } from './el-dm-popover.js';\n\n/**\n * Register the el-dm-popover custom element\n *\n * @example\n * ```ts\n * import { register } from '@duskmoon-dev/el-popover';\n * register();\n * ```\n */\nexport function register(): void {\n if (!customElements.get('el-dm-popover')) {\n customElements.define('el-dm-popover', ElDmPopover);\n }\n}\n"
|
|
7
7
|
],
|
|
8
|
-
"mappings": ";AAyBA;
|
|
9
|
-
"debugId": "
|
|
8
|
+
"mappings": "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",
|
|
9
|
+
"debugId": "4D5B24EDB0D56D8064756E2164756E21",
|
|
10
10
|
"names": []
|
|
11
11
|
}
|
package/dist/esm/register.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
// src/el-dm-popover.ts
|
|
2
|
-
import { BaseElement, css } from "@duskmoon-dev/el-
|
|
2
|
+
import { BaseElement, css, animationStyles } from "@duskmoon-dev/el-base";
|
|
3
|
+
import { css as popoverCSS } from "@duskmoon-dev/core/components/popover";
|
|
4
|
+
var coreStyles = popoverCSS.replace(/@layer\s+components\s*\{/, "").replace(/\}\s*$/, "");
|
|
3
5
|
var styles = css`
|
|
4
6
|
:host {
|
|
5
7
|
display: inline-block;
|
|
@@ -10,116 +12,86 @@ var styles = css`
|
|
|
10
12
|
display: none !important;
|
|
11
13
|
}
|
|
12
14
|
|
|
15
|
+
/* Import core popover styles */
|
|
16
|
+
${coreStyles}
|
|
17
|
+
|
|
13
18
|
.popover-trigger {
|
|
14
19
|
display: inline-flex;
|
|
15
20
|
}
|
|
16
21
|
|
|
17
|
-
|
|
22
|
+
/* Override core's position: absolute for JS-based positioning */
|
|
23
|
+
.popover-content {
|
|
18
24
|
position: fixed;
|
|
19
|
-
z-index: 1000;
|
|
20
25
|
min-width: 8rem;
|
|
21
|
-
max-width: 20rem;
|
|
22
|
-
padding: 0.75rem 1rem;
|
|
23
|
-
background-color: var(--color-surface, #ffffff);
|
|
24
|
-
border: 1px solid var(--color-outline, #e0e0e0);
|
|
25
|
-
border-radius: 0.5rem;
|
|
26
|
-
box-shadow:
|
|
27
|
-
0 4px 6px -1px rgb(0 0 0 / 0.1),
|
|
28
|
-
0 2px 4px -2px rgb(0 0 0 / 0.1);
|
|
29
|
-
opacity: 0;
|
|
30
|
-
visibility: hidden;
|
|
31
|
-
transform: scale(0.95);
|
|
32
|
-
transition:
|
|
33
|
-
opacity 150ms ease,
|
|
34
|
-
visibility 150ms ease,
|
|
35
|
-
transform 150ms ease;
|
|
36
26
|
pointer-events: none;
|
|
37
27
|
font-family: inherit;
|
|
38
28
|
}
|
|
39
29
|
|
|
40
|
-
.popover-
|
|
41
|
-
opacity: 1;
|
|
42
|
-
visibility: visible;
|
|
43
|
-
transform: scale(1);
|
|
30
|
+
.popover-content.show {
|
|
44
31
|
pointer-events: auto;
|
|
45
32
|
}
|
|
46
33
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
width: 0.75rem;
|
|
50
|
-
height: 0.75rem;
|
|
51
|
-
background-color: var(--color-surface, #ffffff);
|
|
52
|
-
border: 1px solid var(--color-outline, #e0e0e0);
|
|
53
|
-
transform: rotate(45deg);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/* Arrow positioning based on popover placement */
|
|
57
|
-
.popover-panel[data-placement^='top'] .popover-arrow {
|
|
34
|
+
/* Arrow positioning based on popover placement (data-attribute based) */
|
|
35
|
+
.popover-content[data-placement^='top'] .popover-arrow {
|
|
58
36
|
bottom: -0.4375rem;
|
|
59
37
|
border-top: none;
|
|
60
38
|
border-left: none;
|
|
61
39
|
}
|
|
62
40
|
|
|
63
|
-
.popover-
|
|
41
|
+
.popover-content[data-placement^='bottom'] .popover-arrow {
|
|
64
42
|
top: -0.4375rem;
|
|
65
43
|
border-bottom: none;
|
|
66
44
|
border-right: none;
|
|
67
45
|
}
|
|
68
46
|
|
|
69
|
-
.popover-
|
|
47
|
+
.popover-content[data-placement^='left'] .popover-arrow {
|
|
70
48
|
right: -0.4375rem;
|
|
71
49
|
border-top: none;
|
|
72
50
|
border-left: none;
|
|
73
51
|
}
|
|
74
52
|
|
|
75
|
-
.popover-
|
|
53
|
+
.popover-content[data-placement^='right'] .popover-arrow {
|
|
76
54
|
left: -0.4375rem;
|
|
77
55
|
border-bottom: none;
|
|
78
56
|
border-right: none;
|
|
79
57
|
}
|
|
80
58
|
|
|
81
59
|
/* Center aligned arrows */
|
|
82
|
-
.popover-
|
|
83
|
-
.popover-
|
|
60
|
+
.popover-content[data-placement='top'] .popover-arrow,
|
|
61
|
+
.popover-content[data-placement='bottom'] .popover-arrow {
|
|
84
62
|
left: 50%;
|
|
85
63
|
transform: translateX(-50%) rotate(45deg);
|
|
86
64
|
}
|
|
87
65
|
|
|
88
|
-
.popover-
|
|
89
|
-
.popover-
|
|
66
|
+
.popover-content[data-placement='left'] .popover-arrow,
|
|
67
|
+
.popover-content[data-placement='right'] .popover-arrow {
|
|
90
68
|
top: 50%;
|
|
91
69
|
transform: translateY(-50%) rotate(45deg);
|
|
92
70
|
}
|
|
93
71
|
|
|
94
72
|
/* Start aligned arrows */
|
|
95
|
-
.popover-
|
|
96
|
-
.popover-
|
|
73
|
+
.popover-content[data-placement='top-start'] .popover-arrow,
|
|
74
|
+
.popover-content[data-placement='bottom-start'] .popover-arrow {
|
|
97
75
|
left: 1rem;
|
|
98
76
|
}
|
|
99
77
|
|
|
100
|
-
.popover-
|
|
101
|
-
.popover-
|
|
78
|
+
.popover-content[data-placement='left-start'] .popover-arrow,
|
|
79
|
+
.popover-content[data-placement='right-start'] .popover-arrow {
|
|
102
80
|
top: 1rem;
|
|
103
81
|
}
|
|
104
82
|
|
|
105
83
|
/* End aligned arrows */
|
|
106
|
-
.popover-
|
|
107
|
-
.popover-
|
|
84
|
+
.popover-content[data-placement='top-end'] .popover-arrow,
|
|
85
|
+
.popover-content[data-placement='bottom-end'] .popover-arrow {
|
|
108
86
|
right: 1rem;
|
|
109
87
|
left: auto;
|
|
110
88
|
}
|
|
111
89
|
|
|
112
|
-
.popover-
|
|
113
|
-
.popover-
|
|
90
|
+
.popover-content[data-placement='left-end'] .popover-arrow,
|
|
91
|
+
.popover-content[data-placement='right-end'] .popover-arrow {
|
|
114
92
|
bottom: 1rem;
|
|
115
93
|
top: auto;
|
|
116
94
|
}
|
|
117
|
-
|
|
118
|
-
.popover-content {
|
|
119
|
-
color: var(--color-on-surface, #1f1f1f);
|
|
120
|
-
font-size: 0.875rem;
|
|
121
|
-
line-height: 1.5;
|
|
122
|
-
}
|
|
123
95
|
`;
|
|
124
96
|
|
|
125
97
|
class ElDmPopover extends BaseElement {
|
|
@@ -138,7 +110,7 @@ class ElDmPopover extends BaseElement {
|
|
|
138
110
|
_currentPlacement = "bottom";
|
|
139
111
|
constructor() {
|
|
140
112
|
super();
|
|
141
|
-
this.attachStyles(styles);
|
|
113
|
+
this.attachStyles([styles, animationStyles]);
|
|
142
114
|
this._boundHandleClickOutside = this._handleClickOutside.bind(this);
|
|
143
115
|
this._boundHandleKeyDown = this._handleKeyDown.bind(this);
|
|
144
116
|
this._boundHandleScroll = this._handleScroll.bind(this);
|
|
@@ -179,9 +151,9 @@ class ElDmPopover extends BaseElement {
|
|
|
179
151
|
}
|
|
180
152
|
}
|
|
181
153
|
_setVisible(visible) {
|
|
182
|
-
const panel = this.shadowRoot?.querySelector(".popover-
|
|
154
|
+
const panel = this.shadowRoot?.querySelector(".popover-content");
|
|
183
155
|
if (panel) {
|
|
184
|
-
panel.classList.toggle("
|
|
156
|
+
panel.classList.toggle("show", visible);
|
|
185
157
|
}
|
|
186
158
|
}
|
|
187
159
|
_setupTriggerListeners() {
|
|
@@ -302,7 +274,7 @@ class ElDmPopover extends BaseElement {
|
|
|
302
274
|
}
|
|
303
275
|
_updatePosition() {
|
|
304
276
|
const triggerEl = this._getTriggerElement();
|
|
305
|
-
const panel = this.shadowRoot?.querySelector(".popover-
|
|
277
|
+
const panel = this.shadowRoot?.querySelector(".popover-content");
|
|
306
278
|
if (!triggerEl || !panel)
|
|
307
279
|
return;
|
|
308
280
|
const triggerRect = triggerEl.getBoundingClientRect();
|
|
@@ -405,14 +377,14 @@ class ElDmPopover extends BaseElement {
|
|
|
405
377
|
<slot name="trigger"></slot>
|
|
406
378
|
</div>
|
|
407
379
|
<div
|
|
408
|
-
class="popover-
|
|
380
|
+
class="popover-content"
|
|
409
381
|
part="popover"
|
|
410
382
|
role="dialog"
|
|
411
383
|
aria-modal="false"
|
|
412
384
|
data-placement="${this.placement}"
|
|
413
385
|
>
|
|
414
386
|
${this.arrow ? '<div class="popover-arrow" part="arrow"></div>' : ""}
|
|
415
|
-
<div class="popover-
|
|
387
|
+
<div class="popover-body" part="content">
|
|
416
388
|
<slot></slot>
|
|
417
389
|
</div>
|
|
418
390
|
</div>
|
|
@@ -430,5 +402,5 @@ function register() {
|
|
|
430
402
|
// src/register.ts
|
|
431
403
|
register();
|
|
432
404
|
|
|
433
|
-
//# debugId=
|
|
405
|
+
//# debugId=421734A82AD65F9964756E2164756E21
|
|
434
406
|
//# sourceMappingURL=register.js.map
|
package/dist/esm/register.js.map
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/el-dm-popover.ts", "../../src/index.ts", "../../src/register.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"/**\n * DuskMoon Popover Element\n *\n * A contextual overlay/popup component that appears relative to a trigger element.\n * Supports multiple trigger modes, placements, and auto-flip when near viewport edges.\n *\n * @element el-dm-popover\n *\n * @attr {boolean} open - Whether the popover is visible\n * @attr {string} trigger - Trigger mode: click, hover, focus, manual\n * @attr {string} placement - Popover position relative to trigger\n * @attr {number} offset - Distance from trigger element in pixels\n * @attr {boolean} arrow - Whether to show arrow pointing to trigger\n *\n * @slot trigger - The element that triggers the popover\n * @slot - Default slot for popover content\n *\n * @fires open - Fired when popover opens\n * @fires close - Fired when popover closes\n *\n * @csspart popover - The popover container\n * @csspart content - The popover content area\n * @csspart arrow - The popover arrow\n */\n\nimport { BaseElement, css } from '@duskmoon-dev/el-core';\n\nexport type PopoverPlacement =\n | 'top'\n | 'top-start'\n | 'top-end'\n | 'bottom'\n | 'bottom-start'\n | 'bottom-end'\n | 'left'\n | 'left-start'\n | 'left-end'\n | 'right'\n | 'right-start'\n | 'right-end';\n\nexport type PopoverTrigger = 'click' | 'hover' | 'focus' | 'manual';\n\nconst styles = css`\n :host {\n display: inline-block;\n position: relative;\n }\n\n :host([hidden]) {\n display: none !important;\n }\n\n .popover-trigger {\n display: inline-flex;\n }\n\n .popover-panel {\n position: fixed;\n z-index: 1000;\n min-width: 8rem;\n max-width: 20rem;\n padding: 0.75rem 1rem;\n background-color: var(--color-surface, #ffffff);\n border: 1px solid var(--color-outline, #e0e0e0);\n border-radius: 0.5rem;\n box-shadow:\n 0 4px 6px -1px rgb(0 0 0 / 0.1),\n 0 2px 4px -2px rgb(0 0 0 / 0.1);\n opacity: 0;\n visibility: hidden;\n transform: scale(0.95);\n transition:\n opacity 150ms ease,\n visibility 150ms ease,\n transform 150ms ease;\n pointer-events: none;\n font-family: inherit;\n }\n\n .popover-panel.visible {\n opacity: 1;\n visibility: visible;\n transform: scale(1);\n pointer-events: auto;\n }\n\n .popover-arrow {\n position: absolute;\n width: 0.75rem;\n height: 0.75rem;\n background-color: var(--color-surface, #ffffff);\n border: 1px solid var(--color-outline, #e0e0e0);\n transform: rotate(45deg);\n }\n\n /* Arrow positioning based on popover placement */\n .popover-panel[data-placement^='top'] .popover-arrow {\n bottom: -0.4375rem;\n border-top: none;\n border-left: none;\n }\n\n .popover-panel[data-placement^='bottom'] .popover-arrow {\n top: -0.4375rem;\n border-bottom: none;\n border-right: none;\n }\n\n .popover-panel[data-placement^='left'] .popover-arrow {\n right: -0.4375rem;\n border-top: none;\n border-left: none;\n }\n\n .popover-panel[data-placement^='right'] .popover-arrow {\n left: -0.4375rem;\n border-bottom: none;\n border-right: none;\n }\n\n /* Center aligned arrows */\n .popover-panel[data-placement='top'] .popover-arrow,\n .popover-panel[data-placement='bottom'] .popover-arrow {\n left: 50%;\n transform: translateX(-50%) rotate(45deg);\n }\n\n .popover-panel[data-placement='left'] .popover-arrow,\n .popover-panel[data-placement='right'] .popover-arrow {\n top: 50%;\n transform: translateY(-50%) rotate(45deg);\n }\n\n /* Start aligned arrows */\n .popover-panel[data-placement='top-start'] .popover-arrow,\n .popover-panel[data-placement='bottom-start'] .popover-arrow {\n left: 1rem;\n }\n\n .popover-panel[data-placement='left-start'] .popover-arrow,\n .popover-panel[data-placement='right-start'] .popover-arrow {\n top: 1rem;\n }\n\n /* End aligned arrows */\n .popover-panel[data-placement='top-end'] .popover-arrow,\n .popover-panel[data-placement='bottom-end'] .popover-arrow {\n right: 1rem;\n left: auto;\n }\n\n .popover-panel[data-placement='left-end'] .popover-arrow,\n .popover-panel[data-placement='right-end'] .popover-arrow {\n bottom: 1rem;\n top: auto;\n }\n\n .popover-content {\n color: var(--color-on-surface, #1f1f1f);\n font-size: 0.875rem;\n line-height: 1.5;\n }\n`;\n\nexport class ElDmPopover extends BaseElement {\n static properties = {\n open: { type: Boolean, reflect: true, default: false },\n trigger: { type: String, reflect: true, default: 'click' },\n placement: { type: String, reflect: true, default: 'bottom' },\n offset: { type: Number, reflect: true, default: 8 },\n arrow: { type: Boolean, reflect: true, default: true },\n };\n\n declare open: boolean;\n declare trigger: PopoverTrigger;\n declare placement: PopoverPlacement;\n declare offset: number;\n declare arrow: boolean;\n\n private _boundHandleClickOutside: (e: MouseEvent) => void;\n private _boundHandleKeyDown: (e: KeyboardEvent) => void;\n private _boundHandleScroll: () => void;\n private _boundUpdatePosition: () => void;\n private _hoverTimeout: number | null = null;\n private _currentPlacement: PopoverPlacement = 'bottom';\n\n constructor() {\n super();\n this.attachStyles(styles);\n this._boundHandleClickOutside = this._handleClickOutside.bind(this);\n this._boundHandleKeyDown = this._handleKeyDown.bind(this);\n this._boundHandleScroll = this._handleScroll.bind(this);\n this._boundUpdatePosition = this._updatePosition.bind(this);\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n this._setupTriggerListeners();\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback?.();\n this._removeTriggerListeners();\n this._removeGlobalListeners();\n }\n\n /**\n * Show the popover\n */\n show(): void {\n if (this.open) return;\n this.open = true;\n this._currentPlacement = this.placement;\n this._addGlobalListeners();\n this._updatePosition();\n this._setVisible(true);\n this.emit('open');\n }\n\n /**\n * Hide the popover\n */\n hide(): void {\n if (!this.open) return;\n this.open = false;\n this._removeGlobalListeners();\n this._setVisible(false);\n this.emit('close');\n }\n\n /**\n * Toggle the popover visibility\n */\n toggle(): void {\n if (this.open) {\n this.hide();\n } else {\n this.show();\n }\n }\n\n private _setVisible(visible: boolean): void {\n const panel = this.shadowRoot?.querySelector('.popover-panel');\n if (panel) {\n panel.classList.toggle('visible', visible);\n }\n }\n\n private _setupTriggerListeners(): void {\n const triggerSlot = this.shadowRoot?.querySelector(\n 'slot[name=\"trigger\"]',\n ) as HTMLSlotElement | null;\n\n if (!triggerSlot) return;\n\n triggerSlot.addEventListener('slotchange', () => {\n this._attachTriggerEvents();\n });\n\n // Initial attachment\n this._attachTriggerEvents();\n }\n\n private _attachTriggerEvents(): void {\n const triggerEl = this._getTriggerElement();\n if (!triggerEl) return;\n\n // Remove any existing listeners first\n this._detachTriggerEvents(triggerEl);\n\n if (this.trigger === 'click') {\n triggerEl.addEventListener('click', this._handleTriggerClick);\n } else if (this.trigger === 'hover') {\n triggerEl.addEventListener('mouseenter', this._handleTriggerMouseEnter);\n triggerEl.addEventListener('mouseleave', this._handleTriggerMouseLeave);\n // Also track hover on the popover panel\n this.addEventListener('mouseenter', this._handlePopoverMouseEnter);\n this.addEventListener('mouseleave', this._handlePopoverMouseLeave);\n } else if (this.trigger === 'focus') {\n triggerEl.addEventListener('focusin', this._handleTriggerFocus);\n triggerEl.addEventListener('focusout', this._handleTriggerBlur);\n }\n }\n\n private _detachTriggerEvents(triggerEl: Element): void {\n triggerEl.removeEventListener('click', this._handleTriggerClick);\n triggerEl.removeEventListener('mouseenter', this._handleTriggerMouseEnter);\n triggerEl.removeEventListener('mouseleave', this._handleTriggerMouseLeave);\n triggerEl.removeEventListener('focusin', this._handleTriggerFocus);\n triggerEl.removeEventListener('focusout', this._handleTriggerBlur);\n this.removeEventListener('mouseenter', this._handlePopoverMouseEnter);\n this.removeEventListener('mouseleave', this._handlePopoverMouseLeave);\n }\n\n private _removeTriggerListeners(): void {\n const triggerEl = this._getTriggerElement();\n if (triggerEl) {\n this._detachTriggerEvents(triggerEl);\n }\n }\n\n private _getTriggerElement(): Element | null {\n const triggerSlot = this.shadowRoot?.querySelector(\n 'slot[name=\"trigger\"]',\n ) as HTMLSlotElement | null;\n if (!triggerSlot) return null;\n const assigned = triggerSlot.assignedElements();\n return assigned[0] || null;\n }\n\n private _handleTriggerClick = (): void => {\n this.toggle();\n };\n\n private _handleTriggerMouseEnter = (): void => {\n if (this._hoverTimeout) {\n clearTimeout(this._hoverTimeout);\n this._hoverTimeout = null;\n }\n this.show();\n };\n\n private _handleTriggerMouseLeave = (): void => {\n this._hoverTimeout = window.setTimeout(() => {\n this.hide();\n }, 100);\n };\n\n private _handlePopoverMouseEnter = (): void => {\n if (this._hoverTimeout) {\n clearTimeout(this._hoverTimeout);\n this._hoverTimeout = null;\n }\n };\n\n private _handlePopoverMouseLeave = (): void => {\n this._hoverTimeout = window.setTimeout(() => {\n this.hide();\n }, 100);\n };\n\n private _handleTriggerFocus = (): void => {\n this.show();\n };\n\n private _handleTriggerBlur = (): void => {\n // Delay to allow focus to move to popover content\n setTimeout(() => {\n if (!this.contains(document.activeElement)) {\n this.hide();\n }\n }, 0);\n };\n\n private _addGlobalListeners(): void {\n document.addEventListener('click', this._boundHandleClickOutside, true);\n document.addEventListener('keydown', this._boundHandleKeyDown);\n window.addEventListener('scroll', this._boundHandleScroll, true);\n window.addEventListener('resize', this._boundUpdatePosition);\n }\n\n private _removeGlobalListeners(): void {\n document.removeEventListener('click', this._boundHandleClickOutside, true);\n document.removeEventListener('keydown', this._boundHandleKeyDown);\n window.removeEventListener('scroll', this._boundHandleScroll, true);\n window.removeEventListener('resize', this._boundUpdatePosition);\n }\n\n private _handleClickOutside(e: MouseEvent): void {\n if (this.trigger !== 'click') return;\n\n const path = e.composedPath();\n if (!path.includes(this)) {\n this.hide();\n }\n }\n\n private _handleKeyDown(e: KeyboardEvent): void {\n if (e.key === 'Escape') {\n this.hide();\n // Return focus to trigger element\n const triggerEl = this._getTriggerElement() as HTMLElement | null;\n triggerEl?.focus?.();\n }\n }\n\n private _handleScroll(): void {\n if (this.open) {\n this._updatePosition();\n }\n }\n\n private _updatePosition(): void {\n const triggerEl = this._getTriggerElement();\n const panel = this.shadowRoot?.querySelector('.popover-panel') as HTMLElement | null;\n\n if (!triggerEl || !panel) return;\n\n const triggerRect = triggerEl.getBoundingClientRect();\n const panelRect = panel.getBoundingClientRect();\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n\n // Determine the best placement with auto-flip\n const effectivePlacement = this._getEffectivePlacement(\n triggerRect,\n panelRect,\n viewportWidth,\n viewportHeight,\n );\n\n this._currentPlacement = effectivePlacement;\n\n // Calculate position based on placement\n const position = this._calculatePosition(triggerRect, panelRect, effectivePlacement);\n\n // Apply position\n panel.style.left = `${position.x}px`;\n panel.style.top = `${position.y}px`;\n panel.setAttribute('data-placement', effectivePlacement);\n }\n\n private _getEffectivePlacement(\n triggerRect: DOMRect,\n panelRect: DOMRect,\n viewportWidth: number,\n viewportHeight: number,\n ): PopoverPlacement {\n const [mainAxis, alignment] = this.placement.split('-') as [\n 'top' | 'bottom' | 'left' | 'right',\n 'start' | 'end' | undefined,\n ];\n\n // Check if there's enough space in the preferred direction\n const spaceTop = triggerRect.top;\n const spaceBottom = viewportHeight - triggerRect.bottom;\n const spaceLeft = triggerRect.left;\n const spaceRight = viewportWidth - triggerRect.right;\n\n let effectiveMainAxis = mainAxis;\n\n // Flip main axis if needed\n if (mainAxis === 'top' && spaceTop < panelRect.height + this.offset) {\n if (spaceBottom >= panelRect.height + this.offset) {\n effectiveMainAxis = 'bottom';\n }\n } else if (mainAxis === 'bottom' && spaceBottom < panelRect.height + this.offset) {\n if (spaceTop >= panelRect.height + this.offset) {\n effectiveMainAxis = 'top';\n }\n } else if (mainAxis === 'left' && spaceLeft < panelRect.width + this.offset) {\n if (spaceRight >= panelRect.width + this.offset) {\n effectiveMainAxis = 'right';\n }\n } else if (mainAxis === 'right' && spaceRight < panelRect.width + this.offset) {\n if (spaceLeft >= panelRect.width + this.offset) {\n effectiveMainAxis = 'left';\n }\n }\n\n return alignment\n ? (`${effectiveMainAxis}-${alignment}` as PopoverPlacement)\n : effectiveMainAxis;\n }\n\n private _calculatePosition(\n triggerRect: DOMRect,\n panelRect: DOMRect,\n placement: PopoverPlacement,\n ): { x: number; y: number } {\n const [mainAxis, alignment] = placement.split('-') as [\n 'top' | 'bottom' | 'left' | 'right',\n 'start' | 'end' | undefined,\n ];\n\n let x = 0;\n let y = 0;\n\n // Calculate main axis position\n switch (mainAxis) {\n case 'top':\n y = triggerRect.top - panelRect.height - this.offset;\n break;\n case 'bottom':\n y = triggerRect.bottom + this.offset;\n break;\n case 'left':\n x = triggerRect.left - panelRect.width - this.offset;\n break;\n case 'right':\n x = triggerRect.right + this.offset;\n break;\n }\n\n // Calculate cross axis position based on alignment\n if (mainAxis === 'top' || mainAxis === 'bottom') {\n switch (alignment) {\n case 'start':\n x = triggerRect.left;\n break;\n case 'end':\n x = triggerRect.right - panelRect.width;\n break;\n default:\n x = triggerRect.left + (triggerRect.width - panelRect.width) / 2;\n }\n } else {\n switch (alignment) {\n case 'start':\n y = triggerRect.top;\n break;\n case 'end':\n y = triggerRect.bottom - panelRect.height;\n break;\n default:\n y = triggerRect.top + (triggerRect.height - panelRect.height) / 2;\n }\n }\n\n // Constrain to viewport\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n const padding = 8;\n\n x = Math.max(padding, Math.min(x, viewportWidth - panelRect.width - padding));\n y = Math.max(padding, Math.min(y, viewportHeight - panelRect.height - padding));\n\n return { x, y };\n }\n\n update(): void {\n super.update();\n if (this.open) {\n // Defer position update to allow DOM to render\n requestAnimationFrame(() => {\n this._updatePosition();\n this._setVisible(true);\n });\n }\n }\n\n render(): string {\n return `\n <div class=\"popover-trigger\">\n <slot name=\"trigger\"></slot>\n </div>\n <div\n class=\"popover-panel\"\n part=\"popover\"\n role=\"dialog\"\n aria-modal=\"false\"\n data-placement=\"${this.placement}\"\n >\n ${this.arrow ? '<div class=\"popover-arrow\" part=\"arrow\"></div>' : ''}\n <div class=\"popover-content\" part=\"content\">\n <slot></slot>\n </div>\n </div>\n `;\n }\n}\n",
|
|
5
|
+
"/**\n * DuskMoon Popover Element\n *\n * A contextual overlay/popup component that appears relative to a trigger element.\n * Supports multiple trigger modes, placements, and auto-flip when near viewport edges.\n *\n * @element el-dm-popover\n *\n * @attr {boolean} open - Whether the popover is visible\n * @attr {string} trigger - Trigger mode: click, hover, focus, manual\n * @attr {string} placement - Popover position relative to trigger\n * @attr {number} offset - Distance from trigger element in pixels\n * @attr {boolean} arrow - Whether to show arrow pointing to trigger\n *\n * @slot trigger - The element that triggers the popover\n * @slot - Default slot for popover content\n *\n * @fires open - Fired when popover opens\n * @fires close - Fired when popover closes\n *\n * @csspart popover - The popover container\n * @csspart content - The popover content area\n * @csspart arrow - The popover arrow\n */\n\nimport { BaseElement, css, animationStyles } from '@duskmoon-dev/el-base';\nimport { css as popoverCSS } from '@duskmoon-dev/core/components/popover';\n\nexport type PopoverPlacement =\n | 'top'\n | 'top-start'\n | 'top-end'\n | 'bottom'\n | 'bottom-start'\n | 'bottom-end'\n | 'left'\n | 'left-start'\n | 'left-end'\n | 'right'\n | 'right-start'\n | 'right-end';\n\nexport type PopoverTrigger = 'click' | 'hover' | 'focus' | 'manual';\n\n// Strip @layer wrapper for Shadow DOM compatibility\nconst coreStyles = popoverCSS.replace(/@layer\\s+components\\s*\\{/, '').replace(/\\}\\s*$/, '');\n\nconst styles = css`\n :host {\n display: inline-block;\n position: relative;\n }\n\n :host([hidden]) {\n display: none !important;\n }\n\n /* Import core popover styles */\n ${coreStyles}\n\n .popover-trigger {\n display: inline-flex;\n }\n\n /* Override core's position: absolute for JS-based positioning */\n .popover-content {\n position: fixed;\n min-width: 8rem;\n pointer-events: none;\n font-family: inherit;\n }\n\n .popover-content.show {\n pointer-events: auto;\n }\n\n /* Arrow positioning based on popover placement (data-attribute based) */\n .popover-content[data-placement^='top'] .popover-arrow {\n bottom: -0.4375rem;\n border-top: none;\n border-left: none;\n }\n\n .popover-content[data-placement^='bottom'] .popover-arrow {\n top: -0.4375rem;\n border-bottom: none;\n border-right: none;\n }\n\n .popover-content[data-placement^='left'] .popover-arrow {\n right: -0.4375rem;\n border-top: none;\n border-left: none;\n }\n\n .popover-content[data-placement^='right'] .popover-arrow {\n left: -0.4375rem;\n border-bottom: none;\n border-right: none;\n }\n\n /* Center aligned arrows */\n .popover-content[data-placement='top'] .popover-arrow,\n .popover-content[data-placement='bottom'] .popover-arrow {\n left: 50%;\n transform: translateX(-50%) rotate(45deg);\n }\n\n .popover-content[data-placement='left'] .popover-arrow,\n .popover-content[data-placement='right'] .popover-arrow {\n top: 50%;\n transform: translateY(-50%) rotate(45deg);\n }\n\n /* Start aligned arrows */\n .popover-content[data-placement='top-start'] .popover-arrow,\n .popover-content[data-placement='bottom-start'] .popover-arrow {\n left: 1rem;\n }\n\n .popover-content[data-placement='left-start'] .popover-arrow,\n .popover-content[data-placement='right-start'] .popover-arrow {\n top: 1rem;\n }\n\n /* End aligned arrows */\n .popover-content[data-placement='top-end'] .popover-arrow,\n .popover-content[data-placement='bottom-end'] .popover-arrow {\n right: 1rem;\n left: auto;\n }\n\n .popover-content[data-placement='left-end'] .popover-arrow,\n .popover-content[data-placement='right-end'] .popover-arrow {\n bottom: 1rem;\n top: auto;\n }\n`;\n\nexport class ElDmPopover extends BaseElement {\n static properties = {\n open: { type: Boolean, reflect: true, default: false },\n trigger: { type: String, reflect: true, default: 'click' },\n placement: { type: String, reflect: true, default: 'bottom' },\n offset: { type: Number, reflect: true, default: 8 },\n arrow: { type: Boolean, reflect: true, default: true },\n };\n\n declare open: boolean;\n declare trigger: PopoverTrigger;\n declare placement: PopoverPlacement;\n declare offset: number;\n declare arrow: boolean;\n\n private _boundHandleClickOutside: (e: MouseEvent) => void;\n private _boundHandleKeyDown: (e: KeyboardEvent) => void;\n private _boundHandleScroll: () => void;\n private _boundUpdatePosition: () => void;\n private _hoverTimeout: number | null = null;\n private _currentPlacement: PopoverPlacement = 'bottom';\n\n constructor() {\n super();\n this.attachStyles([styles, animationStyles]);\n this._boundHandleClickOutside = this._handleClickOutside.bind(this);\n this._boundHandleKeyDown = this._handleKeyDown.bind(this);\n this._boundHandleScroll = this._handleScroll.bind(this);\n this._boundUpdatePosition = this._updatePosition.bind(this);\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n this._setupTriggerListeners();\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback?.();\n this._removeTriggerListeners();\n this._removeGlobalListeners();\n }\n\n /**\n * Show the popover\n */\n show(): void {\n if (this.open) return;\n this.open = true;\n this._currentPlacement = this.placement;\n this._addGlobalListeners();\n this._updatePosition();\n this._setVisible(true);\n this.emit('open');\n }\n\n /**\n * Hide the popover\n */\n hide(): void {\n if (!this.open) return;\n this.open = false;\n this._removeGlobalListeners();\n this._setVisible(false);\n this.emit('close');\n }\n\n /**\n * Toggle the popover visibility\n */\n toggle(): void {\n if (this.open) {\n this.hide();\n } else {\n this.show();\n }\n }\n\n private _setVisible(visible: boolean): void {\n const panel = this.shadowRoot?.querySelector('.popover-content');\n if (panel) {\n panel.classList.toggle('show', visible);\n }\n }\n\n private _setupTriggerListeners(): void {\n const triggerSlot = this.shadowRoot?.querySelector(\n 'slot[name=\"trigger\"]',\n ) as HTMLSlotElement | null;\n\n if (!triggerSlot) return;\n\n triggerSlot.addEventListener('slotchange', () => {\n this._attachTriggerEvents();\n });\n\n // Initial attachment\n this._attachTriggerEvents();\n }\n\n private _attachTriggerEvents(): void {\n const triggerEl = this._getTriggerElement();\n if (!triggerEl) return;\n\n // Remove any existing listeners first\n this._detachTriggerEvents(triggerEl);\n\n if (this.trigger === 'click') {\n triggerEl.addEventListener('click', this._handleTriggerClick);\n } else if (this.trigger === 'hover') {\n triggerEl.addEventListener('mouseenter', this._handleTriggerMouseEnter);\n triggerEl.addEventListener('mouseleave', this._handleTriggerMouseLeave);\n // Also track hover on the popover panel\n this.addEventListener('mouseenter', this._handlePopoverMouseEnter);\n this.addEventListener('mouseleave', this._handlePopoverMouseLeave);\n } else if (this.trigger === 'focus') {\n triggerEl.addEventListener('focusin', this._handleTriggerFocus);\n triggerEl.addEventListener('focusout', this._handleTriggerBlur);\n }\n }\n\n private _detachTriggerEvents(triggerEl: Element): void {\n triggerEl.removeEventListener('click', this._handleTriggerClick);\n triggerEl.removeEventListener('mouseenter', this._handleTriggerMouseEnter);\n triggerEl.removeEventListener('mouseleave', this._handleTriggerMouseLeave);\n triggerEl.removeEventListener('focusin', this._handleTriggerFocus);\n triggerEl.removeEventListener('focusout', this._handleTriggerBlur);\n this.removeEventListener('mouseenter', this._handlePopoverMouseEnter);\n this.removeEventListener('mouseleave', this._handlePopoverMouseLeave);\n }\n\n private _removeTriggerListeners(): void {\n const triggerEl = this._getTriggerElement();\n if (triggerEl) {\n this._detachTriggerEvents(triggerEl);\n }\n }\n\n private _getTriggerElement(): Element | null {\n const triggerSlot = this.shadowRoot?.querySelector(\n 'slot[name=\"trigger\"]',\n ) as HTMLSlotElement | null;\n if (!triggerSlot) return null;\n const assigned = triggerSlot.assignedElements();\n return assigned[0] || null;\n }\n\n private _handleTriggerClick = (): void => {\n this.toggle();\n };\n\n private _handleTriggerMouseEnter = (): void => {\n if (this._hoverTimeout) {\n clearTimeout(this._hoverTimeout);\n this._hoverTimeout = null;\n }\n this.show();\n };\n\n private _handleTriggerMouseLeave = (): void => {\n this._hoverTimeout = window.setTimeout(() => {\n this.hide();\n }, 100);\n };\n\n private _handlePopoverMouseEnter = (): void => {\n if (this._hoverTimeout) {\n clearTimeout(this._hoverTimeout);\n this._hoverTimeout = null;\n }\n };\n\n private _handlePopoverMouseLeave = (): void => {\n this._hoverTimeout = window.setTimeout(() => {\n this.hide();\n }, 100);\n };\n\n private _handleTriggerFocus = (): void => {\n this.show();\n };\n\n private _handleTriggerBlur = (): void => {\n // Delay to allow focus to move to popover content\n setTimeout(() => {\n if (!this.contains(document.activeElement)) {\n this.hide();\n }\n }, 0);\n };\n\n private _addGlobalListeners(): void {\n document.addEventListener('click', this._boundHandleClickOutside, true);\n document.addEventListener('keydown', this._boundHandleKeyDown);\n window.addEventListener('scroll', this._boundHandleScroll, true);\n window.addEventListener('resize', this._boundUpdatePosition);\n }\n\n private _removeGlobalListeners(): void {\n document.removeEventListener('click', this._boundHandleClickOutside, true);\n document.removeEventListener('keydown', this._boundHandleKeyDown);\n window.removeEventListener('scroll', this._boundHandleScroll, true);\n window.removeEventListener('resize', this._boundUpdatePosition);\n }\n\n private _handleClickOutside(e: MouseEvent): void {\n if (this.trigger !== 'click') return;\n\n const path = e.composedPath();\n if (!path.includes(this)) {\n this.hide();\n }\n }\n\n private _handleKeyDown(e: KeyboardEvent): void {\n if (e.key === 'Escape') {\n this.hide();\n // Return focus to trigger element\n const triggerEl = this._getTriggerElement() as HTMLElement | null;\n triggerEl?.focus?.();\n }\n }\n\n private _handleScroll(): void {\n if (this.open) {\n this._updatePosition();\n }\n }\n\n private _updatePosition(): void {\n const triggerEl = this._getTriggerElement();\n const panel = this.shadowRoot?.querySelector('.popover-content') as HTMLElement | null;\n\n if (!triggerEl || !panel) return;\n\n const triggerRect = triggerEl.getBoundingClientRect();\n const panelRect = panel.getBoundingClientRect();\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n\n // Determine the best placement with auto-flip\n const effectivePlacement = this._getEffectivePlacement(\n triggerRect,\n panelRect,\n viewportWidth,\n viewportHeight,\n );\n\n this._currentPlacement = effectivePlacement;\n\n // Calculate position based on placement\n const position = this._calculatePosition(triggerRect, panelRect, effectivePlacement);\n\n // Apply position\n panel.style.left = `${position.x}px`;\n panel.style.top = `${position.y}px`;\n panel.setAttribute('data-placement', effectivePlacement);\n }\n\n private _getEffectivePlacement(\n triggerRect: DOMRect,\n panelRect: DOMRect,\n viewportWidth: number,\n viewportHeight: number,\n ): PopoverPlacement {\n const [mainAxis, alignment] = this.placement.split('-') as [\n 'top' | 'bottom' | 'left' | 'right',\n 'start' | 'end' | undefined,\n ];\n\n // Check if there's enough space in the preferred direction\n const spaceTop = triggerRect.top;\n const spaceBottom = viewportHeight - triggerRect.bottom;\n const spaceLeft = triggerRect.left;\n const spaceRight = viewportWidth - triggerRect.right;\n\n let effectiveMainAxis = mainAxis;\n\n // Flip main axis if needed\n if (mainAxis === 'top' && spaceTop < panelRect.height + this.offset) {\n if (spaceBottom >= panelRect.height + this.offset) {\n effectiveMainAxis = 'bottom';\n }\n } else if (mainAxis === 'bottom' && spaceBottom < panelRect.height + this.offset) {\n if (spaceTop >= panelRect.height + this.offset) {\n effectiveMainAxis = 'top';\n }\n } else if (mainAxis === 'left' && spaceLeft < panelRect.width + this.offset) {\n if (spaceRight >= panelRect.width + this.offset) {\n effectiveMainAxis = 'right';\n }\n } else if (mainAxis === 'right' && spaceRight < panelRect.width + this.offset) {\n if (spaceLeft >= panelRect.width + this.offset) {\n effectiveMainAxis = 'left';\n }\n }\n\n return alignment\n ? (`${effectiveMainAxis}-${alignment}` as PopoverPlacement)\n : effectiveMainAxis;\n }\n\n private _calculatePosition(\n triggerRect: DOMRect,\n panelRect: DOMRect,\n placement: PopoverPlacement,\n ): { x: number; y: number } {\n const [mainAxis, alignment] = placement.split('-') as [\n 'top' | 'bottom' | 'left' | 'right',\n 'start' | 'end' | undefined,\n ];\n\n let x = 0;\n let y = 0;\n\n // Calculate main axis position\n switch (mainAxis) {\n case 'top':\n y = triggerRect.top - panelRect.height - this.offset;\n break;\n case 'bottom':\n y = triggerRect.bottom + this.offset;\n break;\n case 'left':\n x = triggerRect.left - panelRect.width - this.offset;\n break;\n case 'right':\n x = triggerRect.right + this.offset;\n break;\n }\n\n // Calculate cross axis position based on alignment\n if (mainAxis === 'top' || mainAxis === 'bottom') {\n switch (alignment) {\n case 'start':\n x = triggerRect.left;\n break;\n case 'end':\n x = triggerRect.right - panelRect.width;\n break;\n default:\n x = triggerRect.left + (triggerRect.width - panelRect.width) / 2;\n }\n } else {\n switch (alignment) {\n case 'start':\n y = triggerRect.top;\n break;\n case 'end':\n y = triggerRect.bottom - panelRect.height;\n break;\n default:\n y = triggerRect.top + (triggerRect.height - panelRect.height) / 2;\n }\n }\n\n // Constrain to viewport\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n const padding = 8;\n\n x = Math.max(padding, Math.min(x, viewportWidth - panelRect.width - padding));\n y = Math.max(padding, Math.min(y, viewportHeight - panelRect.height - padding));\n\n return { x, y };\n }\n\n update(): void {\n super.update();\n if (this.open) {\n // Defer position update to allow DOM to render\n requestAnimationFrame(() => {\n this._updatePosition();\n this._setVisible(true);\n });\n }\n }\n\n render(): string {\n return `\n <div class=\"popover-trigger\">\n <slot name=\"trigger\"></slot>\n </div>\n <div\n class=\"popover-content\"\n part=\"popover\"\n role=\"dialog\"\n aria-modal=\"false\"\n data-placement=\"${this.placement}\"\n >\n ${this.arrow ? '<div class=\"popover-arrow\" part=\"arrow\"></div>' : ''}\n <div class=\"popover-body\" part=\"content\">\n <slot></slot>\n </div>\n </div>\n `;\n }\n}\n",
|
|
6
6
|
"/**\n * @duskmoon-dev/el-popover\n *\n * DuskMoon Popover custom element\n */\n\nimport { ElDmPopover } from './el-dm-popover.js';\n\nexport { ElDmPopover };\nexport type { PopoverPlacement, PopoverTrigger } from './el-dm-popover.js';\n\n/**\n * Register the el-dm-popover custom element\n *\n * @example\n * ```ts\n * import { register } from '@duskmoon-dev/el-popover';\n * register();\n * ```\n */\nexport function register(): void {\n if (!customElements.get('el-dm-popover')) {\n customElements.define('el-dm-popover', ElDmPopover);\n }\n}\n",
|
|
7
7
|
"/**\n * Auto-register el-dm-popover custom element\n *\n * @example\n * ```ts\n * import '@duskmoon-dev/el-popover/register';\n *\n * // Now you can use <el-dm-popover> in HTML\n * ```\n */\nimport { register } from './index.js';\n\nregister();\n"
|
|
8
8
|
],
|
|
9
|
-
"mappings": ";AAyBA;
|
|
10
|
-
"debugId": "
|
|
9
|
+
"mappings": "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",
|
|
10
|
+
"debugId": "421734A82AD65F9964756E2164756E21",
|
|
11
11
|
"names": []
|
|
12
12
|
}
|