@mhmo91/schmancy 0.9.16 → 0.9.17

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.
Files changed (51) hide show
  1. package/custom-elements.json +26 -5
  2. package/dist/agent/schmancy.agent.js +119 -15
  3. package/dist/agent/schmancy.agent.js.map +1 -1
  4. package/dist/agent/schmancy.manifest.json +134 -7
  5. package/dist/card-BslSqOsf.cjs.map +1 -1
  6. package/dist/card-CEdgK9nb.js.map +1 -1
  7. package/dist/details-B8p62xmR.cjs.map +1 -1
  8. package/dist/details-CCW52lzz.js.map +1 -1
  9. package/dist/divider-CbEWg3G_.js.map +1 -1
  10. package/dist/divider-JyyFw_3J.cjs.map +1 -1
  11. package/dist/expand-BmwIPNjq.cjs.map +1 -1
  12. package/dist/expand-bFa_qVDT.js.map +1 -1
  13. package/dist/handover/agent-runtime-followups.md +1 -1
  14. package/dist/handover/agent-runtime-v1.md +3 -3
  15. package/dist/page.cjs.map +1 -1
  16. package/dist/page.js.map +1 -1
  17. package/dist/scroll-CdmXRXh2.js.map +1 -1
  18. package/dist/scroll-V1rAZ9fK.cjs.map +1 -1
  19. package/dist/surface-0XM4DBaT.js.map +1 -1
  20. package/dist/surface-B6DA01kL.cjs.map +1 -1
  21. package/dist/theme-Cq_c9IO3.js.map +1 -1
  22. package/dist/theme-DU5yXaV-.cjs.map +1 -1
  23. package/dist/tree.cjs.map +1 -1
  24. package/dist/tree.js.map +1 -1
  25. package/package.json +1 -1
  26. package/src/card/actions.ts +9 -0
  27. package/src/card/card.ts +18 -0
  28. package/src/card/content.ts +9 -0
  29. package/src/card/media.ts +6 -0
  30. package/src/details/details.ts +12 -0
  31. package/src/divider/divider.ts +11 -0
  32. package/src/expand/expand-root.component.ts +12 -0
  33. package/src/expand/expand.component.ts +14 -0
  34. package/src/layout/scroll/scroll.ts +5 -1
  35. package/src/page/page.ts +8 -11
  36. package/src/surface/surface.ts +4 -10
  37. package/src/theme/theme.component.ts +10 -15
  38. package/src/tree/tree.ts +12 -0
  39. package/types/src/card/actions.d.ts +9 -0
  40. package/types/src/card/card.d.ts +18 -0
  41. package/types/src/card/content.d.ts +9 -0
  42. package/types/src/card/media.d.ts +6 -0
  43. package/types/src/details/details.d.ts +12 -0
  44. package/types/src/divider/divider.d.ts +11 -0
  45. package/types/src/expand/expand-root.component.d.ts +12 -0
  46. package/types/src/expand/expand.component.d.ts +14 -0
  47. package/types/src/layout/scroll/scroll.d.ts +5 -1
  48. package/types/src/page/page.d.ts +8 -11
  49. package/types/src/surface/surface.d.ts +4 -10
  50. package/types/src/theme/theme.component.d.ts +10 -15
  51. package/types/src/tree/tree.d.ts +12 -0
