@mhmo91/schmancy 0.9.16 → 0.9.18
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/custom-elements.json +111 -51
- package/dist/agent/schmancy.agent.js +288 -38
- package/dist/agent/schmancy.agent.js.map +1 -1
- package/dist/agent/schmancy.manifest.json +332 -25
- package/dist/breadcrumb.cjs.map +1 -1
- package/dist/breadcrumb.js.map +1 -1
- package/dist/card-BslSqOsf.cjs.map +1 -1
- package/dist/card-CEdgK9nb.js.map +1 -1
- package/dist/details-B8p62xmR.cjs.map +1 -1
- package/dist/details-CCW52lzz.js.map +1 -1
- package/dist/dialog.cjs.map +1 -1
- package/dist/dialog.js.map +1 -1
- package/dist/divider-CbEWg3G_.js.map +1 -1
- package/dist/divider-JyyFw_3J.cjs.map +1 -1
- package/dist/dropdown.cjs.map +1 -1
- package/dist/dropdown.js.map +1 -1
- package/dist/expand-BmwIPNjq.cjs.map +1 -1
- package/dist/expand-bFa_qVDT.js.map +1 -1
- package/dist/handover/agent-runtime-followups.md +1 -1
- package/dist/handover/agent-runtime-v1.md +3 -3
- package/dist/list-BpjKUOzM.js.map +1 -1
- package/dist/list-CMWHu6cV.cjs.map +1 -1
- package/dist/menu-BIBUgS1T.js.map +1 -1
- package/dist/menu-DS8Iz4fJ.cjs.map +1 -1
- package/dist/navigation-rail.cjs.map +1 -1
- package/dist/navigation-rail.js.map +1 -1
- package/dist/page.cjs.map +1 -1
- package/dist/page.js.map +1 -1
- package/dist/scroll-CdmXRXh2.js.map +1 -1
- package/dist/scroll-V1rAZ9fK.cjs.map +1 -1
- package/dist/sheet-DdlZhnDG.cjs.map +1 -1
- package/dist/sheet-LFVo5iN4.js.map +1 -1
- package/dist/src-C7niWYur.js.map +1 -1
- package/dist/src-I4M33WK2.cjs.map +1 -1
- package/dist/surface-0XM4DBaT.js.map +1 -1
- package/dist/surface-B6DA01kL.cjs.map +1 -1
- package/dist/theme-Cq_c9IO3.js.map +1 -1
- package/dist/theme-DU5yXaV-.cjs.map +1 -1
- package/dist/tree.cjs.map +1 -1
- package/dist/tree.js.map +1 -1
- package/package.json +1 -1
- package/src/breadcrumb/breadcrumb.ts +14 -4
- package/src/card/actions.ts +9 -0
- package/src/card/card.ts +18 -0
- package/src/card/content.ts +9 -0
- package/src/card/media.ts +6 -0
- package/src/details/details.ts +12 -0
- package/src/dialog/dialog.component.ts +9 -9
- package/src/divider/divider.ts +11 -0
- package/src/dropdown/dropdown-component.ts +13 -1
- package/src/dropdown/dropdown-content.ts +11 -3
- package/src/expand/expand-root.component.ts +12 -0
- package/src/expand/expand.component.ts +14 -0
- package/src/layout/scroll/scroll.ts +5 -1
- package/src/list/list-item.ts +10 -0
- package/src/list/list.ts +7 -8
- package/src/menu/menu-item.ts +13 -0
- package/src/menu/menu.ts +10 -22
- package/src/nav-drawer/appbar.ts +11 -0
- package/src/nav-drawer/content.ts +11 -0
- package/src/nav-drawer/drawer.ts +15 -0
- package/src/nav-drawer/navbar.ts +14 -0
- package/src/navigation-bar/navigation-bar-item.ts +3 -4
- package/src/navigation-bar/navigation-bar.ts +3 -9
- package/src/navigation-rail/navigation-rail-item.ts +3 -7
- package/src/navigation-rail/navigation-rail.ts +12 -8
- package/src/page/page.ts +8 -11
- package/src/sheet/sheet.ts +17 -0
- package/src/surface/surface.ts +4 -10
- package/src/theme/theme.component.ts +10 -15
- package/src/tree/tree.ts +12 -0
- package/types/src/breadcrumb/breadcrumb.d.ts +14 -4
- package/types/src/card/actions.d.ts +9 -0
- package/types/src/card/card.d.ts +18 -0
- package/types/src/card/content.d.ts +9 -0
- package/types/src/card/media.d.ts +6 -0
- package/types/src/details/details.d.ts +12 -0
- package/types/src/dialog/dialog.component.d.ts +9 -9
- package/types/src/divider/divider.d.ts +11 -0
- package/types/src/dropdown/dropdown-component.d.ts +13 -1
- package/types/src/dropdown/dropdown-content.d.ts +11 -3
- package/types/src/expand/expand-root.component.d.ts +12 -0
- package/types/src/expand/expand.component.d.ts +14 -0
- package/types/src/layout/scroll/scroll.d.ts +5 -1
- package/types/src/list/list-item.d.ts +10 -0
- package/types/src/list/list.d.ts +7 -8
- package/types/src/menu/menu-item.d.ts +13 -0
- package/types/src/menu/menu.d.ts +10 -22
- package/types/src/nav-drawer/appbar.d.ts +11 -0
- package/types/src/nav-drawer/content.d.ts +11 -0
- package/types/src/nav-drawer/drawer.d.ts +15 -0
- package/types/src/nav-drawer/navbar.d.ts +14 -0
- package/types/src/navigation-bar/navigation-bar-item.d.ts +3 -4
- package/types/src/navigation-bar/navigation-bar.d.ts +3 -9
- package/types/src/navigation-rail/navigation-rail-item.d.ts +3 -7
- package/types/src/navigation-rail/navigation-rail.d.ts +12 -8
- package/types/src/page/page.d.ts +8 -11
- package/types/src/sheet/sheet.d.ts +17 -0
- package/types/src/surface/surface.d.ts +4 -10
- package/types/src/theme/theme.component.d.ts +10 -15
- package/types/src/tree/tree.d.ts +12 -0
package/dist/dropdown.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dropdown.js","names":[],"sources":["../src/dropdown/dropdown-component.ts","../src/dropdown/dropdown-content.ts"],"sourcesContent":["import { autoUpdate, computePosition, flip, offset, shift } from '@floating-ui/dom'\nimport { $LitElement } from '@mixins/index'\nimport { html } from 'lit'\nimport { customElement, property, query, queryAssignedElements, state } from 'lit/decorators.js'\nimport { filter, fromEvent, takeUntil, Subscription } from 'rxjs'\n\n/**\n * A dropdown component that displays content when triggered.\n *\n * @element schmancy-dropdown\n * @slot trigger - The element that triggers the dropdown\n * @slot - Default slot for the dropdown content\n */\n@customElement('schmancy-dropdown')\nexport class SchmancyDropdown extends $LitElement() {\n\t/**\n\t * Whether the dropdown is currently open\n\t */\n\t@property({ type: Boolean, reflect: true })\n\topen = false\n\n\t/**\n\t * Placement of the dropdown relative to the trigger\n\t */\n\t@property({ type: String })\n\tplacement:\n\t\t| 'top'\n\t\t| 'top-start'\n\t\t| 'top-end'\n\t\t| 'right'\n\t\t| 'right-start'\n\t\t| 'right-end'\n\t\t| 'bottom'\n\t\t| 'bottom-start'\n\t\t| 'bottom-end'\n\t\t| 'left'\n\t\t| 'left-start'\n\t\t| 'left-end' = 'bottom-start'\n\n\t/**\n\t * Offset distance in pixels\n\t */\n\t@property({ type: Number })\n\tdistance = 8\n\n\t@query('.trigger-container') triggerContainer!: HTMLElement\n\t@query('.dropdown-content-container') contentContainer!: HTMLElement\n\t@queryAssignedElements({ flatten: true }) contentElements!: HTMLElement[]\n\t@state() private portal: HTMLElement | null = null\n\n\t@queryAssignedElements({ slot: 'trigger', flatten: true })\n\ttriggerElements!: Array<HTMLElement>\n\n\tprivate cleanupPositioner?: () => void\n\tprivate portalSubscriptions: Subscription[] = []\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback()\n\n\t\t// Create portal container for teleporting content to document body\n\t\tthis.setupPortal()\n\n\t\t// Listen for document clicks to close dropdown when clicking outside\n\t\tfromEvent<MouseEvent>(document, 'click')\n\t\t\t.pipe(\n\t\t\t\tfilter(event => this.open && !this.isEventFromSelf(event)),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe(() => {\n\t\t\t\tthis.open = false\n\t\t\t})\n\n\t\t// Listen for escape key to close dropdown\n\t\tfromEvent<KeyboardEvent>(document, 'keydown')\n\t\t\t.pipe(\n\t\t\t\tfilter(event => this.open && event.key === 'Escape'),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe(() => {\n\t\t\t\tthis.open = false\n\t\t\t})\n\t}\n\n\t/**\n\t * Set up the portal element for teleporting content\n\t */\n\tprivate setupPortal() {\n\t\t// Check if portal container exists\n\t\tlet portalContainer = document.getElementById('schmancy-portal-container')\n\n\t\t// Create portal container if it doesn't exist\n\t\tif (!portalContainer) {\n\t\t\tportalContainer = document.createElement('div')\n\t\t\tportalContainer.id = 'schmancy-portal-container'\n\t\t\tportalContainer.style.position = 'fixed'\n\t\t\tportalContainer.style.zIndex = '10000'\n\t\t\tportalContainer.style.top = '0'\n\t\t\tportalContainer.style.left = '0'\n\t\t\tportalContainer.style.pointerEvents = 'none'\n\t\t\tdocument.body.appendChild(portalContainer)\n\t\t}\n\n\t\t// Create portal for this specific dropdown\n\t\tconst portal = document.createElement('div')\n\t\tportal.className = 'schmancy-dropdown-portal'\n\t\tportal.style.position = 'absolute'\n\t\tportal.style.pointerEvents = 'auto'\n\t\tportal.style.display = 'none'\n\t\tportalContainer.appendChild(portal)\n\n\t\tthis.portal = portal\n\t}\n\n\t/**\n\t * Check if an event originated from within this component\n\t */\n\tprivate isEventFromSelf(event: Event): boolean {\n\t\treturn event.composedPath().some(el => el === this)\n\t}\n\n\tdisconnectedCallback() {\n\t\tthis.cleanupPositioner?.()\n\n\t\t// Clean up portal subscriptions\n\t\tthis.portalSubscriptions.forEach(subscription => subscription.unsubscribe())\n\t\tthis.portalSubscriptions = []\n\n\t\t// Remove portal when component is disconnected\n\t\tif (this.portal) {\n\t\t\tthis.portal.remove()\n\t\t\tthis.portal = null\n\t\t}\n\n\t\tsuper.disconnectedCallback()\n\t}\n\n\t/**\n\t * Toggle the dropdown open state\n\t */\n\ttoggle() {\n\t\tthis.open = !this.open\n\t}\n\n\tupdated(changedProps: Map<string, any>) {\n\t\tsuper.updated(changedProps)\n\n\t\tif (changedProps.has('open')) {\n\t\t\tif (this.open) {\n\t\t\t\tthis.setupPositioner()\n\t\t\t} else {\n\t\t\t\tthis.cleanupPositioner?.()\n\n\t\t\t\t// Hide portal when dropdown is closed\n\t\t\t\tif (this.portal) {\n\t\t\t\t\tthis.portal.style.display = 'none'\n\t\t\t\t\tthis.portal.innerHTML = ''\n\t\t\t\t\t// Clean up subscriptions when content is cleared\n\t\t\t\t\tthis.portalSubscriptions.forEach(subscription => subscription.unsubscribe())\n\t\t\t\t\tthis.portalSubscriptions = []\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Setup floating UI positioning with teleportation\n\t */\n\tprivate setupPositioner() {\n\t\tif (!this.triggerContainer || !this.portal) return\n\n\t\t// Show the portal\n\t\tthis.portal.style.display = 'block'\n\n\t\t// Move content to portal\n\t\tthis.teleportContentToPortal()\n\n\t\t// Setup positioning\n\t\tthis.cleanupPositioner = autoUpdate(this.triggerContainer, this.portal, () => {\n\t\t\tcomputePosition(this.triggerContainer, this.portal, {\n\t\t\t\tplacement: this.placement,\n\t\t\t\tmiddleware: [\n\t\t\t\t\toffset(this.distance),\n\t\t\t\t\tflip({\n\t\t\t\t\t\tfallbackPlacements: ['top-start', 'bottom-start'],\n\t\t\t\t\t}),\n\t\t\t\t\tshift({ padding: 0 }),\n\t\t\t\t],\n\t\t\t}).then(({ x, y }) => {\n\t\t\t\t// Update portal position\n\t\t\t\tObject.assign(this.portal.style, {\n\t\t\t\t\tleft: `${x}px`,\n\t\t\t\t\ttop: `${y - 8}px`,\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * Move slotted content to the portal\n\t */\n\tprivate teleportContentToPortal() {\n\t\tif (!this.portal) return\n\n\t\t// Clean up existing subscriptions\n\t\tthis.portalSubscriptions.forEach(subscription => subscription.unsubscribe())\n\t\tthis.portalSubscriptions = []\n\n\t\t// Clear existing content\n\t\tthis.portal.innerHTML = ''\n\n\t\t// Clone and move slotted content to portal\n\t\tthis.contentElements.forEach(element => {\n\t\t\t// Get computed styles to ensure portal content matches original styling\n\t\t\tconst clonedElement = element.cloneNode(true) as HTMLElement\n\n\t\t\t// Ensure dropdown-content elements maintain their styles when teleported\n\t\t\tif (element.tagName.toLowerCase() === 'schmancy-dropdown-content') {\n\t\t\t\tconst subscription = fromEvent(clonedElement, 'slotchange').subscribe(() => {\n\t\t\t\t\t// Propagate any slot changes to class changes on children\n\t\t\t\t\tconst contentDiv = clonedElement.shadowRoot?.querySelector('[part=\"content\"]')\n\t\t\t\t\tif (contentDiv) {\n\t\t\t\t\t\tcontentDiv.classList.add('schmancy-dropdown-content')\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\tthis.portalSubscriptions.push(subscription)\n\t\t\t}\n\n\t\t\tthis.portal?.appendChild(clonedElement)\n\t\t})\n\t}\n\n\t/**\n\t * Handle trigger click to toggle dropdown\n\t */\n\tprivate handleTriggerClick(e: Event) {\n\t\te.stopPropagation()\n\t\tthis.toggle()\n\t}\n\n\trender() {\n\t\treturn html`\n\t\t\t<div class=\"trigger-container\" @click=${this.handleTriggerClick}>\n\t\t\t\t<slot name=\"trigger\"></slot>\n\t\t\t</div>\n\n\t\t\t<div class=\"dropdown-content-container\" ?hidden=${!this.open}>\n\t\t\t\t<slot\n\t\t\t\t\t@slotchange=${() => {\n\t\t\t\t\t\tif (this.open) {\n\t\t\t\t\t\t\tthis.teleportContentToPortal()\n\t\t\t\t\t\t\tthis.setupPositioner()\n\t\t\t\t\t\t}\n\t\t\t\t\t}}\n\t\t\t\t></slot>\n\t\t\t</div>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-dropdown': SchmancyDropdown\n\t}\n}\n","import { TailwindElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\n/**\n * Content container for the schmancy-dropdown component.\n *\n * @element schmancy-dropdown-content\n * @slot - Default slot for dropdown content.\n * @csspart content - The inner wrapper element; style to override panel\n * backgrounds, shadows, padding, or borders without shadow-root piercing.\n */\n@customElement('schmancy-dropdown-content')\nexport class SchmancyDropdownContent extends TailwindElement(css`\n\t:host {\n\t\tdisplay: block;\n\t\tposition: absolute;\n\t\tz-index: 1000;\n\t\tmin-width: 10rem;\n\t\tmargin: 0;\n\t\ttext-align: left;\n\t\tlist-style: none;\n\t\tbackground-color: var(--schmancy-sys-color-surface-container);\n\t\tbackground-clip: padding-box;\n\t\tborder-radius: 0.375rem;\n\t\tbox-shadow: var(--schmancy-sys-elevation-3);\n\t\twill-change: transform;\n\t\ttransform-origin: top left;\n\t\tanimation: dropdownAnimation 0.1s ease-out forwards;\n\t}\n\n\t:host([hidden]) {\n\t\tdisplay: none;\n\t}\n\n\t@keyframes dropdownAnimation {\n\t\tfrom {\n\t\t\topacity: 0;\n\t\t\ttransform: scale(0.95);\n\t\t}\n\t\tto {\n\t\t\topacity: 1;\n\t\t\ttransform: scale(1);\n\t\t}\n\t}\n\n\t/* Apply styles to content both in the component and when teleported to the portal */\n\t.schmancy-dropdown-content {\n\t\tbackground-color: var(--schmancy-sys-color-surface-container);\n\t\tborder-radius: 0.375rem;\n\t\tbox-shadow: var(--schmancy-sys-elevation-3);\n\t\twill-change: transform;\n\t\ttransform-origin: top left;\n\t\tanimation: dropdownAnimation 0.1s ease-out forwards;\n\t}\n`) {\n\t/**\n\t * Width of the dropdown content\n\t */\n\t@property({ type: String })\n\twidth: string = 'auto'\n\n\t/**\n\t * Maximum height of the dropdown content\n\t */\n\t@property({ type: String })\n\tmaxHeight: string = '80vh'\n\n\t/**\n\t * Whether to render with a shadow\n\t */\n\t@property({ type: Boolean })\n\tshadow: boolean = true\n\n\t/**\n\t * Border radius style\n\t */\n\t@property({ type: String })\n\tradius: 'none' | 'sm' | 'md' | 'lg' | 'full' = 'md'\n\n\trender() {\n\t\tconst classes = {\n\t\t\t'schmancy-dropdown-content': true,\n\t\t\t'overflow-auto': true,\n\t\t\t'shadow-none': !this.shadow,\n\t\t\t'rounded-none': this.radius === 'none',\n\t\t\t'rounded-sm': this.radius === 'sm',\n\t\t\t'rounded-md': this.radius === 'md',\n\t\t\t'rounded-lg': this.radius === 'lg',\n\t\t\t'rounded-full': this.radius === 'full',\n\t\t}\n\n\t\tconst styles = {\n\t\t\twidth: this.width,\n\t\t\tmaxHeight: this.maxHeight,\n\t\t}\n\n\t\treturn html`\n\t\t\t<div class=${this.classMap(classes)} style=${this.styleMap(styles)} part=\"content\">\n\t\t\t\t<slot></slot>\n\t\t\t</div>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-dropdown-content': SchmancyDropdownContent\n\t}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dropdown.js","names":[],"sources":["../src/dropdown/dropdown-component.ts","../src/dropdown/dropdown-content.ts"],"sourcesContent":["import { autoUpdate, computePosition, flip, offset, shift } from '@floating-ui/dom'\nimport { $LitElement } from '@mixins/index'\nimport { html } from 'lit'\nimport { customElement, property, query, queryAssignedElements, state } from 'lit/decorators.js'\nimport { filter, fromEvent, takeUntil, Subscription } from 'rxjs'\n\n/**\n * Anchored floating dropdown — a generic \"show this content relative to that trigger\" primitive. Unlike schmancy-menu (which uses the dialog service and is list-shaped), dropdown is a low-level popover anchored with Floating UI. Use when you want a custom-shaped overlay tied to a specific trigger element without the menu semantics.\n *\n * @element schmancy-dropdown\n * @summary Prefer schmancy-menu for action lists, schmancy-autocomplete for type-ahead, schmancy-tooltip for hover hints. Reach for schmancy-dropdown when none of those fit — custom filters, color pickers, inline forms anchored to a trigger.\n * @example\n * <schmancy-dropdown>\n * <schmancy-button slot=\"trigger\">Filters</schmancy-button>\n * <schmancy-dropdown-content>\n * <schmancy-form>…</schmancy-form>\n * </schmancy-dropdown-content>\n * </schmancy-dropdown>\n * @platform div - Anchored via Floating UI (autoUpdate, flip, shift). Degrades to inline content if the tag never registers — loses positioning but content stays accessible.\n * @attr open - Boolean; whether the dropdown is visible.\n * @fires open - When the dropdown opens.\n * @fires close - When the dropdown closes.\n * @slot trigger - The element that triggers the dropdown\n * @slot - Default slot for the dropdown content\n */\n@customElement('schmancy-dropdown')\nexport class SchmancyDropdown extends $LitElement() {\n\t/**\n\t * Whether the dropdown is currently open\n\t */\n\t@property({ type: Boolean, reflect: true })\n\topen = false\n\n\t/**\n\t * Placement of the dropdown relative to the trigger\n\t */\n\t@property({ type: String })\n\tplacement:\n\t\t| 'top'\n\t\t| 'top-start'\n\t\t| 'top-end'\n\t\t| 'right'\n\t\t| 'right-start'\n\t\t| 'right-end'\n\t\t| 'bottom'\n\t\t| 'bottom-start'\n\t\t| 'bottom-end'\n\t\t| 'left'\n\t\t| 'left-start'\n\t\t| 'left-end' = 'bottom-start'\n\n\t/**\n\t * Offset distance in pixels\n\t */\n\t@property({ type: Number })\n\tdistance = 8\n\n\t@query('.trigger-container') triggerContainer!: HTMLElement\n\t@query('.dropdown-content-container') contentContainer!: HTMLElement\n\t@queryAssignedElements({ flatten: true }) contentElements!: HTMLElement[]\n\t@state() private portal: HTMLElement | null = null\n\n\t@queryAssignedElements({ slot: 'trigger', flatten: true })\n\ttriggerElements!: Array<HTMLElement>\n\n\tprivate cleanupPositioner?: () => void\n\tprivate portalSubscriptions: Subscription[] = []\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback()\n\n\t\t// Create portal container for teleporting content to document body\n\t\tthis.setupPortal()\n\n\t\t// Listen for document clicks to close dropdown when clicking outside\n\t\tfromEvent<MouseEvent>(document, 'click')\n\t\t\t.pipe(\n\t\t\t\tfilter(event => this.open && !this.isEventFromSelf(event)),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe(() => {\n\t\t\t\tthis.open = false\n\t\t\t})\n\n\t\t// Listen for escape key to close dropdown\n\t\tfromEvent<KeyboardEvent>(document, 'keydown')\n\t\t\t.pipe(\n\t\t\t\tfilter(event => this.open && event.key === 'Escape'),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe(() => {\n\t\t\t\tthis.open = false\n\t\t\t})\n\t}\n\n\t/**\n\t * Set up the portal element for teleporting content\n\t */\n\tprivate setupPortal() {\n\t\t// Check if portal container exists\n\t\tlet portalContainer = document.getElementById('schmancy-portal-container')\n\n\t\t// Create portal container if it doesn't exist\n\t\tif (!portalContainer) {\n\t\t\tportalContainer = document.createElement('div')\n\t\t\tportalContainer.id = 'schmancy-portal-container'\n\t\t\tportalContainer.style.position = 'fixed'\n\t\t\tportalContainer.style.zIndex = '10000'\n\t\t\tportalContainer.style.top = '0'\n\t\t\tportalContainer.style.left = '0'\n\t\t\tportalContainer.style.pointerEvents = 'none'\n\t\t\tdocument.body.appendChild(portalContainer)\n\t\t}\n\n\t\t// Create portal for this specific dropdown\n\t\tconst portal = document.createElement('div')\n\t\tportal.className = 'schmancy-dropdown-portal'\n\t\tportal.style.position = 'absolute'\n\t\tportal.style.pointerEvents = 'auto'\n\t\tportal.style.display = 'none'\n\t\tportalContainer.appendChild(portal)\n\n\t\tthis.portal = portal\n\t}\n\n\t/**\n\t * Check if an event originated from within this component\n\t */\n\tprivate isEventFromSelf(event: Event): boolean {\n\t\treturn event.composedPath().some(el => el === this)\n\t}\n\n\tdisconnectedCallback() {\n\t\tthis.cleanupPositioner?.()\n\n\t\t// Clean up portal subscriptions\n\t\tthis.portalSubscriptions.forEach(subscription => subscription.unsubscribe())\n\t\tthis.portalSubscriptions = []\n\n\t\t// Remove portal when component is disconnected\n\t\tif (this.portal) {\n\t\t\tthis.portal.remove()\n\t\t\tthis.portal = null\n\t\t}\n\n\t\tsuper.disconnectedCallback()\n\t}\n\n\t/**\n\t * Toggle the dropdown open state\n\t */\n\ttoggle() {\n\t\tthis.open = !this.open\n\t}\n\n\tupdated(changedProps: Map<string, any>) {\n\t\tsuper.updated(changedProps)\n\n\t\tif (changedProps.has('open')) {\n\t\t\tif (this.open) {\n\t\t\t\tthis.setupPositioner()\n\t\t\t} else {\n\t\t\t\tthis.cleanupPositioner?.()\n\n\t\t\t\t// Hide portal when dropdown is closed\n\t\t\t\tif (this.portal) {\n\t\t\t\t\tthis.portal.style.display = 'none'\n\t\t\t\t\tthis.portal.innerHTML = ''\n\t\t\t\t\t// Clean up subscriptions when content is cleared\n\t\t\t\t\tthis.portalSubscriptions.forEach(subscription => subscription.unsubscribe())\n\t\t\t\t\tthis.portalSubscriptions = []\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Setup floating UI positioning with teleportation\n\t */\n\tprivate setupPositioner() {\n\t\tif (!this.triggerContainer || !this.portal) return\n\n\t\t// Show the portal\n\t\tthis.portal.style.display = 'block'\n\n\t\t// Move content to portal\n\t\tthis.teleportContentToPortal()\n\n\t\t// Setup positioning\n\t\tthis.cleanupPositioner = autoUpdate(this.triggerContainer, this.portal, () => {\n\t\t\tcomputePosition(this.triggerContainer, this.portal, {\n\t\t\t\tplacement: this.placement,\n\t\t\t\tmiddleware: [\n\t\t\t\t\toffset(this.distance),\n\t\t\t\t\tflip({\n\t\t\t\t\t\tfallbackPlacements: ['top-start', 'bottom-start'],\n\t\t\t\t\t}),\n\t\t\t\t\tshift({ padding: 0 }),\n\t\t\t\t],\n\t\t\t}).then(({ x, y }) => {\n\t\t\t\t// Update portal position\n\t\t\t\tObject.assign(this.portal.style, {\n\t\t\t\t\tleft: `${x}px`,\n\t\t\t\t\ttop: `${y - 8}px`,\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * Move slotted content to the portal\n\t */\n\tprivate teleportContentToPortal() {\n\t\tif (!this.portal) return\n\n\t\t// Clean up existing subscriptions\n\t\tthis.portalSubscriptions.forEach(subscription => subscription.unsubscribe())\n\t\tthis.portalSubscriptions = []\n\n\t\t// Clear existing content\n\t\tthis.portal.innerHTML = ''\n\n\t\t// Clone and move slotted content to portal\n\t\tthis.contentElements.forEach(element => {\n\t\t\t// Get computed styles to ensure portal content matches original styling\n\t\t\tconst clonedElement = element.cloneNode(true) as HTMLElement\n\n\t\t\t// Ensure dropdown-content elements maintain their styles when teleported\n\t\t\tif (element.tagName.toLowerCase() === 'schmancy-dropdown-content') {\n\t\t\t\tconst subscription = fromEvent(clonedElement, 'slotchange').subscribe(() => {\n\t\t\t\t\t// Propagate any slot changes to class changes on children\n\t\t\t\t\tconst contentDiv = clonedElement.shadowRoot?.querySelector('[part=\"content\"]')\n\t\t\t\t\tif (contentDiv) {\n\t\t\t\t\t\tcontentDiv.classList.add('schmancy-dropdown-content')\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\tthis.portalSubscriptions.push(subscription)\n\t\t\t}\n\n\t\t\tthis.portal?.appendChild(clonedElement)\n\t\t})\n\t}\n\n\t/**\n\t * Handle trigger click to toggle dropdown\n\t */\n\tprivate handleTriggerClick(e: Event) {\n\t\te.stopPropagation()\n\t\tthis.toggle()\n\t}\n\n\trender() {\n\t\treturn html`\n\t\t\t<div class=\"trigger-container\" @click=${this.handleTriggerClick}>\n\t\t\t\t<slot name=\"trigger\"></slot>\n\t\t\t</div>\n\n\t\t\t<div class=\"dropdown-content-container\" ?hidden=${!this.open}>\n\t\t\t\t<slot\n\t\t\t\t\t@slotchange=${() => {\n\t\t\t\t\t\tif (this.open) {\n\t\t\t\t\t\t\tthis.teleportContentToPortal()\n\t\t\t\t\t\t\tthis.setupPositioner()\n\t\t\t\t\t\t}\n\t\t\t\t\t}}\n\t\t\t\t></slot>\n\t\t\t</div>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-dropdown': SchmancyDropdown\n\t}\n}\n","import { TailwindElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\n/**\n * Content panel for a schmancy-dropdown — a styled positioned surface. Always nested inside schmancy-dropdown and placed alongside the trigger slot.\n *\n * @element schmancy-dropdown-content\n * @summary Nest this inside schmancy-dropdown (not in the trigger slot). Use the `content` CSS part to customize backgrounds / shadows / padding without shadow-root piercing.\n * @example\n * <schmancy-dropdown>\n * <schmancy-button slot=\"trigger\">Open</schmancy-button>\n * <schmancy-dropdown-content>\n * Panel contents…\n * </schmancy-dropdown-content>\n * </schmancy-dropdown>\n * @platform div - Positioned panel with theme-aware styling. Degrades to an inline div if the tag never registers.\n * @slot - Default slot for dropdown content.\n * @csspart content - The inner wrapper element; style to override panel backgrounds, shadows, padding, or borders without shadow-root piercing.\n */\n@customElement('schmancy-dropdown-content')\nexport class SchmancyDropdownContent extends TailwindElement(css`\n\t:host {\n\t\tdisplay: block;\n\t\tposition: absolute;\n\t\tz-index: 1000;\n\t\tmin-width: 10rem;\n\t\tmargin: 0;\n\t\ttext-align: left;\n\t\tlist-style: none;\n\t\tbackground-color: var(--schmancy-sys-color-surface-container);\n\t\tbackground-clip: padding-box;\n\t\tborder-radius: 0.375rem;\n\t\tbox-shadow: var(--schmancy-sys-elevation-3);\n\t\twill-change: transform;\n\t\ttransform-origin: top left;\n\t\tanimation: dropdownAnimation 0.1s ease-out forwards;\n\t}\n\n\t:host([hidden]) {\n\t\tdisplay: none;\n\t}\n\n\t@keyframes dropdownAnimation {\n\t\tfrom {\n\t\t\topacity: 0;\n\t\t\ttransform: scale(0.95);\n\t\t}\n\t\tto {\n\t\t\topacity: 1;\n\t\t\ttransform: scale(1);\n\t\t}\n\t}\n\n\t/* Apply styles to content both in the component and when teleported to the portal */\n\t.schmancy-dropdown-content {\n\t\tbackground-color: var(--schmancy-sys-color-surface-container);\n\t\tborder-radius: 0.375rem;\n\t\tbox-shadow: var(--schmancy-sys-elevation-3);\n\t\twill-change: transform;\n\t\ttransform-origin: top left;\n\t\tanimation: dropdownAnimation 0.1s ease-out forwards;\n\t}\n`) {\n\t/**\n\t * Width of the dropdown content\n\t */\n\t@property({ type: String })\n\twidth: string = 'auto'\n\n\t/**\n\t * Maximum height of the dropdown content\n\t */\n\t@property({ type: String })\n\tmaxHeight: string = '80vh'\n\n\t/**\n\t * Whether to render with a shadow\n\t */\n\t@property({ type: Boolean })\n\tshadow: boolean = true\n\n\t/**\n\t * Border radius style\n\t */\n\t@property({ type: String })\n\tradius: 'none' | 'sm' | 'md' | 'lg' | 'full' = 'md'\n\n\trender() {\n\t\tconst classes = {\n\t\t\t'schmancy-dropdown-content': true,\n\t\t\t'overflow-auto': true,\n\t\t\t'shadow-none': !this.shadow,\n\t\t\t'rounded-none': this.radius === 'none',\n\t\t\t'rounded-sm': this.radius === 'sm',\n\t\t\t'rounded-md': this.radius === 'md',\n\t\t\t'rounded-lg': this.radius === 'lg',\n\t\t\t'rounded-full': this.radius === 'full',\n\t\t}\n\n\t\tconst styles = {\n\t\t\twidth: this.width,\n\t\t\tmaxHeight: this.maxHeight,\n\t\t}\n\n\t\treturn html`\n\t\t\t<div class=${this.classMap(classes)} style=${this.styleMap(styles)} part=\"content\">\n\t\t\t\t<slot></slot>\n\t\t\t</div>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-dropdown-content': SchmancyDropdownContent\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"expand-BmwIPNjq.cjs","names":[],"sources":["../src/expand/expand-root.component.ts","../src/expand/expand.component.ts"],"sourcesContent":["import { css, html, nothing } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { createRef, ref } from 'lit/directives/ref.js'\nimport { TailwindElement, SurfaceMixin } from '@mixins/index'\nimport type { TSurfaceColor } from '@schmancy/types'\nimport { SPRING_SMOOTH } from '../utils/animation.js'\nimport { reducedMotion$ } from '../directives/reduced-motion'\nimport '../surface/surface.js'\n\n@customElement('schmancy-expand-root')\nexport class SchmancyExpandRoot extends SurfaceMixin(TailwindElement(css`\n\t:host {\n\t\tdisplay: contents;\n\t}\n\n\t.portal-panel {\n\t\tposition: fixed;\n\t\ttransform-origin: top left;\n\t\twill-change: clip-path, opacity;\n\t\tborder-radius: 1rem;\n\t\tbox-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.5);\n\t\tz-index: 9999;\n\t}\n\n\t.minimize-btn {\n\t\tposition: absolute;\n\t\ttop: 0.5rem;\n\t\tright: 0.5rem;\n\t\tz-index: 1;\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t\twidth: 2rem;\n\t\theight: 2rem;\n\t\tborder-radius: 9999px;\n\t\tborder: none;\n\t\tbackground: transparent;\n\t\tcursor: pointer;\n\t\topacity: 0.5;\n\t\ttransition: opacity 150ms, background 150ms;\n\t\tcolor: inherit;\n\t}\n\n\t.minimize-btn:hover {\n\t\topacity: 1;\n\t\tbackground: rgb(0 0 0 / 0.08);\n\t}\n`)) {\n\t@property({ reflect: true }) override type: TSurfaceColor = 'solid'\n\t@state() isOpen = false\n\tprivate summaryRect: DOMRect | null = null\n\n\tprivate _panelRef = createRef<HTMLElement>()\n\tprivate _backdropRef = createRef<HTMLDivElement>()\n\tprivate _btnRef = createRef<HTMLButtonElement>()\n\tprivate _owner: (Element & { close?: () => void }) | null = null\n\tprivate _hideIndicator = false\n\tprivate _backdrop = true\n\n\t/** Called by schmancy-expand before nodes are moved */\n\tprepare(rect: DOMRect, owner: Element, hideIndicator = false, backdrop = true) {\n\t\tthis.summaryRect = rect\n\t\tthis._owner = owner as Element & { close?: () => void }\n\t\tthis._hideIndicator = hideIndicator\n\t\tthis._backdrop = backdrop\n\t}\n\n\t/** Called by schmancy-expand after nodes are moved in */\n\tasync triggerOpen() {\n\t\tthis.isOpen = true\n\t\tawait this.updateComplete\n\n\t\tconst panel = this._panelRef.value\n\t\tif (!panel) return\n\n\t\tconst src = this.summaryRect!\n\n\t\t// 1. Anchor at summary's top-left, measure natural content size\n\t\t// Use nearly full viewport height for measurement so content near the bottom\n\t\t// of the screen isn't artificially capped — the positioning step will move the panel up.\n\t\tObject.assign(panel.style, {\n\t\t\tvisibility: 'hidden',\n\t\t\ttop: `${src.top}px`,\n\t\t\tleft: `${src.left}px`,\n\t\t\tminWidth: `${src.width}px`,\n\t\t\twidth: 'max-content',\n\t\t\tmaxWidth: `${window.innerWidth - src.left}px`,\n\t\t\theight: 'auto',\n\t\t\tmaxHeight: `${window.innerHeight - 32}px`,\n\t\t\toverflowY: 'auto',\n\t\t})\n\n\t\tconst measured = panel.getBoundingClientRect()\n\t\tconst finalW = measured.width\n\t\tconst finalH = measured.height\n\n\t\t// 2. Adjust position so panel stays within viewport\n\t\tlet finalTop = src.top\n\t\tlet finalLeft = src.left\n\t\tif (finalTop + finalH > window.innerHeight) {\n\t\t\tfinalTop = Math.max(0, src.bottom - finalH)\n\t\t}\n\t\tif (finalLeft + finalW > window.innerWidth) {\n\t\t\tfinalLeft = Math.max(0, window.innerWidth - finalW)\n\t\t}\n\n\t\t// 3. Compute clip-path insets — summary rect expressed relative to panel final position\n\t\t// These insets shrink the visible area down to exactly the summary box\n\t\tconst insetTop = Math.max(0, src.top - finalTop)\n\t\tconst insetLeft = Math.max(0, src.left - finalLeft)\n\t\tconst insetRight = Math.max(0, finalLeft + finalW - (src.left + src.width))\n\t\tconst insetBottom = Math.max(0, finalTop + finalH - (src.top + src.height))\n\n\t\t// 4. Place panel at final size + position, masked to summary bounds (no flash)\n\t\tObject.assign(panel.style, {\n\t\t\tvisibility: '',\n\t\t\ttop: `${finalTop}px`,\n\t\t\tleft: `${finalLeft}px`,\n\t\t\tminWidth: `${src.width}px`,\n\t\t\twidth: `${finalW}px`,\n\t\t\theight: `${finalH}px`,\n\t\t\tmaxWidth: '',\n\t\t\tmaxHeight: '',\n\t\t\tclipPath: `inset(${insetTop}px ${insetRight}px ${insetBottom}px ${insetLeft}px round 0.5rem)`,\n\t\t})\n\n\t\t// 5. Animate the mask open — content revealed, not stretched\n\t\tthis._animateOpen(insetTop, insetRight, insetBottom, insetLeft, finalTop)\n\t}\n\n\t/** Animate close, return Promise resolving when done */\n\tasync triggerClose(targetRect: DOMRect): Promise<void> {\n\t\tawait this._animateClose(targetRect)\n\t\tthis.isOpen = false\n\t\tthis.summaryRect = null\n\t}\n\n\tprivate _animateOpen(insetTop: number, insetRight: number, insetBottom: number, insetLeft: number, finalTop: number) {\n\t\tconst panel = this._panelRef.value\n\t\tif (!panel) return\n\n\t\tif (reducedMotion$.value) {\n\t\t\tpanel.style.clipPath = ''\n\t\t\treturn\n\t\t}\n\n\t\tconst backdrop = this._backdropRef.value\n\t\tif (backdrop) {\n\t\t\tbackdrop.animate([{ opacity: 0 }, { opacity: 1 }], {\n\t\t\t\tduration: SPRING_SMOOTH.duration,\n\t\t\t\teasing: SPRING_SMOOTH.easingFallback,\n\t\t\t\tfill: 'forwards',\n\t\t\t})\n\t\t}\n\n\t\tconst keyframes: Keyframe[] = [\n\t\t\t{\n\t\t\t\tclipPath: `inset(${insetTop}px ${insetRight}px ${insetBottom}px ${insetLeft}px round 0.5rem)`,\n\t\t\t\topacity: 0.9,\n\t\t\t},\n\t\t\t{\n\t\t\t\tclipPath: 'inset(0px 0px 0px 0px round 1rem)',\n\t\t\t\topacity: 1,\n\t\t\t},\n\t\t]\n\n\t\tconst anim = panel.animate(keyframes, {\n\t\t\tduration: SPRING_SMOOTH.duration,\n\t\t\teasing: SPRING_SMOOTH.easingFallback,\n\t\t\tfill: 'forwards',\n\t\t})\n\n\t\t// Clear clip-path and fixed dimensions after animation so content can grow naturally,\n\t\t// but cap at viewport height so overflow-y: auto can scroll\n\t\tanim.finished.then(() => {\n\t\t\tif (panel.isConnected) {\n\t\t\t\tpanel.style.clipPath = ''\n\t\t\t\tpanel.style.height = 'auto'\n\t\t\t\tpanel.style.maxHeight = `${window.innerHeight - finalTop - 16}px`\n\t\t\t}\n\t\t})\n\n\t\tconst btn = this._btnRef.value\n\t\tif (btn) {\n\t\t\tbtn.animate([{ transform: 'rotate(0deg)' }, { transform: 'rotate(180deg)' }], {\n\t\t\t\tduration: SPRING_SMOOTH.duration,\n\t\t\t\teasing: SPRING_SMOOTH.easingFallback,\n\t\t\t\tfill: 'forwards',\n\t\t\t})\n\t\t}\n\t}\n\n\tprivate _animateClose(targetRect: DOMRect): Promise<void> {\n\t\tconst panel = this._panelRef.value\n\t\tif (!panel) return Promise.resolve()\n\t\tif (reducedMotion$.value) return Promise.resolve()\n\n\t\t// Compute insets to mask panel back down to the summary box\n\t\tconst panelRect = panel.getBoundingClientRect()\n\t\tconst insetTop = Math.max(0, targetRect.top - panelRect.top)\n\t\tconst insetLeft = Math.max(0, targetRect.left - panelRect.left)\n\t\tconst insetRight = Math.max(0, panelRect.right - targetRect.right)\n\t\tconst insetBottom = Math.max(0, panelRect.bottom - targetRect.bottom)\n\n\t\tconst closeDuration = Math.round(SPRING_SMOOTH.duration * 0.4)\n\t\tconst closeEasing = 'cubic-bezier(0.4, 0, 1, 1)'\n\n\t\tconst closeKeyframes: Keyframe[] = [\n\t\t\t{ clipPath: 'inset(0px 0px 0px 0px round 1rem)', opacity: 1 },\n\t\t\t{\n\t\t\t\tclipPath: `inset(${insetTop}px ${insetRight}px ${insetBottom}px ${insetLeft}px round 0.5rem)`,\n\t\t\t\topacity: 0.6,\n\t\t\t},\n\t\t]\n\n\t\tconst anim = panel.animate(closeKeyframes, { duration: closeDuration, easing: closeEasing, fill: 'forwards' })\n\n\t\tconst backdrop = this._backdropRef.value\n\t\tif (backdrop) {\n\t\t\tbackdrop.animate([{ opacity: 1 }, { opacity: 0 }], {\n\t\t\t\tduration: closeDuration,\n\t\t\t\teasing: closeEasing,\n\t\t\t\tfill: 'forwards',\n\t\t\t})\n\t\t}\n\n\t\tconst btn = this._btnRef.value\n\t\tif (btn) {\n\t\t\tbtn.animate([{ transform: 'rotate(180deg)' }, { transform: 'rotate(0deg)' }], {\n\t\t\t\tduration: closeDuration,\n\t\t\t\teasing: closeEasing,\n\t\t\t\tfill: 'forwards',\n\t\t\t})\n\t\t}\n\n\t\treturn anim.finished as unknown as Promise<void>\n\t}\n\n\trender() {\n\t\tif (!this.isOpen) return nothing\n\n\t\treturn html`\n\t\t\t${this._backdrop ? html`\n\t\t\t\t<div\n\t\t\t\t\t${ref(this._backdropRef)}\n\t\t\t\t\tclass=\"fixed inset-0 z-9998 backdrop-blur-sm backdrop-saturate-150 backdrop-brightness-105 bg-black/[0.07] will-change-[opacity]\"\n\t\t\t\t\t@click=${() => this._owner?.close?.()}\n\t\t\t\t></div>\n\t\t\t` : nothing}\n\t\t\t<schmancy-surface\n\t\t\t\t${ref(this._panelRef)}\n\t\t\t\tclass=\"portal-panel\"\n\t\t\t\ttype=${this.type}\n\t\t\t\tstyle=\"overflow-y: auto;\"\n\t\t\t>\n\t\t\t\t${!this._hideIndicator ? html`\n\t\t\t\t\t<button\n\t\t\t\t\t\t${ref(this._btnRef)}\n\t\t\t\t\t\tclass=\"minimize-btn\"\n\t\t\t\t\t\taria-label=\"Minimize\"\n\t\t\t\t\t\t@click=${() => this._owner?.close?.()}\n\t\t\t\t\t>\n\t\t\t\t\t\t<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t<path d=\"M19 9L12 16L5 9\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t</button>\n\t\t\t\t` : nothing}\n\t\t\t\t<slot></slot>\n\t\t\t</schmancy-surface>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-expand-root': SchmancyExpandRoot\n\t}\n}\n","import { css, html, nothing } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { createRef, ref } from 'lit/directives/ref.js'\nimport { styleMap } from 'lit/directives/style-map.js'\nimport { filter, fromEvent, lastValueFrom } from 'rxjs'\nimport { tap, takeUntil } from 'rxjs/operators'\nimport { TailwindElement } from '@mixins/index'\nimport { SPRING_SNAPPY } from '../utils/animation.js'\nimport { reducedMotion$ } from '../directives/reduced-motion'\nimport { SchmancyExpandRoot } from './expand-root.component.js'\n\n/** Dispatch this event on window to close whichever schmancy-expand is currently open */\nexport const SCHMANCY_EXPAND_REQUEST_CLOSE = 'schmancy-expand-request-close'\n\n@customElement('schmancy-expand')\nexport default class SchmancyExpand extends TailwindElement(css`\n\t:host {\n\t\tdisplay: block;\n\t}\n\n\tsummary::-webkit-details-marker {\n\t\tdisplay: none;\n\t}\n\n\tsummary {\n\t\tlist-style: none;\n\t\tcolor: inherit;\n\t}\n\n\t.inline-grid {\n\t\tdisplay: grid;\n\t\tgrid-template-rows: 0fr;\n\t\toverflow: hidden;\n\t\ttransition: grid-template-rows 300ms cubic-bezier(0.22, 1.25, 0.36, 1),\n\t\t opacity 300ms cubic-bezier(0.22, 1.25, 0.36, 1);\n\t\topacity: 0;\n\t}\n\n\t.inline-grid[data-open] {\n\t\tgrid-template-rows: 1fr;\n\t\topacity: 1;\n\t}\n\n\t.inline-grid > .inner {\n\t\tmin-height: 0;\n\t\toverflow: hidden;\n\t}\n`) {\n\t@property() summary = ''\n\n\t@property({ type: Boolean, reflect: true }) open = false\n\n\t@property({ attribute: 'summary-padding' }) summaryPadding = ''\n\n\t@property({ attribute: 'content-padding' }) contentPadding = ''\n\n\t@property({ type: Boolean, attribute: 'hide-indicator' }) hideIndicator = false\n\n\t@property({ type: Number, attribute: 'indicator-rotate' }) indicatorRotate = 90\n\n\t@property({ type: Boolean }) backdrop = true\n\n\t@property({ type: Boolean }) inline = false\n\n\tprivate _summaryRef = createRef<HTMLElement>()\n\tprivate _contentSlotRef = createRef<HTMLSlotElement>()\n\tprivate _root: SchmancyExpandRoot | null = null\n\tprivate _movedNodes: Element[] = []\n\tprivate _currentIndicatorAnim: Animation | undefined\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback()\n\n\t\t// Close on Escape key\n\t\tfromEvent<KeyboardEvent>(window, 'keydown')\n\t\t\t.pipe(\n\t\t\t\tfilter(e => e.key === 'Escape'),\n\t\t\t\tfilter(() => this.open),\n\t\t\t\ttap(() => void this._handleClose()),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe()\n\n\t\t// Close on click outside the portal panel\n\t\tfromEvent<PointerEvent>(document, 'pointerdown')\n\t\t\t.pipe(\n\t\t\t\tfilter(() => this.open),\n\t\t\t\tfilter(e => !!this._root && !e.composedPath().includes(this._root)),\n\t\t\t\ttap(() => void this._handleClose()),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe()\n\t}\n\n\tdisconnectedCallback() {\n\t\tsuper.disconnectedCallback()\n\t\tif (this._movedNodes.length > 0) {\n\t\t\tthis._movedNodes.forEach(n => this.appendChild(n))\n\t\t\tthis._movedNodes = []\n\t\t}\n\t\tif (this._root && this._root.children.length === 0) {\n\t\t\tthis._root.remove()\n\t\t\tthis._root = null\n\t\t}\n\t}\n\n\tprivate async _getOrCreateRoot(): Promise<SchmancyExpandRoot> {\n\t\tconst theme = await lastValueFrom(this.discover<HTMLElement>('schmancy-theme'))\n\t\tconst container: HTMLElement = theme ?? document.querySelector('schmancy-theme') ?? document.body\n\t\tlet root = container.querySelector('schmancy-expand-root') as SchmancyExpandRoot | null\n\t\tif (!root) {\n\t\t\troot = new SchmancyExpandRoot()\n\t\t\tcontainer.appendChild(root)\n\t\t}\n\t\treturn root\n\t}\n\n\t/** Close the expand portal, animating back to the summary position. */\n\tpublic close(): void {\n\t\tvoid this._handleClose()\n\t}\n\n\t/** Programmatically open the expand portal. */\n\tpublic expand(): void {\n\t\tif (this.open) return\n\t\tvoid this._expand()\n\t}\n\n\tprotected override updated(changed: Map<PropertyKey, unknown>) {\n\t\tsuper.updated(changed)\n\t\tif (changed.has('open') && this.open && !this.inline && !this._root) {\n\t\t\tvoid this._expand()\n\t\t}\n\t}\n\n\tprivate _toggle() {\n\t\tif (this.inline) {\n\t\t\tthis.open = !this.open\n\t\t\tthis._animateIndicator(this.open)\n\t\t} else if (!this.open) {\n\t\t\tvoid this._expand()\n\t\t}\n\t}\n\n\tprivate _handleSummaryClick(e: MouseEvent) {\n\t\te.preventDefault()\n\t\tthis._toggle()\n\t}\n\n\tprivate async _expand() {\n\t\tif (this.inline) {\n\t\t\tthis.open = true\n\t\t\tthis._animateIndicator(true)\n\t\t\treturn\n\t\t}\n\n\t\tconst root = await this._getOrCreateRoot()\n\t\tthis._root = root\n\t\tconst summary = this._summaryRef.value\n\t\tconst contentSlot = this._contentSlotRef.value\n\t\tif (!summary || !contentSlot) return\n\n\t\tconst summaryRect = summary.getBoundingClientRect()\n\t\tconst nodes = contentSlot.assignedElements({ flatten: true })\n\t\tif (nodes.length === 0) return\n\n\t\troot.prepare(summaryRect, this, this.hideIndicator, this.backdrop)\n\n\t\tthis._movedNodes = [...nodes]\n\t\tthis._movedNodes.forEach(n => root.appendChild(n))\n\n\t\troot.triggerOpen()\n\n\t\tthis._animateIndicator(true)\n\t\tthis.open = true\n\t}\n\n\tasync _handleClose() {\n\t\tif (this.inline) {\n\t\t\tthis._animateIndicator(false)\n\t\t\tthis.open = false\n\t\t\treturn\n\t\t}\n\n\t\tconst root = this._root\n\t\tconst summary = this._summaryRef.value\n\t\tif (!root || !summary) return\n\n\t\tconst summaryRect = summary.getBoundingClientRect()\n\t\tthis._animateIndicator(false)\n\n\t\tawait root.triggerClose(summaryRect)\n\n\t\tthis._movedNodes.forEach(n => this.appendChild(n))\n\t\tthis._movedNodes = []\n\t\tthis.open = false\n\t}\n\n\tprivate _animateIndicator(isOpen: boolean) {\n\t\tif (reducedMotion$.value) return\n\n\t\tconst indicator = this.shadowRoot?.querySelector('.indicator') as HTMLElement | null\n\t\tif (!indicator) return\n\n\t\tthis._currentIndicatorAnim?.cancel()\n\t\tthis._currentIndicatorAnim = indicator.animate(\n\t\t\t[\n\t\t\t\t{ transform: `rotate(${isOpen ? '0deg' : `${this.indicatorRotate}deg`})` },\n\t\t\t\t{ transform: `rotate(${isOpen ? `${this.indicatorRotate}deg` : '0deg'})` },\n\t\t\t],\n\t\t\t{\n\t\t\t\tduration: SPRING_SNAPPY.duration,\n\t\t\t\teasing: SPRING_SNAPPY.easingFallback,\n\t\t\t\tfill: 'forwards',\n\t\t\t},\n\t\t)\n\t}\n\n\trender() {\n\t\tconst summaryClasses = this.classMap({\n\t\t\t[this.summaryPadding]: true,\n\t\t\t'select-none relative flex items-center gap-2 rounded-xl transition-all duration-150': true,\n\t\t\t'hover:brightness-[0.92] active:brightness-[0.85] cursor-pointer group': true,\n\t\t\t'flex-row-reverse': true,\n\t\t})\n\n\t\treturn html`\n\t\t\t<div class=\"w-full rounded-xl\">\n\t\t\t\t<div\n\t\t\t\t\t${ref(this._summaryRef)}\n\t\t\t\t\tclass=${summaryClasses}\n\t\t\t\t\ttabindex=\"0\"\n\t\t\t\t\trole=\"button\"\n\t\t\t\t\t@click=${this._handleSummaryClick}\n\t\t\t\t\t@keydown=${(e: KeyboardEvent) => {\n\t\t\t\t\t\tif (e.key === 'Enter' || e.key === ' ') {\n\t\t\t\t\t\t\te.preventDefault()\n\t\t\t\t\t\t\tthis._toggle()\n\t\t\t\t\t\t}\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t${!this.hideIndicator\n\t\t\t\t\t\t? html`\n\t\t\t\t\t\t\t\t<span class=\"indicator flex items-center justify-center w-5 h-5 rounded-full shrink-0 opacity-70 group-hover:opacity-100 will-change-transform\">\n\t\t\t\t\t\t\t\t\t<svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t\t\t\t\td=\"M9 6L15 12L9 18\"\n\t\t\t\t\t\t\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\t\t\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\t\t\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\t\t\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t`\n\t\t\t\t\t\t: nothing}\n\n\t\t\t\t\t<span class=\"flex-1 font-medium text-base min-w-0\">\n\t\t\t\t\t\t<slot name=\"summary\">${this.summary}</slot>\n\t\t\t\t\t</span>\n\n\t\t\t\t\t<slot name=\"actions\"></slot>\n\t\t\t\t</div>\n\n\t\t\t\t${this.inline\n\t\t\t\t\t? html`\n\t\t\t\t\t\t<div class=\"inline-grid\" ?data-open=${this.open}>\n\t\t\t\t\t\t\t<div class=\"inner\">\n\t\t\t\t\t\t\t\t<slot ${ref(this._contentSlotRef)}></slot>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t`\n\t\t\t\t\t: html`\n\t\t\t\t\t\t<div style=${styleMap(this.open ? {} : { display: 'none' })}>\n\t\t\t\t\t\t\t<slot ${ref(this._contentSlotRef)}></slot>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t`}\n\t\t\t</div>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-expand': SchmancyExpand\n\t}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"expand-BmwIPNjq.cjs","names":[],"sources":["../src/expand/expand-root.component.ts","../src/expand/expand.component.ts"],"sourcesContent":["import { css, html, nothing } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { createRef, ref } from 'lit/directives/ref.js'\nimport { TailwindElement, SurfaceMixin } from '@mixins/index'\nimport type { TSurfaceColor } from '@schmancy/types'\nimport { SPRING_SMOOTH } from '../utils/animation.js'\nimport { reducedMotion$ } from '../directives/reduced-motion'\nimport '../surface/surface.js'\n\n/**\n * Container for schmancy-expand children — coordinates mutual-exclusion so only one child is open at a time. Also renders the portal panel that the active child expands into.\n *\n * @element schmancy-expand-root\n * @summary Always wrap a group of schmancy-expand children. Without a root, each schmancy-expand behaves independently (which is usually not what you want — prefer schmancy-details for that).\n * @example\n * <schmancy-expand-root>\n * <schmancy-expand summary=\"Step 1\">…</schmancy-expand>\n * <schmancy-expand summary=\"Step 2\">…</schmancy-expand>\n * </schmancy-expand-root>\n * @platform div - Coordinating wrapper. Degrades to a plain div if the tag never registers — children fall back to independent `<details>` behavior.\n */\n@customElement('schmancy-expand-root')\nexport class SchmancyExpandRoot extends SurfaceMixin(TailwindElement(css`\n\t:host {\n\t\tdisplay: contents;\n\t}\n\n\t.portal-panel {\n\t\tposition: fixed;\n\t\ttransform-origin: top left;\n\t\twill-change: clip-path, opacity;\n\t\tborder-radius: 1rem;\n\t\tbox-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.5);\n\t\tz-index: 9999;\n\t}\n\n\t.minimize-btn {\n\t\tposition: absolute;\n\t\ttop: 0.5rem;\n\t\tright: 0.5rem;\n\t\tz-index: 1;\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t\twidth: 2rem;\n\t\theight: 2rem;\n\t\tborder-radius: 9999px;\n\t\tborder: none;\n\t\tbackground: transparent;\n\t\tcursor: pointer;\n\t\topacity: 0.5;\n\t\ttransition: opacity 150ms, background 150ms;\n\t\tcolor: inherit;\n\t}\n\n\t.minimize-btn:hover {\n\t\topacity: 1;\n\t\tbackground: rgb(0 0 0 / 0.08);\n\t}\n`)) {\n\t@property({ reflect: true }) override type: TSurfaceColor = 'solid'\n\t@state() isOpen = false\n\tprivate summaryRect: DOMRect | null = null\n\n\tprivate _panelRef = createRef<HTMLElement>()\n\tprivate _backdropRef = createRef<HTMLDivElement>()\n\tprivate _btnRef = createRef<HTMLButtonElement>()\n\tprivate _owner: (Element & { close?: () => void }) | null = null\n\tprivate _hideIndicator = false\n\tprivate _backdrop = true\n\n\t/** Called by schmancy-expand before nodes are moved */\n\tprepare(rect: DOMRect, owner: Element, hideIndicator = false, backdrop = true) {\n\t\tthis.summaryRect = rect\n\t\tthis._owner = owner as Element & { close?: () => void }\n\t\tthis._hideIndicator = hideIndicator\n\t\tthis._backdrop = backdrop\n\t}\n\n\t/** Called by schmancy-expand after nodes are moved in */\n\tasync triggerOpen() {\n\t\tthis.isOpen = true\n\t\tawait this.updateComplete\n\n\t\tconst panel = this._panelRef.value\n\t\tif (!panel) return\n\n\t\tconst src = this.summaryRect!\n\n\t\t// 1. Anchor at summary's top-left, measure natural content size\n\t\t// Use nearly full viewport height for measurement so content near the bottom\n\t\t// of the screen isn't artificially capped — the positioning step will move the panel up.\n\t\tObject.assign(panel.style, {\n\t\t\tvisibility: 'hidden',\n\t\t\ttop: `${src.top}px`,\n\t\t\tleft: `${src.left}px`,\n\t\t\tminWidth: `${src.width}px`,\n\t\t\twidth: 'max-content',\n\t\t\tmaxWidth: `${window.innerWidth - src.left}px`,\n\t\t\theight: 'auto',\n\t\t\tmaxHeight: `${window.innerHeight - 32}px`,\n\t\t\toverflowY: 'auto',\n\t\t})\n\n\t\tconst measured = panel.getBoundingClientRect()\n\t\tconst finalW = measured.width\n\t\tconst finalH = measured.height\n\n\t\t// 2. Adjust position so panel stays within viewport\n\t\tlet finalTop = src.top\n\t\tlet finalLeft = src.left\n\t\tif (finalTop + finalH > window.innerHeight) {\n\t\t\tfinalTop = Math.max(0, src.bottom - finalH)\n\t\t}\n\t\tif (finalLeft + finalW > window.innerWidth) {\n\t\t\tfinalLeft = Math.max(0, window.innerWidth - finalW)\n\t\t}\n\n\t\t// 3. Compute clip-path insets — summary rect expressed relative to panel final position\n\t\t// These insets shrink the visible area down to exactly the summary box\n\t\tconst insetTop = Math.max(0, src.top - finalTop)\n\t\tconst insetLeft = Math.max(0, src.left - finalLeft)\n\t\tconst insetRight = Math.max(0, finalLeft + finalW - (src.left + src.width))\n\t\tconst insetBottom = Math.max(0, finalTop + finalH - (src.top + src.height))\n\n\t\t// 4. Place panel at final size + position, masked to summary bounds (no flash)\n\t\tObject.assign(panel.style, {\n\t\t\tvisibility: '',\n\t\t\ttop: `${finalTop}px`,\n\t\t\tleft: `${finalLeft}px`,\n\t\t\tminWidth: `${src.width}px`,\n\t\t\twidth: `${finalW}px`,\n\t\t\theight: `${finalH}px`,\n\t\t\tmaxWidth: '',\n\t\t\tmaxHeight: '',\n\t\t\tclipPath: `inset(${insetTop}px ${insetRight}px ${insetBottom}px ${insetLeft}px round 0.5rem)`,\n\t\t})\n\n\t\t// 5. Animate the mask open — content revealed, not stretched\n\t\tthis._animateOpen(insetTop, insetRight, insetBottom, insetLeft, finalTop)\n\t}\n\n\t/** Animate close, return Promise resolving when done */\n\tasync triggerClose(targetRect: DOMRect): Promise<void> {\n\t\tawait this._animateClose(targetRect)\n\t\tthis.isOpen = false\n\t\tthis.summaryRect = null\n\t}\n\n\tprivate _animateOpen(insetTop: number, insetRight: number, insetBottom: number, insetLeft: number, finalTop: number) {\n\t\tconst panel = this._panelRef.value\n\t\tif (!panel) return\n\n\t\tif (reducedMotion$.value) {\n\t\t\tpanel.style.clipPath = ''\n\t\t\treturn\n\t\t}\n\n\t\tconst backdrop = this._backdropRef.value\n\t\tif (backdrop) {\n\t\t\tbackdrop.animate([{ opacity: 0 }, { opacity: 1 }], {\n\t\t\t\tduration: SPRING_SMOOTH.duration,\n\t\t\t\teasing: SPRING_SMOOTH.easingFallback,\n\t\t\t\tfill: 'forwards',\n\t\t\t})\n\t\t}\n\n\t\tconst keyframes: Keyframe[] = [\n\t\t\t{\n\t\t\t\tclipPath: `inset(${insetTop}px ${insetRight}px ${insetBottom}px ${insetLeft}px round 0.5rem)`,\n\t\t\t\topacity: 0.9,\n\t\t\t},\n\t\t\t{\n\t\t\t\tclipPath: 'inset(0px 0px 0px 0px round 1rem)',\n\t\t\t\topacity: 1,\n\t\t\t},\n\t\t]\n\n\t\tconst anim = panel.animate(keyframes, {\n\t\t\tduration: SPRING_SMOOTH.duration,\n\t\t\teasing: SPRING_SMOOTH.easingFallback,\n\t\t\tfill: 'forwards',\n\t\t})\n\n\t\t// Clear clip-path and fixed dimensions after animation so content can grow naturally,\n\t\t// but cap at viewport height so overflow-y: auto can scroll\n\t\tanim.finished.then(() => {\n\t\t\tif (panel.isConnected) {\n\t\t\t\tpanel.style.clipPath = ''\n\t\t\t\tpanel.style.height = 'auto'\n\t\t\t\tpanel.style.maxHeight = `${window.innerHeight - finalTop - 16}px`\n\t\t\t}\n\t\t})\n\n\t\tconst btn = this._btnRef.value\n\t\tif (btn) {\n\t\t\tbtn.animate([{ transform: 'rotate(0deg)' }, { transform: 'rotate(180deg)' }], {\n\t\t\t\tduration: SPRING_SMOOTH.duration,\n\t\t\t\teasing: SPRING_SMOOTH.easingFallback,\n\t\t\t\tfill: 'forwards',\n\t\t\t})\n\t\t}\n\t}\n\n\tprivate _animateClose(targetRect: DOMRect): Promise<void> {\n\t\tconst panel = this._panelRef.value\n\t\tif (!panel) return Promise.resolve()\n\t\tif (reducedMotion$.value) return Promise.resolve()\n\n\t\t// Compute insets to mask panel back down to the summary box\n\t\tconst panelRect = panel.getBoundingClientRect()\n\t\tconst insetTop = Math.max(0, targetRect.top - panelRect.top)\n\t\tconst insetLeft = Math.max(0, targetRect.left - panelRect.left)\n\t\tconst insetRight = Math.max(0, panelRect.right - targetRect.right)\n\t\tconst insetBottom = Math.max(0, panelRect.bottom - targetRect.bottom)\n\n\t\tconst closeDuration = Math.round(SPRING_SMOOTH.duration * 0.4)\n\t\tconst closeEasing = 'cubic-bezier(0.4, 0, 1, 1)'\n\n\t\tconst closeKeyframes: Keyframe[] = [\n\t\t\t{ clipPath: 'inset(0px 0px 0px 0px round 1rem)', opacity: 1 },\n\t\t\t{\n\t\t\t\tclipPath: `inset(${insetTop}px ${insetRight}px ${insetBottom}px ${insetLeft}px round 0.5rem)`,\n\t\t\t\topacity: 0.6,\n\t\t\t},\n\t\t]\n\n\t\tconst anim = panel.animate(closeKeyframes, { duration: closeDuration, easing: closeEasing, fill: 'forwards' })\n\n\t\tconst backdrop = this._backdropRef.value\n\t\tif (backdrop) {\n\t\t\tbackdrop.animate([{ opacity: 1 }, { opacity: 0 }], {\n\t\t\t\tduration: closeDuration,\n\t\t\t\teasing: closeEasing,\n\t\t\t\tfill: 'forwards',\n\t\t\t})\n\t\t}\n\n\t\tconst btn = this._btnRef.value\n\t\tif (btn) {\n\t\t\tbtn.animate([{ transform: 'rotate(180deg)' }, { transform: 'rotate(0deg)' }], {\n\t\t\t\tduration: closeDuration,\n\t\t\t\teasing: closeEasing,\n\t\t\t\tfill: 'forwards',\n\t\t\t})\n\t\t}\n\n\t\treturn anim.finished as unknown as Promise<void>\n\t}\n\n\trender() {\n\t\tif (!this.isOpen) return nothing\n\n\t\treturn html`\n\t\t\t${this._backdrop ? html`\n\t\t\t\t<div\n\t\t\t\t\t${ref(this._backdropRef)}\n\t\t\t\t\tclass=\"fixed inset-0 z-9998 backdrop-blur-sm backdrop-saturate-150 backdrop-brightness-105 bg-black/[0.07] will-change-[opacity]\"\n\t\t\t\t\t@click=${() => this._owner?.close?.()}\n\t\t\t\t></div>\n\t\t\t` : nothing}\n\t\t\t<schmancy-surface\n\t\t\t\t${ref(this._panelRef)}\n\t\t\t\tclass=\"portal-panel\"\n\t\t\t\ttype=${this.type}\n\t\t\t\tstyle=\"overflow-y: auto;\"\n\t\t\t>\n\t\t\t\t${!this._hideIndicator ? html`\n\t\t\t\t\t<button\n\t\t\t\t\t\t${ref(this._btnRef)}\n\t\t\t\t\t\tclass=\"minimize-btn\"\n\t\t\t\t\t\taria-label=\"Minimize\"\n\t\t\t\t\t\t@click=${() => this._owner?.close?.()}\n\t\t\t\t\t>\n\t\t\t\t\t\t<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t<path d=\"M19 9L12 16L5 9\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t</button>\n\t\t\t\t` : nothing}\n\t\t\t\t<slot></slot>\n\t\t\t</schmancy-surface>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-expand-root': SchmancyExpandRoot\n\t}\n}\n","import { css, html, nothing } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { createRef, ref } from 'lit/directives/ref.js'\nimport { styleMap } from 'lit/directives/style-map.js'\nimport { filter, fromEvent, lastValueFrom } from 'rxjs'\nimport { tap, takeUntil } from 'rxjs/operators'\nimport { TailwindElement } from '@mixins/index'\nimport { SPRING_SNAPPY } from '../utils/animation.js'\nimport { reducedMotion$ } from '../directives/reduced-motion'\nimport { SchmancyExpandRoot } from './expand-root.component.js'\n\n/** Dispatch this event on window to close whichever schmancy-expand is currently open */\nexport const SCHMANCY_EXPAND_REQUEST_CLOSE = 'schmancy-expand-request-close'\n\n/**\n * Accordion-style section — expands on click, coordinates with siblings via schmancy-expand-root to close any sibling when a new one opens. Only one schmancy-expand can be open at a time within the same root.\n *\n * @element schmancy-expand\n * @summary Use for grouped progressive-disclosure where only one section should be open at a time. Prefer schmancy-details when sections should be independent.\n * @example\n * <schmancy-expand-root>\n * <schmancy-expand summary=\"Billing\">Billing form…</schmancy-expand>\n * <schmancy-expand summary=\"Shipping\">Shipping form…</schmancy-expand>\n * <schmancy-expand summary=\"Review\">Order review…</schmancy-expand>\n * </schmancy-expand-root>\n * @platform details toggle - Schmancy-skinned accordion section. Degrades to `<details>` if the tag never registers — loses mutual-exclusion behavior but stays functional.\n * @fires toggle - When the open state changes.\n */\n@customElement('schmancy-expand')\nexport default class SchmancyExpand extends TailwindElement(css`\n\t:host {\n\t\tdisplay: block;\n\t}\n\n\tsummary::-webkit-details-marker {\n\t\tdisplay: none;\n\t}\n\n\tsummary {\n\t\tlist-style: none;\n\t\tcolor: inherit;\n\t}\n\n\t.inline-grid {\n\t\tdisplay: grid;\n\t\tgrid-template-rows: 0fr;\n\t\toverflow: hidden;\n\t\ttransition: grid-template-rows 300ms cubic-bezier(0.22, 1.25, 0.36, 1),\n\t\t opacity 300ms cubic-bezier(0.22, 1.25, 0.36, 1);\n\t\topacity: 0;\n\t}\n\n\t.inline-grid[data-open] {\n\t\tgrid-template-rows: 1fr;\n\t\topacity: 1;\n\t}\n\n\t.inline-grid > .inner {\n\t\tmin-height: 0;\n\t\toverflow: hidden;\n\t}\n`) {\n\t@property() summary = ''\n\n\t@property({ type: Boolean, reflect: true }) open = false\n\n\t@property({ attribute: 'summary-padding' }) summaryPadding = ''\n\n\t@property({ attribute: 'content-padding' }) contentPadding = ''\n\n\t@property({ type: Boolean, attribute: 'hide-indicator' }) hideIndicator = false\n\n\t@property({ type: Number, attribute: 'indicator-rotate' }) indicatorRotate = 90\n\n\t@property({ type: Boolean }) backdrop = true\n\n\t@property({ type: Boolean }) inline = false\n\n\tprivate _summaryRef = createRef<HTMLElement>()\n\tprivate _contentSlotRef = createRef<HTMLSlotElement>()\n\tprivate _root: SchmancyExpandRoot | null = null\n\tprivate _movedNodes: Element[] = []\n\tprivate _currentIndicatorAnim: Animation | undefined\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback()\n\n\t\t// Close on Escape key\n\t\tfromEvent<KeyboardEvent>(window, 'keydown')\n\t\t\t.pipe(\n\t\t\t\tfilter(e => e.key === 'Escape'),\n\t\t\t\tfilter(() => this.open),\n\t\t\t\ttap(() => void this._handleClose()),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe()\n\n\t\t// Close on click outside the portal panel\n\t\tfromEvent<PointerEvent>(document, 'pointerdown')\n\t\t\t.pipe(\n\t\t\t\tfilter(() => this.open),\n\t\t\t\tfilter(e => !!this._root && !e.composedPath().includes(this._root)),\n\t\t\t\ttap(() => void this._handleClose()),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe()\n\t}\n\n\tdisconnectedCallback() {\n\t\tsuper.disconnectedCallback()\n\t\tif (this._movedNodes.length > 0) {\n\t\t\tthis._movedNodes.forEach(n => this.appendChild(n))\n\t\t\tthis._movedNodes = []\n\t\t}\n\t\tif (this._root && this._root.children.length === 0) {\n\t\t\tthis._root.remove()\n\t\t\tthis._root = null\n\t\t}\n\t}\n\n\tprivate async _getOrCreateRoot(): Promise<SchmancyExpandRoot> {\n\t\tconst theme = await lastValueFrom(this.discover<HTMLElement>('schmancy-theme'))\n\t\tconst container: HTMLElement = theme ?? document.querySelector('schmancy-theme') ?? document.body\n\t\tlet root = container.querySelector('schmancy-expand-root') as SchmancyExpandRoot | null\n\t\tif (!root) {\n\t\t\troot = new SchmancyExpandRoot()\n\t\t\tcontainer.appendChild(root)\n\t\t}\n\t\treturn root\n\t}\n\n\t/** Close the expand portal, animating back to the summary position. */\n\tpublic close(): void {\n\t\tvoid this._handleClose()\n\t}\n\n\t/** Programmatically open the expand portal. */\n\tpublic expand(): void {\n\t\tif (this.open) return\n\t\tvoid this._expand()\n\t}\n\n\tprotected override updated(changed: Map<PropertyKey, unknown>) {\n\t\tsuper.updated(changed)\n\t\tif (changed.has('open') && this.open && !this.inline && !this._root) {\n\t\t\tvoid this._expand()\n\t\t}\n\t}\n\n\tprivate _toggle() {\n\t\tif (this.inline) {\n\t\t\tthis.open = !this.open\n\t\t\tthis._animateIndicator(this.open)\n\t\t} else if (!this.open) {\n\t\t\tvoid this._expand()\n\t\t}\n\t}\n\n\tprivate _handleSummaryClick(e: MouseEvent) {\n\t\te.preventDefault()\n\t\tthis._toggle()\n\t}\n\n\tprivate async _expand() {\n\t\tif (this.inline) {\n\t\t\tthis.open = true\n\t\t\tthis._animateIndicator(true)\n\t\t\treturn\n\t\t}\n\n\t\tconst root = await this._getOrCreateRoot()\n\t\tthis._root = root\n\t\tconst summary = this._summaryRef.value\n\t\tconst contentSlot = this._contentSlotRef.value\n\t\tif (!summary || !contentSlot) return\n\n\t\tconst summaryRect = summary.getBoundingClientRect()\n\t\tconst nodes = contentSlot.assignedElements({ flatten: true })\n\t\tif (nodes.length === 0) return\n\n\t\troot.prepare(summaryRect, this, this.hideIndicator, this.backdrop)\n\n\t\tthis._movedNodes = [...nodes]\n\t\tthis._movedNodes.forEach(n => root.appendChild(n))\n\n\t\troot.triggerOpen()\n\n\t\tthis._animateIndicator(true)\n\t\tthis.open = true\n\t}\n\n\tasync _handleClose() {\n\t\tif (this.inline) {\n\t\t\tthis._animateIndicator(false)\n\t\t\tthis.open = false\n\t\t\treturn\n\t\t}\n\n\t\tconst root = this._root\n\t\tconst summary = this._summaryRef.value\n\t\tif (!root || !summary) return\n\n\t\tconst summaryRect = summary.getBoundingClientRect()\n\t\tthis._animateIndicator(false)\n\n\t\tawait root.triggerClose(summaryRect)\n\n\t\tthis._movedNodes.forEach(n => this.appendChild(n))\n\t\tthis._movedNodes = []\n\t\tthis.open = false\n\t}\n\n\tprivate _animateIndicator(isOpen: boolean) {\n\t\tif (reducedMotion$.value) return\n\n\t\tconst indicator = this.shadowRoot?.querySelector('.indicator') as HTMLElement | null\n\t\tif (!indicator) return\n\n\t\tthis._currentIndicatorAnim?.cancel()\n\t\tthis._currentIndicatorAnim = indicator.animate(\n\t\t\t[\n\t\t\t\t{ transform: `rotate(${isOpen ? '0deg' : `${this.indicatorRotate}deg`})` },\n\t\t\t\t{ transform: `rotate(${isOpen ? `${this.indicatorRotate}deg` : '0deg'})` },\n\t\t\t],\n\t\t\t{\n\t\t\t\tduration: SPRING_SNAPPY.duration,\n\t\t\t\teasing: SPRING_SNAPPY.easingFallback,\n\t\t\t\tfill: 'forwards',\n\t\t\t},\n\t\t)\n\t}\n\n\trender() {\n\t\tconst summaryClasses = this.classMap({\n\t\t\t[this.summaryPadding]: true,\n\t\t\t'select-none relative flex items-center gap-2 rounded-xl transition-all duration-150': true,\n\t\t\t'hover:brightness-[0.92] active:brightness-[0.85] cursor-pointer group': true,\n\t\t\t'flex-row-reverse': true,\n\t\t})\n\n\t\treturn html`\n\t\t\t<div class=\"w-full rounded-xl\">\n\t\t\t\t<div\n\t\t\t\t\t${ref(this._summaryRef)}\n\t\t\t\t\tclass=${summaryClasses}\n\t\t\t\t\ttabindex=\"0\"\n\t\t\t\t\trole=\"button\"\n\t\t\t\t\t@click=${this._handleSummaryClick}\n\t\t\t\t\t@keydown=${(e: KeyboardEvent) => {\n\t\t\t\t\t\tif (e.key === 'Enter' || e.key === ' ') {\n\t\t\t\t\t\t\te.preventDefault()\n\t\t\t\t\t\t\tthis._toggle()\n\t\t\t\t\t\t}\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t${!this.hideIndicator\n\t\t\t\t\t\t? html`\n\t\t\t\t\t\t\t\t<span class=\"indicator flex items-center justify-center w-5 h-5 rounded-full shrink-0 opacity-70 group-hover:opacity-100 will-change-transform\">\n\t\t\t\t\t\t\t\t\t<svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t\t\t\t\td=\"M9 6L15 12L9 18\"\n\t\t\t\t\t\t\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\t\t\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\t\t\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\t\t\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t`\n\t\t\t\t\t\t: nothing}\n\n\t\t\t\t\t<span class=\"flex-1 font-medium text-base min-w-0\">\n\t\t\t\t\t\t<slot name=\"summary\">${this.summary}</slot>\n\t\t\t\t\t</span>\n\n\t\t\t\t\t<slot name=\"actions\"></slot>\n\t\t\t\t</div>\n\n\t\t\t\t${this.inline\n\t\t\t\t\t? html`\n\t\t\t\t\t\t<div class=\"inline-grid\" ?data-open=${this.open}>\n\t\t\t\t\t\t\t<div class=\"inner\">\n\t\t\t\t\t\t\t\t<slot ${ref(this._contentSlotRef)}></slot>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t`\n\t\t\t\t\t: html`\n\t\t\t\t\t\t<div style=${styleMap(this.open ? {} : { display: 'none' })}>\n\t\t\t\t\t\t\t<slot ${ref(this._contentSlotRef)}></slot>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t`}\n\t\t\t</div>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-expand': SchmancyExpand\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"expand-bFa_qVDT.js","names":[],"sources":["../src/expand/expand-root.component.ts","../src/expand/expand.component.ts"],"sourcesContent":["import { css, html, nothing } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { createRef, ref } from 'lit/directives/ref.js'\nimport { TailwindElement, SurfaceMixin } from '@mixins/index'\nimport type { TSurfaceColor } from '@schmancy/types'\nimport { SPRING_SMOOTH } from '../utils/animation.js'\nimport { reducedMotion$ } from '../directives/reduced-motion'\nimport '../surface/surface.js'\n\n@customElement('schmancy-expand-root')\nexport class SchmancyExpandRoot extends SurfaceMixin(TailwindElement(css`\n\t:host {\n\t\tdisplay: contents;\n\t}\n\n\t.portal-panel {\n\t\tposition: fixed;\n\t\ttransform-origin: top left;\n\t\twill-change: clip-path, opacity;\n\t\tborder-radius: 1rem;\n\t\tbox-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.5);\n\t\tz-index: 9999;\n\t}\n\n\t.minimize-btn {\n\t\tposition: absolute;\n\t\ttop: 0.5rem;\n\t\tright: 0.5rem;\n\t\tz-index: 1;\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t\twidth: 2rem;\n\t\theight: 2rem;\n\t\tborder-radius: 9999px;\n\t\tborder: none;\n\t\tbackground: transparent;\n\t\tcursor: pointer;\n\t\topacity: 0.5;\n\t\ttransition: opacity 150ms, background 150ms;\n\t\tcolor: inherit;\n\t}\n\n\t.minimize-btn:hover {\n\t\topacity: 1;\n\t\tbackground: rgb(0 0 0 / 0.08);\n\t}\n`)) {\n\t@property({ reflect: true }) override type: TSurfaceColor = 'solid'\n\t@state() isOpen = false\n\tprivate summaryRect: DOMRect | null = null\n\n\tprivate _panelRef = createRef<HTMLElement>()\n\tprivate _backdropRef = createRef<HTMLDivElement>()\n\tprivate _btnRef = createRef<HTMLButtonElement>()\n\tprivate _owner: (Element & { close?: () => void }) | null = null\n\tprivate _hideIndicator = false\n\tprivate _backdrop = true\n\n\t/** Called by schmancy-expand before nodes are moved */\n\tprepare(rect: DOMRect, owner: Element, hideIndicator = false, backdrop = true) {\n\t\tthis.summaryRect = rect\n\t\tthis._owner = owner as Element & { close?: () => void }\n\t\tthis._hideIndicator = hideIndicator\n\t\tthis._backdrop = backdrop\n\t}\n\n\t/** Called by schmancy-expand after nodes are moved in */\n\tasync triggerOpen() {\n\t\tthis.isOpen = true\n\t\tawait this.updateComplete\n\n\t\tconst panel = this._panelRef.value\n\t\tif (!panel) return\n\n\t\tconst src = this.summaryRect!\n\n\t\t// 1. Anchor at summary's top-left, measure natural content size\n\t\t// Use nearly full viewport height for measurement so content near the bottom\n\t\t// of the screen isn't artificially capped — the positioning step will move the panel up.\n\t\tObject.assign(panel.style, {\n\t\t\tvisibility: 'hidden',\n\t\t\ttop: `${src.top}px`,\n\t\t\tleft: `${src.left}px`,\n\t\t\tminWidth: `${src.width}px`,\n\t\t\twidth: 'max-content',\n\t\t\tmaxWidth: `${window.innerWidth - src.left}px`,\n\t\t\theight: 'auto',\n\t\t\tmaxHeight: `${window.innerHeight - 32}px`,\n\t\t\toverflowY: 'auto',\n\t\t})\n\n\t\tconst measured = panel.getBoundingClientRect()\n\t\tconst finalW = measured.width\n\t\tconst finalH = measured.height\n\n\t\t// 2. Adjust position so panel stays within viewport\n\t\tlet finalTop = src.top\n\t\tlet finalLeft = src.left\n\t\tif (finalTop + finalH > window.innerHeight) {\n\t\t\tfinalTop = Math.max(0, src.bottom - finalH)\n\t\t}\n\t\tif (finalLeft + finalW > window.innerWidth) {\n\t\t\tfinalLeft = Math.max(0, window.innerWidth - finalW)\n\t\t}\n\n\t\t// 3. Compute clip-path insets — summary rect expressed relative to panel final position\n\t\t// These insets shrink the visible area down to exactly the summary box\n\t\tconst insetTop = Math.max(0, src.top - finalTop)\n\t\tconst insetLeft = Math.max(0, src.left - finalLeft)\n\t\tconst insetRight = Math.max(0, finalLeft + finalW - (src.left + src.width))\n\t\tconst insetBottom = Math.max(0, finalTop + finalH - (src.top + src.height))\n\n\t\t// 4. Place panel at final size + position, masked to summary bounds (no flash)\n\t\tObject.assign(panel.style, {\n\t\t\tvisibility: '',\n\t\t\ttop: `${finalTop}px`,\n\t\t\tleft: `${finalLeft}px`,\n\t\t\tminWidth: `${src.width}px`,\n\t\t\twidth: `${finalW}px`,\n\t\t\theight: `${finalH}px`,\n\t\t\tmaxWidth: '',\n\t\t\tmaxHeight: '',\n\t\t\tclipPath: `inset(${insetTop}px ${insetRight}px ${insetBottom}px ${insetLeft}px round 0.5rem)`,\n\t\t})\n\n\t\t// 5. Animate the mask open — content revealed, not stretched\n\t\tthis._animateOpen(insetTop, insetRight, insetBottom, insetLeft, finalTop)\n\t}\n\n\t/** Animate close, return Promise resolving when done */\n\tasync triggerClose(targetRect: DOMRect): Promise<void> {\n\t\tawait this._animateClose(targetRect)\n\t\tthis.isOpen = false\n\t\tthis.summaryRect = null\n\t}\n\n\tprivate _animateOpen(insetTop: number, insetRight: number, insetBottom: number, insetLeft: number, finalTop: number) {\n\t\tconst panel = this._panelRef.value\n\t\tif (!panel) return\n\n\t\tif (reducedMotion$.value) {\n\t\t\tpanel.style.clipPath = ''\n\t\t\treturn\n\t\t}\n\n\t\tconst backdrop = this._backdropRef.value\n\t\tif (backdrop) {\n\t\t\tbackdrop.animate([{ opacity: 0 }, { opacity: 1 }], {\n\t\t\t\tduration: SPRING_SMOOTH.duration,\n\t\t\t\teasing: SPRING_SMOOTH.easingFallback,\n\t\t\t\tfill: 'forwards',\n\t\t\t})\n\t\t}\n\n\t\tconst keyframes: Keyframe[] = [\n\t\t\t{\n\t\t\t\tclipPath: `inset(${insetTop}px ${insetRight}px ${insetBottom}px ${insetLeft}px round 0.5rem)`,\n\t\t\t\topacity: 0.9,\n\t\t\t},\n\t\t\t{\n\t\t\t\tclipPath: 'inset(0px 0px 0px 0px round 1rem)',\n\t\t\t\topacity: 1,\n\t\t\t},\n\t\t]\n\n\t\tconst anim = panel.animate(keyframes, {\n\t\t\tduration: SPRING_SMOOTH.duration,\n\t\t\teasing: SPRING_SMOOTH.easingFallback,\n\t\t\tfill: 'forwards',\n\t\t})\n\n\t\t// Clear clip-path and fixed dimensions after animation so content can grow naturally,\n\t\t// but cap at viewport height so overflow-y: auto can scroll\n\t\tanim.finished.then(() => {\n\t\t\tif (panel.isConnected) {\n\t\t\t\tpanel.style.clipPath = ''\n\t\t\t\tpanel.style.height = 'auto'\n\t\t\t\tpanel.style.maxHeight = `${window.innerHeight - finalTop - 16}px`\n\t\t\t}\n\t\t})\n\n\t\tconst btn = this._btnRef.value\n\t\tif (btn) {\n\t\t\tbtn.animate([{ transform: 'rotate(0deg)' }, { transform: 'rotate(180deg)' }], {\n\t\t\t\tduration: SPRING_SMOOTH.duration,\n\t\t\t\teasing: SPRING_SMOOTH.easingFallback,\n\t\t\t\tfill: 'forwards',\n\t\t\t})\n\t\t}\n\t}\n\n\tprivate _animateClose(targetRect: DOMRect): Promise<void> {\n\t\tconst panel = this._panelRef.value\n\t\tif (!panel) return Promise.resolve()\n\t\tif (reducedMotion$.value) return Promise.resolve()\n\n\t\t// Compute insets to mask panel back down to the summary box\n\t\tconst panelRect = panel.getBoundingClientRect()\n\t\tconst insetTop = Math.max(0, targetRect.top - panelRect.top)\n\t\tconst insetLeft = Math.max(0, targetRect.left - panelRect.left)\n\t\tconst insetRight = Math.max(0, panelRect.right - targetRect.right)\n\t\tconst insetBottom = Math.max(0, panelRect.bottom - targetRect.bottom)\n\n\t\tconst closeDuration = Math.round(SPRING_SMOOTH.duration * 0.4)\n\t\tconst closeEasing = 'cubic-bezier(0.4, 0, 1, 1)'\n\n\t\tconst closeKeyframes: Keyframe[] = [\n\t\t\t{ clipPath: 'inset(0px 0px 0px 0px round 1rem)', opacity: 1 },\n\t\t\t{\n\t\t\t\tclipPath: `inset(${insetTop}px ${insetRight}px ${insetBottom}px ${insetLeft}px round 0.5rem)`,\n\t\t\t\topacity: 0.6,\n\t\t\t},\n\t\t]\n\n\t\tconst anim = panel.animate(closeKeyframes, { duration: closeDuration, easing: closeEasing, fill: 'forwards' })\n\n\t\tconst backdrop = this._backdropRef.value\n\t\tif (backdrop) {\n\t\t\tbackdrop.animate([{ opacity: 1 }, { opacity: 0 }], {\n\t\t\t\tduration: closeDuration,\n\t\t\t\teasing: closeEasing,\n\t\t\t\tfill: 'forwards',\n\t\t\t})\n\t\t}\n\n\t\tconst btn = this._btnRef.value\n\t\tif (btn) {\n\t\t\tbtn.animate([{ transform: 'rotate(180deg)' }, { transform: 'rotate(0deg)' }], {\n\t\t\t\tduration: closeDuration,\n\t\t\t\teasing: closeEasing,\n\t\t\t\tfill: 'forwards',\n\t\t\t})\n\t\t}\n\n\t\treturn anim.finished as unknown as Promise<void>\n\t}\n\n\trender() {\n\t\tif (!this.isOpen) return nothing\n\n\t\treturn html`\n\t\t\t${this._backdrop ? html`\n\t\t\t\t<div\n\t\t\t\t\t${ref(this._backdropRef)}\n\t\t\t\t\tclass=\"fixed inset-0 z-9998 backdrop-blur-sm backdrop-saturate-150 backdrop-brightness-105 bg-black/[0.07] will-change-[opacity]\"\n\t\t\t\t\t@click=${() => this._owner?.close?.()}\n\t\t\t\t></div>\n\t\t\t` : nothing}\n\t\t\t<schmancy-surface\n\t\t\t\t${ref(this._panelRef)}\n\t\t\t\tclass=\"portal-panel\"\n\t\t\t\ttype=${this.type}\n\t\t\t\tstyle=\"overflow-y: auto;\"\n\t\t\t>\n\t\t\t\t${!this._hideIndicator ? html`\n\t\t\t\t\t<button\n\t\t\t\t\t\t${ref(this._btnRef)}\n\t\t\t\t\t\tclass=\"minimize-btn\"\n\t\t\t\t\t\taria-label=\"Minimize\"\n\t\t\t\t\t\t@click=${() => this._owner?.close?.()}\n\t\t\t\t\t>\n\t\t\t\t\t\t<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t<path d=\"M19 9L12 16L5 9\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t</button>\n\t\t\t\t` : nothing}\n\t\t\t\t<slot></slot>\n\t\t\t</schmancy-surface>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-expand-root': SchmancyExpandRoot\n\t}\n}\n","import { css, html, nothing } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { createRef, ref } from 'lit/directives/ref.js'\nimport { styleMap } from 'lit/directives/style-map.js'\nimport { filter, fromEvent, lastValueFrom } from 'rxjs'\nimport { tap, takeUntil } from 'rxjs/operators'\nimport { TailwindElement } from '@mixins/index'\nimport { SPRING_SNAPPY } from '../utils/animation.js'\nimport { reducedMotion$ } from '../directives/reduced-motion'\nimport { SchmancyExpandRoot } from './expand-root.component.js'\n\n/** Dispatch this event on window to close whichever schmancy-expand is currently open */\nexport const SCHMANCY_EXPAND_REQUEST_CLOSE = 'schmancy-expand-request-close'\n\n@customElement('schmancy-expand')\nexport default class SchmancyExpand extends TailwindElement(css`\n\t:host {\n\t\tdisplay: block;\n\t}\n\n\tsummary::-webkit-details-marker {\n\t\tdisplay: none;\n\t}\n\n\tsummary {\n\t\tlist-style: none;\n\t\tcolor: inherit;\n\t}\n\n\t.inline-grid {\n\t\tdisplay: grid;\n\t\tgrid-template-rows: 0fr;\n\t\toverflow: hidden;\n\t\ttransition: grid-template-rows 300ms cubic-bezier(0.22, 1.25, 0.36, 1),\n\t\t opacity 300ms cubic-bezier(0.22, 1.25, 0.36, 1);\n\t\topacity: 0;\n\t}\n\n\t.inline-grid[data-open] {\n\t\tgrid-template-rows: 1fr;\n\t\topacity: 1;\n\t}\n\n\t.inline-grid > .inner {\n\t\tmin-height: 0;\n\t\toverflow: hidden;\n\t}\n`) {\n\t@property() summary = ''\n\n\t@property({ type: Boolean, reflect: true }) open = false\n\n\t@property({ attribute: 'summary-padding' }) summaryPadding = ''\n\n\t@property({ attribute: 'content-padding' }) contentPadding = ''\n\n\t@property({ type: Boolean, attribute: 'hide-indicator' }) hideIndicator = false\n\n\t@property({ type: Number, attribute: 'indicator-rotate' }) indicatorRotate = 90\n\n\t@property({ type: Boolean }) backdrop = true\n\n\t@property({ type: Boolean }) inline = false\n\n\tprivate _summaryRef = createRef<HTMLElement>()\n\tprivate _contentSlotRef = createRef<HTMLSlotElement>()\n\tprivate _root: SchmancyExpandRoot | null = null\n\tprivate _movedNodes: Element[] = []\n\tprivate _currentIndicatorAnim: Animation | undefined\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback()\n\n\t\t// Close on Escape key\n\t\tfromEvent<KeyboardEvent>(window, 'keydown')\n\t\t\t.pipe(\n\t\t\t\tfilter(e => e.key === 'Escape'),\n\t\t\t\tfilter(() => this.open),\n\t\t\t\ttap(() => void this._handleClose()),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe()\n\n\t\t// Close on click outside the portal panel\n\t\tfromEvent<PointerEvent>(document, 'pointerdown')\n\t\t\t.pipe(\n\t\t\t\tfilter(() => this.open),\n\t\t\t\tfilter(e => !!this._root && !e.composedPath().includes(this._root)),\n\t\t\t\ttap(() => void this._handleClose()),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe()\n\t}\n\n\tdisconnectedCallback() {\n\t\tsuper.disconnectedCallback()\n\t\tif (this._movedNodes.length > 0) {\n\t\t\tthis._movedNodes.forEach(n => this.appendChild(n))\n\t\t\tthis._movedNodes = []\n\t\t}\n\t\tif (this._root && this._root.children.length === 0) {\n\t\t\tthis._root.remove()\n\t\t\tthis._root = null\n\t\t}\n\t}\n\n\tprivate async _getOrCreateRoot(): Promise<SchmancyExpandRoot> {\n\t\tconst theme = await lastValueFrom(this.discover<HTMLElement>('schmancy-theme'))\n\t\tconst container: HTMLElement = theme ?? document.querySelector('schmancy-theme') ?? document.body\n\t\tlet root = container.querySelector('schmancy-expand-root') as SchmancyExpandRoot | null\n\t\tif (!root) {\n\t\t\troot = new SchmancyExpandRoot()\n\t\t\tcontainer.appendChild(root)\n\t\t}\n\t\treturn root\n\t}\n\n\t/** Close the expand portal, animating back to the summary position. */\n\tpublic close(): void {\n\t\tvoid this._handleClose()\n\t}\n\n\t/** Programmatically open the expand portal. */\n\tpublic expand(): void {\n\t\tif (this.open) return\n\t\tvoid this._expand()\n\t}\n\n\tprotected override updated(changed: Map<PropertyKey, unknown>) {\n\t\tsuper.updated(changed)\n\t\tif (changed.has('open') && this.open && !this.inline && !this._root) {\n\t\t\tvoid this._expand()\n\t\t}\n\t}\n\n\tprivate _toggle() {\n\t\tif (this.inline) {\n\t\t\tthis.open = !this.open\n\t\t\tthis._animateIndicator(this.open)\n\t\t} else if (!this.open) {\n\t\t\tvoid this._expand()\n\t\t}\n\t}\n\n\tprivate _handleSummaryClick(e: MouseEvent) {\n\t\te.preventDefault()\n\t\tthis._toggle()\n\t}\n\n\tprivate async _expand() {\n\t\tif (this.inline) {\n\t\t\tthis.open = true\n\t\t\tthis._animateIndicator(true)\n\t\t\treturn\n\t\t}\n\n\t\tconst root = await this._getOrCreateRoot()\n\t\tthis._root = root\n\t\tconst summary = this._summaryRef.value\n\t\tconst contentSlot = this._contentSlotRef.value\n\t\tif (!summary || !contentSlot) return\n\n\t\tconst summaryRect = summary.getBoundingClientRect()\n\t\tconst nodes = contentSlot.assignedElements({ flatten: true })\n\t\tif (nodes.length === 0) return\n\n\t\troot.prepare(summaryRect, this, this.hideIndicator, this.backdrop)\n\n\t\tthis._movedNodes = [...nodes]\n\t\tthis._movedNodes.forEach(n => root.appendChild(n))\n\n\t\troot.triggerOpen()\n\n\t\tthis._animateIndicator(true)\n\t\tthis.open = true\n\t}\n\n\tasync _handleClose() {\n\t\tif (this.inline) {\n\t\t\tthis._animateIndicator(false)\n\t\t\tthis.open = false\n\t\t\treturn\n\t\t}\n\n\t\tconst root = this._root\n\t\tconst summary = this._summaryRef.value\n\t\tif (!root || !summary) return\n\n\t\tconst summaryRect = summary.getBoundingClientRect()\n\t\tthis._animateIndicator(false)\n\n\t\tawait root.triggerClose(summaryRect)\n\n\t\tthis._movedNodes.forEach(n => this.appendChild(n))\n\t\tthis._movedNodes = []\n\t\tthis.open = false\n\t}\n\n\tprivate _animateIndicator(isOpen: boolean) {\n\t\tif (reducedMotion$.value) return\n\n\t\tconst indicator = this.shadowRoot?.querySelector('.indicator') as HTMLElement | null\n\t\tif (!indicator) return\n\n\t\tthis._currentIndicatorAnim?.cancel()\n\t\tthis._currentIndicatorAnim = indicator.animate(\n\t\t\t[\n\t\t\t\t{ transform: `rotate(${isOpen ? '0deg' : `${this.indicatorRotate}deg`})` },\n\t\t\t\t{ transform: `rotate(${isOpen ? `${this.indicatorRotate}deg` : '0deg'})` },\n\t\t\t],\n\t\t\t{\n\t\t\t\tduration: SPRING_SNAPPY.duration,\n\t\t\t\teasing: SPRING_SNAPPY.easingFallback,\n\t\t\t\tfill: 'forwards',\n\t\t\t},\n\t\t)\n\t}\n\n\trender() {\n\t\tconst summaryClasses = this.classMap({\n\t\t\t[this.summaryPadding]: true,\n\t\t\t'select-none relative flex items-center gap-2 rounded-xl transition-all duration-150': true,\n\t\t\t'hover:brightness-[0.92] active:brightness-[0.85] cursor-pointer group': true,\n\t\t\t'flex-row-reverse': true,\n\t\t})\n\n\t\treturn html`\n\t\t\t<div class=\"w-full rounded-xl\">\n\t\t\t\t<div\n\t\t\t\t\t${ref(this._summaryRef)}\n\t\t\t\t\tclass=${summaryClasses}\n\t\t\t\t\ttabindex=\"0\"\n\t\t\t\t\trole=\"button\"\n\t\t\t\t\t@click=${this._handleSummaryClick}\n\t\t\t\t\t@keydown=${(e: KeyboardEvent) => {\n\t\t\t\t\t\tif (e.key === 'Enter' || e.key === ' ') {\n\t\t\t\t\t\t\te.preventDefault()\n\t\t\t\t\t\t\tthis._toggle()\n\t\t\t\t\t\t}\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t${!this.hideIndicator\n\t\t\t\t\t\t? html`\n\t\t\t\t\t\t\t\t<span class=\"indicator flex items-center justify-center w-5 h-5 rounded-full shrink-0 opacity-70 group-hover:opacity-100 will-change-transform\">\n\t\t\t\t\t\t\t\t\t<svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t\t\t\t\td=\"M9 6L15 12L9 18\"\n\t\t\t\t\t\t\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\t\t\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\t\t\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\t\t\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t`\n\t\t\t\t\t\t: nothing}\n\n\t\t\t\t\t<span class=\"flex-1 font-medium text-base min-w-0\">\n\t\t\t\t\t\t<slot name=\"summary\">${this.summary}</slot>\n\t\t\t\t\t</span>\n\n\t\t\t\t\t<slot name=\"actions\"></slot>\n\t\t\t\t</div>\n\n\t\t\t\t${this.inline\n\t\t\t\t\t? html`\n\t\t\t\t\t\t<div class=\"inline-grid\" ?data-open=${this.open}>\n\t\t\t\t\t\t\t<div class=\"inner\">\n\t\t\t\t\t\t\t\t<slot ${ref(this._contentSlotRef)}></slot>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t`\n\t\t\t\t\t: html`\n\t\t\t\t\t\t<div style=${styleMap(this.open ? {} : { display: 'none' })}>\n\t\t\t\t\t\t\t<slot ${ref(this._contentSlotRef)}></slot>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t`}\n\t\t\t</div>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-expand': SchmancyExpand\n\t}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"expand-bFa_qVDT.js","names":[],"sources":["../src/expand/expand-root.component.ts","../src/expand/expand.component.ts"],"sourcesContent":["import { css, html, nothing } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { createRef, ref } from 'lit/directives/ref.js'\nimport { TailwindElement, SurfaceMixin } from '@mixins/index'\nimport type { TSurfaceColor } from '@schmancy/types'\nimport { SPRING_SMOOTH } from '../utils/animation.js'\nimport { reducedMotion$ } from '../directives/reduced-motion'\nimport '../surface/surface.js'\n\n/**\n * Container for schmancy-expand children — coordinates mutual-exclusion so only one child is open at a time. Also renders the portal panel that the active child expands into.\n *\n * @element schmancy-expand-root\n * @summary Always wrap a group of schmancy-expand children. Without a root, each schmancy-expand behaves independently (which is usually not what you want — prefer schmancy-details for that).\n * @example\n * <schmancy-expand-root>\n * <schmancy-expand summary=\"Step 1\">…</schmancy-expand>\n * <schmancy-expand summary=\"Step 2\">…</schmancy-expand>\n * </schmancy-expand-root>\n * @platform div - Coordinating wrapper. Degrades to a plain div if the tag never registers — children fall back to independent `<details>` behavior.\n */\n@customElement('schmancy-expand-root')\nexport class SchmancyExpandRoot extends SurfaceMixin(TailwindElement(css`\n\t:host {\n\t\tdisplay: contents;\n\t}\n\n\t.portal-panel {\n\t\tposition: fixed;\n\t\ttransform-origin: top left;\n\t\twill-change: clip-path, opacity;\n\t\tborder-radius: 1rem;\n\t\tbox-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.5);\n\t\tz-index: 9999;\n\t}\n\n\t.minimize-btn {\n\t\tposition: absolute;\n\t\ttop: 0.5rem;\n\t\tright: 0.5rem;\n\t\tz-index: 1;\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t\twidth: 2rem;\n\t\theight: 2rem;\n\t\tborder-radius: 9999px;\n\t\tborder: none;\n\t\tbackground: transparent;\n\t\tcursor: pointer;\n\t\topacity: 0.5;\n\t\ttransition: opacity 150ms, background 150ms;\n\t\tcolor: inherit;\n\t}\n\n\t.minimize-btn:hover {\n\t\topacity: 1;\n\t\tbackground: rgb(0 0 0 / 0.08);\n\t}\n`)) {\n\t@property({ reflect: true }) override type: TSurfaceColor = 'solid'\n\t@state() isOpen = false\n\tprivate summaryRect: DOMRect | null = null\n\n\tprivate _panelRef = createRef<HTMLElement>()\n\tprivate _backdropRef = createRef<HTMLDivElement>()\n\tprivate _btnRef = createRef<HTMLButtonElement>()\n\tprivate _owner: (Element & { close?: () => void }) | null = null\n\tprivate _hideIndicator = false\n\tprivate _backdrop = true\n\n\t/** Called by schmancy-expand before nodes are moved */\n\tprepare(rect: DOMRect, owner: Element, hideIndicator = false, backdrop = true) {\n\t\tthis.summaryRect = rect\n\t\tthis._owner = owner as Element & { close?: () => void }\n\t\tthis._hideIndicator = hideIndicator\n\t\tthis._backdrop = backdrop\n\t}\n\n\t/** Called by schmancy-expand after nodes are moved in */\n\tasync triggerOpen() {\n\t\tthis.isOpen = true\n\t\tawait this.updateComplete\n\n\t\tconst panel = this._panelRef.value\n\t\tif (!panel) return\n\n\t\tconst src = this.summaryRect!\n\n\t\t// 1. Anchor at summary's top-left, measure natural content size\n\t\t// Use nearly full viewport height for measurement so content near the bottom\n\t\t// of the screen isn't artificially capped — the positioning step will move the panel up.\n\t\tObject.assign(panel.style, {\n\t\t\tvisibility: 'hidden',\n\t\t\ttop: `${src.top}px`,\n\t\t\tleft: `${src.left}px`,\n\t\t\tminWidth: `${src.width}px`,\n\t\t\twidth: 'max-content',\n\t\t\tmaxWidth: `${window.innerWidth - src.left}px`,\n\t\t\theight: 'auto',\n\t\t\tmaxHeight: `${window.innerHeight - 32}px`,\n\t\t\toverflowY: 'auto',\n\t\t})\n\n\t\tconst measured = panel.getBoundingClientRect()\n\t\tconst finalW = measured.width\n\t\tconst finalH = measured.height\n\n\t\t// 2. Adjust position so panel stays within viewport\n\t\tlet finalTop = src.top\n\t\tlet finalLeft = src.left\n\t\tif (finalTop + finalH > window.innerHeight) {\n\t\t\tfinalTop = Math.max(0, src.bottom - finalH)\n\t\t}\n\t\tif (finalLeft + finalW > window.innerWidth) {\n\t\t\tfinalLeft = Math.max(0, window.innerWidth - finalW)\n\t\t}\n\n\t\t// 3. Compute clip-path insets — summary rect expressed relative to panel final position\n\t\t// These insets shrink the visible area down to exactly the summary box\n\t\tconst insetTop = Math.max(0, src.top - finalTop)\n\t\tconst insetLeft = Math.max(0, src.left - finalLeft)\n\t\tconst insetRight = Math.max(0, finalLeft + finalW - (src.left + src.width))\n\t\tconst insetBottom = Math.max(0, finalTop + finalH - (src.top + src.height))\n\n\t\t// 4. Place panel at final size + position, masked to summary bounds (no flash)\n\t\tObject.assign(panel.style, {\n\t\t\tvisibility: '',\n\t\t\ttop: `${finalTop}px`,\n\t\t\tleft: `${finalLeft}px`,\n\t\t\tminWidth: `${src.width}px`,\n\t\t\twidth: `${finalW}px`,\n\t\t\theight: `${finalH}px`,\n\t\t\tmaxWidth: '',\n\t\t\tmaxHeight: '',\n\t\t\tclipPath: `inset(${insetTop}px ${insetRight}px ${insetBottom}px ${insetLeft}px round 0.5rem)`,\n\t\t})\n\n\t\t// 5. Animate the mask open — content revealed, not stretched\n\t\tthis._animateOpen(insetTop, insetRight, insetBottom, insetLeft, finalTop)\n\t}\n\n\t/** Animate close, return Promise resolving when done */\n\tasync triggerClose(targetRect: DOMRect): Promise<void> {\n\t\tawait this._animateClose(targetRect)\n\t\tthis.isOpen = false\n\t\tthis.summaryRect = null\n\t}\n\n\tprivate _animateOpen(insetTop: number, insetRight: number, insetBottom: number, insetLeft: number, finalTop: number) {\n\t\tconst panel = this._panelRef.value\n\t\tif (!panel) return\n\n\t\tif (reducedMotion$.value) {\n\t\t\tpanel.style.clipPath = ''\n\t\t\treturn\n\t\t}\n\n\t\tconst backdrop = this._backdropRef.value\n\t\tif (backdrop) {\n\t\t\tbackdrop.animate([{ opacity: 0 }, { opacity: 1 }], {\n\t\t\t\tduration: SPRING_SMOOTH.duration,\n\t\t\t\teasing: SPRING_SMOOTH.easingFallback,\n\t\t\t\tfill: 'forwards',\n\t\t\t})\n\t\t}\n\n\t\tconst keyframes: Keyframe[] = [\n\t\t\t{\n\t\t\t\tclipPath: `inset(${insetTop}px ${insetRight}px ${insetBottom}px ${insetLeft}px round 0.5rem)`,\n\t\t\t\topacity: 0.9,\n\t\t\t},\n\t\t\t{\n\t\t\t\tclipPath: 'inset(0px 0px 0px 0px round 1rem)',\n\t\t\t\topacity: 1,\n\t\t\t},\n\t\t]\n\n\t\tconst anim = panel.animate(keyframes, {\n\t\t\tduration: SPRING_SMOOTH.duration,\n\t\t\teasing: SPRING_SMOOTH.easingFallback,\n\t\t\tfill: 'forwards',\n\t\t})\n\n\t\t// Clear clip-path and fixed dimensions after animation so content can grow naturally,\n\t\t// but cap at viewport height so overflow-y: auto can scroll\n\t\tanim.finished.then(() => {\n\t\t\tif (panel.isConnected) {\n\t\t\t\tpanel.style.clipPath = ''\n\t\t\t\tpanel.style.height = 'auto'\n\t\t\t\tpanel.style.maxHeight = `${window.innerHeight - finalTop - 16}px`\n\t\t\t}\n\t\t})\n\n\t\tconst btn = this._btnRef.value\n\t\tif (btn) {\n\t\t\tbtn.animate([{ transform: 'rotate(0deg)' }, { transform: 'rotate(180deg)' }], {\n\t\t\t\tduration: SPRING_SMOOTH.duration,\n\t\t\t\teasing: SPRING_SMOOTH.easingFallback,\n\t\t\t\tfill: 'forwards',\n\t\t\t})\n\t\t}\n\t}\n\n\tprivate _animateClose(targetRect: DOMRect): Promise<void> {\n\t\tconst panel = this._panelRef.value\n\t\tif (!panel) return Promise.resolve()\n\t\tif (reducedMotion$.value) return Promise.resolve()\n\n\t\t// Compute insets to mask panel back down to the summary box\n\t\tconst panelRect = panel.getBoundingClientRect()\n\t\tconst insetTop = Math.max(0, targetRect.top - panelRect.top)\n\t\tconst insetLeft = Math.max(0, targetRect.left - panelRect.left)\n\t\tconst insetRight = Math.max(0, panelRect.right - targetRect.right)\n\t\tconst insetBottom = Math.max(0, panelRect.bottom - targetRect.bottom)\n\n\t\tconst closeDuration = Math.round(SPRING_SMOOTH.duration * 0.4)\n\t\tconst closeEasing = 'cubic-bezier(0.4, 0, 1, 1)'\n\n\t\tconst closeKeyframes: Keyframe[] = [\n\t\t\t{ clipPath: 'inset(0px 0px 0px 0px round 1rem)', opacity: 1 },\n\t\t\t{\n\t\t\t\tclipPath: `inset(${insetTop}px ${insetRight}px ${insetBottom}px ${insetLeft}px round 0.5rem)`,\n\t\t\t\topacity: 0.6,\n\t\t\t},\n\t\t]\n\n\t\tconst anim = panel.animate(closeKeyframes, { duration: closeDuration, easing: closeEasing, fill: 'forwards' })\n\n\t\tconst backdrop = this._backdropRef.value\n\t\tif (backdrop) {\n\t\t\tbackdrop.animate([{ opacity: 1 }, { opacity: 0 }], {\n\t\t\t\tduration: closeDuration,\n\t\t\t\teasing: closeEasing,\n\t\t\t\tfill: 'forwards',\n\t\t\t})\n\t\t}\n\n\t\tconst btn = this._btnRef.value\n\t\tif (btn) {\n\t\t\tbtn.animate([{ transform: 'rotate(180deg)' }, { transform: 'rotate(0deg)' }], {\n\t\t\t\tduration: closeDuration,\n\t\t\t\teasing: closeEasing,\n\t\t\t\tfill: 'forwards',\n\t\t\t})\n\t\t}\n\n\t\treturn anim.finished as unknown as Promise<void>\n\t}\n\n\trender() {\n\t\tif (!this.isOpen) return nothing\n\n\t\treturn html`\n\t\t\t${this._backdrop ? html`\n\t\t\t\t<div\n\t\t\t\t\t${ref(this._backdropRef)}\n\t\t\t\t\tclass=\"fixed inset-0 z-9998 backdrop-blur-sm backdrop-saturate-150 backdrop-brightness-105 bg-black/[0.07] will-change-[opacity]\"\n\t\t\t\t\t@click=${() => this._owner?.close?.()}\n\t\t\t\t></div>\n\t\t\t` : nothing}\n\t\t\t<schmancy-surface\n\t\t\t\t${ref(this._panelRef)}\n\t\t\t\tclass=\"portal-panel\"\n\t\t\t\ttype=${this.type}\n\t\t\t\tstyle=\"overflow-y: auto;\"\n\t\t\t>\n\t\t\t\t${!this._hideIndicator ? html`\n\t\t\t\t\t<button\n\t\t\t\t\t\t${ref(this._btnRef)}\n\t\t\t\t\t\tclass=\"minimize-btn\"\n\t\t\t\t\t\taria-label=\"Minimize\"\n\t\t\t\t\t\t@click=${() => this._owner?.close?.()}\n\t\t\t\t\t>\n\t\t\t\t\t\t<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t<path d=\"M19 9L12 16L5 9\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t</button>\n\t\t\t\t` : nothing}\n\t\t\t\t<slot></slot>\n\t\t\t</schmancy-surface>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-expand-root': SchmancyExpandRoot\n\t}\n}\n","import { css, html, nothing } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { createRef, ref } from 'lit/directives/ref.js'\nimport { styleMap } from 'lit/directives/style-map.js'\nimport { filter, fromEvent, lastValueFrom } from 'rxjs'\nimport { tap, takeUntil } from 'rxjs/operators'\nimport { TailwindElement } from '@mixins/index'\nimport { SPRING_SNAPPY } from '../utils/animation.js'\nimport { reducedMotion$ } from '../directives/reduced-motion'\nimport { SchmancyExpandRoot } from './expand-root.component.js'\n\n/** Dispatch this event on window to close whichever schmancy-expand is currently open */\nexport const SCHMANCY_EXPAND_REQUEST_CLOSE = 'schmancy-expand-request-close'\n\n/**\n * Accordion-style section — expands on click, coordinates with siblings via schmancy-expand-root to close any sibling when a new one opens. Only one schmancy-expand can be open at a time within the same root.\n *\n * @element schmancy-expand\n * @summary Use for grouped progressive-disclosure where only one section should be open at a time. Prefer schmancy-details when sections should be independent.\n * @example\n * <schmancy-expand-root>\n * <schmancy-expand summary=\"Billing\">Billing form…</schmancy-expand>\n * <schmancy-expand summary=\"Shipping\">Shipping form…</schmancy-expand>\n * <schmancy-expand summary=\"Review\">Order review…</schmancy-expand>\n * </schmancy-expand-root>\n * @platform details toggle - Schmancy-skinned accordion section. Degrades to `<details>` if the tag never registers — loses mutual-exclusion behavior but stays functional.\n * @fires toggle - When the open state changes.\n */\n@customElement('schmancy-expand')\nexport default class SchmancyExpand extends TailwindElement(css`\n\t:host {\n\t\tdisplay: block;\n\t}\n\n\tsummary::-webkit-details-marker {\n\t\tdisplay: none;\n\t}\n\n\tsummary {\n\t\tlist-style: none;\n\t\tcolor: inherit;\n\t}\n\n\t.inline-grid {\n\t\tdisplay: grid;\n\t\tgrid-template-rows: 0fr;\n\t\toverflow: hidden;\n\t\ttransition: grid-template-rows 300ms cubic-bezier(0.22, 1.25, 0.36, 1),\n\t\t opacity 300ms cubic-bezier(0.22, 1.25, 0.36, 1);\n\t\topacity: 0;\n\t}\n\n\t.inline-grid[data-open] {\n\t\tgrid-template-rows: 1fr;\n\t\topacity: 1;\n\t}\n\n\t.inline-grid > .inner {\n\t\tmin-height: 0;\n\t\toverflow: hidden;\n\t}\n`) {\n\t@property() summary = ''\n\n\t@property({ type: Boolean, reflect: true }) open = false\n\n\t@property({ attribute: 'summary-padding' }) summaryPadding = ''\n\n\t@property({ attribute: 'content-padding' }) contentPadding = ''\n\n\t@property({ type: Boolean, attribute: 'hide-indicator' }) hideIndicator = false\n\n\t@property({ type: Number, attribute: 'indicator-rotate' }) indicatorRotate = 90\n\n\t@property({ type: Boolean }) backdrop = true\n\n\t@property({ type: Boolean }) inline = false\n\n\tprivate _summaryRef = createRef<HTMLElement>()\n\tprivate _contentSlotRef = createRef<HTMLSlotElement>()\n\tprivate _root: SchmancyExpandRoot | null = null\n\tprivate _movedNodes: Element[] = []\n\tprivate _currentIndicatorAnim: Animation | undefined\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback()\n\n\t\t// Close on Escape key\n\t\tfromEvent<KeyboardEvent>(window, 'keydown')\n\t\t\t.pipe(\n\t\t\t\tfilter(e => e.key === 'Escape'),\n\t\t\t\tfilter(() => this.open),\n\t\t\t\ttap(() => void this._handleClose()),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe()\n\n\t\t// Close on click outside the portal panel\n\t\tfromEvent<PointerEvent>(document, 'pointerdown')\n\t\t\t.pipe(\n\t\t\t\tfilter(() => this.open),\n\t\t\t\tfilter(e => !!this._root && !e.composedPath().includes(this._root)),\n\t\t\t\ttap(() => void this._handleClose()),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe()\n\t}\n\n\tdisconnectedCallback() {\n\t\tsuper.disconnectedCallback()\n\t\tif (this._movedNodes.length > 0) {\n\t\t\tthis._movedNodes.forEach(n => this.appendChild(n))\n\t\t\tthis._movedNodes = []\n\t\t}\n\t\tif (this._root && this._root.children.length === 0) {\n\t\t\tthis._root.remove()\n\t\t\tthis._root = null\n\t\t}\n\t}\n\n\tprivate async _getOrCreateRoot(): Promise<SchmancyExpandRoot> {\n\t\tconst theme = await lastValueFrom(this.discover<HTMLElement>('schmancy-theme'))\n\t\tconst container: HTMLElement = theme ?? document.querySelector('schmancy-theme') ?? document.body\n\t\tlet root = container.querySelector('schmancy-expand-root') as SchmancyExpandRoot | null\n\t\tif (!root) {\n\t\t\troot = new SchmancyExpandRoot()\n\t\t\tcontainer.appendChild(root)\n\t\t}\n\t\treturn root\n\t}\n\n\t/** Close the expand portal, animating back to the summary position. */\n\tpublic close(): void {\n\t\tvoid this._handleClose()\n\t}\n\n\t/** Programmatically open the expand portal. */\n\tpublic expand(): void {\n\t\tif (this.open) return\n\t\tvoid this._expand()\n\t}\n\n\tprotected override updated(changed: Map<PropertyKey, unknown>) {\n\t\tsuper.updated(changed)\n\t\tif (changed.has('open') && this.open && !this.inline && !this._root) {\n\t\t\tvoid this._expand()\n\t\t}\n\t}\n\n\tprivate _toggle() {\n\t\tif (this.inline) {\n\t\t\tthis.open = !this.open\n\t\t\tthis._animateIndicator(this.open)\n\t\t} else if (!this.open) {\n\t\t\tvoid this._expand()\n\t\t}\n\t}\n\n\tprivate _handleSummaryClick(e: MouseEvent) {\n\t\te.preventDefault()\n\t\tthis._toggle()\n\t}\n\n\tprivate async _expand() {\n\t\tif (this.inline) {\n\t\t\tthis.open = true\n\t\t\tthis._animateIndicator(true)\n\t\t\treturn\n\t\t}\n\n\t\tconst root = await this._getOrCreateRoot()\n\t\tthis._root = root\n\t\tconst summary = this._summaryRef.value\n\t\tconst contentSlot = this._contentSlotRef.value\n\t\tif (!summary || !contentSlot) return\n\n\t\tconst summaryRect = summary.getBoundingClientRect()\n\t\tconst nodes = contentSlot.assignedElements({ flatten: true })\n\t\tif (nodes.length === 0) return\n\n\t\troot.prepare(summaryRect, this, this.hideIndicator, this.backdrop)\n\n\t\tthis._movedNodes = [...nodes]\n\t\tthis._movedNodes.forEach(n => root.appendChild(n))\n\n\t\troot.triggerOpen()\n\n\t\tthis._animateIndicator(true)\n\t\tthis.open = true\n\t}\n\n\tasync _handleClose() {\n\t\tif (this.inline) {\n\t\t\tthis._animateIndicator(false)\n\t\t\tthis.open = false\n\t\t\treturn\n\t\t}\n\n\t\tconst root = this._root\n\t\tconst summary = this._summaryRef.value\n\t\tif (!root || !summary) return\n\n\t\tconst summaryRect = summary.getBoundingClientRect()\n\t\tthis._animateIndicator(false)\n\n\t\tawait root.triggerClose(summaryRect)\n\n\t\tthis._movedNodes.forEach(n => this.appendChild(n))\n\t\tthis._movedNodes = []\n\t\tthis.open = false\n\t}\n\n\tprivate _animateIndicator(isOpen: boolean) {\n\t\tif (reducedMotion$.value) return\n\n\t\tconst indicator = this.shadowRoot?.querySelector('.indicator') as HTMLElement | null\n\t\tif (!indicator) return\n\n\t\tthis._currentIndicatorAnim?.cancel()\n\t\tthis._currentIndicatorAnim = indicator.animate(\n\t\t\t[\n\t\t\t\t{ transform: `rotate(${isOpen ? '0deg' : `${this.indicatorRotate}deg`})` },\n\t\t\t\t{ transform: `rotate(${isOpen ? `${this.indicatorRotate}deg` : '0deg'})` },\n\t\t\t],\n\t\t\t{\n\t\t\t\tduration: SPRING_SNAPPY.duration,\n\t\t\t\teasing: SPRING_SNAPPY.easingFallback,\n\t\t\t\tfill: 'forwards',\n\t\t\t},\n\t\t)\n\t}\n\n\trender() {\n\t\tconst summaryClasses = this.classMap({\n\t\t\t[this.summaryPadding]: true,\n\t\t\t'select-none relative flex items-center gap-2 rounded-xl transition-all duration-150': true,\n\t\t\t'hover:brightness-[0.92] active:brightness-[0.85] cursor-pointer group': true,\n\t\t\t'flex-row-reverse': true,\n\t\t})\n\n\t\treturn html`\n\t\t\t<div class=\"w-full rounded-xl\">\n\t\t\t\t<div\n\t\t\t\t\t${ref(this._summaryRef)}\n\t\t\t\t\tclass=${summaryClasses}\n\t\t\t\t\ttabindex=\"0\"\n\t\t\t\t\trole=\"button\"\n\t\t\t\t\t@click=${this._handleSummaryClick}\n\t\t\t\t\t@keydown=${(e: KeyboardEvent) => {\n\t\t\t\t\t\tif (e.key === 'Enter' || e.key === ' ') {\n\t\t\t\t\t\t\te.preventDefault()\n\t\t\t\t\t\t\tthis._toggle()\n\t\t\t\t\t\t}\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t${!this.hideIndicator\n\t\t\t\t\t\t? html`\n\t\t\t\t\t\t\t\t<span class=\"indicator flex items-center justify-center w-5 h-5 rounded-full shrink-0 opacity-70 group-hover:opacity-100 will-change-transform\">\n\t\t\t\t\t\t\t\t\t<svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t\t\t\t\td=\"M9 6L15 12L9 18\"\n\t\t\t\t\t\t\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\t\t\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\t\t\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\t\t\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t`\n\t\t\t\t\t\t: nothing}\n\n\t\t\t\t\t<span class=\"flex-1 font-medium text-base min-w-0\">\n\t\t\t\t\t\t<slot name=\"summary\">${this.summary}</slot>\n\t\t\t\t\t</span>\n\n\t\t\t\t\t<slot name=\"actions\"></slot>\n\t\t\t\t</div>\n\n\t\t\t\t${this.inline\n\t\t\t\t\t? html`\n\t\t\t\t\t\t<div class=\"inline-grid\" ?data-open=${this.open}>\n\t\t\t\t\t\t\t<div class=\"inner\">\n\t\t\t\t\t\t\t\t<slot ${ref(this._contentSlotRef)}></slot>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t`\n\t\t\t\t\t: html`\n\t\t\t\t\t\t<div style=${styleMap(this.open ? {} : { display: 'none' })}>\n\t\t\t\t\t\t\t<slot ${ref(this._contentSlotRef)}></slot>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t`}\n\t\t\t</div>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-expand': SchmancyExpand\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -203,7 +203,7 @@ The manifest already has everything needed; the package is just the JSON-RPC wra
|
|
|
203
203
|
|
|
204
204
|
**Problem.** `handover/agent-runtime-v1.md` had `<PENDING>` placeholders that we manually replaced with `0.9.13` after the first publish. Future handover docs will have the same issue.
|
|
205
205
|
|
|
206
|
-
**Fix.** A build step that substitutes `0.9.
|
|
206
|
+
**Fix.** A build step that substitutes `0.9.18` in `handover/**/*.md` against `package.json`'s `version` field on every build. `dist/handover/**/*.md` gets the rendered version; the source stays templated.
|
|
207
207
|
|
|
208
208
|
**Effort:** ~30 min (one sed step or a tiny script).
|
|
209
209
|
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
## The URLs you asked for
|
|
8
8
|
|
|
9
9
|
```
|
|
10
|
-
https://esm.sh/@mhmo91/schmancy/agent@0.9.
|
|
11
|
-
https://esm.sh/@mhmo91/schmancy/agent/manifest@0.9.
|
|
10
|
+
https://esm.sh/@mhmo91/schmancy/agent@0.9.18
|
|
11
|
+
https://esm.sh/@mhmo91/schmancy/agent/manifest@0.9.18
|
|
12
12
|
```
|
|
13
13
|
|
|
14
14
|
`0.9.13` is the first release containing `/agent`; every subsequent publish serves the same subpath. `npm view @mhmo91/schmancy version` always returns the current pin if you want to float forward.
|
|
@@ -20,7 +20,7 @@ One script tag. No bundler, no bare specifiers, no npm install.
|
|
|
20
20
|
```html
|
|
21
21
|
<!doctype html>
|
|
22
22
|
<script type="module">
|
|
23
|
-
import { $dialog, theme } from 'https://esm.sh/@mhmo91/schmancy/agent@0.9.
|
|
23
|
+
import { $dialog, theme } from 'https://esm.sh/@mhmo91/schmancy/agent@0.9.18';
|
|
24
24
|
</script>
|
|
25
25
|
<schmancy-theme root scheme="dark">
|
|
26
26
|
<schmancy-surface type="solid" fill="all">
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list-BpjKUOzM.js","names":[],"sources":["../src/list/context.ts","../src/surface/context.ts","../src/list/list-item.ts","../src/list/list.ts"],"sourcesContent":["import { createContext } from '@lit/context'\nimport { TSurfaceColor } from '@schmancy/types/surface'\nexport const SchmancyListTypeContext = createContext<TSurfaceColor>(undefined)\n","import { createContext } from '@lit/context'\nimport { TSurfaceColor } from '@schmancy/types/surface'\nexport const SchmancySurfaceTypeContext = createContext<TSurfaceColor>('surface')\n","import { consume } from '@lit/context'\nimport { TailwindElement } from '@mixins/index'\nimport { SchmancySurfaceTypeContext } from '@schmancy/surface/context'\nimport { TSurfaceColor } from '@schmancy/types/surface'\nimport { css, html } from 'lit'\nimport { customElement, property, queryAssignedElements } from 'lit/decorators.js'\n\n/**\n * @element schmancy-list-item\n * @slot leading - leading content\n * @slot trailing - trailing content\n * @slot - default content\n */\n@customElement('schmancy-list-item')\nexport class SchmancyListItem extends TailwindElement(css`\n\t:host {\n\t\tdisplay: block;\n\t\tborder-radius: 0.5rem;\n\t\ttransition:\n\t\t\tbackground 200ms ease,\n\t\t\tbox-shadow 300ms ease,\n\t\t\ttransform 200ms cubic-bezier(0.34, 1.56, 0.64, 1);\n\t}\n\t:host(:hover:not([readonly])) {\n\t\tbackground: color-mix(in srgb, var(--schmancy-sys-color-surface-on) 8%, transparent);\n\t\tbox-shadow: 0 2px 8px -4px color-mix(in srgb, var(--schmancy-sys-color-primary-default) 10%, transparent);\n\t}\n\t:host(:active:not([readonly])) {\n\t\ttransform: scale(0.98);\n\t\ttransition-duration: 100ms;\n\t}\n\t:host([selected]) {\n\t\tbackground: color-mix(in srgb, var(--schmancy-sys-color-secondary-container) 30%, transparent);\n\t\tbox-shadow: 0 0 10px -3px color-mix(in srgb, var(--schmancy-sys-color-secondary-default) 12%, transparent);\n\t}\n\t@media (prefers-reduced-motion: reduce) {\n\t\t:host { transition: background 200ms ease; }\n\t\t:host(:active:not([readonly])) { transform: none; }\n\t}\n`) {\n\t@consume({ context: SchmancySurfaceTypeContext, subscribe: true })\n\t@property()\n\tvariant: TSurfaceColor\n\n\t@property({ type: Boolean, reflect: true })\n\trounded: boolean\n\n\t@property({ type: Boolean, reflect: true }) readonly: boolean\n\n\t@property({ type: Boolean, reflect: true }) selected: boolean = false\n\n\t@queryAssignedElements({\n\t\tslot: 'leading',\n\t\tflatten: true,\n\t})\n\tprivate leading!: HTMLElement[]\n\n\t@queryAssignedElements({\n\t\tslot: 'trailing',\n\t\tflatten: true,\n\t})\n\tprivate trailing!: HTMLElement[]\n\n\tprotected get imgClasses(): string[] {\n\t\treturn ['h-4', 'w-4', 'sm:h-5', 'sm:w-5', 'object-contain']\n\t}\n\n\tfirstUpdated() {\n\t\tthis.leading?.forEach(img => {\n\t\t\timg.classList.add(...this.imgClasses)\n\t\t})\n\t\tthis.trailing?.forEach(img => {\n\t\t\timg.classList.add(...this.imgClasses)\n\t\t})\n\t}\n\n\trender() {\n\t\tconst classes = {\n\t\t\t'w-full flex items-center min-h-[36px] sm:min-h-[40px] py-1 px-2 sm:px-3 text-sm': true,\n\t\t\t'focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-offset-0 focus-visible:z-1 outline-secondary-default outline-hidden': true,\n\t\t\t'cursor-pointer': !this.readonly,\n\t\t}\n\n\t\treturn html`<li .tabIndex=${this.readonly ? -1 : 0} class=${this.classMap(classes)}>\n\t\t\t<slot></slot>\n\t\t</li>`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-list-item': SchmancyListItem\n\t}\n}\n","import { provide } from '@lit/context'\nimport { TailwindElement } from '@mixins/index'\nimport { SchmancySurfaceFill } from '@schmancy/surface'\nimport { TSurfaceColor } from '@schmancy/types/surface'\nimport { css, html } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { SchmancyListTypeContext } from './context'\n\n/**\n *
|
|
1
|
+
{"version":3,"file":"list-BpjKUOzM.js","names":[],"sources":["../src/list/context.ts","../src/surface/context.ts","../src/list/list-item.ts","../src/list/list.ts"],"sourcesContent":["import { createContext } from '@lit/context'\nimport { TSurfaceColor } from '@schmancy/types/surface'\nexport const SchmancyListTypeContext = createContext<TSurfaceColor>(undefined)\n","import { createContext } from '@lit/context'\nimport { TSurfaceColor } from '@schmancy/types/surface'\nexport const SchmancySurfaceTypeContext = createContext<TSurfaceColor>('surface')\n","import { consume } from '@lit/context'\nimport { TailwindElement } from '@mixins/index'\nimport { SchmancySurfaceTypeContext } from '@schmancy/surface/context'\nimport { TSurfaceColor } from '@schmancy/types/surface'\nimport { css, html } from 'lit'\nimport { customElement, property, queryAssignedElements } from 'lit/decorators.js'\n\n/**\n * Single row in a schmancy-list — supports leading icon/avatar, main content, trailing actions. Clickable via click event, or used as a schmancy-menu-item's visual base.\n *\n * @element schmancy-list-item\n * @summary Prefer nesting inside schmancy-list for consistent spacing/surface. Use `href` to make the row a navigation target (renders as `<a>`), or a click handler for in-app actions.\n * @example\n * <schmancy-list-item href=\"/profile\">\n * <schmancy-icon slot=\"leading\">person</schmancy-icon>\n * Profile\n * <schmancy-icon slot=\"trailing\">chevron_right</schmancy-icon>\n * </schmancy-list-item>\n * @platform li click - Styled `<li>` or `<a>` depending on `href`. Degrades to a plain list item if the tag never registers.\n * @slot leading - leading content\n * @slot trailing - trailing content\n * @slot - default content\n */\n@customElement('schmancy-list-item')\nexport class SchmancyListItem extends TailwindElement(css`\n\t:host {\n\t\tdisplay: block;\n\t\tborder-radius: 0.5rem;\n\t\ttransition:\n\t\t\tbackground 200ms ease,\n\t\t\tbox-shadow 300ms ease,\n\t\t\ttransform 200ms cubic-bezier(0.34, 1.56, 0.64, 1);\n\t}\n\t:host(:hover:not([readonly])) {\n\t\tbackground: color-mix(in srgb, var(--schmancy-sys-color-surface-on) 8%, transparent);\n\t\tbox-shadow: 0 2px 8px -4px color-mix(in srgb, var(--schmancy-sys-color-primary-default) 10%, transparent);\n\t}\n\t:host(:active:not([readonly])) {\n\t\ttransform: scale(0.98);\n\t\ttransition-duration: 100ms;\n\t}\n\t:host([selected]) {\n\t\tbackground: color-mix(in srgb, var(--schmancy-sys-color-secondary-container) 30%, transparent);\n\t\tbox-shadow: 0 0 10px -3px color-mix(in srgb, var(--schmancy-sys-color-secondary-default) 12%, transparent);\n\t}\n\t@media (prefers-reduced-motion: reduce) {\n\t\t:host { transition: background 200ms ease; }\n\t\t:host(:active:not([readonly])) { transform: none; }\n\t}\n`) {\n\t@consume({ context: SchmancySurfaceTypeContext, subscribe: true })\n\t@property()\n\tvariant: TSurfaceColor\n\n\t@property({ type: Boolean, reflect: true })\n\trounded: boolean\n\n\t@property({ type: Boolean, reflect: true }) readonly: boolean\n\n\t@property({ type: Boolean, reflect: true }) selected: boolean = false\n\n\t@queryAssignedElements({\n\t\tslot: 'leading',\n\t\tflatten: true,\n\t})\n\tprivate leading!: HTMLElement[]\n\n\t@queryAssignedElements({\n\t\tslot: 'trailing',\n\t\tflatten: true,\n\t})\n\tprivate trailing!: HTMLElement[]\n\n\tprotected get imgClasses(): string[] {\n\t\treturn ['h-4', 'w-4', 'sm:h-5', 'sm:w-5', 'object-contain']\n\t}\n\n\tfirstUpdated() {\n\t\tthis.leading?.forEach(img => {\n\t\t\timg.classList.add(...this.imgClasses)\n\t\t})\n\t\tthis.trailing?.forEach(img => {\n\t\t\timg.classList.add(...this.imgClasses)\n\t\t})\n\t}\n\n\trender() {\n\t\tconst classes = {\n\t\t\t'w-full flex items-center min-h-[36px] sm:min-h-[40px] py-1 px-2 sm:px-3 text-sm': true,\n\t\t\t'focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-offset-0 focus-visible:z-1 outline-secondary-default outline-hidden': true,\n\t\t\t'cursor-pointer': !this.readonly,\n\t\t}\n\n\t\treturn html`<li .tabIndex=${this.readonly ? -1 : 0} class=${this.classMap(classes)}>\n\t\t\t<slot></slot>\n\t\t</li>`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-list-item': SchmancyListItem\n\t}\n}\n","import { provide } from '@lit/context'\nimport { TailwindElement } from '@mixins/index'\nimport { SchmancySurfaceFill } from '@schmancy/surface'\nimport { TSurfaceColor } from '@schmancy/types/surface'\nimport { css, html } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { SchmancyListTypeContext } from './context'\n\n/**\n * Wrapped list container — holds schmancy-list-item children on a themed surface. Optionally scrollable.\n *\n * @element schmancy-list\n * @summary Use for vertical lists of similarly-shaped items: settings entries, menu items, contact lists, notification lists. Pair with schmancy-list-item children.\n * @example\n * <schmancy-list surface=\"container\" scroller>\n * <schmancy-list-item>First</schmancy-list-item>\n * <schmancy-list-item>Second</schmancy-list-item>\n * <schmancy-list-item>Third</schmancy-list-item>\n * </schmancy-list>\n * @platform ul - Styled list container. Degrades to a plain ul/div if the tag never registers.\n * @slot - The default slot for list items.\n */\n@customElement('schmancy-list')\nexport class List extends TailwindElement(css`\n\t:host {\n\t\tdisplay: block;\n\t\tpadding-top: 8px;\n\t\tpadding-bottom: 8px;\n\t}\n`) {\n\t/**\n\t * Defines the type or color of the surface used by the component.\n\t * This value is provided to descendant components via context.\n\t *\n\t * @attr surface\n\t * @type {TSurfaceColor}\n\t * @default 'surface'\n\t */\n\t@provide({ context: SchmancyListTypeContext })\n\t@property()\n\tsurface: TSurfaceColor\n\n\t/**\n\t * Determines the fill style of the underlying surface.\n\t *\n\t * @attr fill\n\t * @type {SchmancySurfaceFill}\n\t * @default 'auto'\n\t */\n\t@property({ type: String, reflect: true })\n\tfill: SchmancySurfaceFill = 'auto'\n\n\t/**\n\t * Defines the elevation level of the surface.\n\t *\n\t * @attr elevation\n\t * @type {number}\n\t * @default 0\n\t */\n\t@property({ type: Number })\n\televation: 0 | 1 | 2 | 3 | 4 | 5 = 0\n\n\t/**\n\t * Renders the component's template.\n\t * The list content is wrapped inside a `<schmancy-surface>` element.\n\t * The scroller property is delegated to the surface so that it controls\n\t * the scrollable behavior.\n\t *\n\t * @returns The HTML template for the component.\n\t */\n\trender() {\n\t\treturn html`\n\t\t\t<schmancy-surface .elevation=${this.elevation} .fill=${this.fill} type=${this.surface}>\n\t\t\t\t<ul>\n\t\t\t\t\t<slot></slot>\n\t\t\t\t</ul>\n\t\t\t</schmancy-surface>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-list': List\n\t}\n}\n"],"mappings":";;;;;;AAEA,IAAa,IAA0B,EAAA,KAA6B,EAAA,ECAvD,IAA6B,EAA6B,UAAA,ECsBhE,IAAA,cAA+B,EAAgB,CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAmCQ;;CAchE,IAAA,aAAc;AACb,SAAO;GAAC;GAAO;GAAO;GAAU;GAAU;GAAA;;CAG3C,eAAA;AACC,OAAK,SAAS,SAAQ,MAAA;AACrB,KAAI,UAAU,IAAA,GAAO,KAAK,WAAA;IAAA,EAE3B,KAAK,UAAU,SAAQ,MAAA;AACtB,KAAI,UAAU,IAAA,GAAO,KAAK,WAAA;IAAA;;CAI5B,SAAA;EACC,IAAM,IAAU;GACf,mFAAA,CAAmF;GACnF,iJAAA,CAAiJ;GACjJ,kBAAA,CAAmB,KAAK;GAAA;AAGzB,SAAO,CAAI,iBAAiB,KAAK,WAAA,KAAgB,EAAA,SAAW,KAAK,SAAS,EAAA,CAAA;;;;;GA3C1E,EAAQ;CAAE,SAAS;CAA4B,WAAA,CAAW;CAAA,CAAA,EAC1D,GAAA,CAAA,EAAU,EAAA,WAAA,WAAA,KAAA,EAAA,EAAA,EAAA,CAGV,EAAS;CAAE,MAAM;CAAS,SAAA,CAAS;CAAA,CAAA,CAAA,EAAO,EAAA,WAAA,WAAA,KAAA,EAAA,EAAA,EAAA,CAG1C,EAAS;CAAE,MAAM;CAAS,SAAA,CAAS;CAAA,CAAA,CAAA,EAAO,EAAA,WAAA,YAAA,KAAA,EAAA,EAAA,EAAA,CAE1C,EAAS;CAAE,MAAM;CAAS,SAAA,CAAS;CAAA,CAAA,CAAA,EAAO,EAAA,WAAA,YAAA,KAAA,EAAA,EAAA,EAAA,CAE1C,EAAsB;CACtB,MAAM;CACN,SAAA,CAAS;CAAA,CAAA,CAAA,EACR,EAAA,WAAA,WAAA,KAAA,EAAA,EAAA,EAAA,CAGD,EAAsB;CACtB,MAAM;CACN,SAAA,CAAS;CAAA,CAAA,CAAA,EACR,EAAA,WAAA,YAAA,KAAA,EAAA,EAAA,IAAA,EAAA,CA/CF,EAAc,qBAAA,CAAA,EAAqB,EAAA;ACA7B,IAAA,IAAA,cAAmB,EAAgB,CAAG;;;;;;;;2BA2BhB,QAAA,KAAA,YAUO;;CAUnC,SAAA;AACC,SAAO,CAAI;kCACqB,KAAK,UAAA,SAAmB,KAAK,KAAA,QAAa,KAAK,QAAA;;;;;;;;GAlC/E,EAAQ,EAAE,SAAS,GAAA,CAAA,EACnB,GAAA,CAAA,EAAU,EAAA,WAAA,WAAA,KAAA,EAAA,EAAA,EAAA,CAUV,EAAS;CAAE,MAAM;CAAQ,SAAA,CAAS;CAAA,CAAA,CAAA,EAAO,EAAA,WAAA,QAAA,KAAA,EAAA,EAAA,EAAA,CAUzC,EAAS,EAAE,MAAM,QAAA,CAAA,CAAA,EAAS,EAAA,WAAA,aAAA,KAAA,EAAA,EAAA,IAAA,EAAA,CArC3B,EAAc,gBAAA,CAAA,EAAgB,EAAA;AAAA,SAAA,KAAA,GAAA,KAAA,GAAA,KAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list-CMWHu6cV.cjs","names":[],"sources":["../src/list/context.ts","../src/surface/context.ts","../src/list/list-item.ts","../src/list/list.ts"],"sourcesContent":["import { createContext } from '@lit/context'\nimport { TSurfaceColor } from '@schmancy/types/surface'\nexport const SchmancyListTypeContext = createContext<TSurfaceColor>(undefined)\n","import { createContext } from '@lit/context'\nimport { TSurfaceColor } from '@schmancy/types/surface'\nexport const SchmancySurfaceTypeContext = createContext<TSurfaceColor>('surface')\n","import { consume } from '@lit/context'\nimport { TailwindElement } from '@mixins/index'\nimport { SchmancySurfaceTypeContext } from '@schmancy/surface/context'\nimport { TSurfaceColor } from '@schmancy/types/surface'\nimport { css, html } from 'lit'\nimport { customElement, property, queryAssignedElements } from 'lit/decorators.js'\n\n/**\n * @element schmancy-list-item\n * @slot leading - leading content\n * @slot trailing - trailing content\n * @slot - default content\n */\n@customElement('schmancy-list-item')\nexport class SchmancyListItem extends TailwindElement(css`\n\t:host {\n\t\tdisplay: block;\n\t\tborder-radius: 0.5rem;\n\t\ttransition:\n\t\t\tbackground 200ms ease,\n\t\t\tbox-shadow 300ms ease,\n\t\t\ttransform 200ms cubic-bezier(0.34, 1.56, 0.64, 1);\n\t}\n\t:host(:hover:not([readonly])) {\n\t\tbackground: color-mix(in srgb, var(--schmancy-sys-color-surface-on) 8%, transparent);\n\t\tbox-shadow: 0 2px 8px -4px color-mix(in srgb, var(--schmancy-sys-color-primary-default) 10%, transparent);\n\t}\n\t:host(:active:not([readonly])) {\n\t\ttransform: scale(0.98);\n\t\ttransition-duration: 100ms;\n\t}\n\t:host([selected]) {\n\t\tbackground: color-mix(in srgb, var(--schmancy-sys-color-secondary-container) 30%, transparent);\n\t\tbox-shadow: 0 0 10px -3px color-mix(in srgb, var(--schmancy-sys-color-secondary-default) 12%, transparent);\n\t}\n\t@media (prefers-reduced-motion: reduce) {\n\t\t:host { transition: background 200ms ease; }\n\t\t:host(:active:not([readonly])) { transform: none; }\n\t}\n`) {\n\t@consume({ context: SchmancySurfaceTypeContext, subscribe: true })\n\t@property()\n\tvariant: TSurfaceColor\n\n\t@property({ type: Boolean, reflect: true })\n\trounded: boolean\n\n\t@property({ type: Boolean, reflect: true }) readonly: boolean\n\n\t@property({ type: Boolean, reflect: true }) selected: boolean = false\n\n\t@queryAssignedElements({\n\t\tslot: 'leading',\n\t\tflatten: true,\n\t})\n\tprivate leading!: HTMLElement[]\n\n\t@queryAssignedElements({\n\t\tslot: 'trailing',\n\t\tflatten: true,\n\t})\n\tprivate trailing!: HTMLElement[]\n\n\tprotected get imgClasses(): string[] {\n\t\treturn ['h-4', 'w-4', 'sm:h-5', 'sm:w-5', 'object-contain']\n\t}\n\n\tfirstUpdated() {\n\t\tthis.leading?.forEach(img => {\n\t\t\timg.classList.add(...this.imgClasses)\n\t\t})\n\t\tthis.trailing?.forEach(img => {\n\t\t\timg.classList.add(...this.imgClasses)\n\t\t})\n\t}\n\n\trender() {\n\t\tconst classes = {\n\t\t\t'w-full flex items-center min-h-[36px] sm:min-h-[40px] py-1 px-2 sm:px-3 text-sm': true,\n\t\t\t'focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-offset-0 focus-visible:z-1 outline-secondary-default outline-hidden': true,\n\t\t\t'cursor-pointer': !this.readonly,\n\t\t}\n\n\t\treturn html`<li .tabIndex=${this.readonly ? -1 : 0} class=${this.classMap(classes)}>\n\t\t\t<slot></slot>\n\t\t</li>`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-list-item': SchmancyListItem\n\t}\n}\n","import { provide } from '@lit/context'\nimport { TailwindElement } from '@mixins/index'\nimport { SchmancySurfaceFill } from '@schmancy/surface'\nimport { TSurfaceColor } from '@schmancy/types/surface'\nimport { css, html } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { SchmancyListTypeContext } from './context'\n\n/**\n *
|
|
1
|
+
{"version":3,"file":"list-CMWHu6cV.cjs","names":[],"sources":["../src/list/context.ts","../src/surface/context.ts","../src/list/list-item.ts","../src/list/list.ts"],"sourcesContent":["import { createContext } from '@lit/context'\nimport { TSurfaceColor } from '@schmancy/types/surface'\nexport const SchmancyListTypeContext = createContext<TSurfaceColor>(undefined)\n","import { createContext } from '@lit/context'\nimport { TSurfaceColor } from '@schmancy/types/surface'\nexport const SchmancySurfaceTypeContext = createContext<TSurfaceColor>('surface')\n","import { consume } from '@lit/context'\nimport { TailwindElement } from '@mixins/index'\nimport { SchmancySurfaceTypeContext } from '@schmancy/surface/context'\nimport { TSurfaceColor } from '@schmancy/types/surface'\nimport { css, html } from 'lit'\nimport { customElement, property, queryAssignedElements } from 'lit/decorators.js'\n\n/**\n * Single row in a schmancy-list — supports leading icon/avatar, main content, trailing actions. Clickable via click event, or used as a schmancy-menu-item's visual base.\n *\n * @element schmancy-list-item\n * @summary Prefer nesting inside schmancy-list for consistent spacing/surface. Use `href` to make the row a navigation target (renders as `<a>`), or a click handler for in-app actions.\n * @example\n * <schmancy-list-item href=\"/profile\">\n * <schmancy-icon slot=\"leading\">person</schmancy-icon>\n * Profile\n * <schmancy-icon slot=\"trailing\">chevron_right</schmancy-icon>\n * </schmancy-list-item>\n * @platform li click - Styled `<li>` or `<a>` depending on `href`. Degrades to a plain list item if the tag never registers.\n * @slot leading - leading content\n * @slot trailing - trailing content\n * @slot - default content\n */\n@customElement('schmancy-list-item')\nexport class SchmancyListItem extends TailwindElement(css`\n\t:host {\n\t\tdisplay: block;\n\t\tborder-radius: 0.5rem;\n\t\ttransition:\n\t\t\tbackground 200ms ease,\n\t\t\tbox-shadow 300ms ease,\n\t\t\ttransform 200ms cubic-bezier(0.34, 1.56, 0.64, 1);\n\t}\n\t:host(:hover:not([readonly])) {\n\t\tbackground: color-mix(in srgb, var(--schmancy-sys-color-surface-on) 8%, transparent);\n\t\tbox-shadow: 0 2px 8px -4px color-mix(in srgb, var(--schmancy-sys-color-primary-default) 10%, transparent);\n\t}\n\t:host(:active:not([readonly])) {\n\t\ttransform: scale(0.98);\n\t\ttransition-duration: 100ms;\n\t}\n\t:host([selected]) {\n\t\tbackground: color-mix(in srgb, var(--schmancy-sys-color-secondary-container) 30%, transparent);\n\t\tbox-shadow: 0 0 10px -3px color-mix(in srgb, var(--schmancy-sys-color-secondary-default) 12%, transparent);\n\t}\n\t@media (prefers-reduced-motion: reduce) {\n\t\t:host { transition: background 200ms ease; }\n\t\t:host(:active:not([readonly])) { transform: none; }\n\t}\n`) {\n\t@consume({ context: SchmancySurfaceTypeContext, subscribe: true })\n\t@property()\n\tvariant: TSurfaceColor\n\n\t@property({ type: Boolean, reflect: true })\n\trounded: boolean\n\n\t@property({ type: Boolean, reflect: true }) readonly: boolean\n\n\t@property({ type: Boolean, reflect: true }) selected: boolean = false\n\n\t@queryAssignedElements({\n\t\tslot: 'leading',\n\t\tflatten: true,\n\t})\n\tprivate leading!: HTMLElement[]\n\n\t@queryAssignedElements({\n\t\tslot: 'trailing',\n\t\tflatten: true,\n\t})\n\tprivate trailing!: HTMLElement[]\n\n\tprotected get imgClasses(): string[] {\n\t\treturn ['h-4', 'w-4', 'sm:h-5', 'sm:w-5', 'object-contain']\n\t}\n\n\tfirstUpdated() {\n\t\tthis.leading?.forEach(img => {\n\t\t\timg.classList.add(...this.imgClasses)\n\t\t})\n\t\tthis.trailing?.forEach(img => {\n\t\t\timg.classList.add(...this.imgClasses)\n\t\t})\n\t}\n\n\trender() {\n\t\tconst classes = {\n\t\t\t'w-full flex items-center min-h-[36px] sm:min-h-[40px] py-1 px-2 sm:px-3 text-sm': true,\n\t\t\t'focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-offset-0 focus-visible:z-1 outline-secondary-default outline-hidden': true,\n\t\t\t'cursor-pointer': !this.readonly,\n\t\t}\n\n\t\treturn html`<li .tabIndex=${this.readonly ? -1 : 0} class=${this.classMap(classes)}>\n\t\t\t<slot></slot>\n\t\t</li>`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-list-item': SchmancyListItem\n\t}\n}\n","import { provide } from '@lit/context'\nimport { TailwindElement } from '@mixins/index'\nimport { SchmancySurfaceFill } from '@schmancy/surface'\nimport { TSurfaceColor } from '@schmancy/types/surface'\nimport { css, html } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { SchmancyListTypeContext } from './context'\n\n/**\n * Wrapped list container — holds schmancy-list-item children on a themed surface. Optionally scrollable.\n *\n * @element schmancy-list\n * @summary Use for vertical lists of similarly-shaped items: settings entries, menu items, contact lists, notification lists. Pair with schmancy-list-item children.\n * @example\n * <schmancy-list surface=\"container\" scroller>\n * <schmancy-list-item>First</schmancy-list-item>\n * <schmancy-list-item>Second</schmancy-list-item>\n * <schmancy-list-item>Third</schmancy-list-item>\n * </schmancy-list>\n * @platform ul - Styled list container. Degrades to a plain ul/div if the tag never registers.\n * @slot - The default slot for list items.\n */\n@customElement('schmancy-list')\nexport class List extends TailwindElement(css`\n\t:host {\n\t\tdisplay: block;\n\t\tpadding-top: 8px;\n\t\tpadding-bottom: 8px;\n\t}\n`) {\n\t/**\n\t * Defines the type or color of the surface used by the component.\n\t * This value is provided to descendant components via context.\n\t *\n\t * @attr surface\n\t * @type {TSurfaceColor}\n\t * @default 'surface'\n\t */\n\t@provide({ context: SchmancyListTypeContext })\n\t@property()\n\tsurface: TSurfaceColor\n\n\t/**\n\t * Determines the fill style of the underlying surface.\n\t *\n\t * @attr fill\n\t * @type {SchmancySurfaceFill}\n\t * @default 'auto'\n\t */\n\t@property({ type: String, reflect: true })\n\tfill: SchmancySurfaceFill = 'auto'\n\n\t/**\n\t * Defines the elevation level of the surface.\n\t *\n\t * @attr elevation\n\t * @type {number}\n\t * @default 0\n\t */\n\t@property({ type: Number })\n\televation: 0 | 1 | 2 | 3 | 4 | 5 = 0\n\n\t/**\n\t * Renders the component's template.\n\t * The list content is wrapped inside a `<schmancy-surface>` element.\n\t * The scroller property is delegated to the surface so that it controls\n\t * the scrollable behavior.\n\t *\n\t * @returns The HTML template for the component.\n\t */\n\trender() {\n\t\treturn html`\n\t\t\t<schmancy-surface .elevation=${this.elevation} .fill=${this.fill} type=${this.surface}>\n\t\t\t\t<ul>\n\t\t\t\t\t<slot></slot>\n\t\t\t\t</ul>\n\t\t\t</schmancy-surface>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-list': List\n\t}\n}\n"],"mappings":"sOAEA,IAAa,EAA0B,EAAA,EAAA,IAA6B,GAAA,CCAvD,EAA6B,EAAA,EAA6B,UAAA,CCsBhE,EAAA,cAA+B,EAAA,EAAgB,EAAA,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;gDAmCQ,EAchE,IAAA,YAAc,CACb,MAAO,CAAC,MAAO,MAAO,SAAU,SAAU,iBAAA,CAG3C,cAAA,CACC,KAAK,SAAS,QAAQ,GAAA,CACrB,EAAI,UAAU,IAAA,GAAO,KAAK,WAAA,EAAA,CAE3B,KAAK,UAAU,QAAQ,GAAA,CACtB,EAAI,UAAU,IAAA,GAAO,KAAK,WAAA,EAAA,CAI5B,QAAA,CACC,IAAM,EAAU,CACf,kFAAA,CAAmF,EACnF,gJAAA,CAAiJ,EACjJ,iBAAA,CAAmB,KAAK,SAAA,CAGzB,MAAO,GAAA,IAAI,iBAAiB,KAAK,SAAA,GAAgB,EAAA,SAAW,KAAK,SAAS,EAAA,CAAA;;gBA3C1E,EAAA,EAAQ,CAAE,QAAS,EAA4B,UAAA,CAAW,EAAA,CAAA,EAAO,EAAA,EAAA,WAAA,CAAA,CACvD,EAAA,UAAA,UAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAGD,CAAE,KAAM,QAAS,QAAA,CAAS,EAAA,CAAA,CAAA,CAAO,EAAA,UAAA,UAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAGjC,CAAE,KAAM,QAAS,QAAA,CAAS,EAAA,CAAA,CAAA,CAAO,EAAA,UAAA,WAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAEjC,CAAE,KAAM,QAAS,QAAA,CAAS,EAAA,CAAA,CAAA,CAAO,EAAA,UAAA,WAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,uBAEpB,CACtB,KAAM,UACN,QAAA,CAAS,EAAA,CAAA,CAAA,CACR,EAAA,UAAA,UAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,uBAGqB,CACtB,KAAM,WACN,QAAA,CAAS,EAAA,CAAA,CAAA,CACR,EAAA,UAAA,WAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,eA/CY,qBAAA,CAAA,CAAqB,EAAA,CCA7B,IAAA,EAAA,cAAmB,EAAA,EAAgB,EAAA,GAAG;;;;;;2CA2BhB,OAAA,KAAA,UAUO,EAUnC,QAAA,CACC,MAAO,GAAA,IAAI;kCACqB,KAAK,UAAA,SAAmB,KAAK,KAAA,QAAa,KAAK,QAAA;;;;;WAlC/E,EAAA,EAAQ,CAAE,QAAS,EAAA,CAAA,EAA0B,EAAA,EAAA,WAAA,CAAA,CACnC,EAAA,UAAA,UAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAUD,CAAE,KAAM,OAAQ,QAAA,CAAS,EAAA,CAAA,CAAA,CAAO,EAAA,UAAA,OAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAUhC,CAAE,KAAM,OAAA,CAAA,CAAA,CAAS,EAAA,UAAA,YAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,eArCb,gBAAA,CAAA,CAAgB,EAAA,CAAA,OAAA,eAAA,QAAA,IAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,GAAA,CAAA,CAAA,OAAA,eAAA,QAAA,IAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,GAAA,CAAA,CAAA,OAAA,eAAA,QAAA,IAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,GAAA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu-BIBUgS1T.js","names":[],"sources":["../src/menu/menu-item.ts","../src/menu/menu.ts"],"sourcesContent":["import { $LitElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement } from 'lit/decorators.js'\nimport { $dialog } from '../dialog/dialog-service'\n\n@customElement('schmancy-menu-item')\nexport default class SchmancyMenuItem extends $LitElement(css`\n\t:host {\n\t\tdisplay: block;\n\t}\n`) {\n\n\tprotected render(): unknown {\n\t\treturn html`\n\t\t\t<schmancy-list-item @click=${() => $dialog.dismiss()}>\n\t\t\t\t<slot></slot>\n\t\t\t</schmancy-list-item>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-menu-item': SchmancyMenuItem\n\t}\n}\n","import { $LitElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, query } from 'lit/decorators.js'\nimport { $dialog } from '../dialog/dialog-service'\n\n/**\n *
|
|
1
|
+
{"version":3,"file":"menu-BIBUgS1T.js","names":[],"sources":["../src/menu/menu-item.ts","../src/menu/menu.ts"],"sourcesContent":["import { $LitElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement } from 'lit/decorators.js'\nimport { $dialog } from '../dialog/dialog-service'\n\n/**\n * Single item inside a schmancy-menu. Auto-dismisses the menu dialog on click — attach your action handler to `@click` and it just works.\n *\n * @element schmancy-menu-item\n * @summary Always nested inside schmancy-menu. The click handler runs before the dialog closes, so `@click=${() => doThing()}` is the full pattern.\n * @example\n * <schmancy-menu-item @click=${() => archive()}>\n * <schmancy-icon slot=\"leading\">archive</schmancy-icon>\n * Archive\n * </schmancy-menu-item>\n * @platform menuitem click - Wraps schmancy-list-item with auto-dismiss. Degrades to a styled `<button role=\"menuitem\">` if the tag never registers.\n * @slot - The item label and optional icons.\n */\n@customElement('schmancy-menu-item')\nexport default class SchmancyMenuItem extends $LitElement(css`\n\t:host {\n\t\tdisplay: block;\n\t}\n`) {\n\n\tprotected render(): unknown {\n\t\treturn html`\n\t\t\t<schmancy-list-item @click=${() => $dialog.dismiss()}>\n\t\t\t\t<slot></slot>\n\t\t\t</schmancy-list-item>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-menu-item': SchmancyMenuItem\n\t}\n}\n","import { $LitElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, query } from 'lit/decorators.js'\nimport { $dialog } from '../dialog/dialog-service'\n\n/**\n * Floating menu — a trigger button + a list of schmancy-menu-item children that open as a positioned dialog on click.\n *\n * @element schmancy-menu\n * @summary Use for dropdown menus attached to a button or icon — \"More actions\", \"Account\", row overflow menus in tables. Clicking a schmancy-menu-item inside auto-dismisses; custom components slotted inside must call `$dialog.dismiss()` themselves.\n * @example\n * <schmancy-menu>\n * <schmancy-icon-button slot=\"trigger\" aria-label=\"Actions\">\n * <schmancy-icon>more_vert</schmancy-icon>\n * </schmancy-icon-button>\n * <schmancy-menu-item @click=${() => edit()}>Edit</schmancy-menu-item>\n * <schmancy-menu-item @click=${() => remove()}>Delete</schmancy-menu-item>\n * </schmancy-menu>\n * @platform menu close - Trigger + floating listbox dialog. Degrades to a native `<select>` or inline list if the tag never registers.\n * @slot trigger - Button to open menu (new naming)\n * @slot button - Button to open menu (backward compatible)\n * @slot default - Menu items or any custom component to display in dialog\n */\n@customElement('schmancy-menu')\nexport default class SchmancyMenu extends $LitElement(css`\n\t:host {\n\t\tposition: relative;\n\t\tdisplay: flex;\n\t}\n`) {\n\t@query('slot:not([name])')\n\tprivate menuSlot!: HTMLSlotElement\n\n\tprivate showMenu(event: MouseEvent) {\n\t\tconst menuItems = this.menuSlot?.assignedElements() || []\n\t\tif (menuItems.length === 0) return\n\n\t\t// Create container and move actual elements to preserve full functionality\n\t\tconst dialogContainer = document.createElement('div')\n\t\tmenuItems.forEach(item => dialogContainer.appendChild(item))\n\n\t\t$dialog\n\t\t\t.component(dialogContainer, {\n\t\t\t\tposition: event,\n\t\t\t\thideActions: true,\n\t\t})\n\t\t\t.finally(() => {\n\t\t\t\t// Restore elements as light DOM children (will be projected via slot)\n\t\t\t\tmenuItems.forEach(item => this.appendChild(item))\n\t\t\t})\n\t}\n\n\trender() {\n\t\treturn html`\n\t\t\t<slot name=\"trigger\" @click=${this.showMenu}>\n\t\t\t\t<slot name=\"button\" @click=${this.showMenu}>\n\t\t\t\t\t<schmancy-icon-button>more_vert</schmancy-icon-button>\n\t\t\t\t</slot>\n\t\t\t</slot>\n\t\t\t<div hidden>\n\t\t\t\t<slot></slot>\n\t\t\t</div>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-menu': SchmancyMenu\n\t}\n}\n"],"mappings":";;;;;;AAmBe,IAAA,IAAA,cAA+B,EAAY,CAAG;;;;;CAM5D,SAAA;AACC,SAAO,CAAI;sCACyB,EAAQ,SAAA,CAAA;;;;;;OAT7C,EAAc,qBAAA,CAAA,EAAqB,EAAA;ACMrB,IAAA,IAAA,cAA2B,EAAY,CAAG;;;;;;CASxD,SAAiB,GAAA;EAChB,IAAM,IAAY,KAAK,UAAU,kBAAA,IAAsB,EAAA;AACvD,MAAI,EAAU,WAAW,EAAG;EAG5B,IAAM,IAAkB,SAAS,cAAc,MAAA;AAC/C,IAAU,SAAQ,MAAQ,EAAgB,YAAY,EAAA,CAAA,EAEtD,EACE,UAAU,GAAiB;GAC3B,UAAU;GACV,aAAA,CAAa;GAAA,CAAA,CAEb,cAAA;AAEA,KAAU,SAAQ,MAAQ,KAAK,YAAY,EAAA,CAAA;IAAA;;CAI9C,SAAA;AACC,SAAO,CAAI;iCACoB,KAAK,SAAA;iCACL,KAAK,SAAA;;;;;;;;;;GAzBpC,EAAM,mBAAA,CAAA,EAAmB,EAAA,WAAA,YAAA,KAAA,EAAA,EAAA,IAAA,EAAA,CAP1B,EAAc,gBAAA,CAAA,EAAgB,EAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu-DS8Iz4fJ.cjs","names":[],"sources":["../src/menu/menu-item.ts","../src/menu/menu.ts"],"sourcesContent":["import { $LitElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement } from 'lit/decorators.js'\nimport { $dialog } from '../dialog/dialog-service'\n\n@customElement('schmancy-menu-item')\nexport default class SchmancyMenuItem extends $LitElement(css`\n\t:host {\n\t\tdisplay: block;\n\t}\n`) {\n\n\tprotected render(): unknown {\n\t\treturn html`\n\t\t\t<schmancy-list-item @click=${() => $dialog.dismiss()}>\n\t\t\t\t<slot></slot>\n\t\t\t</schmancy-list-item>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-menu-item': SchmancyMenuItem\n\t}\n}\n","import { $LitElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, query } from 'lit/decorators.js'\nimport { $dialog } from '../dialog/dialog-service'\n\n/**\n *
|
|
1
|
+
{"version":3,"file":"menu-DS8Iz4fJ.cjs","names":[],"sources":["../src/menu/menu-item.ts","../src/menu/menu.ts"],"sourcesContent":["import { $LitElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement } from 'lit/decorators.js'\nimport { $dialog } from '../dialog/dialog-service'\n\n/**\n * Single item inside a schmancy-menu. Auto-dismisses the menu dialog on click — attach your action handler to `@click` and it just works.\n *\n * @element schmancy-menu-item\n * @summary Always nested inside schmancy-menu. The click handler runs before the dialog closes, so `@click=${() => doThing()}` is the full pattern.\n * @example\n * <schmancy-menu-item @click=${() => archive()}>\n * <schmancy-icon slot=\"leading\">archive</schmancy-icon>\n * Archive\n * </schmancy-menu-item>\n * @platform menuitem click - Wraps schmancy-list-item with auto-dismiss. Degrades to a styled `<button role=\"menuitem\">` if the tag never registers.\n * @slot - The item label and optional icons.\n */\n@customElement('schmancy-menu-item')\nexport default class SchmancyMenuItem extends $LitElement(css`\n\t:host {\n\t\tdisplay: block;\n\t}\n`) {\n\n\tprotected render(): unknown {\n\t\treturn html`\n\t\t\t<schmancy-list-item @click=${() => $dialog.dismiss()}>\n\t\t\t\t<slot></slot>\n\t\t\t</schmancy-list-item>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-menu-item': SchmancyMenuItem\n\t}\n}\n","import { $LitElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, query } from 'lit/decorators.js'\nimport { $dialog } from '../dialog/dialog-service'\n\n/**\n * Floating menu — a trigger button + a list of schmancy-menu-item children that open as a positioned dialog on click.\n *\n * @element schmancy-menu\n * @summary Use for dropdown menus attached to a button or icon — \"More actions\", \"Account\", row overflow menus in tables. Clicking a schmancy-menu-item inside auto-dismisses; custom components slotted inside must call `$dialog.dismiss()` themselves.\n * @example\n * <schmancy-menu>\n * <schmancy-icon-button slot=\"trigger\" aria-label=\"Actions\">\n * <schmancy-icon>more_vert</schmancy-icon>\n * </schmancy-icon-button>\n * <schmancy-menu-item @click=${() => edit()}>Edit</schmancy-menu-item>\n * <schmancy-menu-item @click=${() => remove()}>Delete</schmancy-menu-item>\n * </schmancy-menu>\n * @platform menu close - Trigger + floating listbox dialog. Degrades to a native `<select>` or inline list if the tag never registers.\n * @slot trigger - Button to open menu (new naming)\n * @slot button - Button to open menu (backward compatible)\n * @slot default - Menu items or any custom component to display in dialog\n */\n@customElement('schmancy-menu')\nexport default class SchmancyMenu extends $LitElement(css`\n\t:host {\n\t\tposition: relative;\n\t\tdisplay: flex;\n\t}\n`) {\n\t@query('slot:not([name])')\n\tprivate menuSlot!: HTMLSlotElement\n\n\tprivate showMenu(event: MouseEvent) {\n\t\tconst menuItems = this.menuSlot?.assignedElements() || []\n\t\tif (menuItems.length === 0) return\n\n\t\t// Create container and move actual elements to preserve full functionality\n\t\tconst dialogContainer = document.createElement('div')\n\t\tmenuItems.forEach(item => dialogContainer.appendChild(item))\n\n\t\t$dialog\n\t\t\t.component(dialogContainer, {\n\t\t\t\tposition: event,\n\t\t\t\thideActions: true,\n\t\t})\n\t\t\t.finally(() => {\n\t\t\t\t// Restore elements as light DOM children (will be projected via slot)\n\t\t\t\tmenuItems.forEach(item => this.appendChild(item))\n\t\t\t})\n\t}\n\n\trender() {\n\t\treturn html`\n\t\t\t<slot name=\"trigger\" @click=${this.showMenu}>\n\t\t\t\t<slot name=\"button\" @click=${this.showMenu}>\n\t\t\t\t\t<schmancy-icon-button>more_vert</schmancy-icon-button>\n\t\t\t\t</slot>\n\t\t\t</slot>\n\t\t\t<div hidden>\n\t\t\t\t<slot></slot>\n\t\t\t</div>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-menu': SchmancyMenu\n\t}\n}\n"],"mappings":"qPAmBe,IAAA,EAAA,cAA+B,EAAA,EAAY,EAAA,GAAG;;;;GAM5D,QAAA,CACC,MAAO,GAAA,IAAI;oCACyB,EAAA,EAAQ,SAAA,CAAA;;;iCAT/B,qBAAA,CAAA,CAAqB,EAAA,CCMrB,IAAA,EAAA,cAA2B,EAAA,EAAY,EAAA,GAAG;;;;;GASxD,SAAiB,EAAA,CAChB,IAAM,EAAY,KAAK,UAAU,kBAAA,EAAsB,EAAA,CACvD,GAAI,EAAU,SAAW,EAAG,OAG5B,IAAM,EAAkB,SAAS,cAAc,MAAA,CAC/C,EAAU,QAAQ,GAAQ,EAAgB,YAAY,EAAA,CAAA,CAEtD,EAAA,EACE,UAAU,EAAiB,CAC3B,SAAU,EACV,YAAA,CAAa,EAAA,CAAA,CAEb,YAAA,CAEA,EAAU,QAAQ,GAAQ,KAAK,YAAY,EAAA,CAAA,EAAA,CAI9C,QAAA,CACC,MAAO,GAAA,IAAI;iCACoB,KAAK,SAAA;iCACL,KAAK,SAAA;;;;;;;uBAzB9B,mBAAA,CAAA,CAAmB,EAAA,UAAA,WAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,eAPZ,gBAAA,CAAA,CAAgB,EAAA"}
|