ng-hub-ui-nav 22.5.0 → 22.6.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ng-hub-ui-nav",
3
- "version": "22.5.0",
3
+ "version": "22.6.0",
4
4
  "license": "MIT",
5
5
  "description": "A flexible, accessible, and customizable navigation component for Angular 21, part of the ng-hub-ui family.",
6
6
  "author": "Carlos Morcillo <carlos.morcillo@me.com> (https://www.carlosmorcillo.com)",
@@ -0,0 +1,6 @@
1
+ // ── Public SCSS API for ng-hub-ui-nav ────────────────────────────────────────
2
+ //
3
+ // @use 'ng-hub-ui-nav/styles' as *;
4
+ //
5
+ // Forwards the `hub-nav-theme(...)` one-call theming mixin.
6
+ @forward 'nav-theme';
@@ -0,0 +1,84 @@
1
+ // ─────────────────────────────────────────────────────────────────────────
2
+ // hub-nav-theme — one-call token theming for `<hub-nav>`
3
+ // ─────────────────────────────────────────────────────────────────────────
4
+ //
5
+ // Override the most useful `--hub-nav-*` design tokens in a single include. Every
6
+ // parameter is OPTIONAL and defaults to `null`: only the parameters you pass are
7
+ // emitted, so the rest keep their defaults. For any token not exposed here, set the
8
+ // `--hub-nav-*` custom property directly — this mixin is sugar for the common knobs,
9
+ // not a replacement for the full token surface.
10
+ //
11
+ // `$accent` feeds the single `--hub-nav-accent` slot; the component derives the
12
+ // `-emphasis` / `-subtle` / `-on` family from it at runtime, so one colour re-tones
13
+ // the active indicator and hover accents. Pass any value `resolveHubAccent` accepts
14
+ // (a semantic name, a registered accent, or a literal `#hex` / `rgb()` / `oklch()`).
15
+ //
16
+ // @example
17
+ //
18
+ // @use 'ng-hub-ui-nav/styles' as *;
19
+ //
20
+ // .app-shell nav {
21
+ // @include hub-nav-theme($accent: var(--hub-sys-color-brand), $item-border-radius: 0.5rem);
22
+ // }
23
+ //
24
+ // scss-docs-start hub-nav-theme
25
+ @mixin hub-nav-theme(
26
+ $accent: null, // --hub-nav-accent (active indicator + hover accents)
27
+ $bg: null, // --hub-nav-bg (bar surface)
28
+ $color: null, // --hub-nav-color (bar text)
29
+ $border-color: null, // --hub-nav-border-color
30
+ $gap: null, // --hub-nav-gap (spacing between items)
31
+ $padding-x: null, // --hub-nav-padding-x
32
+ $padding-y: null, // --hub-nav-padding-y
33
+ $item-color: null, // --hub-nav-item-color
34
+ $item-active-bg: null, // --hub-nav-item-active-bg
35
+ $item-active-color: null, // --hub-nav-item-active-color
36
+ $item-border-radius: null, // --hub-nav-item-border-radius
37
+ $item-font-size: null, // --hub-nav-item-font-size
38
+ $item-padding-x: null, // --hub-nav-item-padding-x
39
+ $item-padding-y: null // --hub-nav-item-padding-y
40
+ ) {
41
+ @if $accent != null {
42
+ --hub-nav-accent: #{$accent};
43
+ }
44
+ @if $bg != null {
45
+ --hub-nav-bg: #{$bg};
46
+ }
47
+ @if $color != null {
48
+ --hub-nav-color: #{$color};
49
+ }
50
+ @if $border-color != null {
51
+ --hub-nav-border-color: #{$border-color};
52
+ }
53
+ @if $gap != null {
54
+ --hub-nav-gap: #{$gap};
55
+ }
56
+ @if $padding-x != null {
57
+ --hub-nav-padding-x: #{$padding-x};
58
+ }
59
+ @if $padding-y != null {
60
+ --hub-nav-padding-y: #{$padding-y};
61
+ }
62
+ @if $item-color != null {
63
+ --hub-nav-item-color: #{$item-color};
64
+ }
65
+ @if $item-active-bg != null {
66
+ --hub-nav-item-active-bg: #{$item-active-bg};
67
+ }
68
+ @if $item-active-color != null {
69
+ --hub-nav-item-active-color: #{$item-active-color};
70
+ }
71
+ @if $item-border-radius != null {
72
+ --hub-nav-item-border-radius: #{$item-border-radius};
73
+ }
74
+ @if $item-font-size != null {
75
+ --hub-nav-item-font-size: #{$item-font-size};
76
+ }
77
+ @if $item-padding-x != null {
78
+ --hub-nav-item-padding-x: #{$item-padding-x};
79
+ }
80
+ @if $item-padding-y != null {
81
+ --hub-nav-item-padding-y: #{$item-padding-y};
82
+ }
83
+ }
84
+ // scss-docs-end hub-nav-theme
@@ -0,0 +1,209 @@
1
+ // ──────────────────────────────────────────────────────
2
+ // hub-nav — Design Tokens
3
+ // References hub-sys / hub-ref tokens from the design system.
4
+ // ──────────────────────────────────────────────────────
5
+
6
+ :root,
7
+ :host {
8
+ // ── Layout ──
9
+ --hub-nav-height: 3.5rem;
10
+ --hub-nav-padding-x: var(--hub-ref-space-3, 1rem);
11
+ --hub-nav-padding-y: var(--hub-ref-space-2, 0.5rem);
12
+ --hub-nav-gap: var(--hub-ref-space-1, 0.25rem);
13
+ --hub-nav-horizontal-padding-y: 0;
14
+ --hub-nav-horizontal-padding-x: 0;
15
+ --hub-nav-horizontal-row-gap: 0;
16
+ --hub-nav-horizontal-items-justify: center;
17
+ --hub-nav-horizontal-items-overflow-x: auto;
18
+ --hub-nav-horizontal-items-overflow-y: hidden;
19
+ --hub-nav-vertical-items-overflow-y: auto;
20
+ --hub-nav-vertical-items-overflow-x: hidden;
21
+ --hub-nav-vertical-panel-padding-inline: var(--hub-ref-space-2, 0.5rem);
22
+ --hub-nav-vertical-panel-padding-block: 0;
23
+ --hub-nav-horizontal-panel-padding-y: var(--hub-ref-space-2, 0.5rem);
24
+ --hub-nav-horizontal-panel-padding-x: 0;
25
+ --hub-nav-scrollbar-width: none;
26
+ --hub-nav-scrollbar-color: transparent transparent;
27
+ --hub-nav-scrollbar-webkit-size: 0;
28
+ --hub-nav-scrollbar-thumb-color: transparent;
29
+ --hub-nav-scrollbar-track-color: transparent;
30
+ --hub-nav-scrollbar-thumb-radius: var(--hub-ref-radius-pill, 50rem);
31
+
32
+ // ── Colours ──
33
+ // Single semantic accent driving the hover/active affordances. Defaults to
34
+ // `primary` and is re-based per `variant` (see the loop below) or inline by
35
+ // the component, so the whole nav recolours from one hook.
36
+ --hub-nav-accent: var(--hub-sys-color-primary, #0d6efd);
37
+ // Subtle tint of the accent for the soft hover/active surfaces (derived with
38
+ // the canonical design-system formula, so it follows the accent — and the
39
+ // variant — automatically, matching the ds `-subtle` tints exactly).
40
+ --hub-nav-accent-subtle: color-mix(in oklch, var(--hub-nav-accent) 12%, var(--hub-sys-surface-page, #ffffff));
41
+ // Strong/emphasis shade of the accent, mixed over the theme ink. Mirrors the
42
+ // design-system `-emphasis` role so the accent text reads with enough contrast.
43
+ --hub-nav-accent-emphasis: color-mix(in oklch, var(--hub-nav-accent) 80%, var(--hub-sys-color-ink, #212529));
44
+ // Contrast / on-color: text that sits ON the accent. Grayscale flip driven by
45
+ // the accent's own lightness (dark accents → white text, light accents → near
46
+ // black), recomputed at runtime with the accent — no second token needed.
47
+ --hub-nav-accent-on: oklch(from var(--hub-nav-accent) clamp(0, (0.62 - l) * 1000, 1) 0 h);
48
+ // The nav surface carries a faint wash of the accent, so each `variant`
49
+ // reads as a distinctly-themed surface (not just the active item).
50
+ --hub-nav-bg: color-mix(in oklch, var(--hub-nav-accent) 5%, var(--hub-sys-surface-page, #fff));
51
+ --hub-nav-color: var(--hub-sys-text-primary, #212529);
52
+ --hub-nav-border-color: var(--hub-sys-border-color-default, #dee2e6);
53
+ --hub-nav-border-width: 1px;
54
+ --hub-nav-border-style: solid;
55
+
56
+ // ── Brand ──
57
+ --hub-nav-brand-font-size: var(--hub-ref-font-size-lg, 1.25rem);
58
+ --hub-nav-brand-font-weight: var(--hub-ref-font-weight-semibold, 600);
59
+ --hub-nav-brand-color: var(--hub-sys-text-primary, #212529);
60
+ --hub-nav-brand-padding-x: var(--hub-ref-space-2, 0.5rem);
61
+
62
+ // ── Items ──
63
+ --hub-nav-item-padding-x: var(--hub-ref-space-3, 1rem);
64
+ --hub-nav-item-padding-y: var(--hub-ref-space-2, 0.5rem);
65
+ --hub-nav-item-color: var(--hub-sys-text-primary, #212529);
66
+ --hub-nav-item-font-size: var(--hub-ref-font-size-base, 1rem);
67
+ --hub-nav-item-font-weight: var(--hub-ref-font-weight-base, 400);
68
+ --hub-nav-item-border-radius: var(--hub-ref-radius-sm, 0.25rem);
69
+ --hub-nav-item-transition: var(--hub-sys-transition-fast, all 0.15s ease-in-out);
70
+
71
+ // ── Item Hover ── (soft accent tint)
72
+ --hub-nav-item-hover-bg: color-mix(in oklch, var(--hub-nav-accent) 8%, var(--hub-sys-surface-page, #fff));
73
+ --hub-nav-item-hover-color: var(--hub-nav-accent);
74
+
75
+ // ── Item Active ── (soft tint + accent text + accent indicator bar)
76
+ --hub-nav-item-active-bg: var(--hub-nav-accent-subtle);
77
+ --hub-nav-item-active-color: var(--hub-nav-accent);
78
+ --hub-nav-item-active-font-weight: var(--hub-ref-font-weight-semibold, 600);
79
+ --hub-nav-item-active-indicator-color: var(--hub-nav-accent);
80
+ --hub-nav-item-active-indicator-size: 3px;
81
+
82
+ // ── Item Disabled ──
83
+ --hub-nav-item-disabled-color: var(--hub-sys-text-muted, #6c757d);
84
+ --hub-nav-item-disabled-opacity: var(--hub-sys-opacity-disabled, 0.65);
85
+
86
+ // ── Dropdown ──
87
+ --hub-nav-dropdown-bg: var(--hub-sys-surface-elevated, #f8f9fa);
88
+ --hub-nav-dropdown-color: var(--hub-sys-text-primary, #212529);
89
+ --hub-nav-dropdown-border-color: var(--hub-sys-border-color-default, #dee2e6);
90
+ --hub-nav-dropdown-border-radius: var(--hub-nav-item-border-radius, var(--hub-ref-radius-sm, 0.25rem));
91
+ --hub-nav-dropdown-shadow: var(--hub-sys-shadow, 0 0.5rem 1rem rgba(0, 0, 0, 0.15));
92
+ --hub-nav-dropdown-padding-y: var(--hub-ref-space-2, 0.5rem);
93
+ --hub-nav-dropdown-min-width: 12rem;
94
+ --hub-nav-dropdown-zindex: var(--hub-sys-zindex-dropdown, 1000);
95
+
96
+ // ── Caret ──
97
+ --hub-nav-caret-size: 0.3rem;
98
+ --hub-nav-caret-color: currentColor;
99
+
100
+ // ── Header (item type) ──
101
+ --hub-nav-header-font-size: var(--hub-ref-font-size-sm, 0.875rem);
102
+ --hub-nav-header-font-weight: var(--hub-ref-font-weight-semibold, 600);
103
+ --hub-nav-header-color: var(--hub-sys-text-muted, #6c757d);
104
+ --hub-nav-header-padding-x: var(--hub-ref-space-3, 1rem);
105
+ --hub-nav-header-padding-y: var(--hub-ref-space-1, 0.25rem);
106
+ --hub-nav-header-margin-top: var(--hub-ref-space-3, 1rem);
107
+ --hub-nav-header-margin-inline-start: var(--hub-ref-space-3, 1rem);
108
+ --hub-nav-header-horizontal-padding-inline-start: 2rem;
109
+
110
+ // ── Separator ──
111
+ --hub-nav-separator-color: var(--hub-sys-border-color-default, #dee2e6);
112
+ --hub-nav-separator-margin-y: var(--hub-ref-space-2, 0.5rem);
113
+
114
+ // ── Badge ──
115
+ --hub-nav-badge-font-size: var(--hub-ref-font-size-xs, 0.75rem);
116
+ --hub-nav-badge-padding-x: 0.5em;
117
+ --hub-nav-badge-padding-y: 0.25em;
118
+ --hub-nav-badge-bg: var(--hub-sys-color-danger, #dc3545);
119
+ --hub-nav-badge-color: var(--hub-ref-color-white, #fff);
120
+ --hub-nav-badge-border-radius: var(--hub-ref-radius-pill, 50rem);
121
+
122
+ // ── Toggler (hamburger) ──
123
+ --hub-nav-toggler-padding-x: var(--hub-ref-space-2, 0.5rem);
124
+ --hub-nav-toggler-padding-y: var(--hub-ref-space-1, 0.25rem);
125
+ --hub-nav-toggler-font-size: var(--hub-ref-font-size-lg, 1.25rem);
126
+ --hub-nav-toggler-color: var(--hub-sys-text-primary, #212529);
127
+ --hub-nav-toggler-border-color: var(--hub-sys-border-color-default, #dee2e6);
128
+ --hub-nav-toggler-border-radius: var(--hub-ref-radius-sm, 0.25rem);
129
+
130
+ // ── Mobile Panel ──
131
+ --hub-nav-mobile-bg: var(--hub-sys-surface-page, #fff);
132
+ --hub-nav-mobile-color: var(--hub-sys-text-primary, #212529);
133
+ --hub-nav-mobile-width: 18rem;
134
+ --hub-nav-mobile-zindex: var(--hub-sys-zindex-fixed, 1030);
135
+ --hub-nav-mobile-backdrop-bg: rgba(0, 0, 0, 0.5);
136
+ --hub-nav-mobile-transition: var(--hub-sys-transition-base, all 0.2s ease-in-out);
137
+
138
+ // ── Accordion mode (vertical expand) ──
139
+ --hub-nav-accordion-indent: var(--hub-ref-space-3, 1rem);
140
+ // Duration + easing of the expand ANIMATION. It intentionally does NOT
141
+ // reference `--hub-sys-transition-collapse`: the ds value is a transition
142
+ // shorthand carrying a property name (`height 0.35s ease`), which is invalid
143
+ // inside `animation` and would silently disable it. Timing matches ds.
144
+ --hub-nav-accordion-transition: 0.35s ease;
145
+
146
+ // ── Icon ──
147
+ --hub-nav-icon-size: var(--hub-ref-icon-size, 1em);
148
+ --hub-nav-icon-gap: var(--hub-ref-space-2, 0.5rem);
149
+
150
+ // ── Panel mode (stacked side panels) ──
151
+ --hub-nav-panel-width: 16rem;
152
+ --hub-nav-panel-bg: var(--hub-sys-surface-elevated, #f8f9fa);
153
+ --hub-nav-panel-color: var(--hub-sys-text-primary, #212529);
154
+ --hub-nav-panel-border-color: var(--hub-sys-border-color-default, #dee2e6);
155
+ --hub-nav-panel-border-width: 1px;
156
+ --hub-nav-panel-shadow: var(--hub-sys-shadow-sm, 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075));
157
+ --hub-nav-panel-zindex: var(--hub-sys-zindex-dropdown, 1000);
158
+ // Complete `transition` value (the ds base token is already `all …`; a
159
+ // `transform` prefix would make the resolved declaration invalid).
160
+ --hub-nav-panel-transition: var(--hub-sys-transition-base, all 0.2s ease-in-out);
161
+
162
+ // ── Panel header ──
163
+ --hub-nav-panel-header-height: 3rem;
164
+ --hub-nav-panel-header-bg: var(--hub-sys-surface-page, #fff);
165
+ --hub-nav-panel-header-border-color: var(--hub-sys-border-color-default, #dee2e6);
166
+ --hub-nav-panel-header-font-size: var(--hub-ref-font-size-sm, 0.875rem);
167
+ --hub-nav-panel-header-font-weight: var(--hub-ref-font-weight-semibold, 600);
168
+ --hub-nav-panel-header-padding-x: var(--hub-ref-space-3, 1rem);
169
+
170
+ // ── Panel back button ──
171
+ --hub-nav-panel-back-color: var(--hub-sys-text-primary, #212529);
172
+ --hub-nav-panel-back-hover-bg: var(--hub-sys-state-hover-bg, rgba(0, 0, 0, 0.075));
173
+ --hub-nav-panel-back-size: 2rem;
174
+ }
175
+
176
+ // ──────────────────────────────────────────────────────
177
+ // Semantic variant — `<hub-nav [variant]="…">`
178
+ // Re-bases the single `--hub-nav-accent` per variant; the hover/active
179
+ // affordances follow. Built-in variants pick up the exact `--hub-sys-color-*`
180
+ // tints; any custom variant works via the inline accent the component sets.
181
+ // ──────────────────────────────────────────────────────
182
+
183
+ // Open-set default — ANY variant the host application defines. The derived
184
+ // roles (-subtle / -emphasis / -on, plus the nav surface wash and hover tint)
185
+ // are re-mixed from the single `--hub-nav-accent` the component sets inline, so
186
+ // a custom accent (e.g. `variant="brand"` backed by `--hub-sys-color-brand`)
187
+ // interconnects with ONE CSS rule the user writes:
188
+ // :root { --hub-sys-color-brand: #ff6b00; }
189
+ // No per-colour CSS is needed here for custom variants — only the open default.
190
+ :host([data-variant]),
191
+ .hub-nav[data-variant] {
192
+ --hub-nav-accent-subtle: color-mix(in oklch, var(--hub-nav-accent) 12%, var(--hub-sys-surface-page, #ffffff));
193
+ --hub-nav-accent-emphasis: color-mix(in oklch, var(--hub-nav-accent) 80%, var(--hub-sys-color-ink, #212529));
194
+ --hub-nav-accent-on: oklch(from var(--hub-nav-accent) clamp(0, (0.62 - l) * 1000, 1) 0 h);
195
+ --hub-nav-bg: color-mix(in oklch, var(--hub-nav-accent) 5%, var(--hub-sys-surface-page, #fff));
196
+ --hub-nav-item-hover-bg: color-mix(in oklch, var(--hub-nav-accent) 8%, var(--hub-sys-surface-page, #fff));
197
+ }
198
+
199
+ // Built-in semantic variants — re-base the single accent to the exact
200
+ // design-system `--hub-sys-color-<variant>` tint. The full open accent set:
201
+ // primary, secondary, success, danger, warning, info, neutral, light, dark.
202
+ $hub-nav-variants: primary, secondary, success, danger, warning, info, neutral, light, dark;
203
+
204
+ @each $variant in $hub-nav-variants {
205
+ :host([data-variant='#{$variant}']),
206
+ .hub-nav[data-variant='#{$variant}'] {
207
+ --hub-nav-accent: var(--hub-sys-color-#{$variant});
208
+ }
209
+ }