@@ -1 +1 @@
1
- {"version":3,"file":"details-CCW52lzz.js","names":[],"sources":["../src/details/details.ts"],"sourcesContent":["import { TailwindElement, SurfaceMixin } from '@mixins/index'\nimport { css, html, LitElement, nothing } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { cursorGlow } from '../directives/cursor-glow'\nimport { magnetic } from '../directives/magnetic'\nimport { createRef, ref, Ref } from 'lit/directives/ref.js'\nimport { BehaviorSubject, fromEvent, Subscription } from 'rxjs'\nimport { distinctUntilChanged, filter, take, takeUntil, tap } from 'rxjs/operators'\nimport { SPRING_SNAPPY } from '../utils/animation.js'\nimport { reducedMotion$ } from '../directives/reduced-motion'\n\n@customElement('schmancy-details')\nexport default class SchmancyDetails extends SurfaceMixin(\n\tTailwindElement(css`\n\t\t:host {\n\t\t\tdisplay: block;\n\t\t\ttransition: box-shadow 400ms cubic-bezier(0.34, 1.2, 0.64, 1);\n\t\t}\n\n\t\t:host([overlay]) {\n\t\t\tposition: relative;\n\t\t}\n\n\t\t:host([open]) {\n\t\t\tbox-shadow:\n\t\t\t\t0 2px 12px -2px color-mix(in srgb, var(--schmancy-sys-color-primary-default) 15%, transparent),\n\t\t\t\t0 8px 32px -8px color-mix(in srgb, var(--schmancy-sys-color-primary-default) 8%, transparent);\n\t\t\tz-index: 10;\n\t\t}\n\n\t\tdetails {\n\t\t\tbackground: inherit;\n\t\t\tcolor: inherit;\n\t\t\tborder-radius: inherit;\n\t\t}\n\n\t\tsummary::-webkit-details-marker {\n\t\t\tdisplay: none;\n\t\t}\n\n\t\tsummary {\n\t\t\tlist-style: none;\n\t\t\tcolor: inherit;\n\t\t}\n\n\t\t/*\n\t\t * Blackbird 2.1 — CSS-driven collapse/expand\n\t\t *\n\t\t * Single animation system: CSS grid transition handles height,\n\t\t * coordinated opacity fade for buttery smooth feel.\n\t\t * No competing Web Animations API on content.\n\t\t */\n\n\t\t.content-wrapper {\n\t\t\tdisplay: grid;\n\t\t\tgrid-template-rows: 0fr;\n\t\t\toverflow: hidden;\n\t\t\topacity: 0;\n\t\t\ttransition:\n\t\t\t\tgrid-template-rows 400ms cubic-bezier(0.34, 1.2, 0.64, 1),\n\t\t\t\topacity 250ms ease;\n\t\t}\n\n\t\t/* Spring easing when linear() is supported */\n\t\t@supports (animation-timing-function: linear(0, 1)) {\n\t\t\t.content-wrapper {\n\t\t\t\ttransition:\n\t\t\t\t\tgrid-template-rows 400ms linear(\n\t\t\t\t\t\t0, 0.006, 0.025 2.8%, 0.101 6.1%, 0.539 18.9%, 0.721 25.3%, 0.849 31.5%,\n\t\t\t\t\t\t0.937 38.1%, 0.968 41.8%, 0.991 45.7%, 1.006 50%, 1.015 54.8%,\n\t\t\t\t\t\t1.017 63.3%, 1.001\n\t\t\t\t\t),\n\t\t\t\t\topacity 250ms ease;\n\t\t\t}\n\t\t}\n\n\t\t.content-wrapper[data-open='true'] {\n\t\t\tgrid-template-rows: 1fr;\n\t\t\topacity: 1;\n\t\t}\n\n\t\t.content-inner {\n\t\t\tmin-height: 0;\n\t\t\toverflow: hidden;\n\t\t}\n\n\t\t/*\n\t\t * Progressive Enhancement: ::details-content (Chrome 131+)\n\t\t *\n\t\t * When both ::details-content AND interpolate-size are supported,\n\t\t * the browser handles height animation natively — including animated\n\t\t * close via transition-behavior: allow-discrete on content-visibility.\n\t\t * The grid wrapper becomes transparent (display: contents).\n\t\t */\n\t\t@supports selector(::details-content) and (interpolate-size: allow-keywords) {\n\t\t\t:host {\n\t\t\t\tinterpolate-size: allow-keywords;\n\t\t\t}\n\n\t\t\t.content-wrapper {\n\t\t\t\tdisplay: contents;\n\t\t\t}\n\n\t\t\tdetails::details-content {\n\t\t\t\tblock-size: 0;\n\t\t\t\toverflow-y: clip;\n\t\t\t\topacity: 0;\n\t\t\t\ttransition:\n\t\t\t\t\tblock-size 400ms cubic-bezier(0.34, 1.2, 0.64, 1),\n\t\t\t\t\topacity 250ms ease,\n\t\t\t\t\tcontent-visibility 400ms;\n\t\t\t\ttransition-behavior: allow-discrete;\n\t\t\t}\n\n\t\t\tdetails[open]::details-content {\n\t\t\t\tblock-size: auto;\n\t\t\t\topacity: 1;\n\t\t\t}\n\t\t}\n\n\t\t@media (prefers-reduced-motion: reduce) {\n\t\t\t.content-wrapper {\n\t\t\t\ttransition: none;\n\t\t\t}\n\t\t\tdetails::details-content {\n\t\t\t\ttransition: none;\n\t\t\t}\n\t\t}\n\t`),\n) {\n\tprotected static shadowRootOptions = {\n\t\t...LitElement.shadowRootOptions,\n\t\tmode: 'open' as const,\n\t\tdelegatesFocus: true,\n\t}\n\n\t@property() summary = ''\n\n\t@property({ type: Boolean, reflect: true })\n\tget open() {\n\t\treturn this._open$.value\n\t}\n\tset open(value: boolean) {\n\t\tif (this._open$.value !== value) {\n\t\t\tthis._open$.next(value)\n\t\t}\n\t}\n\n\t@property({ attribute: 'indicator-placement', reflect: true })\n\tindicatorPlacement: 'start' | 'end' = 'end'\n\n\t@property({ type: Boolean, attribute: 'hide-indicator' })\n\thideIndicator = false\n\n\t@property({ type: Number, attribute: 'indicator-rotate' })\n\tindicatorRotate: number = 90\n\n\t@property({ type: Boolean, reflect: true })\n\tlocked = false\n\n\t@property({ type: Boolean, reflect: true })\n\toverlay = false\n\n\t@property({ attribute: 'summary-padding' })\n\tsummaryPadding = 'p-3'\n\n\t@property({ attribute: 'content-padding' })\n\tcontentPadding = 'p-3'\n\n\tprivate _open$ = new BehaviorSubject<boolean>(false)\n\tprivate _indicatorRef: Ref<HTMLElement> = createRef()\n\tprivate _contentRef: Ref<HTMLDivElement> = createRef()\n\tprivate _currentAnimation?: Animation\n\tprivate _indicatorIsOpen = false\n\tprivate _closing = false\n\tprivate _closeSub?: Subscription\n\n\t/** True when browser handles close animation natively via ::details-content */\n\tprivate _nativeAnim =\n\t\ttypeof CSS !== 'undefined' &&\n\t\t!!CSS.supports?.('selector(::details-content)') &&\n\t\t!!CSS.supports?.('interpolate-size', 'allow-keywords')\n\n\t/**\n\t * Lazy rendering: tracks if content has ever been opened.\n\t * Once true, content stays rendered (even when closed) for smooth animations.\n\t */\n\t@state() private _hasOpened = false\n\n\tconstructor() {\n\t\tsuper()\n\t\tthis.type = 'solid'\n\t\tthis.rounded = 'all'\n\t}\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback()\n\n\t\tthis._open$\n\t\t\t.pipe(\n\t\t\t\tdistinctUntilChanged(),\n\t\t\t\ttap(isOpen => {\n\t\t\t\t\tif (isOpen && !this._hasOpened) {\n\t\t\t\t\t\tthis._hasOpened = true\n\t\t\t\t\t}\n\t\t\t\t\tthis._animateIndicator(isOpen)\n\t\t\t\t\tthis._updateIndicatorSlot()\n\t\t\t\t}),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe(() => this.requestUpdate())\n\t}\n\n\tdisconnectedCallback() {\n\t\tsuper.disconnectedCallback()\n\t\tthis._closeSub?.unsubscribe()\n\t}\n\n\trender() {\n\t\tconst isOpen = this._open$.value\n\n\t\tconst detailsClasses = this.classMap({\n\t\t\t'w-full rounded-xl transition-shadow duration-200 ease-out': true,\n\t\t\t'overflow-hidden': !this.overlay,\n\t\t\t'overflow-visible relative': this.overlay,\n\t\t})\n\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': true,\n\t\t\t'transition-colors duration-150': true,\n\t\t\t'ring-1 ring-inset ring-transparent': true,\n\t\t\t'hover:bg-surface-on/5 active:bg-surface-on/8 hover:ring-outline-variant/40': !this.locked,\n\t\t\t'focus-visible:ring-2 focus-visible:ring-primary-default/50 focus-visible:ring-offset-1': !this.locked,\n\t\t\t'cursor-pointer group': !this.locked,\n\t\t\t'cursor-default': this.locked,\n\t\t\t'flex-row': this.indicatorPlacement === 'start',\n\t\t\t'flex-row-reverse': this.indicatorPlacement === 'end',\n\t\t})\n\n\t\tconst contentClasses = this.classMap({\n\t\t\t[this.contentPadding]: true,\n\t\t\t'text-sm': true,\n\t\t\t'absolute inset-x-0 bg-surface-lowest/55 backdrop-blur-[16px] shadow-2xl rounded-b-xl z-20 border border-surface-on/10':\n\t\t\t\tthis.overlay,\n\t\t})\n\n\t\treturn html`\n\t\t\t<details ?open=${isOpen} @toggle=${this._handleToggle} class=${detailsClasses}>\n\t\t\t\t<summary ${this.locked ? '' : magnetic({ strength: 2, radius: 50 })} ${this.locked ? '' : cursorGlow({ radius: 250, intensity: 0.08 })} class=${summaryClasses} tabindex=${this.locked ? -1 : 0} @click=${this._handleSummaryClick}>\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\n\t\t\t\t\t\t\t\t\t${ref(this._indicatorRef)}\n\t\t\t\t\t\t\t\t\tclass=\"flex items-center justify-center w-5 h-5 rounded-full shrink-0 opacity-70 group-hover:opacity-100\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<slot name=\"indicator\" @slotchange=${this._handleIndicatorSlotChange}>\n\t\t\t\t\t\t\t\t\t\t<svg\n\t\t\t\t\t\t\t\t\t\t\twidth=\"20\"\n\t\t\t\t\t\t\t\t\t\t\theight=\"20\"\n\t\t\t\t\t\t\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t\t\t\t\tclass=\"w-5 h-5\"\n\t\t\t\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<path\n\t\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\t\tstroke=\"currentColor\"\n\t\t\t\t\t\t\t\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\t\t\t\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\t\t\t\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t\t\t</slot>\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: ''}\n\n\t\t\t\t\t<span class=\"flex-1 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</summary>\n\n\t\t\t\t<div\n\t\t\t\t\t${ref(this._contentRef)}\n\t\t\t\t\tclass=\"content-wrapper\"\n\t\t\t\t\tdata-open=${isOpen && !this._closing}\n\t\t\t\t\taria-hidden=${isOpen ? 'false' : 'true'}\n\t\t\t\t>\n\t\t\t\t\t<div class=\"content-inner\">\n\t\t\t\t\t\t${this._hasOpened\n\t\t\t\t\t\t\t? html`\n\t\t\t\t\t\t\t\t\t<div class=${contentClasses}>\n\t\t\t\t\t\t\t\t\t\t<slot></slot>\n\t\t\t\t\t\t\t\t\t\t<slot name=\"details\"></slot>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t`\n\t\t\t\t\t\t\t: nothing}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</details>\n\t\t`\n\t}\n\n\tprivate _handleSummaryClick(e: MouseEvent) {\n\t\tif ((e.target as HTMLElement).closest('[slot=\"actions\"]')) {\n\t\t\te.preventDefault()\n\t\t\treturn\n\t\t}\n\t\tif (this.locked) {\n\t\t\te.preventDefault()\n\t\t\treturn\n\t\t}\n\t\tif (this._closing) {\n\t\t\te.preventDefault()\n\t\t\treturn\n\t\t}\n\n\t\t// Native animated path (Chromium 131+): browser handles everything via CSS\n\t\tif (this._nativeAnim) return\n\n\t\t// Fallback: manually animate close via CSS transition, then close native details\n\t\tif (this._open$.value) {\n\t\t\te.preventDefault()\n\t\t\tthis._startClose()\n\t\t}\n\t\t// If closed, let native open happen (handled by _handleToggle)\n\t}\n\n\tprivate _handleToggle(e: Event) {\n\t\te.stopPropagation()\n\n\t\tconst ownDetails = this.shadowRoot?.querySelector('details')\n\t\tif (e.target !== ownDetails) return\n\n\t\tconst newState = ownDetails.open\n\n\t\tif (this._nativeAnim) {\n\t\t\t// Native path: handle both open and close\n\t\t\tif (this._open$.value !== newState) {\n\t\t\t\tthis.open = newState\n\t\t\t\tthis.dispatchScopedEvent('toggle', { open: newState })\n\t\t\t}\n\t\t} else {\n\t\t\t// Fallback path: only handle OPEN (close is driven by _startClose)\n\t\t\tif (newState && this._open$.value !== newState) {\n\t\t\t\tthis.open = newState\n\t\t\t\tthis.dispatchScopedEvent('toggle', { open: newState })\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Fallback close: trigger CSS grid+opacity transition, then close native <details>.\n\t * The CSS transition (400ms) handles the visual collapse — no WAAPI needed.\n\t */\n\tprivate _startClose() {\n\t\tthis._closing = true\n\t\tthis._closeSub?.unsubscribe()\n\n\t\t// Immediately collapse the grid wrapper via DOM attribute\n\t\tthis._contentRef.value?.setAttribute('data-open', 'false')\n\n\t\t// Animate indicator immediately\n\t\tthis._animateIndicator(false)\n\n\t\t// After CSS transition completes, close native details and update state\n\t\tconst wrapper = this._contentRef.value\n\t\tif (!wrapper) return\n\n\t\tthis._closeSub = fromEvent<TransitionEvent>(wrapper, 'transitionend').pipe(\n\t\t\tfilter(e => e.propertyName === 'grid-template-rows'),\n\t\t\ttake(1),\n\t\t\ttap(() => {\n\t\t\t\tthis._closing = false\n\t\t\t\tthis.open = false\n\t\t\t\tthis.dispatchScopedEvent('toggle', { open: false })\n\t\t\t}),\n\t\t\ttakeUntil(this.disconnecting),\n\t\t).subscribe()\n\t}\n\n\tprivate _handleIndicatorSlotChange(e: Event) {\n\t\tconst slot = e.target as HTMLSlotElement\n\t\tslot.assignedElements().forEach(el => {\n\t\t\tel.setAttribute('data-open', String(this._open$.value))\n\t\t})\n\t}\n\n\tprivate _updateIndicatorSlot() {\n\t\tconst slot = this.shadowRoot?.querySelector('slot[name=\"indicator\"]') as HTMLSlotElement | null\n\t\tif (slot) {\n\t\t\tslot.assignedElements().forEach(el => {\n\t\t\t\tel.setAttribute('data-open', String(this._open$.value))\n\t\t\t})\n\t\t}\n\t}\n\n\t/** Idempotent indicator rotation — skips if already at target state */\n\tprivate _animateIndicator(isOpen: boolean) {\n\t\tif (this._indicatorIsOpen === isOpen) return\n\t\tthis._indicatorIsOpen = isOpen\n\n\t\tconst indicator = this._indicatorRef.value\n\t\tif (!indicator || reducedMotion$.value) return\n\n\t\tthis._currentAnimation?.cancel()\n\n\t\tthis._currentAnimation = 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\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-details': SchmancyDetails\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"details-CCW52lzz.js","names":[],"sources":["../src/details/details.ts"],"sourcesContent":["import { TailwindElement, SurfaceMixin } from '@mixins/index'\nimport { css, html, LitElement, nothing } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { cursorGlow } from '../directives/cursor-glow'\nimport { magnetic } from '../directives/magnetic'\nimport { createRef, ref, Ref } from 'lit/directives/ref.js'\nimport { BehaviorSubject, fromEvent, Subscription } from 'rxjs'\nimport { distinctUntilChanged, filter, take, takeUntil, tap } from 'rxjs/operators'\nimport { SPRING_SNAPPY } from '../utils/animation.js'\nimport { reducedMotion$ } from '../directives/reduced-motion'\n\n/**\n * Expandable disclosure panel — a styled `<details>` / `<summary>` pair with animated expand + overlay options.\n *\n * @element schmancy-details\n * @summary Use for progressive-disclosure content: FAQs, collapsible settings sections, accordion-style lists. Prefer schmancy-expand for full-page accordions where only one section can be open at a time.\n * @example\n * <schmancy-details summary=\"Shipping details\">\n * <p>Order ships in 2 business days.</p>\n * </schmancy-details>\n * @platform details toggle - Wraps native `<details>`/`<summary>`. Degrades to the native element if the tag never registers — same keyboard accessibility, just no animation.\n * @fires toggle - When the open state changes (bubbles from the native `<details>`).\n */\n@customElement('schmancy-details')\nexport default class SchmancyDetails extends SurfaceMixin(\n\tTailwindElement(css`\n\t\t:host {\n\t\t\tdisplay: block;\n\t\t\ttransition: box-shadow 400ms cubic-bezier(0.34, 1.2, 0.64, 1);\n\t\t}\n\n\t\t:host([overlay]) {\n\t\t\tposition: relative;\n\t\t}\n\n\t\t:host([open]) {\n\t\t\tbox-shadow:\n\t\t\t\t0 2px 12px -2px color-mix(in srgb, var(--schmancy-sys-color-primary-default) 15%, transparent),\n\t\t\t\t0 8px 32px -8px color-mix(in srgb, var(--schmancy-sys-color-primary-default) 8%, transparent);\n\t\t\tz-index: 10;\n\t\t}\n\n\t\tdetails {\n\t\t\tbackground: inherit;\n\t\t\tcolor: inherit;\n\t\t\tborder-radius: inherit;\n\t\t}\n\n\t\tsummary::-webkit-details-marker {\n\t\t\tdisplay: none;\n\t\t}\n\n\t\tsummary {\n\t\t\tlist-style: none;\n\t\t\tcolor: inherit;\n\t\t}\n\n\t\t/*\n\t\t * Blackbird 2.1 — CSS-driven collapse/expand\n\t\t *\n\t\t * Single animation system: CSS grid transition handles height,\n\t\t * coordinated opacity fade for buttery smooth feel.\n\t\t * No competing Web Animations API on content.\n\t\t */\n\n\t\t.content-wrapper {\n\t\t\tdisplay: grid;\n\t\t\tgrid-template-rows: 0fr;\n\t\t\toverflow: hidden;\n\t\t\topacity: 0;\n\t\t\ttransition:\n\t\t\t\tgrid-template-rows 400ms cubic-bezier(0.34, 1.2, 0.64, 1),\n\t\t\t\topacity 250ms ease;\n\t\t}\n\n\t\t/* Spring easing when linear() is supported */\n\t\t@supports (animation-timing-function: linear(0, 1)) {\n\t\t\t.content-wrapper {\n\t\t\t\ttransition:\n\t\t\t\t\tgrid-template-rows 400ms linear(\n\t\t\t\t\t\t0, 0.006, 0.025 2.8%, 0.101 6.1%, 0.539 18.9%, 0.721 25.3%, 0.849 31.5%,\n\t\t\t\t\t\t0.937 38.1%, 0.968 41.8%, 0.991 45.7%, 1.006 50%, 1.015 54.8%,\n\t\t\t\t\t\t1.017 63.3%, 1.001\n\t\t\t\t\t),\n\t\t\t\t\topacity 250ms ease;\n\t\t\t}\n\t\t}\n\n\t\t.content-wrapper[data-open='true'] {\n\t\t\tgrid-template-rows: 1fr;\n\t\t\topacity: 1;\n\t\t}\n\n\t\t.content-inner {\n\t\t\tmin-height: 0;\n\t\t\toverflow: hidden;\n\t\t}\n\n\t\t/*\n\t\t * Progressive Enhancement: ::details-content (Chrome 131+)\n\t\t *\n\t\t * When both ::details-content AND interpolate-size are supported,\n\t\t * the browser handles height animation natively — including animated\n\t\t * close via transition-behavior: allow-discrete on content-visibility.\n\t\t * The grid wrapper becomes transparent (display: contents).\n\t\t */\n\t\t@supports selector(::details-content) and (interpolate-size: allow-keywords) {\n\t\t\t:host {\n\t\t\t\tinterpolate-size: allow-keywords;\n\t\t\t}\n\n\t\t\t.content-wrapper {\n\t\t\t\tdisplay: contents;\n\t\t\t}\n\n\t\t\tdetails::details-content {\n\t\t\t\tblock-size: 0;\n\t\t\t\toverflow-y: clip;\n\t\t\t\topacity: 0;\n\t\t\t\ttransition:\n\t\t\t\t\tblock-size 400ms cubic-bezier(0.34, 1.2, 0.64, 1),\n\t\t\t\t\topacity 250ms ease,\n\t\t\t\t\tcontent-visibility 400ms;\n\t\t\t\ttransition-behavior: allow-discrete;\n\t\t\t}\n\n\t\t\tdetails[open]::details-content {\n\t\t\t\tblock-size: auto;\n\t\t\t\topacity: 1;\n\t\t\t}\n\t\t}\n\n\t\t@media (prefers-reduced-motion: reduce) {\n\t\t\t.content-wrapper {\n\t\t\t\ttransition: none;\n\t\t\t}\n\t\t\tdetails::details-content {\n\t\t\t\ttransition: none;\n\t\t\t}\n\t\t}\n\t`),\n) {\n\tprotected static shadowRootOptions = {\n\t\t...LitElement.shadowRootOptions,\n\t\tmode: 'open' as const,\n\t\tdelegatesFocus: true,\n\t}\n\n\t@property() summary = ''\n\n\t@property({ type: Boolean, reflect: true })\n\tget open() {\n\t\treturn this._open$.value\n\t}\n\tset open(value: boolean) {\n\t\tif (this._open$.value !== value) {\n\t\t\tthis._open$.next(value)\n\t\t}\n\t}\n\n\t@property({ attribute: 'indicator-placement', reflect: true })\n\tindicatorPlacement: 'start' | 'end' = 'end'\n\n\t@property({ type: Boolean, attribute: 'hide-indicator' })\n\thideIndicator = false\n\n\t@property({ type: Number, attribute: 'indicator-rotate' })\n\tindicatorRotate: number = 90\n\n\t@property({ type: Boolean, reflect: true })\n\tlocked = false\n\n\t@property({ type: Boolean, reflect: true })\n\toverlay = false\n\n\t@property({ attribute: 'summary-padding' })\n\tsummaryPadding = 'p-3'\n\n\t@property({ attribute: 'content-padding' })\n\tcontentPadding = 'p-3'\n\n\tprivate _open$ = new BehaviorSubject<boolean>(false)\n\tprivate _indicatorRef: Ref<HTMLElement> = createRef()\n\tprivate _contentRef: Ref<HTMLDivElement> = createRef()\n\tprivate _currentAnimation?: Animation\n\tprivate _indicatorIsOpen = false\n\tprivate _closing = false\n\tprivate _closeSub?: Subscription\n\n\t/** True when browser handles close animation natively via ::details-content */\n\tprivate _nativeAnim =\n\t\ttypeof CSS !== 'undefined' &&\n\t\t!!CSS.supports?.('selector(::details-content)') &&\n\t\t!!CSS.supports?.('interpolate-size', 'allow-keywords')\n\n\t/**\n\t * Lazy rendering: tracks if content has ever been opened.\n\t * Once true, content stays rendered (even when closed) for smooth animations.\n\t */\n\t@state() private _hasOpened = false\n\n\tconstructor() {\n\t\tsuper()\n\t\tthis.type = 'solid'\n\t\tthis.rounded = 'all'\n\t}\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback()\n\n\t\tthis._open$\n\t\t\t.pipe(\n\t\t\t\tdistinctUntilChanged(),\n\t\t\t\ttap(isOpen => {\n\t\t\t\t\tif (isOpen && !this._hasOpened) {\n\t\t\t\t\t\tthis._hasOpened = true\n\t\t\t\t\t}\n\t\t\t\t\tthis._animateIndicator(isOpen)\n\t\t\t\t\tthis._updateIndicatorSlot()\n\t\t\t\t}),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe(() => this.requestUpdate())\n\t}\n\n\tdisconnectedCallback() {\n\t\tsuper.disconnectedCallback()\n\t\tthis._closeSub?.unsubscribe()\n\t}\n\n\trender() {\n\t\tconst isOpen = this._open$.value\n\n\t\tconst detailsClasses = this.classMap({\n\t\t\t'w-full rounded-xl transition-shadow duration-200 ease-out': true,\n\t\t\t'overflow-hidden': !this.overlay,\n\t\t\t'overflow-visible relative': this.overlay,\n\t\t})\n\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': true,\n\t\t\t'transition-colors duration-150': true,\n\t\t\t'ring-1 ring-inset ring-transparent': true,\n\t\t\t'hover:bg-surface-on/5 active:bg-surface-on/8 hover:ring-outline-variant/40': !this.locked,\n\t\t\t'focus-visible:ring-2 focus-visible:ring-primary-default/50 focus-visible:ring-offset-1': !this.locked,\n\t\t\t'cursor-pointer group': !this.locked,\n\t\t\t'cursor-default': this.locked,\n\t\t\t'flex-row': this.indicatorPlacement === 'start',\n\t\t\t'flex-row-reverse': this.indicatorPlacement === 'end',\n\t\t})\n\n\t\tconst contentClasses = this.classMap({\n\t\t\t[this.contentPadding]: true,\n\t\t\t'text-sm': true,\n\t\t\t'absolute inset-x-0 bg-surface-lowest/55 backdrop-blur-[16px] shadow-2xl rounded-b-xl z-20 border border-surface-on/10':\n\t\t\t\tthis.overlay,\n\t\t})\n\n\t\treturn html`\n\t\t\t<details ?open=${isOpen} @toggle=${this._handleToggle} class=${detailsClasses}>\n\t\t\t\t<summary ${this.locked ? '' : magnetic({ strength: 2, radius: 50 })} ${this.locked ? '' : cursorGlow({ radius: 250, intensity: 0.08 })} class=${summaryClasses} tabindex=${this.locked ? -1 : 0} @click=${this._handleSummaryClick}>\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\n\t\t\t\t\t\t\t\t\t${ref(this._indicatorRef)}\n\t\t\t\t\t\t\t\t\tclass=\"flex items-center justify-center w-5 h-5 rounded-full shrink-0 opacity-70 group-hover:opacity-100\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<slot name=\"indicator\" @slotchange=${this._handleIndicatorSlotChange}>\n\t\t\t\t\t\t\t\t\t\t<svg\n\t\t\t\t\t\t\t\t\t\t\twidth=\"20\"\n\t\t\t\t\t\t\t\t\t\t\theight=\"20\"\n\t\t\t\t\t\t\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t\t\t\t\tclass=\"w-5 h-5\"\n\t\t\t\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<path\n\t\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\t\tstroke=\"currentColor\"\n\t\t\t\t\t\t\t\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\t\t\t\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\t\t\t\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t\t\t</slot>\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: ''}\n\n\t\t\t\t\t<span class=\"flex-1 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</summary>\n\n\t\t\t\t<div\n\t\t\t\t\t${ref(this._contentRef)}\n\t\t\t\t\tclass=\"content-wrapper\"\n\t\t\t\t\tdata-open=${isOpen && !this._closing}\n\t\t\t\t\taria-hidden=${isOpen ? 'false' : 'true'}\n\t\t\t\t>\n\t\t\t\t\t<div class=\"content-inner\">\n\t\t\t\t\t\t${this._hasOpened\n\t\t\t\t\t\t\t? html`\n\t\t\t\t\t\t\t\t\t<div class=${contentClasses}>\n\t\t\t\t\t\t\t\t\t\t<slot></slot>\n\t\t\t\t\t\t\t\t\t\t<slot name=\"details\"></slot>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t`\n\t\t\t\t\t\t\t: nothing}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</details>\n\t\t`\n\t}\n\n\tprivate _handleSummaryClick(e: MouseEvent) {\n\t\tif ((e.target as HTMLElement).closest('[slot=\"actions\"]')) {\n\t\t\te.preventDefault()\n\t\t\treturn\n\t\t}\n\t\tif (this.locked) {\n\t\t\te.preventDefault()\n\t\t\treturn\n\t\t}\n\t\tif (this._closing) {\n\t\t\te.preventDefault()\n\t\t\treturn\n\t\t}\n\n\t\t// Native animated path (Chromium 131+): browser handles everything via CSS\n\t\tif (this._nativeAnim) return\n\n\t\t// Fallback: manually animate close via CSS transition, then close native details\n\t\tif (this._open$.value) {\n\t\t\te.preventDefault()\n\t\t\tthis._startClose()\n\t\t}\n\t\t// If closed, let native open happen (handled by _handleToggle)\n\t}\n\n\tprivate _handleToggle(e: Event) {\n\t\te.stopPropagation()\n\n\t\tconst ownDetails = this.shadowRoot?.querySelector('details')\n\t\tif (e.target !== ownDetails) return\n\n\t\tconst newState = ownDetails.open\n\n\t\tif (this._nativeAnim) {\n\t\t\t// Native path: handle both open and close\n\t\t\tif (this._open$.value !== newState) {\n\t\t\t\tthis.open = newState\n\t\t\t\tthis.dispatchScopedEvent('toggle', { open: newState })\n\t\t\t}\n\t\t} else {\n\t\t\t// Fallback path: only handle OPEN (close is driven by _startClose)\n\t\t\tif (newState && this._open$.value !== newState) {\n\t\t\t\tthis.open = newState\n\t\t\t\tthis.dispatchScopedEvent('toggle', { open: newState })\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Fallback close: trigger CSS grid+opacity transition, then close native <details>.\n\t * The CSS transition (400ms) handles the visual collapse — no WAAPI needed.\n\t */\n\tprivate _startClose() {\n\t\tthis._closing = true\n\t\tthis._closeSub?.unsubscribe()\n\n\t\t// Immediately collapse the grid wrapper via DOM attribute\n\t\tthis._contentRef.value?.setAttribute('data-open', 'false')\n\n\t\t// Animate indicator immediately\n\t\tthis._animateIndicator(false)\n\n\t\t// After CSS transition completes, close native details and update state\n\t\tconst wrapper = this._contentRef.value\n\t\tif (!wrapper) return\n\n\t\tthis._closeSub = fromEvent<TransitionEvent>(wrapper, 'transitionend').pipe(\n\t\t\tfilter(e => e.propertyName === 'grid-template-rows'),\n\t\t\ttake(1),\n\t\t\ttap(() => {\n\t\t\t\tthis._closing = false\n\t\t\t\tthis.open = false\n\t\t\t\tthis.dispatchScopedEvent('toggle', { open: false })\n\t\t\t}),\n\t\t\ttakeUntil(this.disconnecting),\n\t\t).subscribe()\n\t}\n\n\tprivate _handleIndicatorSlotChange(e: Event) {\n\t\tconst slot = e.target as HTMLSlotElement\n\t\tslot.assignedElements().forEach(el => {\n\t\t\tel.setAttribute('data-open', String(this._open$.value))\n\t\t})\n\t}\n\n\tprivate _updateIndicatorSlot() {\n\t\tconst slot = this.shadowRoot?.querySelector('slot[name=\"indicator\"]') as HTMLSlotElement | null\n\t\tif (slot) {\n\t\t\tslot.assignedElements().forEach(el => {\n\t\t\t\tel.setAttribute('data-open', String(this._open$.value))\n\t\t\t})\n\t\t}\n\t}\n\n\t/** Idempotent indicator rotation — skips if already at target state */\n\tprivate _animateIndicator(isOpen: boolean) {\n\t\tif (this._indicatorIsOpen === isOpen) return\n\t\tthis._indicatorIsOpen = isOpen\n\n\t\tconst indicator = this._indicatorRef.value\n\t\tif (!indicator || reducedMotion$.value) return\n\n\t\tthis._currentAnimation?.cancel()\n\n\t\tthis._currentAnimation = 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\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-details': SchmancyDetails\n\t}\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"divider-CbEWg3G_.js","names":[],"sources":["../src/divider/divider.ts"],"sourcesContent":["// divider.ts\nimport { $LitElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\n@customElement('schmancy-divider')\nexport default class SchmancyDivider extends $LitElement(css`\n\t:host {\n\t\tdisplay: block;\n\t}\n\n\t@keyframes grow-horizontal {\n\t\tfrom {\n\t\t\ttransform: scaleX(0);\n\t\t}\n\t\tto {\n\t\t\ttransform: scaleX(1);\n\t\t}\n\t}\n\n\t@keyframes grow-vertical {\n\t\tfrom {\n\t\t\ttransform: scaleY(0);\n\t\t}\n\t\tto {\n\t\t\ttransform: scaleY(1);\n\t\t}\n\t}\n\n\t/* Horizontal divider grow animations */\n\t.grow-start:not(.h-full) {\n\t\tanimation: grow-horizontal 400ms ease-out;\n\t\ttransform-origin: left;\n\t}\n\n\t.grow-end:not(.h-full) {\n\t\tanimation: grow-horizontal 400ms ease-out;\n\t\ttransform-origin: right;\n\t}\n\n\t.grow-both:not(.h-full) {\n\t\tanimation: grow-horizontal 400ms ease-out;\n\t\ttransform-origin: center;\n\t}\n\n\t/* Vertical divider grow animations */\n\t.grow-start.h-full {\n\t\tanimation: grow-vertical 400ms ease-out;\n\t\ttransform-origin: top;\n\t}\n\n\t.grow-end.h-full {\n\t\tanimation: grow-vertical 400ms ease-out;\n\t\ttransform-origin: bottom;\n\t}\n\n\t.grow-both.h-full {\n\t\tanimation: grow-vertical 400ms ease-out;\n\t\ttransform-origin: center;\n\t}\n`) {\n\t@property({ type: String }) outline: 'default' | 'variant' = 'variant'\n\t@property({ type: Boolean }) vertical = false\n\t@property({ type: String }) grow: 'start' | 'end' | 'both' = 'start'\n\n\t/**\n\t * @deprecated Use `vertical` property instead. Will be removed in next major version.\n\t */\n\t@property({ reflect: true, type: String })\n\tset orientation(value: 'horizontal' | 'vertical') {\n\t\tthis.vertical = value === 'vertical'\n\t}\n\tget orientation(): 'horizontal' | 'vertical' {\n\t\treturn this.vertical ? 'vertical' : 'horizontal'\n\t}\n\n\tprotected render() {\n\t\treturn html`<div\n\t\t\tclass=${this.classMap({\n\t\t\t\t// Dimensions\n\t\t\t\t'w-full h-px': !this.vertical,\n\t\t\t\t'h-full w-px': this.vertical,\n\t\t\t\t// Border color\n\t\t\t\t'border-outlineVariant': this.outline === 'variant',\n\t\t\t\t'border-outline': this.outline === 'default',\n\t\t\t\t// Border style\n\t\t\t\t'border-t': !this.vertical,\n\t\t\t\t'border-l': this.vertical,\n\t\t\t\t// Grow behavior\n\t\t\t\t[`grow-${this.grow}`]: true,\n\t\t\t})}\n\t\t></div>`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-divider': SchmancyDivider\n\t}\n}\n"],"mappings":";;;;;AAMe,IAAA,IAAA,cAA8B,EAAY,CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BAuDE,WAAA,KAAA,WAAA,CACrB,GAAA,KAAA,OACqB;;CAK7D,IAAA,YACgB,GAAA;AACf,OAAK,WAAW,MAAU;;CAE3B,IAAA,cAAI;AACH,SAAO,KAAK,WAAW,aAAa;;CAGrC,SAAA;AACC,SAAO,CAAI;WACF,KAAK,SAAS;GAErB,eAAA,CAAgB,KAAK;GACrB,eAAe,KAAK;GAEpB,yBAAyB,KAAK,YAAY;GAC1C,kBAAkB,KAAK,YAAY;GAEnC,YAAA,CAAa,KAAK;GAClB,YAAY,KAAK;IAEhB,QAAQ,KAAK,SAAA,CAAS;GAAA,CAAA,CAAA;;;;GA5BzB,EAAS,EAAE,MAAM,QAAA,CAAA,CAAA,EAAS,EAAA,WAAA,WAAA,KAAA,EAAA,EAAA,EAAA,CAC1B,EAAS,EAAE,MAAM,SAAA,CAAA,CAAA,EAAU,EAAA,WAAA,YAAA,KAAA,EAAA,EAAA,EAAA,CAC3B,EAAS,EAAE,MAAM,QAAA,CAAA,CAAA,EAAS,EAAA,WAAA,QAAA,KAAA,EAAA,EAAA,EAAA,CAK1B,EAAS;CAAE,SAAA,CAAS;CAAM,MAAM;CAAA,CAAA,CAAA,EAAS,EAAA,WAAA,eAAA,KAAA,EAAA,IAAA,EAAA,CA/D1C,EAAc,mBAAA,CAAA,EAAmB,EAAA"}
1
+ {"version":3,"file":"divider-CbEWg3G_.js","names":[],"sources":["../src/divider/divider.ts"],"sourcesContent":["// divider.ts\nimport { $LitElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\n/**\n * Thin horizontal (or vertical) separator rule between sections of content.\n *\n * @element schmancy-divider\n * @summary Semantic separator between groups — list items, menu sections, content blocks. Uses outline theme token.\n * @example\n * <schmancy-list-item>First</schmancy-list-item>\n * <schmancy-divider></schmancy-divider>\n * <schmancy-list-item>Second</schmancy-list-item>\n * @platform hr - Styled horizontal rule. Degrades to a native `<hr>` if the tag never registers.\n */\n@customElement('schmancy-divider')\nexport default class SchmancyDivider extends $LitElement(css`\n\t:host {\n\t\tdisplay: block;\n\t}\n\n\t@keyframes grow-horizontal {\n\t\tfrom {\n\t\t\ttransform: scaleX(0);\n\t\t}\n\t\tto {\n\t\t\ttransform: scaleX(1);\n\t\t}\n\t}\n\n\t@keyframes grow-vertical {\n\t\tfrom {\n\t\t\ttransform: scaleY(0);\n\t\t}\n\t\tto {\n\t\t\ttransform: scaleY(1);\n\t\t}\n\t}\n\n\t/* Horizontal divider grow animations */\n\t.grow-start:not(.h-full) {\n\t\tanimation: grow-horizontal 400ms ease-out;\n\t\ttransform-origin: left;\n\t}\n\n\t.grow-end:not(.h-full) {\n\t\tanimation: grow-horizontal 400ms ease-out;\n\t\ttransform-origin: right;\n\t}\n\n\t.grow-both:not(.h-full) {\n\t\tanimation: grow-horizontal 400ms ease-out;\n\t\ttransform-origin: center;\n\t}\n\n\t/* Vertical divider grow animations */\n\t.grow-start.h-full {\n\t\tanimation: grow-vertical 400ms ease-out;\n\t\ttransform-origin: top;\n\t}\n\n\t.grow-end.h-full {\n\t\tanimation: grow-vertical 400ms ease-out;\n\t\ttransform-origin: bottom;\n\t}\n\n\t.grow-both.h-full {\n\t\tanimation: grow-vertical 400ms ease-out;\n\t\ttransform-origin: center;\n\t}\n`) {\n\t@property({ type: String }) outline: 'default' | 'variant' = 'variant'\n\t@property({ type: Boolean }) vertical = false\n\t@property({ type: String }) grow: 'start' | 'end' | 'both' = 'start'\n\n\t/**\n\t * @deprecated Use `vertical` property instead. Will be removed in next major version.\n\t */\n\t@property({ reflect: true, type: String })\n\tset orientation(value: 'horizontal' | 'vertical') {\n\t\tthis.vertical = value === 'vertical'\n\t}\n\tget orientation(): 'horizontal' | 'vertical' {\n\t\treturn this.vertical ? 'vertical' : 'horizontal'\n\t}\n\n\tprotected render() {\n\t\treturn html`<div\n\t\t\tclass=${this.classMap({\n\t\t\t\t// Dimensions\n\t\t\t\t'w-full h-px': !this.vertical,\n\t\t\t\t'h-full w-px': this.vertical,\n\t\t\t\t// Border color\n\t\t\t\t'border-outlineVariant': this.outline === 'variant',\n\t\t\t\t'border-outline': this.outline === 'default',\n\t\t\t\t// Border style\n\t\t\t\t'border-t': !this.vertical,\n\t\t\t\t'border-l': this.vertical,\n\t\t\t\t// Grow behavior\n\t\t\t\t[`grow-${this.grow}`]: true,\n\t\t\t})}\n\t\t></div>`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-divider': SchmancyDivider\n\t}\n}\n"],"mappings":";;;;;AAiBe,IAAA,IAAA,cAA8B,EAAY,CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BAuDE,WAAA,KAAA,WAAA,CACrB,GAAA,KAAA,OACqB;;CAK7D,IAAA,YACgB,GAAA;AACf,OAAK,WAAW,MAAU;;CAE3B,IAAA,cAAI;AACH,SAAO,KAAK,WAAW,aAAa;;CAGrC,SAAA;AACC,SAAO,CAAI;WACF,KAAK,SAAS;GAErB,eAAA,CAAgB,KAAK;GACrB,eAAe,KAAK;GAEpB,yBAAyB,KAAK,YAAY;GAC1C,kBAAkB,KAAK,YAAY;GAEnC,YAAA,CAAa,KAAK;GAClB,YAAY,KAAK;IAEhB,QAAQ,KAAK,SAAA,CAAS;GAAA,CAAA,CAAA;;;;GA5BzB,EAAS,EAAE,MAAM,QAAA,CAAA,CAAA,EAAS,EAAA,WAAA,WAAA,KAAA,EAAA,EAAA,EAAA,CAC1B,EAAS,EAAE,MAAM,SAAA,CAAA,CAAA,EAAU,EAAA,WAAA,YAAA,KAAA,EAAA,EAAA,EAAA,CAC3B,EAAS,EAAE,MAAM,QAAA,CAAA,CAAA,EAAS,EAAA,WAAA,QAAA,KAAA,EAAA,EAAA,EAAA,CAK1B,EAAS;CAAE,SAAA,CAAS;CAAM,MAAM;CAAA,CAAA,CAAA,EAAS,EAAA,WAAA,eAAA,KAAA,EAAA,IAAA,EAAA,CA/D1C,EAAc,mBAAA,CAAA,EAAmB,EAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"divider-JyyFw_3J.cjs","names":[],"sources":["../src/divider/divider.ts"],"sourcesContent":["// divider.ts\nimport { $LitElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\n@customElement('schmancy-divider')\nexport default class SchmancyDivider extends $LitElement(css`\n\t:host {\n\t\tdisplay: block;\n\t}\n\n\t@keyframes grow-horizontal {\n\t\tfrom {\n\t\t\ttransform: scaleX(0);\n\t\t}\n\t\tto {\n\t\t\ttransform: scaleX(1);\n\t\t}\n\t}\n\n\t@keyframes grow-vertical {\n\t\tfrom {\n\t\t\ttransform: scaleY(0);\n\t\t}\n\t\tto {\n\t\t\ttransform: scaleY(1);\n\t\t}\n\t}\n\n\t/* Horizontal divider grow animations */\n\t.grow-start:not(.h-full) {\n\t\tanimation: grow-horizontal 400ms ease-out;\n\t\ttransform-origin: left;\n\t}\n\n\t.grow-end:not(.h-full) {\n\t\tanimation: grow-horizontal 400ms ease-out;\n\t\ttransform-origin: right;\n\t}\n\n\t.grow-both:not(.h-full) {\n\t\tanimation: grow-horizontal 400ms ease-out;\n\t\ttransform-origin: center;\n\t}\n\n\t/* Vertical divider grow animations */\n\t.grow-start.h-full {\n\t\tanimation: grow-vertical 400ms ease-out;\n\t\ttransform-origin: top;\n\t}\n\n\t.grow-end.h-full {\n\t\tanimation: grow-vertical 400ms ease-out;\n\t\ttransform-origin: bottom;\n\t}\n\n\t.grow-both.h-full {\n\t\tanimation: grow-vertical 400ms ease-out;\n\t\ttransform-origin: center;\n\t}\n`) {\n\t@property({ type: String }) outline: 'default' | 'variant' = 'variant'\n\t@property({ type: Boolean }) vertical = false\n\t@property({ type: String }) grow: 'start' | 'end' | 'both' = 'start'\n\n\t/**\n\t * @deprecated Use `vertical` property instead. Will be removed in next major version.\n\t */\n\t@property({ reflect: true, type: String })\n\tset orientation(value: 'horizontal' | 'vertical') {\n\t\tthis.vertical = value === 'vertical'\n\t}\n\tget orientation(): 'horizontal' | 'vertical' {\n\t\treturn this.vertical ? 'vertical' : 'horizontal'\n\t}\n\n\tprotected render() {\n\t\treturn html`<div\n\t\t\tclass=${this.classMap({\n\t\t\t\t// Dimensions\n\t\t\t\t'w-full h-px': !this.vertical,\n\t\t\t\t'h-full w-px': this.vertical,\n\t\t\t\t// Border color\n\t\t\t\t'border-outlineVariant': this.outline === 'variant',\n\t\t\t\t'border-outline': this.outline === 'default',\n\t\t\t\t// Border style\n\t\t\t\t'border-t': !this.vertical,\n\t\t\t\t'border-l': this.vertical,\n\t\t\t\t// Grow behavior\n\t\t\t\t[`grow-${this.grow}`]: true,\n\t\t\t})}\n\t\t></div>`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-divider': SchmancyDivider\n\t}\n}\n"],"mappings":"oMAMe,IAAA,EAAA,cAA8B,EAAA,EAAY,EAAA,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8CAuDE,UAAA,KAAA,SAAA,CACrB,EAAA,KAAA,KACqB,QAK7D,IAAA,YACgB,EAAA,CACf,KAAK,SAAW,IAAU,WAE3B,IAAA,aAAI,CACH,OAAO,KAAK,SAAW,WAAa,aAGrC,QAAA,CACC,MAAO,GAAA,IAAI;WACF,KAAK,SAAS,CAErB,cAAA,CAAgB,KAAK,SACrB,cAAe,KAAK,SAEpB,wBAAyB,KAAK,UAAY,UAC1C,iBAAkB,KAAK,UAAY,UAEnC,WAAA,CAAa,KAAK,SAClB,WAAY,KAAK,UAEhB,QAAQ,KAAK,QAAA,CAAS,EAAA,CAAA,CAAA;iCA5BhB,CAAE,KAAM,OAAA,CAAA,CAAA,CAAS,EAAA,UAAA,UAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UACjB,CAAE,KAAM,QAAA,CAAA,CAAA,CAAU,EAAA,UAAA,WAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAClB,CAAE,KAAM,OAAA,CAAA,CAAA,CAAS,EAAA,UAAA,OAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAKjB,CAAE,QAAA,CAAS,EAAM,KAAM,OAAA,CAAA,CAAA,CAAS,EAAA,UAAA,cAAA,KAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,eA/D5B,mBAAA,CAAA,CAAmB,EAAA"}
1
+ {"version":3,"file":"divider-JyyFw_3J.cjs","names":[],"sources":["../src/divider/divider.ts"],"sourcesContent":["// divider.ts\nimport { $LitElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\n/**\n * Thin horizontal (or vertical) separator rule between sections of content.\n *\n * @element schmancy-divider\n * @summary Semantic separator between groups — list items, menu sections, content blocks. Uses outline theme token.\n * @example\n * <schmancy-list-item>First</schmancy-list-item>\n * <schmancy-divider></schmancy-divider>\n * <schmancy-list-item>Second</schmancy-list-item>\n * @platform hr - Styled horizontal rule. Degrades to a native `<hr>` if the tag never registers.\n */\n@customElement('schmancy-divider')\nexport default class SchmancyDivider extends $LitElement(css`\n\t:host {\n\t\tdisplay: block;\n\t}\n\n\t@keyframes grow-horizontal {\n\t\tfrom {\n\t\t\ttransform: scaleX(0);\n\t\t}\n\t\tto {\n\t\t\ttransform: scaleX(1);\n\t\t}\n\t}\n\n\t@keyframes grow-vertical {\n\t\tfrom {\n\t\t\ttransform: scaleY(0);\n\t\t}\n\t\tto {\n\t\t\ttransform: scaleY(1);\n\t\t}\n\t}\n\n\t/* Horizontal divider grow animations */\n\t.grow-start:not(.h-full) {\n\t\tanimation: grow-horizontal 400ms ease-out;\n\t\ttransform-origin: left;\n\t}\n\n\t.grow-end:not(.h-full) {\n\t\tanimation: grow-horizontal 400ms ease-out;\n\t\ttransform-origin: right;\n\t}\n\n\t.grow-both:not(.h-full) {\n\t\tanimation: grow-horizontal 400ms ease-out;\n\t\ttransform-origin: center;\n\t}\n\n\t/* Vertical divider grow animations */\n\t.grow-start.h-full {\n\t\tanimation: grow-vertical 400ms ease-out;\n\t\ttransform-origin: top;\n\t}\n\n\t.grow-end.h-full {\n\t\tanimation: grow-vertical 400ms ease-out;\n\t\ttransform-origin: bottom;\n\t}\n\n\t.grow-both.h-full {\n\t\tanimation: grow-vertical 400ms ease-out;\n\t\ttransform-origin: center;\n\t}\n`) {\n\t@property({ type: String }) outline: 'default' | 'variant' = 'variant'\n\t@property({ type: Boolean }) vertical = false\n\t@property({ type: String }) grow: 'start' | 'end' | 'both' = 'start'\n\n\t/**\n\t * @deprecated Use `vertical` property instead. Will be removed in next major version.\n\t */\n\t@property({ reflect: true, type: String })\n\tset orientation(value: 'horizontal' | 'vertical') {\n\t\tthis.vertical = value === 'vertical'\n\t}\n\tget orientation(): 'horizontal' | 'vertical' {\n\t\treturn this.vertical ? 'vertical' : 'horizontal'\n\t}\n\n\tprotected render() {\n\t\treturn html`<div\n\t\t\tclass=${this.classMap({\n\t\t\t\t// Dimensions\n\t\t\t\t'w-full h-px': !this.vertical,\n\t\t\t\t'h-full w-px': this.vertical,\n\t\t\t\t// Border color\n\t\t\t\t'border-outlineVariant': this.outline === 'variant',\n\t\t\t\t'border-outline': this.outline === 'default',\n\t\t\t\t// Border style\n\t\t\t\t'border-t': !this.vertical,\n\t\t\t\t'border-l': this.vertical,\n\t\t\t\t// Grow behavior\n\t\t\t\t[`grow-${this.grow}`]: true,\n\t\t\t})}\n\t\t></div>`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-divider': SchmancyDivider\n\t}\n}\n"],"mappings":"oMAiBe,IAAA,EAAA,cAA8B,EAAA,EAAY,EAAA,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8CAuDE,UAAA,KAAA,SAAA,CACrB,EAAA,KAAA,KACqB,QAK7D,IAAA,YACgB,EAAA,CACf,KAAK,SAAW,IAAU,WAE3B,IAAA,aAAI,CACH,OAAO,KAAK,SAAW,WAAa,aAGrC,QAAA,CACC,MAAO,GAAA,IAAI;WACF,KAAK,SAAS,CAErB,cAAA,CAAgB,KAAK,SACrB,cAAe,KAAK,SAEpB,wBAAyB,KAAK,UAAY,UAC1C,iBAAkB,KAAK,UAAY,UAEnC,WAAA,CAAa,KAAK,SAClB,WAAY,KAAK,UAEhB,QAAQ,KAAK,QAAA,CAAS,EAAA,CAAA,CAAA;iCA5BhB,CAAE,KAAM,OAAA,CAAA,CAAA,CAAS,EAAA,UAAA,UAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UACjB,CAAE,KAAM,QAAA,CAAA,CAAA,CAAU,EAAA,UAAA,WAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAClB,CAAE,KAAM,OAAA,CAAA,CAAA,CAAS,EAAA,UAAA,OAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAKjB,CAAE,QAAA,CAAS,EAAM,KAAM,OAAA,CAAA,CAAA,CAAS,EAAA,UAAA,cAAA,KAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,eA/D5B,mBAAA,CAAA,CAAmB,EAAA"}
@@ -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.16` in `handover/**/*.md` against `package.json`'s `version` field on every build. `dist/handover/**/*.md` gets the rendered version; the source stays templated.
206
+ **Fix.** A build step that substitutes `0.9.17` 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.16
11
- https://esm.sh/@mhmo91/schmancy/agent/manifest@0.9.16
10
+ https://esm.sh/@mhmo91/schmancy/agent@0.9.17
11
+ https://esm.sh/@mhmo91/schmancy/agent/manifest@0.9.17
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.16';
23
+ import { $dialog, theme } from 'https://esm.sh/@mhmo91/schmancy/agent@0.9.17';
24
24
  </script>
25
25
  <schmancy-theme root scheme="dark">
26
26
  <schmancy-surface type="solid" fill="all">
package/dist/page.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"page.cjs","names":[],"sources":["../src/page/page.ts"],"sourcesContent":["import { $LitElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport '../layout/scroll/scroll'\nimport { Subject, fromEvent, merge, EMPTY, timer, combineLatest } from 'rxjs'\nimport { debounceTime, switchMap, takeUntil, distinctUntilChanged, map, tap, startWith } from 'rxjs/operators'\nimport { theme } from '../theme/theme.service'\nimport { fromResizeObserver } from '../directives/layout'\n\n/**\n * Native mobile-like page container.\n * Prevents double-tap zoom, pull-to-refresh, rubber-banding.\n * Automatically fills remaining viewport height.\n *\n * @element schmancy-page\n *\n * @example\n * html`\n * <schmancy-page rows=\"1fr_2fr_auto\">\n * <header>App Bar</header>\n * <main>Scrollable content</main>\n * <footer>Navigation</footer>\n * </schmancy-page>\n * `\n */\n@customElement('schmancy-page')\nexport class SchmancyPage extends $LitElement(css`\n\t:host {\n\t\tdisplay: block;\n\t\tbox-sizing: border-box;\n\t\ttouch-action: pan-x pan-y;\n\t\toverscroll-behavior: none;\n\t\t-webkit-tap-highlight-color: transparent;\n\t}\n`) {\n\t/** Custom grid-template-rows using underscores (e.g. \"1fr_2fr_auto\") */\n\t@property({ type: String })\n\trows = 'auto_1fr_auto'\n\n\t@property({ type: Boolean, attribute: 'show-scrollbar' })\n\tshowScrollbar = false\n\n\t@property({ type: Boolean, attribute: 'no-select' })\n\tnoSelect = false\n\n\tprivate heightDisconnecting$ = new Subject<void>()\n\n\tprivate calculateHeight(): number {\n\t\tconst viewportHeight = window.visualViewport?.height ?? window.innerHeight\n\t\tconst topOffset = this.getBoundingClientRect().top\n\t\treturn Math.max(0, viewportHeight - topOffset)\n\t}\n\n\tprivate applyHeight(height: number, bottomPadding: number) {\n\t\tthis.style.height = `${height}px`\n\t\tthis.style.paddingBottom = `${bottomPadding}px`\n\t}\n\n\tprivate setupHeightStream() {\n\t\t// Shared resize stream\n\t\tconst windowResize$ = fromEvent(window, 'resize', { passive: true })\n\t\tconst viewportEvents$ = window.visualViewport\n\t\t\t? merge(\n\t\t\t\t\tfromEvent(window.visualViewport, 'resize', { passive: true }),\n\t\t\t\t\tfromEvent(window.visualViewport, 'scroll', { passive: true })\n\t\t\t\t)\n\t\t\t: windowResize$\n\t\tconst orientation$ = fromEvent(window, 'orientationchange')\n\t\tconst focusOut$ = fromEvent(document, 'focusout', { passive: true }).pipe(\n\t\t\tswitchMap(() => timer(100))\n\t\t)\n\n\t\tconst globalEvents$ = merge(windowResize$, viewportEvents$, orientation$, focusOut$).pipe(\n\t\t\tdebounceTime(16)\n\t\t)\n\n\t\t// Parent resize detects layout shifts\n\t\tconst parentResize$ = this.parentElement\n\t\t\t? fromResizeObserver(this.parentElement)\n\t\t\t: EMPTY\n\n\t\t// Combine all sources, calculate height and padding, dedupe, apply\n\t\tcombineLatest([\n\t\t\tmerge(parentResize$, globalEvents$).pipe(startWith(null)),\n\t\t\ttheme.bottomOffset$,\n\t\t\ttheme.fullscreen$\n\t\t]).pipe(\n\t\t\tmap(([, bottomOffset, isFullscreen]) => ({\n\t\t\t\theight: this.calculateHeight(),\n\t\t\t\tpadding: isFullscreen ? 0 : bottomOffset\n\t\t\t})),\n\t\t\tdistinctUntilChanged((a, b) => a.height === b.height && a.padding === b.padding),\n\t\t\ttap(({ height, padding }) => this.applyHeight(height, padding)),\n\t\t\ttakeUntil(this.heightDisconnecting$)\n\t\t).subscribe()\n\t}\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback()\n\t\t// Auto-assign semantic elements to slots\n\t\tthis.querySelectorAll(':scope > header').forEach(el => el.setAttribute('slot', 'header'))\n\t\tthis.querySelectorAll(':scope > footer').forEach(el => el.setAttribute('slot', 'footer'))\n\t\t// Setup fullHeight on host\n\t\tthis.setupHeightStream()\n\t}\n\n\tdisconnectedCallback() {\n\t\tsuper.disconnectedCallback()\n\t\tthis.heightDisconnecting$.next()\n\t}\n\n\tprotected render() {\n\t\treturn html`\n\t\t\t<section\n\t\t\t\tclass=${this.classMap({\n\t\t\t\t\t'grid overflow-hidden h-full': true,\n\t\t\t\t\t'select-none': this.noSelect,\n\t\t\t\t})}\n\t\t\t\tstyle=\"grid-template-rows: ${this.rows.replace(/_/g, ' ')}\"\n\t\t\t>\n\t\t\t\t<slot name=\"header\"></slot>\n\t\t\t\t<schmancy-scroll ?hide=${!this.showScrollbar}><slot></slot></schmancy-scroll>\n\t\t\t\t<schmancy-scroll ?hide=${!this.showScrollbar}>\n\t\t\t\t\t<slot name=\"footer\"></slot>\n\t\t\t\t</schmancy-scroll>\n\t\t\t</section>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-page': SchmancyPage\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"page.cjs","names":[],"sources":["../src/page/page.ts"],"sourcesContent":["import { $LitElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport '../layout/scroll/scroll'\nimport { Subject, fromEvent, merge, EMPTY, timer, combineLatest } from 'rxjs'\nimport { debounceTime, switchMap, takeUntil, distinctUntilChanged, map, tap, startWith } from 'rxjs/operators'\nimport { theme } from '../theme/theme.service'\nimport { fromResizeObserver } from '../directives/layout'\n\n/**\n * Mobile-first page container fills remaining viewport height, suppresses double-tap zoom / pull-to-refresh / rubber-banding. Lays children in a CSS grid whose row template is `rows`.\n *\n * @element schmancy-page\n * @summary The root of any app view — wraps header / main / footer children in a full-viewport grid. Use rows=\"auto_1fr_auto\" to make the middle child scroll while header/footer stay pinned.\n * @example\n * <schmancy-page rows=\"auto_1fr_auto\">\n * <schmancy-nav-drawer-appbar>Title</schmancy-nav-drawer-appbar>\n * <main>Scrollable content</main>\n * <schmancy-navigation-bar></schmancy-navigation-bar>\n * </schmancy-page>\n * @platform div - Full-height CSS-grid container. Degrades to a plain div if the tag never registers — children still flow vertically but without the height fill and gesture suppression.\n */\n@customElement('schmancy-page')\nexport class SchmancyPage extends $LitElement(css`\n\t:host {\n\t\tdisplay: block;\n\t\tbox-sizing: border-box;\n\t\ttouch-action: pan-x pan-y;\n\t\toverscroll-behavior: none;\n\t\t-webkit-tap-highlight-color: transparent;\n\t}\n`) {\n\t/** Custom grid-template-rows using underscores (e.g. \"1fr_2fr_auto\") */\n\t@property({ type: String })\n\trows = 'auto_1fr_auto'\n\n\t@property({ type: Boolean, attribute: 'show-scrollbar' })\n\tshowScrollbar = false\n\n\t@property({ type: Boolean, attribute: 'no-select' })\n\tnoSelect = false\n\n\tprivate heightDisconnecting$ = new Subject<void>()\n\n\tprivate calculateHeight(): number {\n\t\tconst viewportHeight = window.visualViewport?.height ?? window.innerHeight\n\t\tconst topOffset = this.getBoundingClientRect().top\n\t\treturn Math.max(0, viewportHeight - topOffset)\n\t}\n\n\tprivate applyHeight(height: number, bottomPadding: number) {\n\t\tthis.style.height = `${height}px`\n\t\tthis.style.paddingBottom = `${bottomPadding}px`\n\t}\n\n\tprivate setupHeightStream() {\n\t\t// Shared resize stream\n\t\tconst windowResize$ = fromEvent(window, 'resize', { passive: true })\n\t\tconst viewportEvents$ = window.visualViewport\n\t\t\t? merge(\n\t\t\t\t\tfromEvent(window.visualViewport, 'resize', { passive: true }),\n\t\t\t\t\tfromEvent(window.visualViewport, 'scroll', { passive: true })\n\t\t\t\t)\n\t\t\t: windowResize$\n\t\tconst orientation$ = fromEvent(window, 'orientationchange')\n\t\tconst focusOut$ = fromEvent(document, 'focusout', { passive: true }).pipe(\n\t\t\tswitchMap(() => timer(100))\n\t\t)\n\n\t\tconst globalEvents$ = merge(windowResize$, viewportEvents$, orientation$, focusOut$).pipe(\n\t\t\tdebounceTime(16)\n\t\t)\n\n\t\t// Parent resize detects layout shifts\n\t\tconst parentResize$ = this.parentElement\n\t\t\t? fromResizeObserver(this.parentElement)\n\t\t\t: EMPTY\n\n\t\t// Combine all sources, calculate height and padding, dedupe, apply\n\t\tcombineLatest([\n\t\t\tmerge(parentResize$, globalEvents$).pipe(startWith(null)),\n\t\t\ttheme.bottomOffset$,\n\t\t\ttheme.fullscreen$\n\t\t]).pipe(\n\t\t\tmap(([, bottomOffset, isFullscreen]) => ({\n\t\t\t\theight: this.calculateHeight(),\n\t\t\t\tpadding: isFullscreen ? 0 : bottomOffset\n\t\t\t})),\n\t\t\tdistinctUntilChanged((a, b) => a.height === b.height && a.padding === b.padding),\n\t\t\ttap(({ height, padding }) => this.applyHeight(height, padding)),\n\t\t\ttakeUntil(this.heightDisconnecting$)\n\t\t).subscribe()\n\t}\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback()\n\t\t// Auto-assign semantic elements to slots\n\t\tthis.querySelectorAll(':scope > header').forEach(el => el.setAttribute('slot', 'header'))\n\t\tthis.querySelectorAll(':scope > footer').forEach(el => el.setAttribute('slot', 'footer'))\n\t\t// Setup fullHeight on host\n\t\tthis.setupHeightStream()\n\t}\n\n\tdisconnectedCallback() {\n\t\tsuper.disconnectedCallback()\n\t\tthis.heightDisconnecting$.next()\n\t}\n\n\tprotected render() {\n\t\treturn html`\n\t\t\t<section\n\t\t\t\tclass=${this.classMap({\n\t\t\t\t\t'grid overflow-hidden h-full': true,\n\t\t\t\t\t'select-none': this.noSelect,\n\t\t\t\t})}\n\t\t\t\tstyle=\"grid-template-rows: ${this.rows.replace(/_/g, ' ')}\"\n\t\t\t>\n\t\t\t\t<slot name=\"header\"></slot>\n\t\t\t\t<schmancy-scroll ?hide=${!this.showScrollbar}><slot></slot></schmancy-scroll>\n\t\t\t\t<schmancy-scroll ?hide=${!this.showScrollbar}>\n\t\t\t\t\t<slot name=\"footer\"></slot>\n\t\t\t\t</schmancy-scroll>\n\t\t\t</section>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-page': SchmancyPage\n\t}\n}\n"],"mappings":"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"}
package/dist/page.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"page.js","names":[],"sources":["../src/page/page.ts"],"sourcesContent":["import { $LitElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport '../layout/scroll/scroll'\nimport { Subject, fromEvent, merge, EMPTY, timer, combineLatest } from 'rxjs'\nimport { debounceTime, switchMap, takeUntil, distinctUntilChanged, map, tap, startWith } from 'rxjs/operators'\nimport { theme } from '../theme/theme.service'\nimport { fromResizeObserver } from '../directives/layout'\n\n/**\n * Native mobile-like page container.\n * Prevents double-tap zoom, pull-to-refresh, rubber-banding.\n * Automatically fills remaining viewport height.\n *\n * @element schmancy-page\n *\n * @example\n * html`\n * <schmancy-page rows=\"1fr_2fr_auto\">\n * <header>App Bar</header>\n * <main>Scrollable content</main>\n * <footer>Navigation</footer>\n * </schmancy-page>\n * `\n */\n@customElement('schmancy-page')\nexport class SchmancyPage extends $LitElement(css`\n\t:host {\n\t\tdisplay: block;\n\t\tbox-sizing: border-box;\n\t\ttouch-action: pan-x pan-y;\n\t\toverscroll-behavior: none;\n\t\t-webkit-tap-highlight-color: transparent;\n\t}\n`) {\n\t/** Custom grid-template-rows using underscores (e.g. \"1fr_2fr_auto\") */\n\t@property({ type: String })\n\trows = 'auto_1fr_auto'\n\n\t@property({ type: Boolean, attribute: 'show-scrollbar' })\n\tshowScrollbar = false\n\n\t@property({ type: Boolean, attribute: 'no-select' })\n\tnoSelect = false\n\n\tprivate heightDisconnecting$ = new Subject<void>()\n\n\tprivate calculateHeight(): number {\n\t\tconst viewportHeight = window.visualViewport?.height ?? window.innerHeight\n\t\tconst topOffset = this.getBoundingClientRect().top\n\t\treturn Math.max(0, viewportHeight - topOffset)\n\t}\n\n\tprivate applyHeight(height: number, bottomPadding: number) {\n\t\tthis.style.height = `${height}px`\n\t\tthis.style.paddingBottom = `${bottomPadding}px`\n\t}\n\n\tprivate setupHeightStream() {\n\t\t// Shared resize stream\n\t\tconst windowResize$ = fromEvent(window, 'resize', { passive: true })\n\t\tconst viewportEvents$ = window.visualViewport\n\t\t\t? merge(\n\t\t\t\t\tfromEvent(window.visualViewport, 'resize', { passive: true }),\n\t\t\t\t\tfromEvent(window.visualViewport, 'scroll', { passive: true })\n\t\t\t\t)\n\t\t\t: windowResize$\n\t\tconst orientation$ = fromEvent(window, 'orientationchange')\n\t\tconst focusOut$ = fromEvent(document, 'focusout', { passive: true }).pipe(\n\t\t\tswitchMap(() => timer(100))\n\t\t)\n\n\t\tconst globalEvents$ = merge(windowResize$, viewportEvents$, orientation$, focusOut$).pipe(\n\t\t\tdebounceTime(16)\n\t\t)\n\n\t\t// Parent resize detects layout shifts\n\t\tconst parentResize$ = this.parentElement\n\t\t\t? fromResizeObserver(this.parentElement)\n\t\t\t: EMPTY\n\n\t\t// Combine all sources, calculate height and padding, dedupe, apply\n\t\tcombineLatest([\n\t\t\tmerge(parentResize$, globalEvents$).pipe(startWith(null)),\n\t\t\ttheme.bottomOffset$,\n\t\t\ttheme.fullscreen$\n\t\t]).pipe(\n\t\t\tmap(([, bottomOffset, isFullscreen]) => ({\n\t\t\t\theight: this.calculateHeight(),\n\t\t\t\tpadding: isFullscreen ? 0 : bottomOffset\n\t\t\t})),\n\t\t\tdistinctUntilChanged((a, b) => a.height === b.height && a.padding === b.padding),\n\t\t\ttap(({ height, padding }) => this.applyHeight(height, padding)),\n\t\t\ttakeUntil(this.heightDisconnecting$)\n\t\t).subscribe()\n\t}\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback()\n\t\t// Auto-assign semantic elements to slots\n\t\tthis.querySelectorAll(':scope > header').forEach(el => el.setAttribute('slot', 'header'))\n\t\tthis.querySelectorAll(':scope > footer').forEach(el => el.setAttribute('slot', 'footer'))\n\t\t// Setup fullHeight on host\n\t\tthis.setupHeightStream()\n\t}\n\n\tdisconnectedCallback() {\n\t\tsuper.disconnectedCallback()\n\t\tthis.heightDisconnecting$.next()\n\t}\n\n\tprotected render() {\n\t\treturn html`\n\t\t\t<section\n\t\t\t\tclass=${this.classMap({\n\t\t\t\t\t'grid overflow-hidden h-full': true,\n\t\t\t\t\t'select-none': this.noSelect,\n\t\t\t\t})}\n\t\t\t\tstyle=\"grid-template-rows: ${this.rows.replace(/_/g, ' ')}\"\n\t\t\t>\n\t\t\t\t<slot name=\"header\"></slot>\n\t\t\t\t<schmancy-scroll ?hide=${!this.showScrollbar}><slot></slot></schmancy-scroll>\n\t\t\t\t<schmancy-scroll ?hide=${!this.showScrollbar}>\n\t\t\t\t\t<slot name=\"footer\"></slot>\n\t\t\t\t</schmancy-scroll>\n\t\t\t</section>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-page': SchmancyPage\n\t}\n}\n"],"mappings":";;;;;;;;;;AA0BO,IAAA,IAAA,cAA2B,EAAY,CAAG;;;;;;;;;;2BAWzC,iBAAA,KAAA,gBAAA,CAGS,GAAA,KAAA,WAAA,CAGL,GAAA,KAAA,uBAEoB,IAAI,GAAA;;CAEnC,kBAAA;EACC,IAAM,IAAiB,OAAO,gBAAgB,UAAU,OAAO,aACzD,IAAY,KAAK,uBAAA,CAAwB;AAC/C,SAAO,KAAK,IAAI,GAAG,IAAiB,EAAA;;CAGrC,YAAoB,GAAgB,GAAA;AACnC,OAAK,MAAM,SAAS,GAAG,EAAA,KACvB,KAAK,MAAM,gBAAgB,GAAG,EAAA;;CAG/B,oBAAA;EAEC,IAAM,IAAgB,EAAU,QAAQ,UAAU,EAAE,SAAA,CAAS,GAAA,CAAA,EAYvD,IAAgB,EAAM,GAXJ,OAAO,iBAC5B,EACA,EAAU,OAAO,gBAAgB,UAAU,EAAE,SAAA,CAAS,GAAA,CAAA,EACtD,EAAU,OAAO,gBAAgB,UAAU,EAAE,SAAA,CAAS,GAAA,CAAA,CAAA,GAEtD,GACkB,EAAU,QAAQ,oBAAA,EACrB,EAAU,UAAU,YAAY,EAAE,SAAA,CAAS,GAAA,CAAA,CAAQ,KACpE,QAAgB,EAAM,IAAA,CAAA,CAAA,CAAA,CAG8D,KACpF,EAAa,GAAA,CAAA;AASd,IAAc;GACb,EANqB,KAAK,gBACxB,EAAmB,KAAK,cAAA,GACxB,GAImB,EAAA,CAAe,KAAK,EAAU,KAAA,CAAA;GACnD,EAAM;GACN,EAAM;GAAA,CAAA,CACJ,KACF,GAAA,GAAQ,GAAc,QAAA;GACrB,QAAQ,KAAK,iBAAA;GACb,SAAS,IAAe,IAAI;GAAA,EAAA,EAE7B,GAAsB,GAAG,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,QAAA,EACxE,GAAA,EAAO,QAAA,GAAQ,SAAA,QAAc,KAAK,YAAY,GAAQ,EAAA,CAAA,EACtD,EAAU,KAAK,qBAAA,CAAA,CACd,WAAA;;CAGH,oBAAA;AACC,QAAM,mBAAA,EAEN,KAAK,iBAAiB,kBAAA,CAAmB,SAAQ,MAAM,EAAG,aAAa,QAAQ,SAAA,CAAA,EAC/E,KAAK,iBAAiB,kBAAA,CAAmB,SAAQ,MAAM,EAAG,aAAa,QAAQ,SAAA,CAAA,EAE/E,KAAK,mBAAA;;CAGN,uBAAA;AACC,QAAM,sBAAA,EACN,KAAK,qBAAqB,MAAA;;CAG3B,SAAA;AACC,SAAO,CAAI;;YAED,KAAK,SAAS;GACrB,+BAAA,CAA+B;GAC/B,eAAe,KAAK;GAAA,CAAA,CAAA;iCAEQ,KAAK,KAAK,QAAQ,MAAM,IAAA,CAAA;;;8BAG3B,KAAK,cAAA;8BACL,KAAK,cAAA;;;;;;;GAtFjC,EAAS,EAAE,MAAM,QAAA,CAAA,CAAA,EAAS,EAAA,WAAA,QAAA,KAAA,EAAA,EAAA,EAAA,CAG1B,EAAS;CAAE,MAAM;CAAS,WAAW;CAAA,CAAA,CAAA,EAAmB,EAAA,WAAA,iBAAA,KAAA,EAAA,EAAA,EAAA,CAGxD,EAAS;CAAE,MAAM;CAAS,WAAW;CAAA,CAAA,CAAA,EAAc,EAAA,WAAA,YAAA,KAAA,EAAA,EAAA,IAAA,EAAA,CAjBpD,EAAc,gBAAA,CAAA,EAAgB,EAAA;AAAA,SAAA,KAAA"}
1
+ {"version":3,"file":"page.js","names":[],"sources":["../src/page/page.ts"],"sourcesContent":["import { $LitElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport '../layout/scroll/scroll'\nimport { Subject, fromEvent, merge, EMPTY, timer, combineLatest } from 'rxjs'\nimport { debounceTime, switchMap, takeUntil, distinctUntilChanged, map, tap, startWith } from 'rxjs/operators'\nimport { theme } from '../theme/theme.service'\nimport { fromResizeObserver } from '../directives/layout'\n\n/**\n * Mobile-first page container fills remaining viewport height, suppresses double-tap zoom / pull-to-refresh / rubber-banding. Lays children in a CSS grid whose row template is `rows`.\n *\n * @element schmancy-page\n * @summary The root of any app view — wraps header / main / footer children in a full-viewport grid. Use rows=\"auto_1fr_auto\" to make the middle child scroll while header/footer stay pinned.\n * @example\n * <schmancy-page rows=\"auto_1fr_auto\">\n * <schmancy-nav-drawer-appbar>Title</schmancy-nav-drawer-appbar>\n * <main>Scrollable content</main>\n * <schmancy-navigation-bar></schmancy-navigation-bar>\n * </schmancy-page>\n * @platform div - Full-height CSS-grid container. Degrades to a plain div if the tag never registers — children still flow vertically but without the height fill and gesture suppression.\n */\n@customElement('schmancy-page')\nexport class SchmancyPage extends $LitElement(css`\n\t:host {\n\t\tdisplay: block;\n\t\tbox-sizing: border-box;\n\t\ttouch-action: pan-x pan-y;\n\t\toverscroll-behavior: none;\n\t\t-webkit-tap-highlight-color: transparent;\n\t}\n`) {\n\t/** Custom grid-template-rows using underscores (e.g. \"1fr_2fr_auto\") */\n\t@property({ type: String })\n\trows = 'auto_1fr_auto'\n\n\t@property({ type: Boolean, attribute: 'show-scrollbar' })\n\tshowScrollbar = false\n\n\t@property({ type: Boolean, attribute: 'no-select' })\n\tnoSelect = false\n\n\tprivate heightDisconnecting$ = new Subject<void>()\n\n\tprivate calculateHeight(): number {\n\t\tconst viewportHeight = window.visualViewport?.height ?? window.innerHeight\n\t\tconst topOffset = this.getBoundingClientRect().top\n\t\treturn Math.max(0, viewportHeight - topOffset)\n\t}\n\n\tprivate applyHeight(height: number, bottomPadding: number) {\n\t\tthis.style.height = `${height}px`\n\t\tthis.style.paddingBottom = `${bottomPadding}px`\n\t}\n\n\tprivate setupHeightStream() {\n\t\t// Shared resize stream\n\t\tconst windowResize$ = fromEvent(window, 'resize', { passive: true })\n\t\tconst viewportEvents$ = window.visualViewport\n\t\t\t? merge(\n\t\t\t\t\tfromEvent(window.visualViewport, 'resize', { passive: true }),\n\t\t\t\t\tfromEvent(window.visualViewport, 'scroll', { passive: true })\n\t\t\t\t)\n\t\t\t: windowResize$\n\t\tconst orientation$ = fromEvent(window, 'orientationchange')\n\t\tconst focusOut$ = fromEvent(document, 'focusout', { passive: true }).pipe(\n\t\t\tswitchMap(() => timer(100))\n\t\t)\n\n\t\tconst globalEvents$ = merge(windowResize$, viewportEvents$, orientation$, focusOut$).pipe(\n\t\t\tdebounceTime(16)\n\t\t)\n\n\t\t// Parent resize detects layout shifts\n\t\tconst parentResize$ = this.parentElement\n\t\t\t? fromResizeObserver(this.parentElement)\n\t\t\t: EMPTY\n\n\t\t// Combine all sources, calculate height and padding, dedupe, apply\n\t\tcombineLatest([\n\t\t\tmerge(parentResize$, globalEvents$).pipe(startWith(null)),\n\t\t\ttheme.bottomOffset$,\n\t\t\ttheme.fullscreen$\n\t\t]).pipe(\n\t\t\tmap(([, bottomOffset, isFullscreen]) => ({\n\t\t\t\theight: this.calculateHeight(),\n\t\t\t\tpadding: isFullscreen ? 0 : bottomOffset\n\t\t\t})),\n\t\t\tdistinctUntilChanged((a, b) => a.height === b.height && a.padding === b.padding),\n\t\t\ttap(({ height, padding }) => this.applyHeight(height, padding)),\n\t\t\ttakeUntil(this.heightDisconnecting$)\n\t\t).subscribe()\n\t}\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback()\n\t\t// Auto-assign semantic elements to slots\n\t\tthis.querySelectorAll(':scope > header').forEach(el => el.setAttribute('slot', 'header'))\n\t\tthis.querySelectorAll(':scope > footer').forEach(el => el.setAttribute('slot', 'footer'))\n\t\t// Setup fullHeight on host\n\t\tthis.setupHeightStream()\n\t}\n\n\tdisconnectedCallback() {\n\t\tsuper.disconnectedCallback()\n\t\tthis.heightDisconnecting$.next()\n\t}\n\n\tprotected render() {\n\t\treturn html`\n\t\t\t<section\n\t\t\t\tclass=${this.classMap({\n\t\t\t\t\t'grid overflow-hidden h-full': true,\n\t\t\t\t\t'select-none': this.noSelect,\n\t\t\t\t})}\n\t\t\t\tstyle=\"grid-template-rows: ${this.rows.replace(/_/g, ' ')}\"\n\t\t\t>\n\t\t\t\t<slot name=\"header\"></slot>\n\t\t\t\t<schmancy-scroll ?hide=${!this.showScrollbar}><slot></slot></schmancy-scroll>\n\t\t\t\t<schmancy-scroll ?hide=${!this.showScrollbar}>\n\t\t\t\t\t<slot name=\"footer\"></slot>\n\t\t\t\t</schmancy-scroll>\n\t\t\t</section>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-page': SchmancyPage\n\t}\n}\n"],"mappings":";;;;;;;;;;AAuBO,IAAA,IAAA,cAA2B,EAAY,CAAG;;;;;;;;;;2BAWzC,iBAAA,KAAA,gBAAA,CAGS,GAAA,KAAA,WAAA,CAGL,GAAA,KAAA,uBAEoB,IAAI,GAAA;;CAEnC,kBAAA;EACC,IAAM,IAAiB,OAAO,gBAAgB,UAAU,OAAO,aACzD,IAAY,KAAK,uBAAA,CAAwB;AAC/C,SAAO,KAAK,IAAI,GAAG,IAAiB,EAAA;;CAGrC,YAAoB,GAAgB,GAAA;AACnC,OAAK,MAAM,SAAS,GAAG,EAAA,KACvB,KAAK,MAAM,gBAAgB,GAAG,EAAA;;CAG/B,oBAAA;EAEC,IAAM,IAAgB,EAAU,QAAQ,UAAU,EAAE,SAAA,CAAS,GAAA,CAAA,EAYvD,IAAgB,EAAM,GAXJ,OAAO,iBAC5B,EACA,EAAU,OAAO,gBAAgB,UAAU,EAAE,SAAA,CAAS,GAAA,CAAA,EACtD,EAAU,OAAO,gBAAgB,UAAU,EAAE,SAAA,CAAS,GAAA,CAAA,CAAA,GAEtD,GACkB,EAAU,QAAQ,oBAAA,EACrB,EAAU,UAAU,YAAY,EAAE,SAAA,CAAS,GAAA,CAAA,CAAQ,KACpE,QAAgB,EAAM,IAAA,CAAA,CAAA,CAAA,CAG8D,KACpF,EAAa,GAAA,CAAA;AASd,IAAc;GACb,EANqB,KAAK,gBACxB,EAAmB,KAAK,cAAA,GACxB,GAImB,EAAA,CAAe,KAAK,EAAU,KAAA,CAAA;GACnD,EAAM;GACN,EAAM;GAAA,CAAA,CACJ,KACF,GAAA,GAAQ,GAAc,QAAA;GACrB,QAAQ,KAAK,iBAAA;GACb,SAAS,IAAe,IAAI;GAAA,EAAA,EAE7B,GAAsB,GAAG,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,QAAA,EACxE,GAAA,EAAO,QAAA,GAAQ,SAAA,QAAc,KAAK,YAAY,GAAQ,EAAA,CAAA,EACtD,EAAU,KAAK,qBAAA,CAAA,CACd,WAAA;;CAGH,oBAAA;AACC,QAAM,mBAAA,EAEN,KAAK,iBAAiB,kBAAA,CAAmB,SAAQ,MAAM,EAAG,aAAa,QAAQ,SAAA,CAAA,EAC/E,KAAK,iBAAiB,kBAAA,CAAmB,SAAQ,MAAM,EAAG,aAAa,QAAQ,SAAA,CAAA,EAE/E,KAAK,mBAAA;;CAGN,uBAAA;AACC,QAAM,sBAAA,EACN,KAAK,qBAAqB,MAAA;;CAG3B,SAAA;AACC,SAAO,CAAI;;YAED,KAAK,SAAS;GACrB,+BAAA,CAA+B;GAC/B,eAAe,KAAK;GAAA,CAAA,CAAA;iCAEQ,KAAK,KAAK,QAAQ,MAAM,IAAA,CAAA;;;8BAG3B,KAAK,cAAA;8BACL,KAAK,cAAA;;;;;;;GAtFjC,EAAS,EAAE,MAAM,QAAA,CAAA,CAAA,EAAS,EAAA,WAAA,QAAA,KAAA,EAAA,EAAA,EAAA,CAG1B,EAAS;CAAE,MAAM;CAAS,WAAW;CAAA,CAAA,CAAA,EAAmB,EAAA,WAAA,iBAAA,KAAA,EAAA,EAAA,EAAA,CAGxD,EAAS;CAAE,MAAM;CAAS,WAAW;CAAA,CAAA,CAAA,EAAc,EAAA,WAAA,YAAA,KAAA,EAAA,EAAA,IAAA,EAAA,CAjBpD,EAAc,gBAAA,CAAA,EAAgB,EAAA;AAAA,SAAA,KAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"scroll-CdmXRXh2.js","names":[],"sources":["../src/layout/scroll/scroll.ts"],"sourcesContent":["import { TailwindElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { debounceTime, filter, fromEvent, takeUntil } from 'rxjs'\n\n/**\n * Custom scroll event interface for the SchmancyScroll component.\n * Contains detailed information about the scroll state.\n */\nexport interface SchmancyScrollEvent\n\textends CustomEvent<{\n\t\t/** Current scroll position from the top */\n\t\tscrollTop: number\n\t\t/** Total scrollable height of the content */\n\t\tscrollHeight: number\n\t\t/** Visible height of the container */\n\t\tclientHeight: number\n\t\t/** Original scroll event */\n\t\te: Event\n\t\t/** Current scroll position from the left (for horizontal scrolling) */\n\t\tscrollLeft?: number\n\t\t/** Total scrollable width of the content (for horizontal scrolling) */\n\t\tscrollWidth?: number\n\t\t/** Visible width of the container (for horizontal scrolling) */\n\t\tclientWidth?: number\n\t}> {}\n\n/**\n * Command event interface for controlling SchmancyScroll components\n */\nexport interface SchmancyScrollCommandEvent\n\textends CustomEvent<{\n\t\t/** Target component name */\n\t\tname: string\n\t\t/** Command action to perform */\n\t\taction: 'scrollTo'\n\t\t/** Scroll position for scrollTo action */\n\t\ttop: number\n\t\t/** Horizontal scroll position for scrollTo action (optional) */\n\t\tleft?: number\n\t}> {}\n\n// Augment the HTMLElementEventMap to include our custom events\ndeclare global {\n\tinterface HTMLElementEventMap {\n\t\tscroll: SchmancyScrollEvent\n\t\t'schmancy-scroll-command': SchmancyScrollCommandEvent\n\t}\n}\n\n/**\n * A custom scrollable container with enhanced features.\n *\n * @fires {SchmancyScrollEvent} scroll - Fired when scrolling occurs (with a configurable debounce)\n * @slot - Default slot for content to be scrolled\n * @csspart scroller - The inner scrollable div element\n *\n * @example\n * ```html\n * <schmancy-scroll hide name=\"main-content\">\n * <div>Scrollable content goes here</div>\n * </schmancy-scroll>\n * ```\n *\n * @example\n * ```html\n * <schmancy-scroll direction=\"horizontal\" hide name=\"image-carousel\">\n * <div class=\"flex\">\n * <img src=\"image1.jpg\" alt=\"Image 1\">\n * <img src=\"image2.jpg\" alt=\"Image 2\">\n * </div>\n * </schmancy-scroll>\n * ```\n *\n * @example Programmatic scroll with Lit ref\n * ```typescript\n * private scrollRef = createRef<HTMLElement>()\n *\n * // In template:\n * html`<schmancy-scroll ${ref(this.scrollRef)}>...</schmancy-scroll>`\n *\n * // Scroll to top (smooth — host has scroll-behavior: smooth):\n * this.scrollRef.value?.scrollTo({ top: 0 })\n * ```\n */\n@customElement('schmancy-scroll')\nexport class SchmancyScroll extends TailwindElement(css`\n\t:host {\n\t\t/* Flexible sizing for different layout contexts */\n\t\twidth: 100%;\n\t\tmin-height: 0; /* Allow flex shrinking */\n\t\tflex: 1; /* Grow in flex containers */\n\t\tbox-sizing: border-box; /* Ensures proper sizing */\n\t\tdisplay: block;\n\t\tposition: relative;\n\t\tscroll-behavior: smooth;\n\t\toverscroll-behavior-x: contain;\n\t\toverscroll-behavior-y: auto;\n\t}\n\t/* Fallback for non-flex contexts */\n\t:host(.explicit-height) {\n\t\theight: 100%;\n\t\tflex: none;\n\t}\n\t:host([hide]) {\n\t\t-ms-overflow-style: none; /* IE and Edge */\n\t\tscrollbar-width: none; /* Firefox */\n\t}\n\t:host([hide])::-webkit-scrollbar {\n\t\tdisplay: none; /* Chrome, Safari, and Opera */\n\t}\n`) {\n\t/**\n\t * Determines whether the scrollbar is hidden.\n\t *\n\t * When `hide` is true, the host element's scrollbars are hidden\n\t * in supported browsers using CSS.\n\t *\n\t * @attr hide\n\t * @example <schmancy-scroll hide></schmancy-scroll>\n\t */\n\t@property({ type: Boolean, reflect: true })\n\tpublic hide = false\n\n\t/**\n\t * Optional name identifier for the component.\n\t * Used for targeting this specific component with global events.\n\t *\n\t * @attr name\n\t * @example <schmancy-scroll name=\"main-content\"></schmancy-scroll>\n\t */\n\t@property({ type: String, reflect: true })\n\tpublic name?: string\n\n\t/**\n\t * Direction of scrolling: vertical, horizontal, or both.\n\t * - vertical: Only allows vertical scrolling\n\t * - horizontal: Only allows horizontal scrolling\n\t * - both: Allows both horizontal and vertical scrolling (default)\n\t *\n\t * @attr direction\n\t * @example <schmancy-scroll direction=\"horizontal\"></schmancy-scroll>\n\t */\n\t@property({ type: String, reflect: true })\n\tpublic direction: 'vertical' | 'horizontal' | 'both' = 'both'\n\n\t/**\n\t * Reference to the scrollable element (the host element itself)\n\t * @public\n\t */\n\tget scroller(): HTMLElement {\n\t\treturn this\n\t}\n\n\t/**\n\t * Debounce time in milliseconds for the scroll event.\n\t * Higher values reduce the frequency of scroll events being dispatched.\n\t *\n\t * @attr debounce\n\t * @example <schmancy-scroll debounce=\"50\"></schmancy-scroll>\n\t */\n\t@property({ type: Number })\n\tpublic debounce = 10\n\n\t/**\n\t * Scrolls the container to the specified position\n\t * @param options - ScrollToOptions or a number representing the top position\n\t * @param top - For backward compatibility, if options is a number, this is treated as \"behavior\"\n\t */\n\tpublic override scrollTo(options?: ScrollToOptions | number, top?: number): void {\n\t\tif (typeof options === 'number') {\n\t\t\tsuper.scrollTo({ top: options, behavior: top ? 'smooth' : 'auto' })\n\t\t} else if (options) {\n\t\t\tsuper.scrollTo(options)\n\t\t} else {\n\t\t\tsuper.scrollTo({ top: 0, left: 0, behavior: 'auto' })\n\t\t}\n\t}\n\n\t/**\n\t * Scrolls the container horizontally to the specified position\n\t * @param left - The horizontal position to scroll to (in pixels)\n\t * @param behavior - The scroll behavior ('auto' or 'smooth')\n\t */\n\tpublic scrollToLeft(left: number, behavior: ScrollBehavior = 'auto'): void {\n\t\tsuper.scrollTo({ left, behavior })\n\t}\n\n\t/**\n\t * Called when the component is connected to the DOM\n\t * Applies scrolling styles directly to the host element\n\t * @protected\n\t */\n\tconnectedCallback(): void {\n\t\tsuper.connectedCallback()\n\t\tthis.updateScrollingStyles()\n\t\tthis.updateLayoutContext()\n\t\t// Set the part attribute on the host element\n\t\tthis.setAttribute('part', 'scroller')\n\t}\n\n\t/**\n\t * Updates the overflow styles based on the direction property\n\t * @private\n\t */\n\tprivate updateScrollingStyles(): void {\n\t\t// Apply overflow styles based on direction\n\t\tif (this.direction === 'horizontal') {\n\t\t\tthis.style.setProperty('overflow-y', 'hidden')\n\t\t\tthis.style.setProperty('overflow-x', 'auto')\n\t\t} else if (this.direction === 'vertical') {\n\t\t\tthis.style.setProperty('overflow-y', 'auto')\n\t\t\tthis.style.setProperty('overflow-x', 'hidden')\n\t\t} else {\n\t\t\t// both\n\t\t\tthis.style.setProperty('overflow-y', 'auto')\n\t\t\tthis.style.setProperty('overflow-x', 'auto')\n\t\t}\n\t}\n\n\t/**\n\t * Updates the layout context based on parent container type\n\t * @private\n\t */\n\tprivate updateLayoutContext(): void {\n\t\t// Use requestAnimationFrame to ensure DOM is fully rendered\n\t\trequestAnimationFrame(() => {\n\t\t\t// Check if parent is a flex container\n\t\t\tconst parent = this.parentElement\n\t\t\tif (parent) {\n\t\t\t\tconst parentStyles = getComputedStyle(parent)\n\t\t\t\tconst isFlexParent = parentStyles.display === 'flex' || parentStyles.display === 'inline-flex'\n\n\t\t\t\t// For debugging - remove in production\n\t\t\t\tconsole.debug('schmancy-scroll parent detection:', {\n\t\t\t\t\tparent: parent.tagName,\n\t\t\t\t\tdisplay: parentStyles.display,\n\t\t\t\t\tisFlexParent,\n\t\t\t\t})\n\n\t\t\t\t// Apply appropriate class based on parent layout\n\t\t\t\tif (isFlexParent) {\n\t\t\t\t\tthis.classList.remove('explicit-height')\n\t\t\t\t} else {\n\t\t\t\t\tthis.classList.add('explicit-height')\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Default to explicit height if no parent\n\t\t\t\tthis.classList.add('explicit-height')\n\t\t\t}\n\t\t})\n\t}\n\n\t/**\n\t * Called when properties change\n\t * @protected\n\t */\n\tprotected updated(changedProperties: Map<string | number | symbol, unknown>): void {\n\t\tsuper.updated(changedProperties)\n\t\t// Update styles if direction changes\n\t\tif (changedProperties.has('direction')) {\n\t\t\tthis.updateScrollingStyles()\n\t\t}\n\t\t// Always update layout context in case parent layout changed\n\t\tthis.updateLayoutContext()\n\t}\n\n\t/**\n\t * Called after the component's first update\n\t * Sets up the scroll event listener with debouncing\n\t * @protected\n\t */\n\tprotected firstUpdated(): void {\n\t\t// Set up scroll event listening with debounce\n\t\tfromEvent(this.scroller, 'scroll', {\n\t\t\tpassive: true,\n\t\t})\n\t\t\t.pipe(\n\t\t\t\tdebounceTime(this.debounce),\n\t\t\t\ttakeUntil(this.disconnecting), // Unsubscribe when the element is destroyed\n\t\t\t)\n\t\t\t.subscribe(e => {\n\t\t\t\t// Always include the original required properties for backward compatibility\n\t\t\t\tconst scrollTop = this.scroller.scrollTop\n\t\t\t\tconst scrollHeight = this.scroller.scrollHeight\n\t\t\t\tconst clientHeight = this.scroller.clientHeight\n\n\t\t\t\t// Include horizontal scroll information as optional properties\n\t\t\t\tconst scrollLeft = this.scroller.scrollLeft\n\t\t\t\tconst scrollWidth = this.scroller.scrollWidth\n\t\t\t\tconst clientWidth = this.scroller.clientWidth\n\n\t\t\t\tthis.dispatchEvent(\n\t\t\t\t\tnew CustomEvent('scroll', {\n\t\t\t\t\t\tdetail: {\n\t\t\t\t\t\t\t// Original required properties first\n\t\t\t\t\t\t\tscrollTop,\n\t\t\t\t\t\t\tscrollHeight,\n\t\t\t\t\t\t\tclientHeight,\n\t\t\t\t\t\t\te,\n\t\t\t\t\t\t\t// New optional properties last\n\t\t\t\t\t\t\tscrollLeft,\n\t\t\t\t\t\t\tscrollWidth,\n\t\t\t\t\t\t\tclientWidth,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbubbles: true,\n\t\t\t\t\t\tcomposed: true,\n\t\t\t\t\t}) as SchmancyScrollEvent,\n\t\t\t\t)\n\t\t\t})\n\n\t\t// Set up global command event listener\n\t\tfromEvent<SchmancyScrollCommandEvent>(window, '@schmancy:scrollTo')\n\t\t\t.pipe(\n\t\t\t\t// Only process events targeting this component by name\n\t\t\t\tfilter(e => this.name !== undefined && e.detail.name === this.name),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe(e => {\n\t\t\t\tif (e.detail.action === 'scrollTo' && typeof e.detail.top === 'number') {\n\t\t\t\t\tconst options: ScrollToOptions = {\n\t\t\t\t\t\tbehavior: 'smooth',\n\t\t\t\t\t\ttop: e.detail.top, // Required for backward compatibility\n\t\t\t\t\t}\n\n\t\t\t\t\t// Add optional left position if provided\n\t\t\t\t\tif (typeof e.detail.left === 'number') {\n\t\t\t\t\t\toptions.left = e.detail.left\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.scrollTo(options)\n\t\t\t\t}\n\t\t\t})\n\t}\n\n\t/**\n\t * Renders the component template\n\t * @returns {TemplateResult} The template to render\n\t * @protected\n\t */\n\tprotected render() {\n\t\t// Only render the slot, all styling is applied to the host\n\t\treturn html`<slot></slot>`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-scroll': SchmancyScroll\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"scroll-CdmXRXh2.js","names":[],"sources":["../src/layout/scroll/scroll.ts"],"sourcesContent":["import { TailwindElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { debounceTime, filter, fromEvent, takeUntil } from 'rxjs'\n\n/**\n * Custom scroll event interface for the SchmancyScroll component.\n * Contains detailed information about the scroll state.\n */\nexport interface SchmancyScrollEvent\n\textends CustomEvent<{\n\t\t/** Current scroll position from the top */\n\t\tscrollTop: number\n\t\t/** Total scrollable height of the content */\n\t\tscrollHeight: number\n\t\t/** Visible height of the container */\n\t\tclientHeight: number\n\t\t/** Original scroll event */\n\t\te: Event\n\t\t/** Current scroll position from the left (for horizontal scrolling) */\n\t\tscrollLeft?: number\n\t\t/** Total scrollable width of the content (for horizontal scrolling) */\n\t\tscrollWidth?: number\n\t\t/** Visible width of the container (for horizontal scrolling) */\n\t\tclientWidth?: number\n\t}> {}\n\n/**\n * Command event interface for controlling SchmancyScroll components\n */\nexport interface SchmancyScrollCommandEvent\n\textends CustomEvent<{\n\t\t/** Target component name */\n\t\tname: string\n\t\t/** Command action to perform */\n\t\taction: 'scrollTo'\n\t\t/** Scroll position for scrollTo action */\n\t\ttop: number\n\t\t/** Horizontal scroll position for scrollTo action (optional) */\n\t\tleft?: number\n\t}> {}\n\n// Augment the HTMLElementEventMap to include our custom events\ndeclare global {\n\tinterface HTMLElementEventMap {\n\t\tscroll: SchmancyScrollEvent\n\t\t'schmancy-scroll-command': SchmancyScrollCommandEvent\n\t}\n}\n\n/**\n * Scrollable container with debounced scroll events, horizontal/vertical direction, optional hidden scrollbar, and programmatic scrollTo via command events or refs.\n *\n * @element schmancy-scroll\n * @summary Use anywhere you'd reach for `overflow: auto` but also need debounced scroll events (for sticky headers, scroll spies, virtualization triggers) or the ability to drive scroll from elsewhere in the app by dispatching a schmancy-scroll-command event.\n * @platform div - Styled scrollable `<div>`. Degrades to a plain scrollable div if the tag never registers — loses the debounced scroll event and the command-bus integration.\n *\n * @fires {SchmancyScrollEvent} scroll - Fired when scrolling occurs (with a configurable debounce)\n * @slot - Default slot for content to be scrolled\n * @csspart scroller - The inner scrollable div element\n *\n * @example\n * ```html\n * <schmancy-scroll hide name=\"main-content\">\n * <div>Scrollable content goes here</div>\n * </schmancy-scroll>\n * ```\n *\n * @example\n * ```html\n * <schmancy-scroll direction=\"horizontal\" hide name=\"image-carousel\">\n * <div class=\"flex\">\n * <img src=\"image1.jpg\" alt=\"Image 1\">\n * <img src=\"image2.jpg\" alt=\"Image 2\">\n * </div>\n * </schmancy-scroll>\n * ```\n *\n * @example Programmatic scroll with Lit ref\n * ```typescript\n * private scrollRef = createRef<HTMLElement>()\n *\n * // In template:\n * html`<schmancy-scroll ${ref(this.scrollRef)}>...</schmancy-scroll>`\n *\n * // Scroll to top (smooth — host has scroll-behavior: smooth):\n * this.scrollRef.value?.scrollTo({ top: 0 })\n * ```\n */\n@customElement('schmancy-scroll')\nexport class SchmancyScroll extends TailwindElement(css`\n\t:host {\n\t\t/* Flexible sizing for different layout contexts */\n\t\twidth: 100%;\n\t\tmin-height: 0; /* Allow flex shrinking */\n\t\tflex: 1; /* Grow in flex containers */\n\t\tbox-sizing: border-box; /* Ensures proper sizing */\n\t\tdisplay: block;\n\t\tposition: relative;\n\t\tscroll-behavior: smooth;\n\t\toverscroll-behavior-x: contain;\n\t\toverscroll-behavior-y: auto;\n\t}\n\t/* Fallback for non-flex contexts */\n\t:host(.explicit-height) {\n\t\theight: 100%;\n\t\tflex: none;\n\t}\n\t:host([hide]) {\n\t\t-ms-overflow-style: none; /* IE and Edge */\n\t\tscrollbar-width: none; /* Firefox */\n\t}\n\t:host([hide])::-webkit-scrollbar {\n\t\tdisplay: none; /* Chrome, Safari, and Opera */\n\t}\n`) {\n\t/**\n\t * Determines whether the scrollbar is hidden.\n\t *\n\t * When `hide` is true, the host element's scrollbars are hidden\n\t * in supported browsers using CSS.\n\t *\n\t * @attr hide\n\t * @example <schmancy-scroll hide></schmancy-scroll>\n\t */\n\t@property({ type: Boolean, reflect: true })\n\tpublic hide = false\n\n\t/**\n\t * Optional name identifier for the component.\n\t * Used for targeting this specific component with global events.\n\t *\n\t * @attr name\n\t * @example <schmancy-scroll name=\"main-content\"></schmancy-scroll>\n\t */\n\t@property({ type: String, reflect: true })\n\tpublic name?: string\n\n\t/**\n\t * Direction of scrolling: vertical, horizontal, or both.\n\t * - vertical: Only allows vertical scrolling\n\t * - horizontal: Only allows horizontal scrolling\n\t * - both: Allows both horizontal and vertical scrolling (default)\n\t *\n\t * @attr direction\n\t * @example <schmancy-scroll direction=\"horizontal\"></schmancy-scroll>\n\t */\n\t@property({ type: String, reflect: true })\n\tpublic direction: 'vertical' | 'horizontal' | 'both' = 'both'\n\n\t/**\n\t * Reference to the scrollable element (the host element itself)\n\t * @public\n\t */\n\tget scroller(): HTMLElement {\n\t\treturn this\n\t}\n\n\t/**\n\t * Debounce time in milliseconds for the scroll event.\n\t * Higher values reduce the frequency of scroll events being dispatched.\n\t *\n\t * @attr debounce\n\t * @example <schmancy-scroll debounce=\"50\"></schmancy-scroll>\n\t */\n\t@property({ type: Number })\n\tpublic debounce = 10\n\n\t/**\n\t * Scrolls the container to the specified position\n\t * @param options - ScrollToOptions or a number representing the top position\n\t * @param top - For backward compatibility, if options is a number, this is treated as \"behavior\"\n\t */\n\tpublic override scrollTo(options?: ScrollToOptions | number, top?: number): void {\n\t\tif (typeof options === 'number') {\n\t\t\tsuper.scrollTo({ top: options, behavior: top ? 'smooth' : 'auto' })\n\t\t} else if (options) {\n\t\t\tsuper.scrollTo(options)\n\t\t} else {\n\t\t\tsuper.scrollTo({ top: 0, left: 0, behavior: 'auto' })\n\t\t}\n\t}\n\n\t/**\n\t * Scrolls the container horizontally to the specified position\n\t * @param left - The horizontal position to scroll to (in pixels)\n\t * @param behavior - The scroll behavior ('auto' or 'smooth')\n\t */\n\tpublic scrollToLeft(left: number, behavior: ScrollBehavior = 'auto'): void {\n\t\tsuper.scrollTo({ left, behavior })\n\t}\n\n\t/**\n\t * Called when the component is connected to the DOM\n\t * Applies scrolling styles directly to the host element\n\t * @protected\n\t */\n\tconnectedCallback(): void {\n\t\tsuper.connectedCallback()\n\t\tthis.updateScrollingStyles()\n\t\tthis.updateLayoutContext()\n\t\t// Set the part attribute on the host element\n\t\tthis.setAttribute('part', 'scroller')\n\t}\n\n\t/**\n\t * Updates the overflow styles based on the direction property\n\t * @private\n\t */\n\tprivate updateScrollingStyles(): void {\n\t\t// Apply overflow styles based on direction\n\t\tif (this.direction === 'horizontal') {\n\t\t\tthis.style.setProperty('overflow-y', 'hidden')\n\t\t\tthis.style.setProperty('overflow-x', 'auto')\n\t\t} else if (this.direction === 'vertical') {\n\t\t\tthis.style.setProperty('overflow-y', 'auto')\n\t\t\tthis.style.setProperty('overflow-x', 'hidden')\n\t\t} else {\n\t\t\t// both\n\t\t\tthis.style.setProperty('overflow-y', 'auto')\n\t\t\tthis.style.setProperty('overflow-x', 'auto')\n\t\t}\n\t}\n\n\t/**\n\t * Updates the layout context based on parent container type\n\t * @private\n\t */\n\tprivate updateLayoutContext(): void {\n\t\t// Use requestAnimationFrame to ensure DOM is fully rendered\n\t\trequestAnimationFrame(() => {\n\t\t\t// Check if parent is a flex container\n\t\t\tconst parent = this.parentElement\n\t\t\tif (parent) {\n\t\t\t\tconst parentStyles = getComputedStyle(parent)\n\t\t\t\tconst isFlexParent = parentStyles.display === 'flex' || parentStyles.display === 'inline-flex'\n\n\t\t\t\t// For debugging - remove in production\n\t\t\t\tconsole.debug('schmancy-scroll parent detection:', {\n\t\t\t\t\tparent: parent.tagName,\n\t\t\t\t\tdisplay: parentStyles.display,\n\t\t\t\t\tisFlexParent,\n\t\t\t\t})\n\n\t\t\t\t// Apply appropriate class based on parent layout\n\t\t\t\tif (isFlexParent) {\n\t\t\t\t\tthis.classList.remove('explicit-height')\n\t\t\t\t} else {\n\t\t\t\t\tthis.classList.add('explicit-height')\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Default to explicit height if no parent\n\t\t\t\tthis.classList.add('explicit-height')\n\t\t\t}\n\t\t})\n\t}\n\n\t/**\n\t * Called when properties change\n\t * @protected\n\t */\n\tprotected updated(changedProperties: Map<string | number | symbol, unknown>): void {\n\t\tsuper.updated(changedProperties)\n\t\t// Update styles if direction changes\n\t\tif (changedProperties.has('direction')) {\n\t\t\tthis.updateScrollingStyles()\n\t\t}\n\t\t// Always update layout context in case parent layout changed\n\t\tthis.updateLayoutContext()\n\t}\n\n\t/**\n\t * Called after the component's first update\n\t * Sets up the scroll event listener with debouncing\n\t * @protected\n\t */\n\tprotected firstUpdated(): void {\n\t\t// Set up scroll event listening with debounce\n\t\tfromEvent(this.scroller, 'scroll', {\n\t\t\tpassive: true,\n\t\t})\n\t\t\t.pipe(\n\t\t\t\tdebounceTime(this.debounce),\n\t\t\t\ttakeUntil(this.disconnecting), // Unsubscribe when the element is destroyed\n\t\t\t)\n\t\t\t.subscribe(e => {\n\t\t\t\t// Always include the original required properties for backward compatibility\n\t\t\t\tconst scrollTop = this.scroller.scrollTop\n\t\t\t\tconst scrollHeight = this.scroller.scrollHeight\n\t\t\t\tconst clientHeight = this.scroller.clientHeight\n\n\t\t\t\t// Include horizontal scroll information as optional properties\n\t\t\t\tconst scrollLeft = this.scroller.scrollLeft\n\t\t\t\tconst scrollWidth = this.scroller.scrollWidth\n\t\t\t\tconst clientWidth = this.scroller.clientWidth\n\n\t\t\t\tthis.dispatchEvent(\n\t\t\t\t\tnew CustomEvent('scroll', {\n\t\t\t\t\t\tdetail: {\n\t\t\t\t\t\t\t// Original required properties first\n\t\t\t\t\t\t\tscrollTop,\n\t\t\t\t\t\t\tscrollHeight,\n\t\t\t\t\t\t\tclientHeight,\n\t\t\t\t\t\t\te,\n\t\t\t\t\t\t\t// New optional properties last\n\t\t\t\t\t\t\tscrollLeft,\n\t\t\t\t\t\t\tscrollWidth,\n\t\t\t\t\t\t\tclientWidth,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbubbles: true,\n\t\t\t\t\t\tcomposed: true,\n\t\t\t\t\t}) as SchmancyScrollEvent,\n\t\t\t\t)\n\t\t\t})\n\n\t\t// Set up global command event listener\n\t\tfromEvent<SchmancyScrollCommandEvent>(window, '@schmancy:scrollTo')\n\t\t\t.pipe(\n\t\t\t\t// Only process events targeting this component by name\n\t\t\t\tfilter(e => this.name !== undefined && e.detail.name === this.name),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe(e => {\n\t\t\t\tif (e.detail.action === 'scrollTo' && typeof e.detail.top === 'number') {\n\t\t\t\t\tconst options: ScrollToOptions = {\n\t\t\t\t\t\tbehavior: 'smooth',\n\t\t\t\t\t\ttop: e.detail.top, // Required for backward compatibility\n\t\t\t\t\t}\n\n\t\t\t\t\t// Add optional left position if provided\n\t\t\t\t\tif (typeof e.detail.left === 'number') {\n\t\t\t\t\t\toptions.left = e.detail.left\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.scrollTo(options)\n\t\t\t\t}\n\t\t\t})\n\t}\n\n\t/**\n\t * Renders the component template\n\t * @returns {TemplateResult} The template to render\n\t * @protected\n\t */\n\tprotected render() {\n\t\t// Only render the slot, all styling is applied to the host\n\t\treturn html`<slot></slot>`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-scroll': SchmancyScroll\n\t}\n}\n"],"mappings":"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"}