@timmo001/groundwork-ui 0.9.26 → 0.9.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/custom-elements.json +14 -2
- package/package.json +1 -1
- package/src/gw-app-bar.ts +39 -19
package/custom-elements.json
CHANGED
|
@@ -1485,7 +1485,7 @@
|
|
|
1485
1485
|
"declarations": [
|
|
1486
1486
|
{
|
|
1487
1487
|
"kind": "class",
|
|
1488
|
-
"description": "A site or app header pinned to the top of the page, with a brand, nav\nlinks and actions, full width with its content kept to the content width.\nIt's transparent at first, then gets a blurred surface and a bottom border\nonce the page scrolls, or once the element\n`reveal-after` names scrolls out of view, such as a hero. With\n`reveal-after` the brand stays hidden, taking no room, until then, so a\nlarge logo in the hero hands over to the small one in the bar. The nav\nslides over as it opens.\n\n`overlay` lays it over the top of the page rather than taking room, for a\npage that opens with a hero. Below `menu-below`, 600px wide by default,\nthe nav moves into a menu opened from a button, which closes on Esc, a\nclick outside or a link. Raise it when the nav and actions need more room.",
|
|
1488
|
+
"description": "A site or app header pinned to the top of the page, with a brand, nav\nlinks and actions, full width with its content kept to the content width.\nIt's transparent at first, then gets a blurred surface and a bottom border\nonce the page scrolls, or once the element\n`reveal-after` names scrolls out of view, such as a hero. With\n`reveal-after` the brand stays hidden, taking no room, until then, so a\nlarge logo in the hero hands over to the small one in the bar. The nav\nslides over as it opens.\n\n`overlay` lays it over the top of the page rather than taking room, for a\npage that opens with a hero. Below `menu-below`, 600px wide by default,\nthe nav moves into a menu opened from a button, which closes on Esc, a\nclick outside or a link. Raise it when the nav and actions need more room.\nWith no nav links there's no menu button, so a bar of only a brand and\nactions keeps its layout at every width.",
|
|
1489
1489
|
"name": "GwAppBar",
|
|
1490
1490
|
"cssParts": [
|
|
1491
1491
|
{
|
|
@@ -1540,7 +1540,7 @@
|
|
|
1540
1540
|
"text": "readonly CSSStyleSheet[]"
|
|
1541
1541
|
},
|
|
1542
1542
|
"static": true,
|
|
1543
|
-
"default": "[ base, css` :host { position: sticky; inset-block-start: 0; z-index: 50; display: block; } :host([overlay]) { position: fixed; inset-inline: 0; } .bar { position: relative; display: flex; gap: var(--gw-space-3); align-items: center; min-height: 3.5rem; padding: var(--gw-space-1) max(var(--gw-space-3), (100% - var(--gw-content-width)) / 2); border-block-end: max(var(--gw-border-width), 1px) solid transparent; transition: background-color var(--gw-motion-normal) var(--gw-motion-easing), border-color var(--gw-motion-normal) var(--gw-motion-easing), backdrop-filter var(--gw-motion-normal) var(--gw-motion-easing); } :host([floating]) .bar, :host([menu-open]) .bar { background: color-mix( in oklab, var(--gw-color-surface-default) 82%, transparent ); border-color: var(--gw-color-border-quiet); backdrop-filter: blur(12px) saturate(1.4); } /* A one-column grid, so a hidden brand can fold its width to nothing and the nav slides over as it opens, rather than leaving a gap */ .brand { display: grid; flex: none; grid-template-columns: 1fr; align-items: center; transition: grid-template-columns var(--gw-motion-slow) var(--gw-motion-easing), margin var(--gw-motion-slow) var(--gw-motion-easing), opacity var(--gw-motion-normal) var(--gw-motion-easing), translate var(--gw-motion-normal) var(--gw-motion-easing); } .brand > slot { display: flex; align-items: center; min-width: 0; overflow: clip; overflow-clip-margin: calc( var(--gw-focus-width) + var(--gw-focus-offset) ); } :host([reveal-after]:not([floating])) .brand { grid-template-columns: 0fr; margin-inline-end: calc(var(--gw-space-3) * -1); pointer-events: none; visibility: hidden; opacity: 0; translate: 0 -0.25rem; transition: grid-template-columns var(--gw-motion-slow) var(--gw-motion-easing), margin var(--gw-motion-slow) var(--gw-motion-easing), opacity var(--gw-motion-normal) var(--gw-motion-easing), translate var(--gw-motion-normal) var(--gw-motion-easing), visibility var(--gw-motion-slow) allow-discrete; } /* The nav keeps its room; the actions take the rest, which a theme picker fills or gives up by moving its controls into its popover */ .nav { display: flex; flex: none; gap: var(--gw-space-1); align-items: center; min-width: 0; } .actions { display: flex; flex: 1 1 auto; gap: var(--gw-space-1); align-items: center; justify-content: flex-end; } .menu { display: none; place-items: center; width: 2.5rem; height: 2.5rem; padding: 0; color: var(--gw-color-text-strong); cursor: pointer; background: none; border: 0; border-radius: var(--gw-radius-pill); transition: background-color var(--gw-motion-fast) var(--gw-motion-easing); } .menu:hover { background: var(--gw-color-fill-neutral-hovered); } /* Below menu-below, which sets collapsed, the nav folds into a menu */ :host([collapsed]) .menu { display: inline-grid; } :host([collapsed]) .nav { position: absolute; inset-block-start: 100%; inset-inline: 0; flex-direction: column; gap: var(--gw-space-0-5); align-items: stretch; padding: var(--gw-space-2) max(var(--gw-space-3), (100% - var(--gw-content-width)) / 2); visibility: hidden; background: var(--gw-color-surface-default); border-block-end: max(var(--gw-border-width), 1px) solid var(--gw-color-border-quiet); box-shadow: var(--gw-shadow-m); opacity: 0; translate: 0 -0.5rem; transition: opacity var(--gw-motion-fast) var(--gw-motion-easing), translate var(--gw-motion-normal) var(--gw-motion-easing), visibility var(--gw-motion-normal) allow-discrete; } :host([collapsed][menu-open]) .nav { visibility: visible; opacity: 1; translate: 0 0; } `, ]",
|
|
1543
|
+
"default": "[ base, css` :host { position: sticky; inset-block-start: 0; z-index: 50; display: block; } :host([overlay]) { position: fixed; inset-inline: 0; } .bar { position: relative; display: flex; gap: var(--gw-space-3); align-items: center; min-height: 3.5rem; padding: var(--gw-space-1) max(var(--gw-space-3), (100% - var(--gw-content-width)) / 2); border-block-end: max(var(--gw-border-width), 1px) solid transparent; transition: background-color var(--gw-motion-normal) var(--gw-motion-easing), border-color var(--gw-motion-normal) var(--gw-motion-easing), backdrop-filter var(--gw-motion-normal) var(--gw-motion-easing); } :host([floating]) .bar, :host([menu-open]) .bar { background: color-mix( in oklab, var(--gw-color-surface-default) 82%, transparent ); border-color: var(--gw-color-border-quiet); backdrop-filter: blur(12px) saturate(1.4); } /* A one-column grid, so a hidden brand can fold its width to nothing and the nav slides over as it opens, rather than leaving a gap */ .brand { display: grid; flex: none; grid-template-columns: 1fr; align-items: center; transition: grid-template-columns var(--gw-motion-slow) var(--gw-motion-easing), margin var(--gw-motion-slow) var(--gw-motion-easing), opacity var(--gw-motion-normal) var(--gw-motion-easing), translate var(--gw-motion-normal) var(--gw-motion-easing); } .brand > slot { display: flex; align-items: center; min-width: 0; overflow: clip; overflow-clip-margin: calc( var(--gw-focus-width) + var(--gw-focus-offset) ); } :host([reveal-after]:not([floating])) .brand { grid-template-columns: 0fr; margin-inline-end: calc(var(--gw-space-3) * -1); pointer-events: none; visibility: hidden; opacity: 0; translate: 0 -0.25rem; transition: grid-template-columns var(--gw-motion-slow) var(--gw-motion-easing), margin var(--gw-motion-slow) var(--gw-motion-easing), opacity var(--gw-motion-normal) var(--gw-motion-easing), translate var(--gw-motion-normal) var(--gw-motion-easing), visibility var(--gw-motion-slow) allow-discrete; } /* The nav keeps its room; the actions take the rest, which a theme picker fills or gives up by moving its controls into its popover */ .nav { display: flex; flex: none; gap: var(--gw-space-1); align-items: center; min-width: 0; } .actions { display: flex; flex: 1 1 auto; gap: var(--gw-space-1); align-items: center; justify-content: flex-end; } .menu { display: none; place-items: center; width: 2.5rem; height: 2.5rem; padding: 0; color: var(--gw-color-text-strong); cursor: pointer; background: none; border: 0; border-radius: var(--gw-radius-pill); transition: background-color var(--gw-motion-fast) var(--gw-motion-easing); } .menu:hover { background: var(--gw-color-fill-neutral-hovered); } /* Below menu-below, which sets collapsed, the nav folds into a menu, unless there's no nav to fold */ :host([collapsed]) .bar:not(.no-nav) .menu { display: inline-grid; } .no-nav .nav { display: none; } :host([collapsed]) .nav { position: absolute; inset-block-start: 100%; inset-inline: 0; flex-direction: column; gap: var(--gw-space-0-5); align-items: stretch; padding: var(--gw-space-2) max(var(--gw-space-3), (100% - var(--gw-content-width)) / 2); visibility: hidden; background: var(--gw-color-surface-default); border-block-end: max(var(--gw-border-width), 1px) solid var(--gw-color-border-quiet); box-shadow: var(--gw-shadow-m); opacity: 0; translate: 0 -0.5rem; transition: opacity var(--gw-motion-fast) var(--gw-motion-easing), translate var(--gw-motion-normal) var(--gw-motion-easing), visibility var(--gw-motion-normal) allow-discrete; } :host([collapsed][menu-open]) .nav { visibility: visible; opacity: 1; translate: 0 0; } `, ]",
|
|
1544
1544
|
"inheritedFrom": {
|
|
1545
1545
|
"name": "GwElement",
|
|
1546
1546
|
"module": "src/element.ts"
|
|
@@ -1630,6 +1630,12 @@
|
|
|
1630
1630
|
"privacy": "private",
|
|
1631
1631
|
"readonly": true
|
|
1632
1632
|
},
|
|
1633
|
+
{
|
|
1634
|
+
"kind": "field",
|
|
1635
|
+
"name": "#navSlot",
|
|
1636
|
+
"privacy": "private",
|
|
1637
|
+
"readonly": true
|
|
1638
|
+
},
|
|
1633
1639
|
{
|
|
1634
1640
|
"kind": "field",
|
|
1635
1641
|
"name": "#nav",
|
|
@@ -1639,6 +1645,12 @@
|
|
|
1639
1645
|
},
|
|
1640
1646
|
"readonly": true
|
|
1641
1647
|
},
|
|
1648
|
+
{
|
|
1649
|
+
"kind": "field",
|
|
1650
|
+
"name": "#bar",
|
|
1651
|
+
"privacy": "private",
|
|
1652
|
+
"readonly": true
|
|
1653
|
+
},
|
|
1642
1654
|
{
|
|
1643
1655
|
"kind": "field",
|
|
1644
1656
|
"name": "#observer",
|
package/package.json
CHANGED
package/src/gw-app-bar.ts
CHANGED
|
@@ -27,6 +27,8 @@ const closeIcon =
|
|
|
27
27
|
* page that opens with a hero. Below `menu-below`, 600px wide by default,
|
|
28
28
|
* the nav moves into a menu opened from a button, which closes on Esc, a
|
|
29
29
|
* click outside or a link. Raise it when the nav and actions need more room.
|
|
30
|
+
* With no nav links there's no menu button, so a bar of only a brand and
|
|
31
|
+
* actions keeps its layout at every width.
|
|
30
32
|
*
|
|
31
33
|
* @element gw-app-bar
|
|
32
34
|
* @summary A header pinned to the top, floating once the page scrolls.
|
|
@@ -178,11 +180,16 @@ export class GwAppBar extends GwElement {
|
|
|
178
180
|
background: var(--gw-color-fill-neutral-hovered);
|
|
179
181
|
}
|
|
180
182
|
|
|
181
|
-
/* Below menu-below, which sets collapsed, the nav folds into a menu
|
|
182
|
-
|
|
183
|
+
/* Below menu-below, which sets collapsed, the nav folds into a menu,
|
|
184
|
+
unless there's no nav to fold */
|
|
185
|
+
:host([collapsed]) .bar:not(.no-nav) .menu {
|
|
183
186
|
display: inline-grid;
|
|
184
187
|
}
|
|
185
188
|
|
|
189
|
+
.no-nav .nav {
|
|
190
|
+
display: none;
|
|
191
|
+
}
|
|
192
|
+
|
|
186
193
|
:host([collapsed]) .nav {
|
|
187
194
|
position: absolute;
|
|
188
195
|
inset-block-start: 100%;
|
|
@@ -239,12 +246,16 @@ export class GwAppBar extends GwElement {
|
|
|
239
246
|
this.#menuIcon,
|
|
240
247
|
);
|
|
241
248
|
|
|
249
|
+
readonly #navSlot = h("slot");
|
|
250
|
+
|
|
242
251
|
readonly #nav: HTMLDivElement = h(
|
|
243
252
|
"div",
|
|
244
253
|
{ class: "nav", part: "nav" },
|
|
245
|
-
|
|
254
|
+
this.#navSlot,
|
|
246
255
|
);
|
|
247
256
|
|
|
257
|
+
readonly #bar = h("div", { class: "bar no-nav", part: "bar" });
|
|
258
|
+
|
|
248
259
|
#observer: IntersectionObserver | undefined;
|
|
249
260
|
|
|
250
261
|
#frame = 0;
|
|
@@ -263,8 +274,10 @@ export class GwAppBar extends GwElement {
|
|
|
263
274
|
/** Follows the viewport across `menuBelow`, setting `collapsed`. */
|
|
264
275
|
#watchWidth() {
|
|
265
276
|
this.#narrow?.removeEventListener("change", this.#onNarrow);
|
|
277
|
+
const below = Number(this.menuBelow);
|
|
278
|
+
|
|
266
279
|
this.#narrow = window.matchMedia(
|
|
267
|
-
`(max-width: ${(Number(
|
|
280
|
+
`(max-width: ${(Number.isFinite(below) ? below : 600) - 0.02}px)`,
|
|
268
281
|
);
|
|
269
282
|
this.#narrow.addEventListener("change", this.#onNarrow);
|
|
270
283
|
this.#onNarrow();
|
|
@@ -370,25 +383,32 @@ export class GwAppBar extends GwElement {
|
|
|
370
383
|
}
|
|
371
384
|
});
|
|
372
385
|
|
|
373
|
-
|
|
386
|
+
// Without nav links there's nothing to fold, so no menu button
|
|
387
|
+
this.#navSlot.addEventListener("slotchange", () => {
|
|
388
|
+
this.#bar.classList.toggle(
|
|
389
|
+
"no-nav",
|
|
390
|
+
this.#navSlot
|
|
391
|
+
.assignedNodes()
|
|
392
|
+
.every(
|
|
393
|
+
(node) =>
|
|
394
|
+
node.nodeType === Node.TEXT_NODE &&
|
|
395
|
+
node.textContent?.trim() === "",
|
|
396
|
+
),
|
|
397
|
+
);
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
this.#bar.append(
|
|
401
|
+
// The menu button leads, so a revealed brand opens beside it
|
|
402
|
+
this.#menu,
|
|
403
|
+
h("div", { class: "brand", part: "brand" }, h("slot", { name: "brand" })),
|
|
404
|
+
this.#nav,
|
|
374
405
|
h(
|
|
375
406
|
"div",
|
|
376
|
-
{ class: "
|
|
377
|
-
|
|
378
|
-
this.#menu,
|
|
379
|
-
h(
|
|
380
|
-
"div",
|
|
381
|
-
{ class: "brand", part: "brand" },
|
|
382
|
-
h("slot", { name: "brand" }),
|
|
383
|
-
),
|
|
384
|
-
this.#nav,
|
|
385
|
-
h(
|
|
386
|
-
"div",
|
|
387
|
-
{ class: "actions", part: "actions" },
|
|
388
|
-
h("slot", { name: "actions" }),
|
|
389
|
-
),
|
|
407
|
+
{ class: "actions", part: "actions" },
|
|
408
|
+
h("slot", { name: "actions" }),
|
|
390
409
|
),
|
|
391
410
|
);
|
|
411
|
+
root.append(this.#bar);
|
|
392
412
|
}
|
|
393
413
|
|
|
394
414
|
protected override update(changed: ReadonlySet<string>) {
|