@nextrap/nte-navbar 1.0.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/demo/main.scss +75 -0
- package/index.d.ts +2 -0
- package/index.js +98 -0
- package/index.scss +2 -0
- package/package.json +30 -0
- package/src/components/nte-navbar/nte-navbar.d.ts +22 -0
- package/src/components/nte-navbar/nte-navbar.scss +43 -0
- package/src/components/nte-navbar-line/nte-navbar-line.d.ts +12 -0
- package/src/components/nte-navbar-line/nte-navbar-line.scss +112 -0
- package/src/scss/default-style.scss +105 -0
- package/src/scss/with-btn-compat.scss +18 -0
package/demo/main.scss
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
@use '../index' as navbar;
|
|
2
|
+
|
|
3
|
+
.nte-navbar-demo {
|
|
4
|
+
@include navbar.default-style();
|
|
5
|
+
|
|
6
|
+
display: grid;
|
|
7
|
+
gap: 2rem;
|
|
8
|
+
|
|
9
|
+
nte-navbar {
|
|
10
|
+
border: 1px solid color-mix(in srgb, currentColor 18%, transparent);
|
|
11
|
+
border-radius: 0.75rem;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
nte-navbar-line {
|
|
15
|
+
--background: color-mix(in srgb, Canvas 94%, currentColor);
|
|
16
|
+
padding-inline: 1rem;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.demo-brand {
|
|
20
|
+
color: inherit;
|
|
21
|
+
font-weight: 700;
|
|
22
|
+
text-decoration: none;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.demo-links {
|
|
26
|
+
display: flex;
|
|
27
|
+
gap: 1rem;
|
|
28
|
+
align-items: center;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.demo-links a {
|
|
32
|
+
color: inherit;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.demo-scroll-page {
|
|
37
|
+
@include navbar.default-style();
|
|
38
|
+
|
|
39
|
+
min-height: 220dvh;
|
|
40
|
+
|
|
41
|
+
nte-navbar {
|
|
42
|
+
--nte-navbar-background: Canvas;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
nte-navbar-line {
|
|
46
|
+
padding-inline: 1rem;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.demo-links {
|
|
50
|
+
display: flex;
|
|
51
|
+
gap: 1rem;
|
|
52
|
+
align-items: center;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.demo-scroll-content {
|
|
56
|
+
width: min(100% - 2rem, 72rem);
|
|
57
|
+
margin-inline: auto;
|
|
58
|
+
padding-block: 3rem;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.demo-scroll-spacer {
|
|
62
|
+
min-height: 125dvh;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.demo-offcanvas-nav {
|
|
67
|
+
display: grid;
|
|
68
|
+
gap: 1rem;
|
|
69
|
+
padding: 1rem;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.demo-responsive-content {
|
|
73
|
+
min-height: 60dvh;
|
|
74
|
+
padding: 2rem;
|
|
75
|
+
}
|
package/index.d.ts
ADDED
package/index.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { nextrap_element as k } from "@nextrap/nt-core";
|
|
2
|
+
import { unsafeCSS as S, html as z } from "lit";
|
|
3
|
+
import { customElement as $ } from "lit/decorators.js";
|
|
4
|
+
const N = "*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}html,body{height:100%;width:100%;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}img,picture,video,canvas,svg{display:block;max-width:100%}input,button,textarea,select{font:inherit;color:inherit;background:none;border:none;outline:none}dialog{color:inherit;background:transparent;border:none}a,i{color:inherit;text-decoration:none}ul,ol{list-style:none}table{border-collapse:collapse;border-spacing:0}slot{display:contents}:host{--container-width: var(--nt-container-width, 100%);--nte-navbar-position: static;--nte-navbar-scroll-threshold: 1;--nte-navbar-top: 0;--nte-navbar-background: Canvas;--nte-navbar-background-at-top: var(--nte-navbar-background);--nte-navbar-shadow: 0 .25rem 1rem color-mix(in srgb, currentColor 12%, transparent);--nte-navbar-overlay-offset: 0px;display:block;position:var(--nte-navbar-position);inset-block-start:var(--nte-navbar-top);z-index:var(--nt-navbar-z-index, 10);width:100%;background:var(--nte-navbar-background);transition:background-color .2s ease-in-out,box-shadow .2s ease-in-out}:host(.with-shadow){box-shadow:var(--nte-navbar-shadow)}:host(.with-shadow-on-scroll.is-below-threshold){box-shadow:var(--nte-navbar-shadow)}:host(.with-transparent-at-top:not(.is-below-threshold)){background:transparent;box-shadow:none}:host(.with-overlay-at-top:not(.is-below-threshold)){margin-block-end:calc(-1 * var(--nte-navbar-overlay-offset))}#navbar{display:block;width:100%}";
|
|
5
|
+
var A = Object.create, g = Object.defineProperty, M = Object.getOwnPropertyDescriptor, C = (e, t) => (t = Symbol[e]) ? t : Symbol.for("Symbol." + e), O = (e) => {
|
|
6
|
+
throw TypeError(e);
|
|
7
|
+
}, V = (e, t, r) => t in e ? g(e, t, { enumerable: !0, configurable: !0, writable: !0, value: r }) : e[t] = r, Y = (e, t) => g(e, "name", { value: t, configurable: !0 }), q = (e) => [, , , A((e == null ? void 0 : e[C("metadata")]) ?? null)], B = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"], T = (e) => e !== void 0 && typeof e != "function" ? O("Function expected") : e, U = (e, t, r, n, o) => ({ kind: B[e], name: t, metadata: n, addInitializer: (a) => r._ ? O("Already initialized") : o.push(T(a || null)) }), G = (e, t) => V(t, C("metadata"), e[3]), H = (e, t, r, n) => {
|
|
8
|
+
for (var o = 0, a = e[t >> 1], i = a && a.length; o < i; o++) a[o].call(r);
|
|
9
|
+
return n;
|
|
10
|
+
}, J = (e, t, r, n, o, a) => {
|
|
11
|
+
var i, d, h, s = t & 7, b = !1, v = 0, m = e[v] || (e[v] = []), l = s && (o = o.prototype, s < 5 && (s > 3 || !b) && M(o, r));
|
|
12
|
+
Y(o, r);
|
|
13
|
+
for (var c = n.length - 1; c >= 0; c--)
|
|
14
|
+
h = U(s, r, d = {}, e[3], m), i = (0, n[c])(o, h), d._ = 1, T(i) && (o = i);
|
|
15
|
+
return G(e, o), l && g(o, r, l), b ? s ^ 4 ? a : l : o;
|
|
16
|
+
}, P, _, E;
|
|
17
|
+
P = [$("nte-navbar")];
|
|
18
|
+
const f = class f extends (E = k({})) {
|
|
19
|
+
constructor() {
|
|
20
|
+
super(...arguments), this.scrollThreshold = 1, this.styleObserver = new MutationObserver(() => this.refreshComponentStyle()), this._onScroll = () => this.updateScrollState(), this._onSlotChange = () => this.updateScrollState();
|
|
21
|
+
}
|
|
22
|
+
static get is() {
|
|
23
|
+
return "nte-navbar";
|
|
24
|
+
}
|
|
25
|
+
connectedCallback() {
|
|
26
|
+
super.connectedCallback(), this.styleObserver.observe(this, { attributes: !0, attributeFilter: ["class", "style"] }), window.addEventListener("scroll", this._onScroll, { passive: !0 }), this.refreshComponentStyle();
|
|
27
|
+
}
|
|
28
|
+
disconnectedCallback() {
|
|
29
|
+
this.styleObserver.disconnect(), window.removeEventListener("scroll", this._onScroll), super.disconnectedCallback();
|
|
30
|
+
}
|
|
31
|
+
refreshComponentStyle() {
|
|
32
|
+
const t = this.getComponentStyle();
|
|
33
|
+
this.scrollThreshold = t.scrollThreshold, this.updateScrollState();
|
|
34
|
+
}
|
|
35
|
+
getComponentStyle() {
|
|
36
|
+
const r = getComputedStyle(this).getPropertyValue("--nte-navbar-scroll-threshold").trim(), n = Number.parseFloat(r);
|
|
37
|
+
return {
|
|
38
|
+
scrollThreshold: Number.isFinite(n) ? Math.max(0, n) : 1
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
updateScrollState() {
|
|
42
|
+
const t = Math.max(0, window.scrollY), r = t > 0, n = t > this.scrollThreshold;
|
|
43
|
+
this.classList.toggle("is-scrolled", r), this.classList.toggle("is-below-threshold", n), this.syncLineScrollState(r, n);
|
|
44
|
+
}
|
|
45
|
+
syncLineScrollState(t, r) {
|
|
46
|
+
for (const n of Array.from(this.querySelectorAll("nte-navbar-line")))
|
|
47
|
+
n.classList.toggle("is-navbar-scrolled", t), n.classList.toggle("is-navbar-below-threshold", r);
|
|
48
|
+
}
|
|
49
|
+
render() {
|
|
50
|
+
return z`<div id="navbar" part="navbar"><slot @slotchange=${this._onSlotChange}></slot></div>`;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
f.styles = [S(N)];
|
|
54
|
+
let p = f;
|
|
55
|
+
_ = q(E);
|
|
56
|
+
p = J(_, 0, "NteNavbar", P, p);
|
|
57
|
+
H(_, 1, p);
|
|
58
|
+
const K = "*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}html,body{height:100%;width:100%;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}img,picture,video,canvas,svg{display:block;max-width:100%}input,button,textarea,select{font:inherit;color:inherit;background:none;border:none;outline:none}dialog{color:inherit;background:transparent;border:none}a,i{color:inherit;text-decoration:none}ul,ol{list-style:none}table{border-collapse:collapse;border-spacing:0}slot{display:contents}:host{--height: auto;--height-scrolled: var(--height);--background: transparent;--text-color: var(--nt-text);display:block;position:relative;isolation:isolate;width:100%;block-size:var(--height);max-block-size:var(--height);min-block-size:0;overflow:clip;color:var(--text-color);background:var(--background);transition:block-size .2s ease-in-out,max-block-size .2s ease-in-out,opacity .2s ease-in-out}:host(.with-shrink-on-scroll){max-block-size:var(--height)}:host(.is-navbar-below-threshold.with-shrink-on-scroll){block-size:var(--height-scrolled);max-block-size:var(--height-scrolled)}:host(.with-collapse-on-scroll),:host(.hide-on-scroll){max-block-size:var(--height)}:host(.is-navbar-below-threshold.with-collapse-on-scroll),:host(.is-navbar-below-threshold.hide-on-scroll){block-size:0;max-block-size:0;opacity:0}#line{width:100%;block-size:100%;min-block-size:0}#container{width:min(100%,var(--container-width, var(--nt-container-width, 100%)));block-size:100%;min-block-size:0;margin-inline:auto;display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);align-items:center}.region{min-width:0;min-block-size:0;block-size:100%;display:flex;align-items:center;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.region ::slotted(*){min-width:0;max-width:100%;overflow:hidden;text-overflow:ellipsis}#start{justify-content:flex-start}#center{justify-content:center;justify-self:center}#end{justify-content:flex-end}#container:has(>#center>slot.slot-empty){display:flex;justify-content:space-between}#container:has(>#center>slot.slot-empty) #start,#container:has(>#center>slot.slot-empty) #end{flex:0 1 auto}#container:has(>#center>slot.slot-empty) #center{display:none}.region:has(>slot.slot-empty){visibility:hidden;pointer-events:none}";
|
|
59
|
+
var Q = Object.create, w = Object.defineProperty, R = Object.getOwnPropertyDescriptor, L = (e, t) => (t = Symbol[e]) ? t : Symbol.for("Symbol." + e), j = (e) => {
|
|
60
|
+
throw TypeError(e);
|
|
61
|
+
}, W = (e, t, r) => t in e ? w(e, t, { enumerable: !0, configurable: !0, writable: !0, value: r }) : e[t] = r, X = (e, t) => w(e, "name", { value: t, configurable: !0 }), Z = (e) => [, , , Q((e == null ? void 0 : e[L("metadata")]) ?? null)], ee = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"], F = (e) => e !== void 0 && typeof e != "function" ? j("Function expected") : e, te = (e, t, r, n, o) => ({ kind: ee[e], name: t, metadata: n, addInitializer: (a) => r._ ? j("Already initialized") : o.push(F(a || null)) }), oe = (e, t) => W(t, L("metadata"), e[3]), re = (e, t, r, n) => {
|
|
62
|
+
for (var o = 0, a = e[t >> 1], i = a && a.length; o < i; o++) a[o].call(r);
|
|
63
|
+
return n;
|
|
64
|
+
}, ne = (e, t, r, n, o, a) => {
|
|
65
|
+
var i, d, h, s = t & 7, b = !1, v = 0, m = e[v] || (e[v] = []), l = s && (o = o.prototype, s < 5 && (s > 3 || !b) && R(o, r));
|
|
66
|
+
X(o, r);
|
|
67
|
+
for (var c = n.length - 1; c >= 0; c--)
|
|
68
|
+
h = te(s, r, d = {}, e[3], m), i = (0, n[c])(o, h), d._ = 1, F(i) && (o = i);
|
|
69
|
+
return oe(e, o), l && w(o, r, l), b ? s ^ 4 ? a : l : o;
|
|
70
|
+
}, D, y, I;
|
|
71
|
+
D = [$("nte-navbar-line")];
|
|
72
|
+
const x = class x extends (I = k({ slotVisibility: !0 })) {
|
|
73
|
+
static get is() {
|
|
74
|
+
return "nte-navbar-line";
|
|
75
|
+
}
|
|
76
|
+
render() {
|
|
77
|
+
return z`
|
|
78
|
+
<div id="line" part="line">
|
|
79
|
+
<div id="container" part="container">
|
|
80
|
+
<div id="start" class="region" part="start"><slot name="start"></slot></div>
|
|
81
|
+
<div id="center" class="region" part="center"><slot name="center"></slot></div>
|
|
82
|
+
<div id="end" class="region" part="end"><slot name="end"></slot></div>
|
|
83
|
+
</div>
|
|
84
|
+
</div>
|
|
85
|
+
<!-- Der Default-Slot bleibt als sichtbarer Diagnose-Fallback bestehen; Inhalte darin zeigen einen falschen Slot-Namen an. -->
|
|
86
|
+
<slot NO-DEFAULT-SLOT></slot>
|
|
87
|
+
`;
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
x.styles = [S(K)];
|
|
91
|
+
let u = x;
|
|
92
|
+
y = Z(I);
|
|
93
|
+
u = ne(y, 0, "NteNavbarLine", D, u);
|
|
94
|
+
re(y, 1, u);
|
|
95
|
+
export {
|
|
96
|
+
p as NteNavbar,
|
|
97
|
+
u as NteNavbarLine
|
|
98
|
+
};
|
package/index.scss
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nextrap/nte-navbar",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"files": [
|
|
5
|
+
"*.*",
|
|
6
|
+
"src",
|
|
7
|
+
"demo"
|
|
8
|
+
],
|
|
9
|
+
"main": "./index.js",
|
|
10
|
+
"repository": {
|
|
11
|
+
"directory": "nextrap-elements/nte-navbar",
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "https://github.com/nextrap/nextrap-monorepo"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"@nextrap/nt-core": "^2.0.0",
|
|
17
|
+
"@nextrap/style-reset": "^2.0.0",
|
|
18
|
+
"lit": "^3.3.1",
|
|
19
|
+
"@nextrap/nte-nav": "^2.0.0"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@nextrap/nte-burger": "^2.0.0",
|
|
23
|
+
"@nextrap/nte-nav": "^1.0.0",
|
|
24
|
+
"@nextrap/nte-offcanvas": "^2.0.0",
|
|
25
|
+
"@trunkjs/element-relocator": "^1.0.1",
|
|
26
|
+
"@trunkjs/responsive": "^1.0.11"
|
|
27
|
+
},
|
|
28
|
+
"type": "module",
|
|
29
|
+
"types": "./index.d.ts"
|
|
30
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
declare const NteNavbar_base: import('@nextrap/nt-core').InternalNextrapElementType;
|
|
2
|
+
export declare class NteNavbar extends NteNavbar_base {
|
|
3
|
+
static get is(): string;
|
|
4
|
+
static styles: import('lit').CSSResult[];
|
|
5
|
+
private scrollThreshold;
|
|
6
|
+
private readonly styleObserver;
|
|
7
|
+
private readonly _onScroll;
|
|
8
|
+
private readonly _onSlotChange;
|
|
9
|
+
connectedCallback(): void;
|
|
10
|
+
disconnectedCallback(): void;
|
|
11
|
+
refreshComponentStyle(): void;
|
|
12
|
+
private getComponentStyle;
|
|
13
|
+
private updateScrollState;
|
|
14
|
+
private syncLineScrollState;
|
|
15
|
+
render(): import('lit-html').TemplateResult<1>;
|
|
16
|
+
}
|
|
17
|
+
declare global {
|
|
18
|
+
interface HTMLElementTagNameMap {
|
|
19
|
+
'nte-navbar': NteNavbar;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
@use '@nextrap/style-reset' as reset;
|
|
2
|
+
|
|
3
|
+
@include reset.reset();
|
|
4
|
+
|
|
5
|
+
:host {
|
|
6
|
+
--container-width: var(--nt-container-width, 100%);
|
|
7
|
+
--nte-navbar-position: static;
|
|
8
|
+
--nte-navbar-scroll-threshold: 1;
|
|
9
|
+
--nte-navbar-top: 0;
|
|
10
|
+
--nte-navbar-background: Canvas;
|
|
11
|
+
--nte-navbar-background-at-top: var(--nte-navbar-background);
|
|
12
|
+
--nte-navbar-shadow: 0 0.25rem 1rem color-mix(in srgb, currentColor 12%, transparent);
|
|
13
|
+
--nte-navbar-overlay-offset: 0px;
|
|
14
|
+
display: block;
|
|
15
|
+
position: var(--nte-navbar-position);
|
|
16
|
+
inset-block-start: var(--nte-navbar-top);
|
|
17
|
+
z-index: var(--nt-navbar-z-index, 10);
|
|
18
|
+
width: 100%;
|
|
19
|
+
background: var(--nte-navbar-background);
|
|
20
|
+
transition: background-color 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
:host(.with-shadow) {
|
|
24
|
+
box-shadow: var(--nte-navbar-shadow);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
:host(.with-shadow-on-scroll.is-below-threshold) {
|
|
28
|
+
box-shadow: var(--nte-navbar-shadow);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
:host(.with-transparent-at-top:not(.is-below-threshold)) {
|
|
32
|
+
background: transparent;
|
|
33
|
+
box-shadow: none;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
:host(.with-overlay-at-top:not(.is-below-threshold)) {
|
|
37
|
+
margin-block-end: calc(-1 * var(--nte-navbar-overlay-offset));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
#navbar {
|
|
41
|
+
display: block;
|
|
42
|
+
width: 100%;
|
|
43
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
declare const NteNavbarLine_base: import('@nextrap/nt-core').InternalNextrapElementType;
|
|
2
|
+
export declare class NteNavbarLine extends NteNavbarLine_base {
|
|
3
|
+
static get is(): string;
|
|
4
|
+
static styles: import('lit').CSSResult[];
|
|
5
|
+
render(): import('lit-html').TemplateResult<1>;
|
|
6
|
+
}
|
|
7
|
+
declare global {
|
|
8
|
+
interface HTMLElementTagNameMap {
|
|
9
|
+
'nte-navbar-line': NteNavbarLine;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
@use '@nextrap/style-reset' as reset;
|
|
2
|
+
|
|
3
|
+
@include reset.reset();
|
|
4
|
+
|
|
5
|
+
:host {
|
|
6
|
+
--height: auto;
|
|
7
|
+
--height-scrolled: var(--height);
|
|
8
|
+
--background: transparent;
|
|
9
|
+
--text-color: var(--nt-text);
|
|
10
|
+
display: block;
|
|
11
|
+
position: relative;
|
|
12
|
+
isolation: isolate;
|
|
13
|
+
width: 100%;
|
|
14
|
+
block-size: var(--height);
|
|
15
|
+
max-block-size: var(--height);
|
|
16
|
+
min-block-size: 0;
|
|
17
|
+
overflow: clip;
|
|
18
|
+
color: var(--text-color);
|
|
19
|
+
background: var(--background);
|
|
20
|
+
transition:
|
|
21
|
+
block-size 0.2s ease-in-out,
|
|
22
|
+
max-block-size 0.2s ease-in-out,
|
|
23
|
+
opacity 0.2s ease-in-out;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
:host(.with-shrink-on-scroll) {
|
|
27
|
+
max-block-size: var(--height);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
:host(.is-navbar-below-threshold.with-shrink-on-scroll) {
|
|
31
|
+
block-size: var(--height-scrolled);
|
|
32
|
+
max-block-size: var(--height-scrolled);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
:host(.with-collapse-on-scroll),
|
|
36
|
+
:host(.hide-on-scroll) {
|
|
37
|
+
max-block-size: var(--height);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Collapses opt-in lines when the navbar propagates its configured scroll threshold state.
|
|
41
|
+
:host(.is-navbar-below-threshold.with-collapse-on-scroll),
|
|
42
|
+
:host(.is-navbar-below-threshold.hide-on-scroll) {
|
|
43
|
+
block-size: 0;
|
|
44
|
+
max-block-size: 0;
|
|
45
|
+
opacity: 0;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
#line {
|
|
49
|
+
width: 100%;
|
|
50
|
+
block-size: 100%;
|
|
51
|
+
min-block-size: 0;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
#container {
|
|
55
|
+
width: min(100%, var(--container-width, var(--nt-container-width, 100%)));
|
|
56
|
+
block-size: 100%;
|
|
57
|
+
min-block-size: 0;
|
|
58
|
+
margin-inline: auto;
|
|
59
|
+
display: grid;
|
|
60
|
+
grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
|
|
61
|
+
align-items: center;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.region {
|
|
65
|
+
min-width: 0;
|
|
66
|
+
min-block-size: 0;
|
|
67
|
+
block-size: 100%;
|
|
68
|
+
display: flex;
|
|
69
|
+
align-items: center;
|
|
70
|
+
overflow: hidden;
|
|
71
|
+
text-overflow: ellipsis;
|
|
72
|
+
white-space: nowrap;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.region ::slotted(*) {
|
|
76
|
+
min-width: 0;
|
|
77
|
+
max-width: 100%;
|
|
78
|
+
overflow: hidden;
|
|
79
|
+
text-overflow: ellipsis;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
#start {
|
|
83
|
+
justify-content: flex-start;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
#center {
|
|
87
|
+
justify-content: center;
|
|
88
|
+
justify-self: center;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
#end {
|
|
92
|
+
justify-content: flex-end;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
#container:has(> #center > slot.slot-empty) {
|
|
96
|
+
display: flex;
|
|
97
|
+
justify-content: space-between;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
#container:has(> #center > slot.slot-empty) #start,
|
|
101
|
+
#container:has(> #center > slot.slot-empty) #end {
|
|
102
|
+
flex: 0 1 auto;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
#container:has(> #center > slot.slot-empty) #center {
|
|
106
|
+
display: none;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.region:has(> slot.slot-empty) {
|
|
110
|
+
visibility: hidden;
|
|
111
|
+
pointer-events: none;
|
|
112
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
@use 'with-btn-compat' as btn-compat;
|
|
2
|
+
|
|
3
|
+
// Provides the reusable public default styling mixin for navbar state and utility classes.
|
|
4
|
+
@mixin default-style() {
|
|
5
|
+
// Keeps legacy button controls from touching the navbar line edges.
|
|
6
|
+
@include btn-compat.with-btn-compat();
|
|
7
|
+
|
|
8
|
+
// Animates optional navbar-line size and position changes from public light-DOM state classes.
|
|
9
|
+
nte-navbar-line.with-collapse-on-scroll,
|
|
10
|
+
nte-navbar-line.hide-on-scroll {
|
|
11
|
+
transition:
|
|
12
|
+
block-size 0.2s ease-in-out,
|
|
13
|
+
max-block-size 0.2s ease-in-out,
|
|
14
|
+
opacity 0.2s ease-in-out,
|
|
15
|
+
transform 0.2s ease-in-out;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Slides and collapses the opt-in top line when the parent navbar is scrolled.
|
|
19
|
+
nte-navbar.is-scrolled > nte-navbar-line.with-collapse-on-scroll {
|
|
20
|
+
block-size: 0;
|
|
21
|
+
max-block-size: 0;
|
|
22
|
+
opacity: 0;
|
|
23
|
+
transform: translateY(-100%);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Hides compatibility lines after the configured navbar threshold.
|
|
27
|
+
nte-navbar.is-below-threshold > nte-navbar-line.hide-on-scroll {
|
|
28
|
+
block-size: 0;
|
|
29
|
+
max-block-size: 0;
|
|
30
|
+
opacity: 0;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Aligns the brand logo and its dimensions within a navbar line.
|
|
34
|
+
.brand-logo {
|
|
35
|
+
--nt-navbar-brand-logo-aspect-ratio: 3 / 1;
|
|
36
|
+
|
|
37
|
+
position: relative;
|
|
38
|
+
z-index: var(--nt-navbar-content-z-index, 1);
|
|
39
|
+
display: flex;
|
|
40
|
+
align-items: center;
|
|
41
|
+
block-size: 100%;
|
|
42
|
+
// Safari braucht eine definite Inline-Größe, damit der Flex-Brand-Bereich nicht auf 0px kollabiert.
|
|
43
|
+
inline-size: 200px;
|
|
44
|
+
max-inline-size: 100%;
|
|
45
|
+
aspect-ratio: var(--nt-navbar-brand-logo-aspect-ratio);
|
|
46
|
+
transition:
|
|
47
|
+
inline-size 0.2s ease-in-out,
|
|
48
|
+
block-size 0.2s ease-in-out,
|
|
49
|
+
max-inline-size 0.2s ease-in-out;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.brand-logo[slot='start'] {
|
|
53
|
+
justify-content: flex-start;
|
|
54
|
+
margin-inline-end: auto;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.brand-logo[slot='center'] {
|
|
58
|
+
justify-content: center;
|
|
59
|
+
margin-inline: auto;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.brand-logo[slot='end'] {
|
|
63
|
+
justify-content: flex-end;
|
|
64
|
+
margin-inline-start: auto;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Reserves an inner focus frame so the indicator remains visible at clipped container edges.
|
|
68
|
+
.brand-logo {
|
|
69
|
+
box-sizing: border-box;
|
|
70
|
+
border: 2px solid transparent;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.brand-logo:focus-visible {
|
|
74
|
+
border-color: var(--nt-primary, #0d6efd);
|
|
75
|
+
outline: 0;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.brand-logo > img {
|
|
79
|
+
display: block;
|
|
80
|
+
inline-size: 100%;
|
|
81
|
+
block-size: 100%;
|
|
82
|
+
max-inline-size: 100%;
|
|
83
|
+
max-block-size: 100%;
|
|
84
|
+
object-fit: contain;
|
|
85
|
+
object-position: center;
|
|
86
|
+
transition:
|
|
87
|
+
inline-size 0.2s ease-in-out,
|
|
88
|
+
block-size 0.2s ease-in-out;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.brand-logo[slot='start'] > img {
|
|
92
|
+
object-position: left center;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.brand-logo[slot='end'] > img {
|
|
96
|
+
object-position: right center;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.navbar-control {
|
|
100
|
+
position: relative;
|
|
101
|
+
z-index: var(--nt-navbar-control-z-index, 2);
|
|
102
|
+
min-inline-size: 0;
|
|
103
|
+
pointer-events: auto;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// Adds the outer spacing required by legacy .btn controls placed directly in a navbar line.
|
|
2
|
+
@mixin with-btn-compat($margin: var(--nt-space-1)) {
|
|
3
|
+
// Fits the button into the line's content height while preserving the configured outer spacing.
|
|
4
|
+
nte-navbar-line :where(.btn, .btn-group) {
|
|
5
|
+
box-sizing: border-box;
|
|
6
|
+
display: inline-flex;
|
|
7
|
+
align-items: center;
|
|
8
|
+
block-size: calc(100% - (2 * #{$margin}));
|
|
9
|
+
min-block-size: 0;
|
|
10
|
+
margin: $margin;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Lets grouped buttons share the compatibility height without multiplying the outer margin.
|
|
14
|
+
nte-navbar-line :where(.btn-group) > .btn {
|
|
15
|
+
block-size: 100%;
|
|
16
|
+
margin: 0;
|
|
17
|
+
}
|
|
18
|
+
}
|