@rcarls/rc-app-bar 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/dist/custom-elements.json +52 -1
- package/dist/{rc-app-bar-DcYvkEsy.js → rc-app-bar-C9IC9WXj.js} +32 -45
- package/dist/rc-app-bar-C9IC9WXj.js.map +1 -0
- package/dist/rc-app-bar-define.js +1 -1
- package/dist/rc-app-bar.js +1 -1
- package/dist/types/packages/rc-app-bar/src/rc-app-bar.d.ts +9 -1
- package/package.json +8 -11
- package/dist/demo.css +0 -85
- package/dist/demo.js +0 -40
- package/dist/rc-app-bar-DcYvkEsy.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# `@rcarls/rc-app-bar`
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
App bar modeled after the [Material 3 Top app bar](https://m3.material.io/components/top-app-bar/overview), with leading, title, center, trailing regions and optional scroll behavior.
|
|
4
|
+
|
|
5
|
+
Docs: [https://richardcarls.github.io/rc-webcomponents/components/rc-app-bar](https://richardcarls.github.io/rc-webcomponents/components/rc-app-bar).
|
|
6
6
|
|
|
7
7
|
Material 3 and Apple HIG inform the available structures and behaviors, but the
|
|
8
8
|
default appearance remains deliberately UA-like: system colors, a thin
|
|
@@ -195,7 +195,7 @@ rc-app-bar.glass::part(root) {
|
|
|
195
195
|
| `--rc-app-bar-padding-inline` | `0.75em` | Horizontal padding |
|
|
196
196
|
| `--rc-app-bar-gap` | `0.5em` | Gap between regions |
|
|
197
197
|
| `--rc-app-bar-transition-duration` | `200ms` | Endpoint and hide transition duration |
|
|
198
|
-
| `--rc-app-bar-scroll-
|
|
198
|
+
| `--rc-app-bar-scroll-divider` | `1px solid GrayText` | Scrolled separator border |
|
|
199
199
|
|
|
200
200
|
### CSS parts
|
|
201
201
|
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"declarations": [
|
|
47
47
|
{
|
|
48
48
|
"kind": "class",
|
|
49
|
-
"description": "
|
|
49
|
+
"description": "App bar modeled after the Material 3 Top app bar, with leading, title, center, trailing\nregions and optional scroll behavior.\n\nThe element carries no landmark role. Consumers provide all controls and\nicons, and wrap page-level instances in `<header>` when a banner landmark is\nappropriate.\n\nScrolled state is dual-mode. Uncontrolled: set `scrollTarget` (or the\n`scroll-target` selector attribute) and the bar observes the container.\nControlled: assign `scrolled`; assigning `undefined` releases observation.\nHost writes are silent.",
|
|
50
50
|
"name": "RCAppBar",
|
|
51
51
|
"cssProperties": [
|
|
52
52
|
{
|
|
@@ -300,6 +300,13 @@
|
|
|
300
300
|
"privacy": "private",
|
|
301
301
|
"default": "null"
|
|
302
302
|
},
|
|
303
|
+
{
|
|
304
|
+
"kind": "field",
|
|
305
|
+
"name": "_layoutMeasure",
|
|
306
|
+
"privacy": "private",
|
|
307
|
+
"readonly": true,
|
|
308
|
+
"default": "new RafScheduler(this)"
|
|
309
|
+
},
|
|
303
310
|
{
|
|
304
311
|
"kind": "field",
|
|
305
312
|
"name": "_scroll",
|
|
@@ -354,6 +361,26 @@
|
|
|
354
361
|
}
|
|
355
362
|
}
|
|
356
363
|
},
|
|
364
|
+
{
|
|
365
|
+
"kind": "method",
|
|
366
|
+
"name": "_queueLayoutMeasure",
|
|
367
|
+
"privacy": "private",
|
|
368
|
+
"return": {
|
|
369
|
+
"type": {
|
|
370
|
+
"text": "void"
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
"kind": "method",
|
|
376
|
+
"name": "_cancelQueuedLayoutMeasure",
|
|
377
|
+
"privacy": "private",
|
|
378
|
+
"return": {
|
|
379
|
+
"type": {
|
|
380
|
+
"text": "void"
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
},
|
|
357
384
|
{
|
|
358
385
|
"kind": "method",
|
|
359
386
|
"name": "_syncScrollObserver",
|
|
@@ -436,6 +463,30 @@
|
|
|
436
463
|
}
|
|
437
464
|
}
|
|
438
465
|
},
|
|
466
|
+
{
|
|
467
|
+
"kind": "method",
|
|
468
|
+
"name": "_setGeometryProperty",
|
|
469
|
+
"privacy": "private",
|
|
470
|
+
"return": {
|
|
471
|
+
"type": {
|
|
472
|
+
"text": "void"
|
|
473
|
+
}
|
|
474
|
+
},
|
|
475
|
+
"parameters": [
|
|
476
|
+
{
|
|
477
|
+
"name": "name",
|
|
478
|
+
"type": {
|
|
479
|
+
"text": "string"
|
|
480
|
+
}
|
|
481
|
+
},
|
|
482
|
+
{
|
|
483
|
+
"name": "value",
|
|
484
|
+
"type": {
|
|
485
|
+
"text": "string"
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
]
|
|
489
|
+
},
|
|
439
490
|
{
|
|
440
491
|
"kind": "method",
|
|
441
492
|
"name": "_setHidden",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { css as f, LitElement as v, nothing as
|
|
1
|
+
import { css as f, LitElement as v, nothing as y, html as b } from "lit";
|
|
2
2
|
import { property as n, state as c } from "lit/decorators.js";
|
|
3
3
|
import { classMap as d } from "lit/directives/class-map.js";
|
|
4
|
-
import {
|
|
5
|
-
const
|
|
4
|
+
import { RafScheduler as x, ScrollObserverController as S } from "@rcarls/rc-common";
|
|
5
|
+
const w = f`
|
|
6
6
|
:host {
|
|
7
7
|
display: block;
|
|
8
8
|
container-type: inline-size;
|
|
@@ -171,14 +171,14 @@ const S = f`
|
|
|
171
171
|
}
|
|
172
172
|
}
|
|
173
173
|
`;
|
|
174
|
-
var
|
|
175
|
-
for (var s = a > 1 ? void 0 : a ?
|
|
176
|
-
(
|
|
177
|
-
return a && s &&
|
|
174
|
+
var C = Object.defineProperty, z = Object.getOwnPropertyDescriptor, i = (p, e, t, a) => {
|
|
175
|
+
for (var s = a > 1 ? void 0 : a ? z(e, t) : e, o = p.length - 1, l; o >= 0; o--)
|
|
176
|
+
(l = p[o]) && (s = (a ? l(e, t, s) : l(s)) || s);
|
|
177
|
+
return a && s && C(e, t, s), s;
|
|
178
178
|
};
|
|
179
179
|
const h = class h extends v {
|
|
180
180
|
constructor() {
|
|
181
|
-
super(...arguments), this.variant = "compact", this.scrollBehavior = "pinned", this.scrollTarget = null, this.scrollThreshold = 4, this._scrolled = void 0, this._observedScrolled = !1, this._hasLeading = !1, this._hasCenter = !1, this._hasTrailing = !1, this._collapsed = !1, this._hidden = !1, this._collapseDistance = 0, this._collapseOffsetDistance = 0, this._collapseProgress = 0, this._reducedMotion = typeof window < "u" ? window.matchMedia("(prefers-reduced-motion: reduce)") : null, this._internals = this.attachInternals(), this._resizeObserver = null, this.
|
|
181
|
+
super(...arguments), this.variant = "compact", this.scrollBehavior = "pinned", this.scrollTarget = null, this.scrollThreshold = 4, this._scrolled = void 0, this._observedScrolled = !1, this._hasLeading = !1, this._hasCenter = !1, this._hasTrailing = !1, this._collapsed = !1, this._hidden = !1, this._collapseDistance = 0, this._collapseOffsetDistance = 0, this._collapseProgress = 0, this._reducedMotion = typeof window < "u" ? window.matchMedia("(prefers-reduced-motion: reduce)") : null, this._internals = this.attachInternals(), this._resizeObserver = null, this._layoutMeasure = new x(this), this._scroll = new S(this, {
|
|
182
182
|
target: () => this._resolveScrollTarget(),
|
|
183
183
|
threshold: this.scrollThreshold,
|
|
184
184
|
disabled: !0,
|
|
@@ -209,7 +209,7 @@ const h = class h extends v {
|
|
|
209
209
|
super.connectedCallback(), this._connectResizeObserver();
|
|
210
210
|
}
|
|
211
211
|
disconnectedCallback() {
|
|
212
|
-
super.disconnectedCallback(), this._resizeObserver?.disconnect();
|
|
212
|
+
super.disconnectedCallback(), this._resizeObserver?.disconnect(), this._cancelQueuedLayoutMeasure();
|
|
213
213
|
}
|
|
214
214
|
willUpdate(e) {
|
|
215
215
|
(e.has("scrollTarget") || e.has("scrollThreshold") || e.has("scrollBehavior")) && this._syncScrollObserver(), (e.has("variant") || e.has("scrollBehavior")) && this._syncVisualState();
|
|
@@ -221,7 +221,7 @@ const h = class h extends v {
|
|
|
221
221
|
this._observeLayout(), (e.has("variant") || e.has("_hasLeading") || e.has("_hasCenter") || e.has("_hasTrailing")) && this._measureLayout(), this._syncStateOutputs();
|
|
222
222
|
}
|
|
223
223
|
_connectResizeObserver() {
|
|
224
|
-
"ResizeObserver" in globalThis && (this._resizeObserver ??= new ResizeObserver(() => this.
|
|
224
|
+
"ResizeObserver" in globalThis && (this._resizeObserver ??= new ResizeObserver(() => this._queueLayoutMeasure()), this._observeLayout());
|
|
225
225
|
}
|
|
226
226
|
_observeLayout() {
|
|
227
227
|
this._resizeObserver && (this._resizeObserver.disconnect(), ["#leading", "#title", "#center", "#trailing"].forEach((e) => {
|
|
@@ -233,17 +233,20 @@ const h = class h extends v {
|
|
|
233
233
|
const e = this.shadowRoot?.querySelector("#leading"), t = this.shadowRoot?.querySelector("#title"), a = this.shadowRoot?.querySelector("#trailing");
|
|
234
234
|
if (!e || !t || !a) return;
|
|
235
235
|
const s = Math.max(e.offsetWidth, a.offsetWidth);
|
|
236
|
-
if (this.
|
|
237
|
-
const
|
|
238
|
-
if (
|
|
239
|
-
const
|
|
240
|
-
this._collapseDistance =
|
|
241
|
-
"--_rc-app-bar-collapse-distance",
|
|
242
|
-
`${l}px`
|
|
243
|
-
), this._applyCollapseGeometry();
|
|
236
|
+
if (this._setGeometryProperty("--_rc-app-bar-edge-size", `${s}px`), this.variant === "expanded" && !this._collapsed) {
|
|
237
|
+
const o = t.offsetHeight;
|
|
238
|
+
if (o > 0) {
|
|
239
|
+
const l = getComputedStyle(t), g = Number.parseFloat(l.paddingBlockStart) + Number.parseFloat(l.paddingBlockEnd), u = Math.max(t.offsetHeight - g, 0), _ = t.offsetTop, m = Math.max(_, u);
|
|
240
|
+
this._collapseDistance = o, this._collapseOffsetDistance = _ - (m - u) / 2, this._setGeometryProperty("--_rc-app-bar-collapse-distance", `${o}px`), this._applyCollapseGeometry();
|
|
244
241
|
}
|
|
245
242
|
}
|
|
246
243
|
}
|
|
244
|
+
_queueLayoutMeasure() {
|
|
245
|
+
this._layoutMeasure.schedule(() => this._measureLayout());
|
|
246
|
+
}
|
|
247
|
+
_cancelQueuedLayoutMeasure() {
|
|
248
|
+
this._layoutMeasure.cancel();
|
|
249
|
+
}
|
|
247
250
|
_syncScrollObserver() {
|
|
248
251
|
this._scroll.setOptions({
|
|
249
252
|
threshold: this.scrollThreshold,
|
|
@@ -288,10 +291,10 @@ const h = class h extends v {
|
|
|
288
291
|
}
|
|
289
292
|
_applyCollapseGeometry() {
|
|
290
293
|
const e = this._collapseOffsetDistance * this._collapseProgress, t = this._collapseDistance * (1 - this._collapseProgress);
|
|
291
|
-
this.
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
);
|
|
294
|
+
this._setGeometryProperty("--_rc-app-bar-collapse-offset", `${-e}px`), this._setGeometryProperty("--_rc-app-bar-expanded-size", `${t}px`), this._setGeometryProperty("--_rc-app-bar-expanded-opacity", `${1 - this._collapseProgress}`);
|
|
295
|
+
}
|
|
296
|
+
_setGeometryProperty(e, t) {
|
|
297
|
+
this.style.getPropertyValue(e) !== t && this.style.setProperty(e, t);
|
|
295
298
|
}
|
|
296
299
|
_setHidden(e) {
|
|
297
300
|
e !== this._hidden && (this._hidden = e, this.toggleAttribute("data-hidden", e), this._setCustomState("hidden", e));
|
|
@@ -318,34 +321,18 @@ const h = class h extends v {
|
|
|
318
321
|
queueMicrotask(() => this._measureLayout());
|
|
319
322
|
}
|
|
320
323
|
render() {
|
|
321
|
-
return
|
|
322
|
-
<div
|
|
323
|
-
id="
|
|
324
|
-
part="root"
|
|
325
|
-
data-has-center=${this._hasCenter ? "" : b}
|
|
326
|
-
>
|
|
327
|
-
<div
|
|
328
|
-
id="leading"
|
|
329
|
-
part="leading"
|
|
330
|
-
class=${d({ empty: !this._hasLeading })}
|
|
331
|
-
>
|
|
324
|
+
return b`
|
|
325
|
+
<div id="root" part="root" data-has-center=${this._hasCenter ? "" : y}>
|
|
326
|
+
<div id="leading" part="leading" class=${d({ empty: !this._hasLeading })}>
|
|
332
327
|
<slot name="leading" @slotchange=${this._onSlotChange}></slot>
|
|
333
328
|
</div>
|
|
334
329
|
<div id="title" part="title">
|
|
335
330
|
<slot @slotchange=${this._onSlotChange}></slot>
|
|
336
331
|
</div>
|
|
337
|
-
<div
|
|
338
|
-
id="center"
|
|
339
|
-
part="center"
|
|
340
|
-
class=${d({ empty: !this._hasCenter })}
|
|
341
|
-
>
|
|
332
|
+
<div id="center" part="center" class=${d({ empty: !this._hasCenter })}>
|
|
342
333
|
<slot name="center" @slotchange=${this._onSlotChange}></slot>
|
|
343
334
|
</div>
|
|
344
|
-
<div
|
|
345
|
-
id="trailing"
|
|
346
|
-
part="trailing"
|
|
347
|
-
class=${d({ empty: !this._hasTrailing })}
|
|
348
|
-
>
|
|
335
|
+
<div id="trailing" part="trailing" class=${d({ empty: !this._hasTrailing })}>
|
|
349
336
|
<slot name="trailing" @slotchange=${this._onSlotChange}></slot>
|
|
350
337
|
</div>
|
|
351
338
|
<div id="scroll-shadow" part="scroll-shadow"></div>
|
|
@@ -353,7 +340,7 @@ const h = class h extends v {
|
|
|
353
340
|
`;
|
|
354
341
|
}
|
|
355
342
|
};
|
|
356
|
-
h.styles = [
|
|
343
|
+
h.styles = [w];
|
|
357
344
|
let r = h;
|
|
358
345
|
i([
|
|
359
346
|
n({ type: String, reflect: !0 })
|
|
@@ -385,4 +372,4 @@ i([
|
|
|
385
372
|
export {
|
|
386
373
|
r as R
|
|
387
374
|
};
|
|
388
|
-
//# sourceMappingURL=rc-app-bar-
|
|
375
|
+
//# sourceMappingURL=rc-app-bar-C9IC9WXj.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rc-app-bar-C9IC9WXj.js","sources":["../src/rc-app-bar.styles.ts","../src/rc-app-bar.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const appBarStyles = css`\n :host {\n display: block;\n container-type: inline-size;\n background: var(--rc-app-bar-bg, Canvas);\n color: var(--rc-app-bar-color, CanvasText);\n --_rc-app-bar-collapse-distance: 0px;\n --_rc-app-bar-collapse-offset: 0px;\n --rc-app-bar-collapse-progress: 0;\n --_rc-app-bar-edge-size: 0px;\n --_rc-app-bar-expanded-opacity: 1;\n --_rc-app-bar-expanded-size: 0px;\n transition: translate var(--rc-app-bar-transition-duration, 200ms) ease;\n }\n\n :host([data-hidden]) {\n translate: 0 -100%;\n }\n\n #root {\n display: grid;\n grid-template-columns: auto minmax(0, 1fr) auto;\n grid-template-rows:\n minmax(var(--rc-app-bar-compact-min-height, 3rem), auto)\n 0;\n align-items: center;\n column-gap: var(--rc-app-bar-gap, 0.5em);\n padding-inline: var(--rc-app-bar-padding-inline, 0.75em);\n background: inherit;\n color: inherit;\n }\n\n #root[data-has-center] {\n grid-template-columns:\n var(--_rc-app-bar-edge-size)\n minmax(0, 1fr)\n auto\n minmax(0, 1fr)\n var(--_rc-app-bar-edge-size);\n }\n\n #leading,\n #center,\n #trailing {\n display: flex;\n align-items: center;\n min-inline-size: 0;\n }\n\n #leading {\n grid-column: 1;\n grid-row: 1;\n }\n\n #title {\n grid-column: 2;\n grid-row: 1;\n min-inline-size: 0;\n overflow: clip;\n }\n\n /* Compact-row title: all non-expanded states and the collapsed endpoint. */\n :host(:not([variant='expanded'])) #title ::slotted(*),\n :host([variant='expanded'][data-collapsed]) #title ::slotted(*) {\n font-size: var(--rc-app-bar-title-font-size, inherit);\n }\n\n /* Expanded-row title: only while uncollapsed. */\n :host([variant='expanded']:not([data-collapsed])) #title ::slotted(*) {\n font-size: var(--rc-app-bar-expanded-title-font-size, inherit);\n }\n\n #center {\n grid-column: 2;\n grid-row: 1;\n justify-self: center;\n }\n\n #trailing {\n grid-column: 3;\n grid-row: 1;\n justify-self: end;\n }\n\n #root[data-has-center] #center {\n grid-column: 3;\n }\n\n #root[data-has-center] #trailing {\n grid-column: 5;\n }\n\n .empty {\n visibility: hidden;\n pointer-events: none;\n }\n\n :host([variant='expanded']:not([data-collapsed])) #root {\n grid-template-rows:\n minmax(var(--rc-app-bar-compact-min-height, 3rem), auto)\n var(--_rc-app-bar-expanded-size);\n }\n\n :host([variant='expanded']:not([data-collapsed])) #title {\n grid-column: 1 / -1;\n grid-row: 2;\n align-self: start;\n padding-block: var(--rc-app-bar-expanded-padding-block, 0.75em);\n translate: 0 var(--_rc-app-bar-collapse-offset);\n opacity: var(--_rc-app-bar-expanded-opacity);\n }\n\n :host([variant='expanded'][data-collapsed]) #title {\n animation: rc-app-bar-title-in var(--rc-app-bar-transition-duration, 200ms)\n ease;\n }\n\n #scroll-shadow {\n grid-column: 1 / -1;\n grid-row: 3;\n align-self: end;\n inline-size: calc(100% + 2 * var(--rc-app-bar-padding-inline, 0.75em));\n margin-inline: calc(var(--rc-app-bar-padding-inline, 0.75em) * -1);\n border-block-end: 1px solid transparent;\n }\n\n :host([data-scrolled]) #scroll-shadow {\n border-block-end: var(--rc-app-bar-scroll-divider, 1px solid GrayText);\n }\n\n @keyframes rc-app-bar-title-in {\n from {\n opacity: 0;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n :host,\n :host([variant='expanded'][data-collapsed]) #title {\n transition-duration: 0s;\n animation-duration: 0s;\n }\n }\n\n /*\n * Narrow-viewport fallback for the center-slot layout.\n *\n * The default data-has-center grid forces both outer columns to\n * --_rc-app-bar-edge-size px (= max of leading/trailing widths) so that the\n * center slot stays perfectly symmetric. On screens ≤ 480 px that symmetry\n * can push the total width past the viewport. Below the threshold:\n * - leading and trailing size to their natural content width (auto)\n * - the center slot takes all remaining space (minmax(0, 1fr))\n * - the two inner spacer columns collapse to 0\n *\n * Grid column assignments (1 leading / 2 spacer / 3 center / 4 spacer / 5\n * trailing) are unchanged, so no JS or placement CSS needs to change.\n */\n @container (max-inline-size: 480px) {\n #root[data-has-center] {\n grid-template-columns: auto 0 minmax(0, 1fr) 0 auto;\n }\n\n #root[data-has-center] #center {\n justify-self: stretch;\n justify-content: flex-end;\n }\n }\n`;\n\nexport default appBarStyles;\n","import { LitElement, html, nothing, type PropertyValues } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\n\nimport {\n RafScheduler,\n ScrollObserverController,\n type ScrollObserverTarget,\n} from '@rcarls/rc-common';\n\nimport appBarStyles from './rc-app-bar.styles';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'rc-app-bar': RCAppBar;\n }\n}\n\nexport type RCAppBarVariant = 'compact' | 'expanded';\n\nexport type RCAppBarScrollBehavior = 'pinned' | 'collapse' | 'hide';\n\nexport interface RCAppBarScrollDetail {\n /** Whether the observed scroll target is past the threshold. */\n scrolled: boolean;\n}\n\n/**\n * App bar modeled after the Material 3 Top app bar, with leading, title, center, trailing\n * regions and optional scroll behavior.\n *\n * The element carries no landmark role. Consumers provide all controls and\n * icons, and wrap page-level instances in `<header>` when a banner landmark is\n * appropriate.\n *\n * Scrolled state is dual-mode. Uncontrolled: set `scrollTarget` (or the\n * `scroll-target` selector attribute) and the bar observes the container.\n * Controlled: assign `scrolled`; assigning `undefined` releases observation.\n * Host writes are silent.\n *\n * @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-app-bar rc-app-bar docs}\n * @see {@link https://m3.material.io/components/top-app-bar/overview Material 3 Top app bar}\n *\n * @slot leading - Leading navigation or controls; accepts multiple children\n * @slot - The single title region; may contain title and subtitle markup\n * @slot center - Content kept at the exact horizontal center, such as search\n * @slot trailing - Trailing action controls\n * @fires rc-app-bar-scroll - When observed scroll state crosses the threshold;\n * `detail: { scrolled }`\n * @cssprop [--rc-app-bar-bg=Canvas] - Bar background\n * @cssprop [--rc-app-bar-color=CanvasText] - Bar text color\n * @cssprop [--rc-app-bar-compact-min-height=3rem] - Compact row minimum height\n * @cssprop [--rc-app-bar-expanded-padding-block=0.75em] - Expanded title padding\n * @cssprop [--rc-app-bar-padding-inline=0.75em] - Horizontal padding\n * @cssprop [--rc-app-bar-gap=0.5em] - Gap between regions\n * @cssprop [--rc-app-bar-transition-duration=200ms] - Endpoint and hide duration\n * @cssprop [--rc-app-bar-scroll-divider=1px solid GrayText] - Scrolled divider\n * @cssprop [--rc-app-bar-collapse-progress=0] - Collapse animation progress 0–1; read-only\n * @cssprop [--rc-app-bar-title-font-size] - Compact-row title font size (opt-in; inherits when unset)\n * @cssprop [--rc-app-bar-expanded-title-font-size] - Expanded-row title font size (opt-in)\n * @csspart root - The grid container\n * @csspart leading - Wrapper around the leading slot\n * @csspart title - Wrapper around the single title slot\n * @csspart center - Wrapper around the centered slot\n * @csspart trailing - Wrapper around the trailing slot\n * @csspart scroll-shadow - Scrolled-state separator\n */\nexport class RCAppBar extends LitElement {\n static styles = [appBarStyles];\n\n /** Structural variant. `expanded` adds a flexible title row. */\n @property({ type: String, reflect: true })\n variant: RCAppBarVariant = 'compact';\n\n /** Visual response to observed scrolling. */\n @property({ type: String, attribute: 'scroll-behavior', reflect: true })\n scrollBehavior: RCAppBarScrollBehavior = 'pinned';\n\n /**\n * Scroll container to observe. The attribute accepts a CSS selector or\n * `window`; the property also accepts an element, document, or window.\n */\n @property({ attribute: 'scroll-target' })\n scrollTarget: ScrollObserverTarget | string | null = null;\n\n /** Scroll offset in px past which the bar is scrolled (strict `>`). */\n @property({ type: Number, attribute: 'scroll-threshold' })\n scrollThreshold = 4;\n\n private _scrolled: boolean | undefined = undefined;\n\n @state()\n private _observedScrolled = false;\n\n @state()\n private _hasLeading = false;\n\n @state()\n private _hasCenter = false;\n\n @state()\n private _hasTrailing = false;\n\n private _collapsed = false;\n\n private _hidden = false;\n\n private _collapseDistance = 0;\n\n private _collapseOffsetDistance = 0;\n\n private _collapseProgress = 0;\n\n private readonly _reducedMotion =\n typeof window !== 'undefined' ? window.matchMedia('(prefers-reduced-motion: reduce)') : null;\n\n private _internals = this.attachInternals();\n\n private _resizeObserver: ResizeObserver | null = null;\n\n private readonly _layoutMeasure = new RafScheduler(this);\n\n private readonly _scroll = new ScrollObserverController(this, {\n target: () => this._resolveScrollTarget(),\n threshold: this.scrollThreshold,\n disabled: true,\n onChange: (scrolled) => {\n this._observedScrolled = scrolled;\n this._syncVisualState();\n this.dispatchEvent(\n new CustomEvent<RCAppBarScrollDetail>('rc-app-bar-scroll', {\n bubbles: true,\n composed: true,\n detail: { scrolled },\n }),\n );\n },\n onScroll: (scrollTop, delta) => this._onObservedScroll(scrollTop, delta),\n });\n\n /**\n * Whether the bar is past its scroll threshold. Host writes are silent and\n * controlled; assigning `undefined` releases observation.\n */\n @property({ attribute: false })\n get scrolled(): boolean {\n return this._scrolled ?? this._observedScrolled;\n }\n set scrolled(value: boolean | undefined) {\n const oldValue = this.scrolled;\n\n this._scrolled = value;\n this._syncScrollObserver();\n this._syncVisualState();\n this.requestUpdate('scrolled', oldValue);\n }\n\n /** Whether the expanded title row is currently collapsed. */\n get collapsed(): boolean {\n return this._collapsed;\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n this._connectResizeObserver();\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._resizeObserver?.disconnect();\n this._cancelQueuedLayoutMeasure();\n }\n\n protected override willUpdate(changed: PropertyValues<this>): void {\n if (\n changed.has('scrollTarget') ||\n changed.has('scrollThreshold') ||\n changed.has('scrollBehavior')\n ) {\n this._syncScrollObserver();\n }\n\n if (changed.has('variant') || changed.has('scrollBehavior')) {\n this._syncVisualState();\n }\n }\n\n protected override firstUpdated(): void {\n this._observeLayout();\n this._measureLayout();\n this._syncScrollObserver();\n this._syncVisualState();\n }\n\n protected override updated(changed: PropertyValues): void {\n this._observeLayout();\n if (\n changed.has('variant') ||\n changed.has('_hasLeading') ||\n changed.has('_hasCenter') ||\n changed.has('_hasTrailing')\n ) {\n this._measureLayout();\n }\n this._syncStateOutputs();\n }\n\n private _connectResizeObserver(): void {\n if (!('ResizeObserver' in globalThis)) return;\n\n this._resizeObserver ??= new ResizeObserver(() => this._queueLayoutMeasure());\n this._observeLayout();\n }\n\n private _observeLayout(): void {\n if (!this._resizeObserver) return;\n\n this._resizeObserver.disconnect();\n ['#leading', '#title', '#center', '#trailing'].forEach((selector) => {\n const element = this.shadowRoot?.querySelector<HTMLElement>(selector);\n if (element) this._resizeObserver?.observe(element);\n });\n }\n\n private _measureLayout(): void {\n const leading = this.shadowRoot?.querySelector<HTMLElement>('#leading');\n const title = this.shadowRoot?.querySelector<HTMLElement>('#title');\n const trailing = this.shadowRoot?.querySelector<HTMLElement>('#trailing');\n if (!leading || !title || !trailing) return;\n\n const edgeSize = Math.max(leading.offsetWidth, trailing.offsetWidth);\n this._setGeometryProperty('--_rc-app-bar-edge-size', `${edgeSize}px`);\n\n if (this.variant === 'expanded' && !this._collapsed) {\n const nextDistance = title.offsetHeight;\n if (nextDistance > 0) {\n const titleStyle = getComputedStyle(title);\n const padding =\n Number.parseFloat(titleStyle.paddingBlockStart) +\n Number.parseFloat(titleStyle.paddingBlockEnd);\n const contentHeight = Math.max(title.offsetHeight - padding, 0);\n const compactHeight = title.offsetTop;\n const endpointCompactHeight = Math.max(compactHeight, contentHeight);\n\n this._collapseDistance = nextDistance;\n this._collapseOffsetDistance = compactHeight - (endpointCompactHeight - contentHeight) / 2;\n this._setGeometryProperty('--_rc-app-bar-collapse-distance', `${nextDistance}px`);\n this._applyCollapseGeometry();\n }\n }\n }\n\n private _queueLayoutMeasure(): void {\n this._layoutMeasure.schedule(() => this._measureLayout());\n }\n\n private _cancelQueuedLayoutMeasure(): void {\n this._layoutMeasure.cancel();\n }\n\n private _syncScrollObserver(): void {\n this._scroll.setOptions({\n threshold: this.scrollThreshold,\n disabled: this._scrolled !== undefined || this._resolveScrollTarget() === null,\n });\n }\n\n private _resolveScrollTarget(): ScrollObserverTarget | null {\n const target = this.scrollTarget;\n if (target === null || target === undefined) return null;\n\n if (typeof target !== 'string') return target;\n if (target === 'window') return window;\n\n try {\n return this.ownerDocument?.querySelector(target) ?? null;\n } catch {\n return null;\n }\n }\n\n private _onObservedScroll(scrollTop: number, delta: number): void {\n if (this._scrolled !== undefined) return;\n\n if (this.scrollBehavior === 'collapse' && this.variant === 'expanded') {\n if (this._collapseDistance <= 0) return;\n\n const distance = this._collapseDistance;\n let progress = Math.min(Math.max(scrollTop / distance, 0), 1);\n if (this._reducedMotion?.matches) {\n progress = scrollTop > this.scrollThreshold ? 1 : 0;\n } else {\n progress = progress >= 0.999 ? 1 : progress;\n }\n this._setCollapseProgress(progress);\n } else {\n this._setCollapseProgress(0);\n }\n\n if (this.scrollBehavior === 'hide') {\n if (scrollTop <= this.scrollThreshold || delta < 0) {\n this._setHidden(false);\n } else if (delta > 0) {\n this._setHidden(true);\n }\n } else {\n this._setHidden(false);\n }\n }\n\n private _syncVisualState(): void {\n if (this._scrolled === undefined) {\n if (this.scrollBehavior !== 'collapse' || this.variant !== 'expanded') {\n this._setCollapseProgress(0);\n }\n if (this.scrollBehavior !== 'hide') this._setHidden(false);\n\n return;\n }\n\n const collapse = this.variant === 'expanded' && this.scrollBehavior === 'collapse';\n this._setCollapseProgress(collapse && this.scrolled ? 1 : 0);\n this._setHidden(false);\n }\n\n private _setCollapseProgress(progress: number): void {\n this._collapseProgress = progress;\n this.style.setProperty('--rc-app-bar-collapse-progress', `${progress}`);\n this._applyCollapseGeometry();\n\n const collapsed = progress >= 1;\n if (collapsed === this._collapsed) return;\n\n this._collapsed = collapsed;\n this.toggleAttribute('data-collapsed', collapsed);\n this._setCustomState('collapsed', collapsed);\n this._measureLayout();\n }\n\n private _applyCollapseGeometry(): void {\n const offset = this._collapseOffsetDistance * this._collapseProgress;\n const remainingRow = this._collapseDistance * (1 - this._collapseProgress);\n\n this._setGeometryProperty('--_rc-app-bar-collapse-offset', `${-offset}px`);\n this._setGeometryProperty('--_rc-app-bar-expanded-size', `${remainingRow}px`);\n this._setGeometryProperty('--_rc-app-bar-expanded-opacity', `${1 - this._collapseProgress}`);\n }\n\n private _setGeometryProperty(name: string, value: string): void {\n if (this.style.getPropertyValue(name) === value) return;\n\n this.style.setProperty(name, value);\n }\n\n private _setHidden(hidden: boolean): void {\n if (hidden === this._hidden) return;\n\n this._hidden = hidden;\n this.toggleAttribute('data-hidden', hidden);\n this._setCustomState('hidden', hidden);\n }\n\n private _syncStateOutputs(): void {\n this.toggleAttribute('data-scrolled', this.scrolled);\n this._setCustomState('scrolled', this.scrolled);\n this.toggleAttribute('data-collapsed', this._collapsed);\n this.toggleAttribute('data-hidden', this._hidden);\n }\n\n private _setCustomState(name: string, active: boolean): void {\n if (!this._internals.states) return;\n\n if (active) {\n this._internals.states.add(name);\n } else {\n this._internals.states.delete(name);\n }\n }\n\n private _onSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n const hasContent = slot.assignedElements({ flatten: true }).length > 0;\n\n switch (slot.name) {\n case 'leading':\n this._hasLeading = hasContent;\n break;\n\n case 'center':\n this._hasCenter = hasContent;\n break;\n\n case 'trailing':\n this._hasTrailing = hasContent;\n break;\n }\n\n queueMicrotask(() => this._measureLayout());\n }\n\n protected override render() {\n return html`\n <div id=\"root\" part=\"root\" data-has-center=${this._hasCenter ? '' : nothing}>\n <div id=\"leading\" part=\"leading\" class=${classMap({ empty: !this._hasLeading })}>\n <slot name=\"leading\" @slotchange=${this._onSlotChange}></slot>\n </div>\n <div id=\"title\" part=\"title\">\n <slot @slotchange=${this._onSlotChange}></slot>\n </div>\n <div id=\"center\" part=\"center\" class=${classMap({ empty: !this._hasCenter })}>\n <slot name=\"center\" @slotchange=${this._onSlotChange}></slot>\n </div>\n <div id=\"trailing\" part=\"trailing\" class=${classMap({ empty: !this._hasTrailing })}>\n <slot name=\"trailing\" @slotchange=${this._onSlotChange}></slot>\n </div>\n <div id=\"scroll-shadow\" part=\"scroll-shadow\"></div>\n </div>\n `;\n }\n}\n\nexport default RCAppBar;\n"],"names":["appBarStyles","css","_RCAppBar","LitElement","RafScheduler","ScrollObserverController","scrolled","scrollTop","delta","value","oldValue","changed","selector","element","leading","title","trailing","edgeSize","nextDistance","titleStyle","padding","contentHeight","compactHeight","endpointCompactHeight","target","distance","progress","collapse","collapsed","offset","remainingRow","name","hidden","active","slot","hasContent","html","nothing","classMap","RCAppBar","__decorateClass","property","state"],"mappings":"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"}
|
package/dist/rc-app-bar.js
CHANGED
|
@@ -12,7 +12,8 @@ export interface RCAppBarScrollDetail {
|
|
|
12
12
|
scrolled: boolean;
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
15
|
+
* App bar modeled after the Material 3 Top app bar, with leading, title, center, trailing
|
|
16
|
+
* regions and optional scroll behavior.
|
|
16
17
|
*
|
|
17
18
|
* The element carries no landmark role. Consumers provide all controls and
|
|
18
19
|
* icons, and wrap page-level instances in `<header>` when a banner landmark is
|
|
@@ -23,6 +24,9 @@ export interface RCAppBarScrollDetail {
|
|
|
23
24
|
* Controlled: assign `scrolled`; assigning `undefined` releases observation.
|
|
24
25
|
* Host writes are silent.
|
|
25
26
|
*
|
|
27
|
+
* @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-app-bar rc-app-bar docs}
|
|
28
|
+
* @see {@link https://m3.material.io/components/top-app-bar/overview Material 3 Top app bar}
|
|
29
|
+
*
|
|
26
30
|
* @slot leading - Leading navigation or controls; accepts multiple children
|
|
27
31
|
* @slot - The single title region; may contain title and subtitle markup
|
|
28
32
|
* @slot center - Content kept at the exact horizontal center, such as search
|
|
@@ -73,6 +77,7 @@ export declare class RCAppBar extends LitElement {
|
|
|
73
77
|
private readonly _reducedMotion;
|
|
74
78
|
private _internals;
|
|
75
79
|
private _resizeObserver;
|
|
80
|
+
private readonly _layoutMeasure;
|
|
76
81
|
private readonly _scroll;
|
|
77
82
|
/**
|
|
78
83
|
* Whether the bar is past its scroll threshold. Host writes are silent and
|
|
@@ -90,12 +95,15 @@ export declare class RCAppBar extends LitElement {
|
|
|
90
95
|
private _connectResizeObserver;
|
|
91
96
|
private _observeLayout;
|
|
92
97
|
private _measureLayout;
|
|
98
|
+
private _queueLayoutMeasure;
|
|
99
|
+
private _cancelQueuedLayoutMeasure;
|
|
93
100
|
private _syncScrollObserver;
|
|
94
101
|
private _resolveScrollTarget;
|
|
95
102
|
private _onObservedScroll;
|
|
96
103
|
private _syncVisualState;
|
|
97
104
|
private _setCollapseProgress;
|
|
98
105
|
private _applyCollapseGeometry;
|
|
106
|
+
private _setGeometryProperty;
|
|
99
107
|
private _setHidden;
|
|
100
108
|
private _syncStateOutputs;
|
|
101
109
|
private _setCustomState;
|
package/package.json
CHANGED
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.
|
|
7
|
-
"description": "
|
|
6
|
+
"version": "0.3.0",
|
|
7
|
+
"description": "App bar modeled after the Material 3 Top app bar, with leading, title, center, trailing regions and optional scroll behavior.",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
10
10
|
"url": "git+https://github.com/richardcarls/rc-webcomponents.git",
|
|
11
11
|
"directory": "packages/rc-app-bar"
|
|
12
12
|
},
|
|
13
|
-
"homepage": "https://github.
|
|
13
|
+
"homepage": "https://richardcarls.github.io/rc-webcomponents/components/rc-app-bar",
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"type": "module",
|
|
16
16
|
"files": [
|
|
@@ -37,22 +37,19 @@
|
|
|
37
37
|
],
|
|
38
38
|
"customElements": "dist/custom-elements.json",
|
|
39
39
|
"scripts": {
|
|
40
|
-
"dev": "vite",
|
|
41
40
|
"build": "tsc && vite build && cem analyze",
|
|
42
41
|
"cem:analyze": "cem analyze",
|
|
43
42
|
"preview": "vite preview",
|
|
44
|
-
"test:browser": "vitest",
|
|
45
|
-
"test:browser:chrome": "vitest --project=chromium",
|
|
46
|
-
"test:browser:firefox": "vitest --project=firefox"
|
|
47
|
-
"yalc:publish": "yalc publish --push"
|
|
43
|
+
"test:browser": "vitest --run",
|
|
44
|
+
"test:browser:chrome": "vitest --run --project=chromium",
|
|
45
|
+
"test:browser:firefox": "vitest --run --project=firefox"
|
|
48
46
|
},
|
|
49
47
|
"dependencies": {
|
|
50
|
-
"@rcarls/rc-common": "workspace
|
|
48
|
+
"@rcarls/rc-common": "workspace:*"
|
|
51
49
|
},
|
|
52
50
|
"devDependencies": {
|
|
53
51
|
"@custom-elements-manifest/analyzer": "0.11.0",
|
|
54
|
-
"@
|
|
55
|
-
"@rcarls/rc-search-bar": "workspace:^",
|
|
52
|
+
"@rcarls/rc-search-bar": "workspace:*",
|
|
56
53
|
"@vitest/browser-playwright": "4.1.5",
|
|
57
54
|
"lit": "^3.0.0",
|
|
58
55
|
"playwright": "^1.56.0",
|
package/dist/demo.css
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
*, *::before, *::after {
|
|
2
|
-
box-sizing: border-box;
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
:root {
|
|
6
|
-
color-scheme: light dark;
|
|
7
|
-
--rc-accent: Highlight; /* Chrome doesn't support AccentColor on the open web */
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
@supports (color: AccentColor) {
|
|
11
|
-
:root {
|
|
12
|
-
--rc-accent: AccentColor;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
[data-theme="light"] { color-scheme: light; }
|
|
17
|
-
[data-theme="dark"] { color-scheme: dark; }
|
|
18
|
-
|
|
19
|
-
[data-theme="solarized-light"] {
|
|
20
|
-
color-scheme: light;
|
|
21
|
-
--rc-surface: #fdf6e3;
|
|
22
|
-
--rc-text: #657b83;
|
|
23
|
-
--rc-border: 1px solid #93a1a1;
|
|
24
|
-
--rc-shadow: 0 2px 8px rgba(0, 0, 0, .12);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
[data-theme="solarized-dark"] {
|
|
28
|
-
color-scheme: dark;
|
|
29
|
-
--rc-surface: #002b36;
|
|
30
|
-
--rc-text: #839496;
|
|
31
|
-
--rc-border: 1px solid #586e75;
|
|
32
|
-
--rc-shadow: 0 2px 8px rgba(0, 0, 0, .3);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
body {
|
|
36
|
-
font-family: system-ui, sans-serif;
|
|
37
|
-
margin: 0;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
.demo-page {
|
|
41
|
-
max-width: 60rem;
|
|
42
|
-
margin: 0 auto;
|
|
43
|
-
padding: 2rem 1.5rem;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
.demo-controls {
|
|
47
|
-
display: flex;
|
|
48
|
-
align-items: center;
|
|
49
|
-
gap: 1rem;
|
|
50
|
-
margin-bottom: 2rem;
|
|
51
|
-
padding-bottom: 1rem;
|
|
52
|
-
border-bottom: 1px solid ButtonBorder;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
.demo-controls .demo-title {
|
|
56
|
-
flex: 1;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
.demo-controls h1 {
|
|
60
|
-
margin: 0 0 0.15rem;
|
|
61
|
-
font-size: 1.5rem;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
.demo-controls a {
|
|
65
|
-
font-size: 0.8rem;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
.demo-section {
|
|
69
|
-
margin-bottom: 2rem;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
.demo-section h2 {
|
|
73
|
-
margin: 0 0 0.5rem;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
.theme-picker {
|
|
77
|
-
padding: 0.35em 0.75em;
|
|
78
|
-
font-family: inherit;
|
|
79
|
-
font-size: 0.8rem;
|
|
80
|
-
cursor: pointer;
|
|
81
|
-
border: 1px solid ButtonBorder;
|
|
82
|
-
border-radius: 4px;
|
|
83
|
-
background: Canvas;
|
|
84
|
-
color: CanvasText;
|
|
85
|
-
}
|
package/dist/demo.js
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
const THEMES = ['', 'light', 'dark', 'solarized-light', 'solarized-dark'];
|
|
2
|
-
const LABELS = ['Auto', 'Light', 'Dark', 'Solarized ☀', 'Solarized ☾'];
|
|
3
|
-
|
|
4
|
-
const stored = localStorage.getItem('rc-demo-theme') ?? '';
|
|
5
|
-
applyTheme(stored);
|
|
6
|
-
|
|
7
|
-
function applyTheme(theme) {
|
|
8
|
-
if (theme) {
|
|
9
|
-
document.documentElement.dataset.theme = theme;
|
|
10
|
-
} else {
|
|
11
|
-
delete document.documentElement.dataset.theme;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function currentIndex() {
|
|
16
|
-
const current = document.documentElement.dataset.theme ?? '';
|
|
17
|
-
const idx = THEMES.indexOf(current);
|
|
18
|
-
return idx === -1 ? 0 : idx;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function updateButtons() {
|
|
22
|
-
const label = LABELS[currentIndex()];
|
|
23
|
-
document.querySelectorAll('.theme-picker').forEach((btn) => {
|
|
24
|
-
btn.textContent = label;
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
window.cycleTheme = function () {
|
|
29
|
-
const next = THEMES[(currentIndex() + 1) % THEMES.length];
|
|
30
|
-
applyTheme(next);
|
|
31
|
-
localStorage.setItem('rc-demo-theme', next);
|
|
32
|
-
updateButtons();
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
document.addEventListener('DOMContentLoaded', () => {
|
|
36
|
-
updateButtons();
|
|
37
|
-
document.querySelectorAll('.theme-picker').forEach((btn) => {
|
|
38
|
-
btn.addEventListener('click', window.cycleTheme);
|
|
39
|
-
});
|
|
40
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rc-app-bar-DcYvkEsy.js","sources":["../src/rc-app-bar.styles.ts","../src/rc-app-bar.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const appBarStyles = css`\n :host {\n display: block;\n container-type: inline-size;\n background: var(--rc-app-bar-bg, Canvas);\n color: var(--rc-app-bar-color, CanvasText);\n --_rc-app-bar-collapse-distance: 0px;\n --_rc-app-bar-collapse-offset: 0px;\n --rc-app-bar-collapse-progress: 0;\n --_rc-app-bar-edge-size: 0px;\n --_rc-app-bar-expanded-opacity: 1;\n --_rc-app-bar-expanded-size: 0px;\n transition: translate var(--rc-app-bar-transition-duration, 200ms) ease;\n }\n\n :host([data-hidden]) {\n translate: 0 -100%;\n }\n\n #root {\n display: grid;\n grid-template-columns: auto minmax(0, 1fr) auto;\n grid-template-rows:\n minmax(var(--rc-app-bar-compact-min-height, 3rem), auto)\n 0;\n align-items: center;\n column-gap: var(--rc-app-bar-gap, 0.5em);\n padding-inline: var(--rc-app-bar-padding-inline, 0.75em);\n background: inherit;\n color: inherit;\n }\n\n #root[data-has-center] {\n grid-template-columns:\n var(--_rc-app-bar-edge-size)\n minmax(0, 1fr)\n auto\n minmax(0, 1fr)\n var(--_rc-app-bar-edge-size);\n }\n\n #leading,\n #center,\n #trailing {\n display: flex;\n align-items: center;\n min-inline-size: 0;\n }\n\n #leading {\n grid-column: 1;\n grid-row: 1;\n }\n\n #title {\n grid-column: 2;\n grid-row: 1;\n min-inline-size: 0;\n overflow: clip;\n }\n\n /* Compact-row title: all non-expanded states and the collapsed endpoint. */\n :host(:not([variant='expanded'])) #title ::slotted(*),\n :host([variant='expanded'][data-collapsed]) #title ::slotted(*) {\n font-size: var(--rc-app-bar-title-font-size, inherit);\n }\n\n /* Expanded-row title: only while uncollapsed. */\n :host([variant='expanded']:not([data-collapsed])) #title ::slotted(*) {\n font-size: var(--rc-app-bar-expanded-title-font-size, inherit);\n }\n\n #center {\n grid-column: 2;\n grid-row: 1;\n justify-self: center;\n }\n\n #trailing {\n grid-column: 3;\n grid-row: 1;\n justify-self: end;\n }\n\n #root[data-has-center] #center {\n grid-column: 3;\n }\n\n #root[data-has-center] #trailing {\n grid-column: 5;\n }\n\n .empty {\n visibility: hidden;\n pointer-events: none;\n }\n\n :host([variant='expanded']:not([data-collapsed])) #root {\n grid-template-rows:\n minmax(var(--rc-app-bar-compact-min-height, 3rem), auto)\n var(--_rc-app-bar-expanded-size);\n }\n\n :host([variant='expanded']:not([data-collapsed])) #title {\n grid-column: 1 / -1;\n grid-row: 2;\n align-self: start;\n padding-block: var(--rc-app-bar-expanded-padding-block, 0.75em);\n translate: 0 var(--_rc-app-bar-collapse-offset);\n opacity: var(--_rc-app-bar-expanded-opacity);\n }\n\n :host([variant='expanded'][data-collapsed]) #title {\n animation: rc-app-bar-title-in var(--rc-app-bar-transition-duration, 200ms)\n ease;\n }\n\n #scroll-shadow {\n grid-column: 1 / -1;\n grid-row: 3;\n align-self: end;\n inline-size: calc(100% + 2 * var(--rc-app-bar-padding-inline, 0.75em));\n margin-inline: calc(var(--rc-app-bar-padding-inline, 0.75em) * -1);\n border-block-end: 1px solid transparent;\n }\n\n :host([data-scrolled]) #scroll-shadow {\n border-block-end: var(--rc-app-bar-scroll-divider, 1px solid GrayText);\n }\n\n @keyframes rc-app-bar-title-in {\n from {\n opacity: 0;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n :host,\n :host([variant='expanded'][data-collapsed]) #title {\n transition-duration: 0s;\n animation-duration: 0s;\n }\n }\n\n /*\n * Narrow-viewport fallback for the center-slot layout.\n *\n * The default data-has-center grid forces both outer columns to\n * --_rc-app-bar-edge-size px (= max of leading/trailing widths) so that the\n * center slot stays perfectly symmetric. On screens ≤ 480 px that symmetry\n * can push the total width past the viewport. Below the threshold:\n * - leading and trailing size to their natural content width (auto)\n * - the center slot takes all remaining space (minmax(0, 1fr))\n * - the two inner spacer columns collapse to 0\n *\n * Grid column assignments (1 leading / 2 spacer / 3 center / 4 spacer / 5\n * trailing) are unchanged, so no JS or placement CSS needs to change.\n */\n @container (max-inline-size: 480px) {\n #root[data-has-center] {\n grid-template-columns: auto 0 minmax(0, 1fr) 0 auto;\n }\n\n #root[data-has-center] #center {\n justify-self: stretch;\n justify-content: flex-end;\n }\n }\n`;\n\nexport default appBarStyles;\n","import { LitElement, html, nothing, type PropertyValues } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\n\nimport {\n ScrollObserverController,\n type ScrollObserverTarget,\n} from '@rcarls/rc-common';\n\nimport appBarStyles from './rc-app-bar.styles';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'rc-app-bar': RCAppBar;\n }\n}\n\nexport type RCAppBarVariant = 'compact' | 'expanded';\n\nexport type RCAppBarScrollBehavior = 'pinned' | 'collapse' | 'hide';\n\nexport interface RCAppBarScrollDetail {\n /** Whether the observed scroll target is past the threshold. */\n scrolled: boolean;\n}\n\n/**\n * A headless app bar with leading, title, exact-center, and trailing regions.\n *\n * The element carries no landmark role. Consumers provide all controls and\n * icons, and wrap page-level instances in `<header>` when a banner landmark is\n * appropriate.\n *\n * Scrolled state is dual-mode. Uncontrolled: set `scrollTarget` (or the\n * `scroll-target` selector attribute) and the bar observes the container.\n * Controlled: assign `scrolled`; assigning `undefined` releases observation.\n * Host writes are silent.\n *\n * @slot leading - Leading navigation or controls; accepts multiple children\n * @slot - The single title region; may contain title and subtitle markup\n * @slot center - Content kept at the exact horizontal center, such as search\n * @slot trailing - Trailing action controls\n * @fires rc-app-bar-scroll - When observed scroll state crosses the threshold;\n * `detail: { scrolled }`\n * @cssprop [--rc-app-bar-bg=Canvas] - Bar background\n * @cssprop [--rc-app-bar-color=CanvasText] - Bar text color\n * @cssprop [--rc-app-bar-compact-min-height=3rem] - Compact row minimum height\n * @cssprop [--rc-app-bar-expanded-padding-block=0.75em] - Expanded title padding\n * @cssprop [--rc-app-bar-padding-inline=0.75em] - Horizontal padding\n * @cssprop [--rc-app-bar-gap=0.5em] - Gap between regions\n * @cssprop [--rc-app-bar-transition-duration=200ms] - Endpoint and hide duration\n * @cssprop [--rc-app-bar-scroll-divider=1px solid GrayText] - Scrolled divider\n * @cssprop [--rc-app-bar-collapse-progress=0] - Collapse animation progress 0–1; read-only\n * @cssprop [--rc-app-bar-title-font-size] - Compact-row title font size (opt-in; inherits when unset)\n * @cssprop [--rc-app-bar-expanded-title-font-size] - Expanded-row title font size (opt-in)\n * @csspart root - The grid container\n * @csspart leading - Wrapper around the leading slot\n * @csspart title - Wrapper around the single title slot\n * @csspart center - Wrapper around the centered slot\n * @csspart trailing - Wrapper around the trailing slot\n * @csspart scroll-shadow - Scrolled-state separator\n */\nexport class RCAppBar extends LitElement {\n static styles = [appBarStyles];\n\n /** Structural variant. `expanded` adds a flexible title row. */\n @property({ type: String, reflect: true })\n variant: RCAppBarVariant = 'compact';\n\n /** Visual response to observed scrolling. */\n @property({ type: String, attribute: 'scroll-behavior', reflect: true })\n scrollBehavior: RCAppBarScrollBehavior = 'pinned';\n\n /**\n * Scroll container to observe. The attribute accepts a CSS selector or\n * `window`; the property also accepts an element, document, or window.\n */\n @property({ attribute: 'scroll-target' })\n scrollTarget: ScrollObserverTarget | string | null = null;\n\n /** Scroll offset in px past which the bar is scrolled (strict `>`). */\n @property({ type: Number, attribute: 'scroll-threshold' })\n scrollThreshold = 4;\n\n private _scrolled: boolean | undefined = undefined;\n\n @state()\n private _observedScrolled = false;\n\n @state()\n private _hasLeading = false;\n\n @state()\n private _hasCenter = false;\n\n @state()\n private _hasTrailing = false;\n\n private _collapsed = false;\n\n private _hidden = false;\n\n private _collapseDistance = 0;\n\n private _collapseOffsetDistance = 0;\n\n private _collapseProgress = 0;\n\n private readonly _reducedMotion =\n typeof window !== 'undefined'\n ? window.matchMedia('(prefers-reduced-motion: reduce)')\n : null;\n\n private _internals = this.attachInternals();\n\n private _resizeObserver: ResizeObserver | null = null;\n\n private readonly _scroll = new ScrollObserverController(this, {\n target: () => this._resolveScrollTarget(),\n threshold: this.scrollThreshold,\n disabled: true,\n onChange: (scrolled) => {\n this._observedScrolled = scrolled;\n this._syncVisualState();\n this.dispatchEvent(\n new CustomEvent<RCAppBarScrollDetail>('rc-app-bar-scroll', {\n bubbles: true,\n composed: true,\n detail: { scrolled },\n }),\n );\n },\n onScroll: (scrollTop, delta) => this._onObservedScroll(scrollTop, delta),\n });\n\n /**\n * Whether the bar is past its scroll threshold. Host writes are silent and\n * controlled; assigning `undefined` releases observation.\n */\n @property({ attribute: false })\n get scrolled(): boolean {\n return this._scrolled ?? this._observedScrolled;\n }\n set scrolled(value: boolean | undefined) {\n const oldValue = this.scrolled;\n\n this._scrolled = value;\n this._syncScrollObserver();\n this._syncVisualState();\n this.requestUpdate('scrolled', oldValue);\n }\n\n /** Whether the expanded title row is currently collapsed. */\n get collapsed(): boolean {\n return this._collapsed;\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n this._connectResizeObserver();\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._resizeObserver?.disconnect();\n }\n\n protected override willUpdate(changed: PropertyValues<this>): void {\n if (\n changed.has('scrollTarget') ||\n changed.has('scrollThreshold') ||\n changed.has('scrollBehavior')\n ) {\n this._syncScrollObserver();\n }\n\n if (changed.has('variant') || changed.has('scrollBehavior')) {\n this._syncVisualState();\n }\n }\n\n protected override firstUpdated(): void {\n this._observeLayout();\n this._measureLayout();\n this._syncScrollObserver();\n this._syncVisualState();\n }\n\n protected override updated(changed: PropertyValues): void {\n this._observeLayout();\n if (\n changed.has('variant') ||\n changed.has('_hasLeading') ||\n changed.has('_hasCenter') ||\n changed.has('_hasTrailing')\n ) {\n this._measureLayout();\n }\n this._syncStateOutputs();\n }\n\n private _connectResizeObserver(): void {\n if (!('ResizeObserver' in globalThis)) return;\n\n this._resizeObserver ??= new ResizeObserver(() => this._measureLayout());\n this._observeLayout();\n }\n\n private _observeLayout(): void {\n if (!this._resizeObserver) return;\n\n this._resizeObserver.disconnect();\n ['#leading', '#title', '#center', '#trailing'].forEach((selector) => {\n const element = this.shadowRoot?.querySelector<HTMLElement>(selector);\n if (element) this._resizeObserver?.observe(element);\n });\n }\n\n private _measureLayout(): void {\n const leading = this.shadowRoot?.querySelector<HTMLElement>('#leading');\n const title = this.shadowRoot?.querySelector<HTMLElement>('#title');\n const trailing = this.shadowRoot?.querySelector<HTMLElement>('#trailing');\n if (!leading || !title || !trailing) return;\n\n const edgeSize = Math.max(leading.offsetWidth, trailing.offsetWidth);\n this.style.setProperty('--_rc-app-bar-edge-size', `${edgeSize}px`);\n\n if (this.variant === 'expanded' && !this._collapsed) {\n const nextDistance = title.offsetHeight;\n if (nextDistance > 0) {\n const titleStyle = getComputedStyle(title);\n const padding =\n Number.parseFloat(titleStyle.paddingBlockStart) +\n Number.parseFloat(titleStyle.paddingBlockEnd);\n const contentHeight = Math.max(title.offsetHeight - padding, 0);\n const compactHeight = title.offsetTop;\n const endpointCompactHeight = Math.max(compactHeight, contentHeight);\n\n this._collapseDistance = nextDistance;\n this._collapseOffsetDistance =\n compactHeight - (endpointCompactHeight - contentHeight) / 2;\n this.style.setProperty(\n '--_rc-app-bar-collapse-distance',\n `${nextDistance}px`,\n );\n this._applyCollapseGeometry();\n }\n }\n }\n\n private _syncScrollObserver(): void {\n this._scroll.setOptions({\n threshold: this.scrollThreshold,\n disabled: this._scrolled !== undefined || this._resolveScrollTarget() === null,\n });\n }\n\n private _resolveScrollTarget(): ScrollObserverTarget | null {\n const target = this.scrollTarget;\n if (target === null || target === undefined) return null;\n\n if (typeof target !== 'string') return target;\n if (target === 'window') return window;\n\n try {\n return this.ownerDocument?.querySelector(target) ?? null;\n } catch {\n return null;\n }\n }\n\n private _onObservedScroll(scrollTop: number, delta: number): void {\n if (this._scrolled !== undefined) return;\n\n if (this.scrollBehavior === 'collapse' && this.variant === 'expanded') {\n if (this._collapseDistance <= 0) return;\n\n const distance = this._collapseDistance;\n let progress = Math.min(Math.max(scrollTop / distance, 0), 1);\n if (this._reducedMotion?.matches) {\n progress = scrollTop > this.scrollThreshold ? 1 : 0;\n } else {\n progress = progress >= 0.999 ? 1 : progress;\n }\n this._setCollapseProgress(progress);\n } else {\n this._setCollapseProgress(0);\n }\n\n if (this.scrollBehavior === 'hide') {\n if (scrollTop <= this.scrollThreshold || delta < 0) {\n this._setHidden(false);\n } else if (delta > 0) {\n this._setHidden(true);\n }\n } else {\n this._setHidden(false);\n }\n }\n\n private _syncVisualState(): void {\n if (this._scrolled === undefined) {\n if (this.scrollBehavior !== 'collapse' || this.variant !== 'expanded') {\n this._setCollapseProgress(0);\n }\n if (this.scrollBehavior !== 'hide') this._setHidden(false);\n\n return;\n }\n\n const collapse = this.variant === 'expanded' && this.scrollBehavior === 'collapse';\n this._setCollapseProgress(collapse && this.scrolled ? 1 : 0);\n this._setHidden(false);\n }\n\n private _setCollapseProgress(progress: number): void {\n this._collapseProgress = progress;\n this.style.setProperty('--rc-app-bar-collapse-progress', `${progress}`);\n this._applyCollapseGeometry();\n\n const collapsed = progress >= 1;\n if (collapsed === this._collapsed) return;\n\n this._collapsed = collapsed;\n this.toggleAttribute('data-collapsed', collapsed);\n this._setCustomState('collapsed', collapsed);\n this._measureLayout();\n }\n\n private _applyCollapseGeometry(): void {\n const offset = this._collapseOffsetDistance * this._collapseProgress;\n const remainingRow =\n this._collapseDistance * (1 - this._collapseProgress);\n\n this.style.setProperty('--_rc-app-bar-collapse-offset', `${-offset}px`);\n this.style.setProperty('--_rc-app-bar-expanded-size', `${remainingRow}px`);\n this.style.setProperty(\n '--_rc-app-bar-expanded-opacity',\n `${1 - this._collapseProgress}`,\n );\n }\n\n private _setHidden(hidden: boolean): void {\n if (hidden === this._hidden) return;\n\n this._hidden = hidden;\n this.toggleAttribute('data-hidden', hidden);\n this._setCustomState('hidden', hidden);\n }\n\n private _syncStateOutputs(): void {\n this.toggleAttribute('data-scrolled', this.scrolled);\n this._setCustomState('scrolled', this.scrolled);\n this.toggleAttribute('data-collapsed', this._collapsed);\n this.toggleAttribute('data-hidden', this._hidden);\n }\n\n private _setCustomState(name: string, active: boolean): void {\n if (!this._internals.states) return;\n\n if (active) {\n this._internals.states.add(name);\n } else {\n this._internals.states.delete(name);\n }\n }\n\n private _onSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n const hasContent = slot.assignedElements({ flatten: true }).length > 0;\n\n switch (slot.name) {\n case 'leading':\n this._hasLeading = hasContent;\n break;\n\n case 'center':\n this._hasCenter = hasContent;\n break;\n\n case 'trailing':\n this._hasTrailing = hasContent;\n break;\n }\n\n queueMicrotask(() => this._measureLayout());\n }\n\n protected override render() {\n return html`\n <div\n id=\"root\"\n part=\"root\"\n data-has-center=${this._hasCenter ? '' : nothing}\n >\n <div\n id=\"leading\"\n part=\"leading\"\n class=${classMap({ empty: !this._hasLeading })}\n >\n <slot name=\"leading\" @slotchange=${this._onSlotChange}></slot>\n </div>\n <div id=\"title\" part=\"title\">\n <slot @slotchange=${this._onSlotChange}></slot>\n </div>\n <div\n id=\"center\"\n part=\"center\"\n class=${classMap({ empty: !this._hasCenter })}\n >\n <slot name=\"center\" @slotchange=${this._onSlotChange}></slot>\n </div>\n <div\n id=\"trailing\"\n part=\"trailing\"\n class=${classMap({ empty: !this._hasTrailing })}\n >\n <slot name=\"trailing\" @slotchange=${this._onSlotChange}></slot>\n </div>\n <div id=\"scroll-shadow\" part=\"scroll-shadow\"></div>\n </div>\n `;\n }\n}\n\nexport default RCAppBar;\n"],"names":["appBarStyles","css","_RCAppBar","LitElement","ScrollObserverController","scrolled","scrollTop","delta","value","oldValue","changed","selector","element","leading","title","trailing","edgeSize","nextDistance","titleStyle","padding","contentHeight","compactHeight","endpointCompactHeight","target","distance","progress","collapse","collapsed","offset","remainingRow","hidden","name","active","slot","hasContent","html","nothing","classMap","RCAppBar","__decorateClass","property","state"],"mappings":";;;;AAEO,MAAMA,IAAeC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;AC4DrB,MAAMC,IAAN,MAAMA,UAAiBC,EAAW;AAAA,EAAlC,cAAA;AAAA,UAAA,GAAA,SAAA,GAKL,KAAA,UAA2B,WAI3B,KAAA,iBAAyC,UAOzC,KAAA,eAAqD,MAIrD,KAAA,kBAAkB,GAElB,KAAQ,YAAiC,QAGzC,KAAQ,oBAAoB,IAG5B,KAAQ,cAAc,IAGtB,KAAQ,aAAa,IAGrB,KAAQ,eAAe,IAEvB,KAAQ,aAAa,IAErB,KAAQ,UAAU,IAElB,KAAQ,oBAAoB,GAE5B,KAAQ,0BAA0B,GAElC,KAAQ,oBAAoB,GAE5B,KAAiB,iBACf,OAAO,SAAW,MACd,OAAO,WAAW,kCAAkC,IACpD,MAEN,KAAQ,aAAa,KAAK,gBAAA,GAE1B,KAAQ,kBAAyC,MAEjD,KAAiB,UAAU,IAAIC,EAAyB,MAAM;AAAA,MAC5D,QAAQ,MAAM,KAAK,qBAAA;AAAA,MACnB,WAAW,KAAK;AAAA,MAChB,UAAU;AAAA,MACV,UAAU,CAACC,MAAa;AACtB,aAAK,oBAAoBA,GACzB,KAAK,iBAAA,GACL,KAAK;AAAA,UACH,IAAI,YAAkC,qBAAqB;AAAA,YACzD,SAAS;AAAA,YACT,UAAU;AAAA,YACV,QAAQ,EAAE,UAAAA,EAAA;AAAA,UAAS,CACpB;AAAA,QAAA;AAAA,MAEL;AAAA,MACA,UAAU,CAACC,GAAWC,MAAU,KAAK,kBAAkBD,GAAWC,CAAK;AAAA,IAAA,CACxE;AAAA,EAAA;AAAA,EAOD,IAAI,WAAoB;AACtB,WAAO,KAAK,aAAa,KAAK;AAAA,EAChC;AAAA,EACA,IAAI,SAASC,GAA4B;AACvC,UAAMC,IAAW,KAAK;AAEtB,SAAK,YAAYD,GACjB,KAAK,oBAAA,GACL,KAAK,iBAAA,GACL,KAAK,cAAc,YAAYC,CAAQ;AAAA,EACzC;AAAA;AAAA,EAGA,IAAI,YAAqB;AACvB,WAAO,KAAK;AAAA,EACd;AAAA,EAES,oBAA0B;AACjC,UAAM,kBAAA,GACN,KAAK,uBAAA;AAAA,EACP;AAAA,EAES,uBAA6B;AACpC,UAAM,qBAAA,GACN,KAAK,iBAAiB,WAAA;AAAA,EACxB;AAAA,EAEmB,WAAWC,GAAqC;AACjE,KACEA,EAAQ,IAAI,cAAc,KAC1BA,EAAQ,IAAI,iBAAiB,KAC7BA,EAAQ,IAAI,gBAAgB,MAE5B,KAAK,oBAAA,IAGHA,EAAQ,IAAI,SAAS,KAAKA,EAAQ,IAAI,gBAAgB,MACxD,KAAK,iBAAA;AAAA,EAET;AAAA,EAEmB,eAAqB;AACtC,SAAK,eAAA,GACL,KAAK,eAAA,GACL,KAAK,oBAAA,GACL,KAAK,iBAAA;AAAA,EACP;AAAA,EAEmB,QAAQA,GAA+B;AACxD,SAAK,eAAA,IAEHA,EAAQ,IAAI,SAAS,KACrBA,EAAQ,IAAI,aAAa,KACzBA,EAAQ,IAAI,YAAY,KACxBA,EAAQ,IAAI,cAAc,MAE1B,KAAK,eAAA,GAEP,KAAK,kBAAA;AAAA,EACP;AAAA,EAEQ,yBAA+B;AACrC,IAAM,oBAAoB,eAE1B,KAAK,oBAAoB,IAAI,eAAe,MAAM,KAAK,gBAAgB,GACvE,KAAK,eAAA;AAAA,EACP;AAAA,EAEQ,iBAAuB;AAC7B,IAAK,KAAK,oBAEV,KAAK,gBAAgB,WAAA,GACrB,CAAC,YAAY,UAAU,WAAW,WAAW,EAAE,QAAQ,CAACC,MAAa;AACnE,YAAMC,IAAU,KAAK,YAAY,cAA2BD,CAAQ;AACpE,MAAIC,KAAS,KAAK,iBAAiB,QAAQA,CAAO;AAAA,IACpD,CAAC;AAAA,EACH;AAAA,EAEQ,iBAAuB;AAC7B,UAAMC,IAAU,KAAK,YAAY,cAA2B,UAAU,GAChEC,IAAQ,KAAK,YAAY,cAA2B,QAAQ,GAC5DC,IAAW,KAAK,YAAY,cAA2B,WAAW;AACxE,QAAI,CAACF,KAAW,CAACC,KAAS,CAACC,EAAU;AAErC,UAAMC,IAAW,KAAK,IAAIH,EAAQ,aAAaE,EAAS,WAAW;AAGnE,QAFA,KAAK,MAAM,YAAY,2BAA2B,GAAGC,CAAQ,IAAI,GAE7D,KAAK,YAAY,cAAc,CAAC,KAAK,YAAY;AACnD,YAAMC,IAAeH,EAAM;AAC3B,UAAIG,IAAe,GAAG;AACpB,cAAMC,IAAa,iBAAiBJ,CAAK,GACnCK,IACJ,OAAO,WAAWD,EAAW,iBAAiB,IAC9C,OAAO,WAAWA,EAAW,eAAe,GACxCE,IAAgB,KAAK,IAAIN,EAAM,eAAeK,GAAS,CAAC,GACxDE,IAAgBP,EAAM,WACtBQ,IAAwB,KAAK,IAAID,GAAeD,CAAa;AAEnE,aAAK,oBAAoBH,GACzB,KAAK,0BACHI,KAAiBC,IAAwBF,KAAiB,GAC5D,KAAK,MAAM;AAAA,UACT;AAAA,UACA,GAAGH,CAAY;AAAA,QAAA,GAEjB,KAAK,uBAAA;AAAA,MACP;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,sBAA4B;AAClC,SAAK,QAAQ,WAAW;AAAA,MACtB,WAAW,KAAK;AAAA,MAChB,UAAU,KAAK,cAAc,UAAa,KAAK,2BAA2B;AAAA,IAAA,CAC3E;AAAA,EACH;AAAA,EAEQ,uBAAoD;AAC1D,UAAMM,IAAS,KAAK;AACpB,QAAIA,KAAW,KAA8B,QAAO;AAEpD,QAAI,OAAOA,KAAW,SAAU,QAAOA;AACvC,QAAIA,MAAW,SAAU,QAAO;AAEhC,QAAI;AACF,aAAO,KAAK,eAAe,cAAcA,CAAM,KAAK;AAAA,IACtD,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEQ,kBAAkBjB,GAAmBC,GAAqB;AAChE,QAAI,KAAK,cAAc,QAEvB;AAAA,UAAI,KAAK,mBAAmB,cAAc,KAAK,YAAY,YAAY;AACrE,YAAI,KAAK,qBAAqB,EAAG;AAEjC,cAAMiB,IAAW,KAAK;AACtB,YAAIC,IAAW,KAAK,IAAI,KAAK,IAAInB,IAAYkB,GAAU,CAAC,GAAG,CAAC;AAC5D,QAAI,KAAK,gBAAgB,UACvBC,IAAWnB,IAAY,KAAK,kBAAkB,IAAI,IAElDmB,IAAWA,KAAY,QAAQ,IAAIA,GAErC,KAAK,qBAAqBA,CAAQ;AAAA,MACpC;AACE,aAAK,qBAAqB,CAAC;AAG7B,MAAI,KAAK,mBAAmB,SACtBnB,KAAa,KAAK,mBAAmBC,IAAQ,IAC/C,KAAK,WAAW,EAAK,IACZA,IAAQ,KACjB,KAAK,WAAW,EAAI,IAGtB,KAAK,WAAW,EAAK;AAAA;AAAA,EAEzB;AAAA,EAEQ,mBAAyB;AAC/B,QAAI,KAAK,cAAc,QAAW;AAChC,OAAI,KAAK,mBAAmB,cAAc,KAAK,YAAY,eACzD,KAAK,qBAAqB,CAAC,GAEzB,KAAK,mBAAmB,UAAQ,KAAK,WAAW,EAAK;AAEzD;AAAA,IACF;AAEA,UAAMmB,IAAW,KAAK,YAAY,cAAc,KAAK,mBAAmB;AACxE,SAAK,qBAAqBA,KAAY,KAAK,WAAW,IAAI,CAAC,GAC3D,KAAK,WAAW,EAAK;AAAA,EACvB;AAAA,EAEQ,qBAAqBD,GAAwB;AACnD,SAAK,oBAAoBA,GACzB,KAAK,MAAM,YAAY,kCAAkC,GAAGA,CAAQ,EAAE,GACtE,KAAK,uBAAA;AAEL,UAAME,IAAYF,KAAY;AAC9B,IAAIE,MAAc,KAAK,eAEvB,KAAK,aAAaA,GAClB,KAAK,gBAAgB,kBAAkBA,CAAS,GAChD,KAAK,gBAAgB,aAAaA,CAAS,GAC3C,KAAK,eAAA;AAAA,EACP;AAAA,EAEQ,yBAA+B;AACrC,UAAMC,IAAS,KAAK,0BAA0B,KAAK,mBAC7CC,IACJ,KAAK,qBAAqB,IAAI,KAAK;AAErC,SAAK,MAAM,YAAY,iCAAiC,GAAG,CAACD,CAAM,IAAI,GACtE,KAAK,MAAM,YAAY,+BAA+B,GAAGC,CAAY,IAAI,GACzE,KAAK,MAAM;AAAA,MACT;AAAA,MACA,GAAG,IAAI,KAAK,iBAAiB;AAAA,IAAA;AAAA,EAEjC;AAAA,EAEQ,WAAWC,GAAuB;AACxC,IAAIA,MAAW,KAAK,YAEpB,KAAK,UAAUA,GACf,KAAK,gBAAgB,eAAeA,CAAM,GAC1C,KAAK,gBAAgB,UAAUA,CAAM;AAAA,EACvC;AAAA,EAEQ,oBAA0B;AAChC,SAAK,gBAAgB,iBAAiB,KAAK,QAAQ,GACnD,KAAK,gBAAgB,YAAY,KAAK,QAAQ,GAC9C,KAAK,gBAAgB,kBAAkB,KAAK,UAAU,GACtD,KAAK,gBAAgB,eAAe,KAAK,OAAO;AAAA,EAClD;AAAA,EAEQ,gBAAgBC,GAAcC,GAAuB;AAC3D,IAAK,KAAK,WAAW,WAEjBA,IACF,KAAK,WAAW,OAAO,IAAID,CAAI,IAE/B,KAAK,WAAW,OAAO,OAAOA,CAAI;AAAA,EAEtC;AAAA,EAEQ,cAAc,GAAgB;AACpC,UAAME,IAAO,EAAE,QACTC,IAAaD,EAAK,iBAAiB,EAAE,SAAS,GAAA,CAAM,EAAE,SAAS;AAErE,YAAQA,EAAK,MAAA;AAAA,MACX,KAAK;AACH,aAAK,cAAcC;AACnB;AAAA,MAEF,KAAK;AACH,aAAK,aAAaA;AAClB;AAAA,MAEF,KAAK;AACH,aAAK,eAAeA;AACpB;AAAA,IAAA;AAGJ,mBAAe,MAAM,KAAK,gBAAgB;AAAA,EAC5C;AAAA,EAEmB,SAAS;AAC1B,WAAOC;AAAA;AAAA;AAAA;AAAA,0BAIe,KAAK,aAAa,KAAKC,CAAO;AAAA;AAAA;AAAA;AAAA;AAAA,kBAKtCC,EAAS,EAAE,OAAO,CAAC,KAAK,YAAA,CAAa,CAAC;AAAA;AAAA,6CAEX,KAAK,aAAa;AAAA;AAAA;AAAA,8BAGjC,KAAK,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA,kBAK9BA,EAAS,EAAE,OAAO,CAAC,KAAK,WAAA,CAAY,CAAC;AAAA;AAAA,4CAEX,KAAK,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA,kBAK5CA,EAAS,EAAE,OAAO,CAAC,KAAK,aAAA,CAAc,CAAC;AAAA;AAAA,8CAEX,KAAK,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA,EAK9D;AACF;AAxWEnC,EAAO,SAAS,CAACF,CAAY;AADxB,IAAMsC,IAANpC;AAKLqC,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GAJ9BF,EAKX,WAAA,WAAA,CAAA;AAIAC,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,WAAW,mBAAmB,SAAS,IAAM;AAAA,GAR5DF,EASX,WAAA,kBAAA,CAAA;AAOAC,EAAA;AAAA,EADCC,EAAS,EAAE,WAAW,gBAAA,CAAiB;AAAA,GAf7BF,EAgBX,WAAA,gBAAA,CAAA;AAIAC,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,WAAW,oBAAoB;AAAA,GAnB9CF,EAoBX,WAAA,mBAAA,CAAA;AAKQC,EAAA;AAAA,EADPE,EAAA;AAAM,GAxBIH,EAyBH,WAAA,qBAAA,CAAA;AAGAC,EAAA;AAAA,EADPE,EAAA;AAAM,GA3BIH,EA4BH,WAAA,eAAA,CAAA;AAGAC,EAAA;AAAA,EADPE,EAAA;AAAM,GA9BIH,EA+BH,WAAA,cAAA,CAAA;AAGAC,EAAA;AAAA,EADPE,EAAA;AAAM,GAjCIH,EAkCH,WAAA,gBAAA,CAAA;AA4CJC,EAAA;AAAA,EADHC,EAAS,EAAE,WAAW,GAAA,CAAO;AAAA,GA7EnBF,EA8EP,WAAA,YAAA,CAAA;"}
|