@mhmo91/schmancy 0.10.34 → 0.10.35

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.
@@ -1,216 +0,0 @@
1
- import { t as e, u as t } from "./SchmancyElement-CA0Wqt8m.js";
2
- import "./mixins-Bp0wIHg2.js";
3
- import { d as n } from "./animation-DCznELuT.js";
4
- import { t as r } from "./reduced-motion-D-L12p7G.js";
5
- import { n as i } from "./theme.service-hc4N-1Oz.js";
6
- import { o as a } from "./overlay.service-DTE6NwIM.js";
7
- import { filter as o, finalize as s, fromEvent as c, map as l, merge as u, switchMap as d, takeUntil as f, tap as p } from "rxjs";
8
- import { classMap as m } from "lit/directives/class-map.js";
9
- import { styleMap as h } from "lit/directives/style-map.js";
10
- import { customElement as g, property as _, queryAssignedElements as v, state as y } from "lit/decorators.js";
11
- import { css as b, html as x, nothing as S } from "lit";
12
- import { createRef as C, ref as w } from "lit/directives/ref.js";
13
- import { when as T } from "lit/directives/when.js";
14
- var E = "schmancy-boat-", D = class extends e {
15
- constructor(...e) {
16
- super(...e), this.id = "default", this.lowered = !1, this.corner = "bottom-right", this.open = !1, this.isDragging = !1, this._currentCorner = "bottom-right", this._position = {
17
- x: 16,
18
- y: 16
19
- }, this._containerRef = C(), this._headerRef = C(), this.#e = !1, this.#n = [];
20
- }
21
- static {
22
- this.styles = [b`
23
- :host {
24
- display: contents;
25
- }
26
- :host([hidden]) {
27
- display: none !important;
28
- }
29
- `];
30
- }
31
- #e;
32
- #t;
33
- #n;
34
- _applyContainerPosition() {
35
- let e = this._containerRef.value;
36
- if (!e) return;
37
- e.style.removeProperty("left"), e.style.removeProperty("right"), e.style.removeProperty("top"), e.style.removeProperty("bottom");
38
- let { x: t, y: n } = this._position;
39
- this._currentCorner.includes("right") ? e.style.right = `${t}px` : e.style.left = `${t}px`, this._currentCorner.includes("bottom") ? e.style.bottom = `${n + i.bottomOffset}px` : e.style.top = `${n}px`;
40
- }
41
- _loadPosition() {
42
- try {
43
- let e = localStorage.getItem(E + this.id);
44
- if (e) {
45
- let t = JSON.parse(e);
46
- this._position = {
47
- x: t.x,
48
- y: t.y
49
- }, this._currentCorner = t.anchor;
50
- }
51
- } catch {}
52
- }
53
- _savePosition() {
54
- try {
55
- localStorage.setItem(E + this.id, JSON.stringify({
56
- ...this._position,
57
- anchor: this._currentCorner
58
- }));
59
- } catch {}
60
- }
61
- _validateBounds() {
62
- let e = this._containerRef.value;
63
- if (!e) return;
64
- let t = e.getBoundingClientRect();
65
- if (t.width === 0) return;
66
- let n = window.innerWidth, r = window.innerHeight, i = this._currentCorner.includes("right"), a = this._currentCorner.includes("bottom"), o = i ? n - this._position.x - t.width : this._position.x, s = a ? r - this._position.y - t.height : this._position.y, c = Math.max(0, Math.min(o, n - t.width)), l = Math.max(0, Math.min(s, r - t.height));
67
- this._position = {
68
- x: i ? n - c - t.width : c,
69
- y: a ? r - l - t.height : l
70
- }, this._applyContainerPosition();
71
- }
72
- _reorientToNearestCorner() {
73
- let e = this._containerRef.value;
74
- if (!e) return;
75
- let t = e.getBoundingClientRect(), i = t.left + t.width / 2, a = t.top + t.height / 2, o = i > window.innerWidth / 2 ? "right" : "left", s = a > window.innerHeight / 2 ? "bottom" : "top";
76
- if (this._currentCorner = `${s}-${o}`, this._position = {
77
- x: 16,
78
- y: 16
79
- }, this._applyContainerPosition(), r.value) return void this._savePosition();
80
- let c = e.getBoundingClientRect(), l = t.left - c.left, u = t.top - c.top;
81
- e.style.transform = `translate(${l}px, ${u}px)`, this._currentAnimation?.cancel();
82
- let d = e.animate([{ transform: e.style.transform }, { transform: "translate(0,0)" }], {
83
- duration: n.duration,
84
- easing: n.easingFallback,
85
- fill: "forwards"
86
- });
87
- this._currentAnimation = d, d.finished.then(() => {
88
- e.isConnected && (e.style.transform = "");
89
- }), this._savePosition();
90
- }
91
- _setupDrag() {
92
- let e = this._headerRef.value, t = this._containerRef.value;
93
- if (!e || !t) return;
94
- let n = !1;
95
- c(e, "pointerdown").pipe(o((e) => e.button === 0), p((t) => {
96
- t.preventDefault(), t.stopPropagation(), e.setPointerCapture(t.pointerId);
97
- }), l((e) => {
98
- let r = t.getBoundingClientRect();
99
- return n = !1, {
100
- pointerId: e.pointerId,
101
- startX: e.clientX,
102
- startY: e.clientY,
103
- offsetX: e.clientX - r.left,
104
- offsetY: e.clientY - r.top,
105
- rect: r
106
- };
107
- }), d(({ pointerId: e, startX: t, startY: r, offsetX: i, offsetY: a, rect: l }) => {
108
- let d = (t) => t.pointerId === e, m = c(window, "pointermove").pipe(o(d)), h = u(c(window, "pointerup"), c(window, "pointercancel")).pipe(o(d));
109
- return m.pipe(p(({ clientX: e, clientY: o }) => {
110
- let s = e - t, c = o - r;
111
- if (Math.sqrt(s * s + c * c) > 5 && !n && (n = !0, this.isDragging = !0), !n) return;
112
- let u = window.innerWidth, d = window.innerHeight, f = Math.max(0, Math.min(e - i, u - l.width)), p = Math.max(0, Math.min(o - a, d - l.height));
113
- this._position = {
114
- x: this._currentCorner.includes("right") ? u - f - l.width : f,
115
- y: this._currentCorner.includes("bottom") ? d - p - l.height : p
116
- }, this._applyContainerPosition();
117
- }), f(h), s(() => {
118
- n ? (this._reorientToNearestCorner(), this.isDragging = !1, n = !1) : (this.isDragging = !1, n = !1, this.toggle());
119
- }));
120
- }), f(this.disconnecting)).subscribe();
121
- }
122
- _openOverlay() {
123
- if (this.#t) return;
124
- let e = this._containerRef.value, t = document.createElement("div");
125
- t.className = "flex flex-col", this.#n = [...this._slotted], this.#n.forEach((e) => t.appendChild(e)), this.#t = a(t, {
126
- anchor: e ?? void 0,
127
- dismissable: !0,
128
- historyStrategy: "silent"
129
- }).pipe(s(() => this._restoreSlotted()), f(this.disconnecting)).subscribe(), this.dispatchScopedEvent("toggle", "open");
130
- }
131
- _restoreSlotted() {
132
- this.#n.forEach((e) => this.appendChild(e)), this.#n = [], this.#t = void 0, this.open &&= !1, this.dispatchScopedEvent("toggle", "closed");
133
- }
134
- connectedCallback() {
135
- super.connectedCallback(), c(window, "resize").pipe(f(this.disconnecting)).subscribe(() => this._validateBounds()), i.bottomOffset$.pipe(p(() => this._applyContainerPosition()), f(this.disconnecting)).subscribe();
136
- }
137
- firstUpdated() {
138
- this._currentCorner = this.corner, this._loadPosition(), this._containerRef.value && (this._applyContainerPosition(), this._setupDrag(), this.#e = !0, this.open && this._openOverlay());
139
- }
140
- willUpdate(e) {
141
- this.#e && e.has("open") && (this.open && !this.#t ? this._openOverlay() : !this.open && this.#t && this.#t.unsubscribe());
142
- }
143
- disconnectedCallback() {
144
- super.disconnectedCallback(), this._currentAnimation?.cancel(), this.#t?.unsubscribe();
145
- }
146
- toggle() {
147
- this.open = !this.open;
148
- }
149
- render() {
150
- let e = m({
151
- "inline-flex": !0,
152
- "rounded-full": !0,
153
- "overflow-hidden": !0,
154
- "transition-opacity": !0,
155
- "duration-200": !0,
156
- "opacity-85": this.isDragging,
157
- "scale-95": this.isDragging
158
- }), t = h({
159
- position: "fixed",
160
- "pointer-events": "auto"
161
- }), n = m({
162
- "h-14": !0,
163
- "rounded-full": !0,
164
- flex: !0,
165
- "items-center": !0,
166
- "gap-3": !0,
167
- "select-none": !0,
168
- "touch-none": !0,
169
- "cursor-grabbing": this.isDragging,
170
- "cursor-pointer": !this.isDragging,
171
- "px-5": !!this.label,
172
- "w-14": !this.label,
173
- "justify-center": !this.label
174
- });
175
- return x`
176
- <schmancy-surface
177
- ${w(this._containerRef)}
178
- type="glass"
179
- .elevation=${this.lowered ? 1 : 3}
180
- class=${e}
181
- style=${t}
182
- aria-expanded=${this.open}
183
- >
184
- <div
185
- ${w(this._headerRef)}
186
- class=${n}
187
- role="button"
188
- tabindex="0"
189
- aria-label=${this.label ?? "Open panel"}
190
- title="Drag to move · click to open"
191
- >
192
- <slot name="header">
193
- ${T(!!this.icon, () => x`<schmancy-icon>${this.icon}</schmancy-icon>`, () => S)}
194
- </slot>
195
- ${T(!!this.label, () => x`<schmancy-typography type="label" token="lg" class="whitespace-nowrap">
196
- ${this.label}
197
- </schmancy-typography>`, () => S)}
198
- <slot name="summary"></slot>
199
- </div>
200
-
201
- <!-- Default-slot content parks here (hidden) while collapsed;
202
- relocated into the show() overlay on open. -->
203
- <div hidden><slot></slot></div>
204
- </schmancy-surface>
205
- `;
206
- }
207
- };
208
- t([_({ type: String })], D.prototype, "id", void 0), t([_({ type: String })], D.prototype, "icon", void 0), t([_({ type: String })], D.prototype, "label", void 0), t([_({
209
- type: Boolean,
210
- reflect: !0
211
- })], D.prototype, "lowered", void 0), t([_({ type: String })], D.prototype, "corner", void 0), t([_({
212
- type: Boolean,
213
- reflect: !0
214
- })], D.prototype, "open", void 0), t([y()], D.prototype, "isDragging", void 0), t([y()], D.prototype, "_currentCorner", void 0), t([v()], D.prototype, "_slotted", void 0);
215
- var O = D = t([g("schmancy-boat")], D);
216
- export { O as t };
@@ -1 +0,0 @@
1
- {"version":3,"file":"boat-Y5UMiJCV.js","names":["#sub","#captured","#ready"],"sources":["../src/boat/boat.ts"],"sourcesContent":["import { SchmancyElement } from '@mixins/index'\nimport { css, html, nothing, type PropertyValues } from 'lit'\nimport { customElement, property, queryAssignedElements, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { createRef, ref } from 'lit/directives/ref.js'\nimport { styleMap } from 'lit/directives/style-map.js'\nimport { when } from 'lit/directives/when.js'\nimport { filter, finalize, fromEvent, map, merge, type Subscription, switchMap, takeUntil, tap } from 'rxjs'\nimport { SPRING_SMOOTH } from '../utils/animation.js'\nimport { reducedMotion$ } from '../directives/reduced-motion'\nimport { show } from '../overlay/overlay.service'\nimport { theme } from '../theme/theme.service.js'\n\nconst DRAG_THRESHOLD = 5\nconst POSITION_STORAGE_KEY_PREFIX = 'schmancy-boat-'\n\ntype Corner = 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left'\ninterface Position {\n\tx: number\n\ty: number\n}\n\n/**\n * Material-3 extended FAB that delegates its expanded panel to the `show()`\n * overlay service. Collapsed: a draggable, corner-anchored pill (icon + label,\n * circular when no label). Activated: the default-slot content blooms from the\n * FAB as an overlay (backdrop / Esc / back-button / sheet-on-narrow handled by\n * the overlay primitive).\n */\n@customElement('schmancy-boat')\nexport default class SchmancyBoat extends SchmancyElement {\n\tstatic styles = [css`\n\t\t:host {\n\t\t\tdisplay: contents;\n\t\t}\n\t\t:host([hidden]) {\n\t\t\tdisplay: none !important;\n\t\t}\n\t`]\n\n\t@property({ type: String }) id: string = 'default'\n\t@property({ type: String }) icon?: string\n\t@property({ type: String }) label?: string\n\t/** When true, uses a lower elevation shadow on the FAB. */\n\t@property({ type: Boolean, reflect: true }) lowered: boolean = false\n\t/** Corner the FAB is anchored to. */\n\t@property({ type: String }) corner: Corner = 'bottom-right'\n\t/** Open state. Bind `?open=${…}` to drive the overlay; reflected to the attribute. */\n\t@property({ type: Boolean, reflect: true }) open: boolean = false\n\n\t@state() private isDragging = false\n\t@state() private _currentCorner: Corner = 'bottom-right'\n\n\t@queryAssignedElements() private _slotted!: Element[]\n\n\tprivate _position: Position = { x: 16, y: 16 }\n\tprivate _containerRef = createRef<HTMLElement>()\n\tprivate _headerRef = createRef<HTMLElement>()\n\tprivate _currentAnimation?: Animation\n\n\t#ready = false\n\t#sub?: Subscription\n\t#captured: Element[] = []\n\n\t// ============================================\n\t// POSITION MANAGEMENT\n\t// ============================================\n\n\tprivate _applyContainerPosition() {\n\t\tconst container = this._containerRef.value\n\t\tif (!container) return\n\t\tcontainer.style.removeProperty('left')\n\t\tcontainer.style.removeProperty('right')\n\t\tcontainer.style.removeProperty('top')\n\t\tcontainer.style.removeProperty('bottom')\n\t\tconst { x, y } = this._position\n\t\tif (this._currentCorner.includes('right')) {\n\t\t\tcontainer.style.right = `${x}px`\n\t\t} else {\n\t\t\tcontainer.style.left = `${x}px`\n\t\t}\n\t\tif (this._currentCorner.includes('bottom')) {\n\t\t\tcontainer.style.bottom = `${y + theme.bottomOffset}px`\n\t\t} else {\n\t\t\tcontainer.style.top = `${y}px`\n\t\t}\n\t}\n\n\tprivate _loadPosition() {\n\t\ttry {\n\t\t\tconst saved = localStorage.getItem(POSITION_STORAGE_KEY_PREFIX + this.id)\n\t\t\tif (saved) {\n\t\t\t\tconst parsed = JSON.parse(saved) as { x: number; y: number; anchor: Corner }\n\t\t\t\tthis._position = { x: parsed.x, y: parsed.y }\n\t\t\t\tthis._currentCorner = parsed.anchor\n\t\t\t}\n\t\t} catch {\n\t\t\t// ignore localStorage errors\n\t\t}\n\t}\n\n\tprivate _savePosition() {\n\t\ttry {\n\t\t\tlocalStorage.setItem(\n\t\t\t\tPOSITION_STORAGE_KEY_PREFIX + this.id,\n\t\t\t\tJSON.stringify({ ...this._position, anchor: this._currentCorner }),\n\t\t\t)\n\t\t} catch {\n\t\t\t// ignore localStorage errors\n\t\t}\n\t}\n\n\tprivate _validateBounds() {\n\t\tconst container = this._containerRef.value\n\t\tif (!container) return\n\t\tconst rect = container.getBoundingClientRect()\n\t\tif (rect.width === 0) return\n\t\tconst vw = window.innerWidth\n\t\tconst vh = window.innerHeight\n\t\tconst isRight = this._currentCorner.includes('right')\n\t\tconst isBottom = this._currentCorner.includes('bottom')\n\t\tconst actualLeft = isRight ? vw - this._position.x - rect.width : this._position.x\n\t\tconst actualTop = isBottom ? vh - this._position.y - rect.height : this._position.y\n\t\tconst newLeft = Math.max(0, Math.min(actualLeft, vw - rect.width))\n\t\tconst newTop = Math.max(0, Math.min(actualTop, vh - rect.height))\n\t\tthis._position = {\n\t\t\tx: isRight ? vw - newLeft - rect.width : newLeft,\n\t\t\ty: isBottom ? vh - newTop - rect.height : newTop,\n\t\t}\n\t\tthis._applyContainerPosition()\n\t}\n\n\t// ============================================\n\t// CORNER SNAPPING (FLIP)\n\t// ============================================\n\n\tprivate _reorientToNearestCorner(): void {\n\t\tconst container = this._containerRef.value\n\t\tif (!container) return\n\n\t\tconst rect = container.getBoundingClientRect()\n\t\tconst fabCenterX = rect.left + rect.width / 2\n\t\tconst fabCenterY = rect.top + rect.height / 2\n\t\tconst side = fabCenterX > window.innerWidth / 2 ? 'right' : 'left'\n\t\tconst vert = fabCenterY > window.innerHeight / 2 ? 'bottom' : 'top'\n\t\tthis._currentCorner = `${vert}-${side}` as Corner\n\t\tthis._position = { x: 16, y: 16 }\n\t\tthis._applyContainerPosition()\n\n\t\tif (reducedMotion$.value) {\n\t\t\tthis._savePosition()\n\t\t\treturn\n\t\t}\n\n\t\tconst newRect = container.getBoundingClientRect()\n\t\tconst dx = rect.left - newRect.left\n\t\tconst dy = rect.top - newRect.top\n\t\tcontainer.style.transform = `translate(${dx}px, ${dy}px)`\n\n\t\tthis._currentAnimation?.cancel()\n\t\tconst anim = container.animate(\n\t\t\t[{ transform: container.style.transform }, { transform: 'translate(0,0)' }],\n\t\t\t{\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\tthis._currentAnimation = anim\n\t\tanim.finished.then(() => {\n\t\t\tif (container.isConnected) container.style.transform = ''\n\t\t\treturn\n\t\t})\n\n\t\tthis._savePosition()\n\t}\n\n\t// ============================================\n\t// DRAG PIPELINE\n\t// ============================================\n\n\tprivate _setupDrag() {\n\t\tconst header = this._headerRef.value\n\t\tconst container = this._containerRef.value\n\t\tif (!header || !container) return\n\n\t\tlet didDrag = false\n\n\t\tfromEvent<PointerEvent>(header, 'pointerdown')\n\t\t\t.pipe(\n\t\t\t\tfilter(e => e.button === 0),\n\t\t\t\ttap(e => {\n\t\t\t\t\te.preventDefault()\n\t\t\t\t\te.stopPropagation()\n\t\t\t\t\theader.setPointerCapture(e.pointerId)\n\t\t\t\t}),\n\t\t\t\tmap(e => {\n\t\t\t\t\tconst rect = container.getBoundingClientRect()\n\t\t\t\t\tdidDrag = false\n\t\t\t\t\treturn {\n\t\t\t\t\t\tpointerId: e.pointerId,\n\t\t\t\t\t\tstartX: e.clientX,\n\t\t\t\t\t\tstartY: e.clientY,\n\t\t\t\t\t\toffsetX: e.clientX - rect.left,\n\t\t\t\t\t\toffsetY: e.clientY - rect.top,\n\t\t\t\t\t\trect,\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t\tswitchMap(({ pointerId, startX, startY, offsetX, offsetY, rect }) => {\n\t\t\t\t\tconst sameId = (e: PointerEvent) => e.pointerId === pointerId\n\t\t\t\t\tconst move$ = fromEvent<PointerEvent>(window, 'pointermove').pipe(filter(sameId))\n\t\t\t\t\tconst end$ = merge(\n\t\t\t\t\t\tfromEvent<PointerEvent>(window, 'pointerup'),\n\t\t\t\t\t\tfromEvent<PointerEvent>(window, 'pointercancel'),\n\t\t\t\t\t).pipe(filter(sameId))\n\n\t\t\t\t\treturn move$.pipe(\n\t\t\t\t\t\ttap(({ clientX, clientY }) => {\n\t\t\t\t\t\t\tconst dx = clientX - startX\n\t\t\t\t\t\t\tconst dy = clientY - startY\n\t\t\t\t\t\t\tif (Math.sqrt(dx * dx + dy * dy) > DRAG_THRESHOLD && !didDrag) {\n\t\t\t\t\t\t\t\tdidDrag = true\n\t\t\t\t\t\t\t\tthis.isDragging = true\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (!didDrag) return\n\n\t\t\t\t\t\t\tconst vw = window.innerWidth\n\t\t\t\t\t\t\tconst vh = window.innerHeight\n\t\t\t\t\t\t\tconst left = Math.max(0, Math.min(clientX - offsetX, vw - rect.width))\n\t\t\t\t\t\t\tconst top = Math.max(0, Math.min(clientY - offsetY, vh - rect.height))\n\t\t\t\t\t\t\tthis._position = {\n\t\t\t\t\t\t\t\tx: this._currentCorner.includes('right') ? vw - left - rect.width : left,\n\t\t\t\t\t\t\t\ty: this._currentCorner.includes('bottom') ? vh - top - rect.height : top,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthis._applyContainerPosition()\n\t\t\t\t\t\t}),\n\t\t\t\t\t\ttakeUntil(end$),\n\t\t\t\t\t\tfinalize(() => {\n\t\t\t\t\t\t\tif (didDrag) {\n\t\t\t\t\t\t\t\tthis._reorientToNearestCorner()\n\t\t\t\t\t\t\t\tthis.isDragging = false\n\t\t\t\t\t\t\t\tdidDrag = false\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.isDragging = false\n\t\t\t\t\t\t\t\tdidDrag = false\n\t\t\t\t\t\t\t\tthis.toggle()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}),\n\t\t\t\t\t)\n\t\t\t\t}),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe()\n\t}\n\n\t// ============================================\n\t// OVERLAY DELEGATION\n\t// ============================================\n\n\tprivate _openOverlay() {\n\t\tif (this.#sub) return\n\t\tconst anchor = this._containerRef.value\n\t\tconst wrapper = document.createElement('div')\n\t\twrapper.className = 'flex flex-col'\n\t\tthis.#captured = [...this._slotted]\n\t\tthis.#captured.forEach(node => wrapper.appendChild(node))\n\n\t\tthis.#sub = show(wrapper, {\n\t\t\tanchor: anchor ?? undefined,\n\t\t\tdismissable: true,\n\t\t\thistoryStrategy: 'silent',\n\t\t})\n\t\t\t.pipe(\n\t\t\t\tfinalize(() => this._restoreSlotted()),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe()\n\n\t\tthis.dispatchScopedEvent('toggle', 'open')\n\t}\n\n\tprivate _restoreSlotted() {\n\t\tthis.#captured.forEach(node => this.appendChild(node))\n\t\tthis.#captured = []\n\t\tthis.#sub = undefined\n\t\tif (this.open) this.open = false\n\t\tthis.dispatchScopedEvent('toggle', 'closed')\n\t}\n\n\t// ============================================\n\t// LIFECYCLE\n\t// ============================================\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback()\n\n\t\tfromEvent(window, 'resize')\n\t\t\t.pipe(takeUntil(this.disconnecting))\n\t\t\t.subscribe(() => this._validateBounds())\n\n\t\ttheme.bottomOffset$.pipe(\n\t\t\ttap(() => this._applyContainerPosition()),\n\t\t\ttakeUntil(this.disconnecting),\n\t\t).subscribe()\n\t}\n\n\tfirstUpdated() {\n\t\tthis._currentCorner = this.corner\n\t\tthis._loadPosition()\n\t\tif (!this._containerRef.value) return\n\t\tthis._applyContainerPosition()\n\t\tthis._setupDrag()\n\t\tthis.#ready = true\n\t\tif (this.open) this._openOverlay()\n\t}\n\n\tprotected willUpdate(changed: PropertyValues<this>) {\n\t\tif (!this.#ready || !changed.has('open')) return\n\t\tif (this.open && !this.#sub) this._openOverlay()\n\t\telse if (!this.open && this.#sub) this.#sub.unsubscribe()\n\t}\n\n\tdisconnectedCallback() {\n\t\tsuper.disconnectedCallback()\n\t\tthis._currentAnimation?.cancel()\n\t\tthis.#sub?.unsubscribe()\n\t}\n\n\t// ============================================\n\t// PUBLIC API\n\t// ============================================\n\n\t/** Flip open ↔ closed. */\n\ttoggle() {\n\t\tthis.open = !this.open\n\t}\n\n\t// ============================================\n\t// RENDER\n\t// ============================================\n\n\tprotected render(): unknown {\n\t\tconst containerClasses = classMap({\n\t\t\t'inline-flex': true,\n\t\t\t'rounded-full': true,\n\t\t\t'overflow-hidden': true,\n\t\t\t'transition-opacity': true,\n\t\t\t'duration-200': true,\n\t\t\t'opacity-85': this.isDragging,\n\t\t\t'scale-95': this.isDragging,\n\t\t})\n\n\t\tconst containerStyles = styleMap({\n\t\t\tposition: 'fixed',\n\t\t\t'pointer-events': 'auto',\n\t\t})\n\n\t\tconst fabClasses = classMap({\n\t\t\t'h-14': true,\n\t\t\t'rounded-full': true,\n\t\t\tflex: true,\n\t\t\t'items-center': true,\n\t\t\t'gap-3': true,\n\t\t\t'select-none': true,\n\t\t\t'touch-none': true,\n\t\t\t'cursor-grabbing': this.isDragging,\n\t\t\t'cursor-pointer': !this.isDragging,\n\t\t\t'px-5': !!this.label,\n\t\t\t'w-14': !this.label,\n\t\t\t'justify-center': !this.label,\n\t\t})\n\n\t\treturn html`\n\t\t\t<schmancy-surface\n\t\t\t\t${ref(this._containerRef)}\n\t\t\t\ttype=\"glass\"\n\t\t\t\t.elevation=${this.lowered ? 1 : 3}\n\t\t\t\tclass=${containerClasses}\n\t\t\t\tstyle=${containerStyles}\n\t\t\t\taria-expanded=${this.open}\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\t${ref(this._headerRef)}\n\t\t\t\t\tclass=${fabClasses}\n\t\t\t\t\trole=\"button\"\n\t\t\t\t\ttabindex=\"0\"\n\t\t\t\t\taria-label=${this.label ?? 'Open panel'}\n\t\t\t\t\ttitle=\"Drag to move · click to open\"\n\t\t\t\t>\n\t\t\t\t\t<slot name=\"header\">\n\t\t\t\t\t\t${when(\n\t\t\t\t\t\t\t!!this.icon,\n\t\t\t\t\t\t\t() => html`<schmancy-icon>${this.icon}</schmancy-icon>`,\n\t\t\t\t\t\t\t() => nothing,\n\t\t\t\t\t\t)}\n\t\t\t\t\t</slot>\n\t\t\t\t\t${when(\n\t\t\t\t\t\t!!this.label,\n\t\t\t\t\t\t() => html`<schmancy-typography type=\"label\" token=\"lg\" class=\"whitespace-nowrap\">\n\t\t\t\t\t\t\t${this.label}\n\t\t\t\t\t\t</schmancy-typography>`,\n\t\t\t\t\t\t() => nothing,\n\t\t\t\t\t)}\n\t\t\t\t\t<slot name=\"summary\"></slot>\n\t\t\t\t</div>\n\n\t\t\t\t<!-- Default-slot content parks here (hidden) while collapsed;\n\t\t\t\t relocated into the show() overlay on open. -->\n\t\t\t\t<div hidden><slot></slot></div>\n\t\t\t</schmancy-surface>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-boat': SchmancyBoat\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;AAaA,IACM,IAA8B,kBAgBrB,IAAA,cAA2B,EAAA;CAAA,YAAA,GAAA,GAAA;EAAA,MAAA,GAAA,CAAA,GAAA,KAAA,KAUA,WAAA,KAAA,UAAA,CAIsB,GAAA,KAAA,SAElB,gBAAA,KAAA,OAAA,CAEe,GAAA,KAAA,aAAA,CAE9B,GAAA,KAAA,iBACY,gBAAA,KAAA,YAIZ;GAAE,GAAG;GAAI,GAAG;EAAA,GAAA,KAAA,gBAClB,EAAA,GAAA,KAAA,aACH,EAAA,GAAA,KAAA,KAAA,CAGZ,GAAA,KAAA,KAEc,CAAA;CAAA;CAAA;EAAA,KAAA,SA/BP,CAAC,CAAG;;;;;;;;;CA6BpB;CACA;CACA;CAMA,0BAAA;EACC,IAAM,IAAY,KAAK,cAAc;EACrC,IAAA,CAAK,GAAW;EAChB,EAAU,MAAM,eAAe,MAAA,GAC/B,EAAU,MAAM,eAAe,OAAA,GAC/B,EAAU,MAAM,eAAe,KAAA,GAC/B,EAAU,MAAM,eAAe,QAAA;EAC/B,IAAA,EAAM,GAAE,GAAA,GAAG,MAAM,KAAK;EAClB,KAAK,eAAe,SAAS,OAAA,IAChC,EAAU,MAAM,QAAQ,GAAG,EAAA,MAE3B,EAAU,MAAM,OAAO,GAAG,EAAA,KAEvB,KAAK,eAAe,SAAS,QAAA,IAChC,EAAU,MAAM,SAAS,GAAG,IAAI,EAAM,aAAA,MAEtC,EAAU,MAAM,MAAM,GAAG,EAAA;CAE3B;CAEA,gBAAA;EACC,IAAA;GACC,IAAM,IAAQ,aAAa,QAAQ,IAA8B,KAAK,EAAA;GACtE,IAAI,GAAO;IACV,IAAM,IAAS,KAAK,MAAM,CAAA;IAC1B,KAAK,YAAY;KAAE,GAAG,EAAO;KAAG,GAAG,EAAO;IAAA,GAC1C,KAAK,iBAAiB,EAAO;GAC9B;EACD,QAAA,CAEA;CACD;CAEA,gBAAA;EACC,IAAA;GACC,aAAa,QACZ,IAA8B,KAAK,IACnC,KAAK,UAAU;IAAA,GAAK,KAAK;IAAW,QAAQ,KAAK;GAAA,CAAA,CAAA;EAEnD,QAAA,CAEA;CACD;CAEA,kBAAA;EACC,IAAM,IAAY,KAAK,cAAc;EACrC,IAAA,CAAK,GAAW;EAChB,IAAM,IAAO,EAAU,sBAAA;EACvB,IAAI,EAAK,UAAU,GAAG;EACtB,IAAM,IAAK,OAAO,YACZ,IAAK,OAAO,aACZ,IAAU,KAAK,eAAe,SAAS,OAAA,GACvC,IAAW,KAAK,eAAe,SAAS,QAAA,GACxC,IAAa,IAAU,IAAK,KAAK,UAAU,IAAI,EAAK,QAAQ,KAAK,UAAU,GAC3E,IAAY,IAAW,IAAK,KAAK,UAAU,IAAI,EAAK,SAAS,KAAK,UAAU,GAC5E,IAAU,KAAK,IAAI,GAAG,KAAK,IAAI,GAAY,IAAK,EAAK,KAAA,CAAA,GACrD,IAAS,KAAK,IAAI,GAAG,KAAK,IAAI,GAAW,IAAK,EAAK,MAAA,CAAA;EACzD,KAAK,YAAY;GAChB,GAAG,IAAU,IAAK,IAAU,EAAK,QAAQ;GACzC,GAAG,IAAW,IAAK,IAAS,EAAK,SAAS;EAAA,GAE3C,KAAK,wBAAA;CACN;CAMA,2BAAA;EACC,IAAM,IAAY,KAAK,cAAc;EACrC,IAAA,CAAK,GAAW;EAEhB,IAAM,IAAO,EAAU,sBAAA,GACjB,IAAa,EAAK,OAAO,EAAK,QAAQ,GACtC,IAAa,EAAK,MAAM,EAAK,SAAS,GACtC,IAAO,IAAa,OAAO,aAAa,IAAI,UAAU,QACtD,IAAO,IAAa,OAAO,cAAc,IAAI,WAAW;EAK9D,IAJA,KAAK,iBAAiB,GAAG,EAAA,GAAQ,KACjC,KAAK,YAAY;GAAE,GAAG;GAAI,GAAG;EAAA,GAC7B,KAAK,wBAAA,GAED,EAAe,OAElB,OAAA,KADA,KAAK,cAAA;EAIN,IAAM,IAAU,EAAU,sBAAA,GACpB,IAAK,EAAK,OAAO,EAAQ,MACzB,IAAK,EAAK,MAAM,EAAQ;EAC9B,EAAU,MAAM,YAAY,aAAa,EAAA,MAAS,EAAA,MAElD,KAAK,mBAAmB,OAAA;EACxB,IAAM,IAAO,EAAU,QACtB,CAAC,EAAE,WAAW,EAAU,MAAM,UAAA,GAAa,EAAE,WAAW,iBAAA,CAAA,GACxD;GACC,UAAU,EAAc;GACxB,QAAQ,EAAc;GACtB,MAAM;EAAA,CAAA;EAGR,KAAK,oBAAoB,GACzB,EAAK,SAAS,WAAA;GACT,EAAU,gBAAa,EAAU,MAAM,YAAY;EAAA,CAAA,GAIxD,KAAK,cAAA;CACN;CAMA,aAAA;EACC,IAAM,IAAS,KAAK,WAAW,OACzB,IAAY,KAAK,cAAc;EACrC,IAAA,CAAK,KAAA,CAAW,GAAW;EAE3B,IAAI,IAAA,CAAU;EAEd,EAAwB,GAAQ,aAAA,EAC9B,KACA,GAAO,MAAK,EAAE,WAAW,CAAX,GACd,GAAI,MAAA;GACH,EAAE,eAAA,GACF,EAAE,gBAAA,GACF,EAAO,kBAAkB,EAAE,SAAA;EAAA,CAAA,GAE5B,GAAI,MAAA;GACH,IAAM,IAAO,EAAU,sBAAA;GAEvB,OADA,IAAA,CAAU,GACH;IACN,WAAW,EAAE;IACb,QAAQ,EAAE;IACV,QAAQ,EAAE;IACV,SAAS,EAAE,UAAU,EAAK;IAC1B,SAAS,EAAE,UAAU,EAAK;IAC1B,MAAA;GAAA;EAAA,CAAA,GAGF,GAAA,EAAa,WAAA,GAAW,QAAA,GAAQ,QAAA,GAAQ,SAAA,GAAS,SAAA,GAAS,MAAA,QAAA;GACzD,IAAM,KAAU,MAAoB,EAAE,cAAc,GAC9C,IAAQ,EAAwB,QAAQ,aAAA,EAAe,KAAK,EAAO,CAAA,CAAA,GACnE,IAAO,EACZ,EAAwB,QAAQ,WAAA,GAChC,EAAwB,QAAQ,eAAA,CAAA,EAC/B,KAAK,EAAO,CAAA,CAAA;GAEd,OAAO,EAAM,KACZ,GAAA,EAAO,SAAA,GAAS,SAAA,QAAA;IACf,IAAM,IAAK,IAAU,GACf,IAAK,IAAU;IAKrB,IAJI,KAAK,KAAK,IAAK,IAAK,IAAK,CAAA,IA/Mb,KAAA,CA+MsC,MACrD,IAAA,CAAU,GACV,KAAK,aAAA,CAAa,IAAA,CAEd,GAAS;IAEd,IAAM,IAAK,OAAO,YACZ,IAAK,OAAO,aACZ,IAAO,KAAK,IAAI,GAAG,KAAK,IAAI,IAAU,GAAS,IAAK,EAAK,KAAA,CAAA,GACzD,IAAM,KAAK,IAAI,GAAG,KAAK,IAAI,IAAU,GAAS,IAAK,EAAK,MAAA,CAAA;IAC9D,KAAK,YAAY;KAChB,GAAG,KAAK,eAAe,SAAS,OAAA,IAAW,IAAK,IAAO,EAAK,QAAQ;KACpE,GAAG,KAAK,eAAe,SAAS,QAAA,IAAY,IAAK,IAAM,EAAK,SAAS;IAAA,GAEtE,KAAK,wBAAA;GAAA,CAAA,GAEN,EAAU,CAAA,GACV,QAAA;IACK,KACH,KAAK,yBAAA,GACL,KAAK,aAAA,CAAa,GAClB,IAAA,CAAU,MAEV,KAAK,aAAA,CAAa,GAClB,IAAA,CAAU,GACV,KAAK,OAAA;GAAA,CAAA,CAAA;EAAA,CAAA,GAKT,EAAU,KAAK,aAAA,CAAA,EAEf,UAAA;CACH;CAMA,eAAA;EACC,IAAI,KAAA,IAAW;EACf,IAAM,IAAS,KAAK,cAAc,OAC5B,IAAU,SAAS,cAAc,KAAA;EACvC,EAAQ,YAAY,iBACpB,KAAA,KAAiB,CAAA,GAAI,KAAK,QAAA,GAC1B,KAAA,GAAe,SAAQ,MAAQ,EAAQ,YAAY,CAAA,CAAA,GAEnD,KAAA,KAAY,EAAK,GAAS;GACzB,QAAQ,KAAA,KAAU;GAClB,aAAA,CAAa;GACb,iBAAiB;EAAA,CAAA,EAEhB,KACA,QAAe,KAAK,gBAAA,CAAA,GACpB,EAAU,KAAK,aAAA,CAAA,EAEf,UAAA,GAEF,KAAK,oBAAoB,UAAU,MAAA;CACpC;CAEA,kBAAA;EACC,KAAA,GAAe,SAAQ,MAAQ,KAAK,YAAY,CAAA,CAAA,GAChD,KAAA,KAAiB,CAAA,GACjB,KAAA,KAAKA,KAAO,GACR,AAAW,KAAK,SAAA,CAAO,GAC3B,KAAK,oBAAoB,UAAU,QAAA;CACpC;CAMA,oBAAA;EACC,MAAM,kBAAA,GAEN,EAAU,QAAQ,QAAA,EAChB,KAAK,EAAU,KAAK,aAAA,CAAA,EACpB,gBAAgB,KAAK,gBAAA,CAAA,GAEvB,EAAM,cAAc,KACnB,QAAU,KAAK,wBAAA,CAAA,GACf,EAAU,KAAK,aAAA,CAAA,EACd,UAAA;CACH;CAEA,eAAA;EACC,KAAK,iBAAiB,KAAK,QAC3B,KAAK,cAAA,GACA,KAAK,cAAc,UACxB,KAAK,wBAAA,GACL,KAAK,WAAA,GACL,KAAA,KAAKE,CAAS,GACV,KAAK,QAAM,KAAK,aAAA;CACrB;CAEA,WAAqB,GAAA;EACf,KAAA,MAAgB,EAAQ,IAAI,MAAA,MAC7B,KAAK,QAAA,CAAS,KAAA,KAAW,KAAK,aAAA,IAAA,CACxB,KAAK,QAAQ,KAAA,MAAW,KAAA,GAAU,YAAA;CAC7C;CAEA,uBAAA;EACC,MAAM,qBAAA,GACN,KAAK,mBAAmB,OAAA,GACxB,KAAA,IAAW,YAAA;CACZ;CAOA,SAAA;EACC,KAAK,OAAA,CAAQ,KAAK;CACnB;CAMA,SAAA;EACC,IAAM,IAAmB,EAAS;GACjC,eAAA,CAAe;GACf,gBAAA,CAAgB;GAChB,mBAAA,CAAmB;GACnB,sBAAA,CAAsB;GACtB,gBAAA,CAAgB;GAChB,cAAc,KAAK;GACnB,YAAY,KAAK;EAAA,CAAA,GAGZ,IAAkB,EAAS;GAChC,UAAU;GACV,kBAAkB;EAAA,CAAA,GAGb,IAAa,EAAS;GAC3B,QAAA,CAAQ;GACR,gBAAA,CAAgB;GAChB,MAAA,CAAM;GACN,gBAAA,CAAgB;GAChB,SAAA,CAAS;GACT,eAAA,CAAe;GACf,cAAA,CAAc;GACd,mBAAmB,KAAK;GACxB,kBAAA,CAAmB,KAAK;GACxB,QAAA,CAAA,CAAU,KAAK;GACf,QAAA,CAAS,KAAK;GACd,kBAAA,CAAmB,KAAK;EAAA,CAAA;EAGzB,OAAO,CAAI;;MAEP,EAAI,KAAK,aAAA,EAAA;;iBAEE,KAAK,UAAU,IAAI,EAAA;YACxB,EAAA;YACA,EAAA;oBACQ,KAAK,KAAA;;;OAGlB,EAAI,KAAK,UAAA,EAAA;aACH,EAAA;;;kBAGK,KAAK,SAAS,aAAA;;;;QAIxB,EAAA,CAAA,CACC,KAAK,YACD,CAAI,kBAAkB,KAAK,KAAA,yBAC3B,CAAA,EAAA;;OAGN,EAAA,CAAA,CACC,KAAK,aACD,CAAI;SACP,KAAK,MAAA;qCAEF,CAAA,EAAA;;;;;;;;;CAUX;AAAA;AAAA,EAAA,CAnXC,EAAS,EAAE,MAAM,OAAA,CAAA,CAAA,GAAQ,EAAA,WAAA,MAAA,KAAA,CAAA,GAAA,EAAA,CACzB,EAAS,EAAE,MAAM,OAAA,CAAA,CAAA,GAAQ,EAAA,WAAA,QAAA,KAAA,CAAA,GAAA,EAAA,CACzB,EAAS,EAAE,MAAM,OAAA,CAAA,CAAA,GAAQ,EAAA,WAAA,SAAA,KAAA,CAAA,GAAA,EAAA,CAEzB,EAAS;CAAE,MAAM;CAAS,SAAA,CAAS;AAAA,CAAA,CAAA,GAAM,EAAA,WAAA,WAAA,KAAA,CAAA,GAAA,EAAA,CAEzC,EAAS,EAAE,MAAM,OAAA,CAAA,CAAA,GAAQ,EAAA,WAAA,UAAA,KAAA,CAAA,GAAA,EAAA,CAEzB,EAAS;CAAE,MAAM;CAAS,SAAA,CAAS;AAAA,CAAA,CAAA,GAAM,EAAA,WAAA,QAAA,KAAA,CAAA,GAAA,EAAA,CAEzC,EAAA,CAAA,GAAM,EAAA,WAAA,cAAA,KAAA,CAAA,GAAA,EAAA,CACN,EAAA,CAAA,GAAM,EAAA,WAAA,kBAAA,KAAA,CAAA,GAAA,EAAA,CAEN,EAAA,CAAA,GAAsB,EAAA,WAAA,YAAA,KAAA,CAAA;AAAA,IAAA,IAAA,IAAA,EAAA,CAxBvB,EAAc,eAAA,CAAA,GAAe,CAAA;AAAA,SAAA,KAAA"}