@grantcodes/ui 2.5.0 → 2.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/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.6.0](https://github.com/grantcodes/ui/compare/ui-v2.5.1...ui-v2.6.0) (2026-04-06)
4
+
5
+
6
+ ### Features
7
+
8
+ * **08-02:** add nav-link component, fix CSS cascade, refactor base styles ([fa143e2](https://github.com/grantcodes/ui/commit/fa143e2362b90b8d2879148bee7044db21dcb5e7))
9
+ * **08-02:** rewrite app bar Storybook stories without inline styles ([1424640](https://github.com/grantcodes/ui/commit/1424640b696b5c97aca269f2594cbad8b51ec45f))
10
+ * **08-03:** redesign mobile menu as full-screen overlay with animation ([600dc6e](https://github.com/grantcodes/ui/commit/600dc6e478691d0642ca34f52306ff67489baf12))
11
+ * app bar improvements — nav-link component, CSS fixes, mobile menu overlay ([d1e66a2](https://github.com/grantcodes/ui/commit/d1e66a20d9d258eda22303f827491780d1d2467b))
12
+
13
+
14
+ ### Bug Fixes
15
+
16
+ * **08-01:** clean up app-bar CSS — dead code, tokens, sticky, a11y, responsive ([000fd4b](https://github.com/grantcodes/ui/commit/000fd4b2c5b4be04900ab42a63298e6d8735d67c))
17
+ * **08-03:** close mobile menu on resize past desktop breakpoint ([dac56e1](https://github.com/grantcodes/ui/commit/dac56e1bcfa735e37fe82c43fde89be3c211d0c3))
18
+ * move font shorthand before line-height in reset.css to fix lint error ([98c9bba](https://github.com/grantcodes/ui/commit/98c9bbac15e3a7db81c103023352f6f8f071dbb6))
19
+
20
+ ## [2.5.1](https://github.com/grantcodes/ui/compare/ui-v2.5.0...ui-v2.5.1) (2026-04-05)
21
+
22
+
23
+ ### Bug Fixes
24
+
25
+ * add .light sub-element override CSS and fix ::selection token ([1ae9007](https://github.com/grantcodes/ui/commit/1ae900779cf6a241a7e430b86a3e3c0cb988f954))
26
+ * add .light sub-element override CSS and fix ::selection token ([9e9c0c3](https://github.com/grantcodes/ui/commit/9e9c0c32d3b68fd6db5b0b7f40ab14341cc96684))
27
+
3
28
  ## [2.5.0](https://github.com/grantcodes/ui/compare/ui-v2.4.1...ui-v2.5.0) (2026-04-05)
4
29
 
5
30
 
@@ -266,6 +266,67 @@
266
266
  }
267
267
  ]
268
268
  },
269
+ {
270
+ "kind": "javascript-module",
271
+ "path": "src/components/app-bar/nav-link.component.js",
272
+ "declarations": [
273
+ {
274
+ "kind": "class",
275
+ "description": "",
276
+ "name": "GrantCodesNavLink",
277
+ "members": [],
278
+ "superclass": {
279
+ "name": "LitElement",
280
+ "package": "lit"
281
+ },
282
+ "tagName": "grantcodes-nav-link",
283
+ "customElement": true,
284
+ "modulePath": "src/components/app-bar/nav-link.component.js",
285
+ "definitionPath": "src/components/app-bar/nav-link.js"
286
+ }
287
+ ],
288
+ "exports": [
289
+ {
290
+ "kind": "js",
291
+ "name": "GrantCodesNavLink",
292
+ "declaration": {
293
+ "name": "GrantCodesNavLink",
294
+ "module": "src/components/app-bar/nav-link.component.js"
295
+ }
296
+ }
297
+ ]
298
+ },
299
+ {
300
+ "kind": "javascript-module",
301
+ "path": "src/components/app-bar/nav-link.js",
302
+ "declarations": [],
303
+ "exports": [
304
+ {
305
+ "kind": "js",
306
+ "name": "*",
307
+ "declaration": {
308
+ "name": "*",
309
+ "module": "src/components/app-bar/nav-link.component.js"
310
+ }
311
+ },
312
+ {
313
+ "kind": "js",
314
+ "name": "default",
315
+ "declaration": {
316
+ "name": "GrantCodesNavLink",
317
+ "module": "src/components/app-bar/nav-link.js"
318
+ }
319
+ },
320
+ {
321
+ "kind": "custom-element-definition",
322
+ "name": "grantcodes-nav-link",
323
+ "declaration": {
324
+ "name": "GrantCodesNavLink",
325
+ "module": "/src/components/app-bar/nav-link.component.js"
326
+ }
327
+ }
328
+ ]
329
+ },
269
330
  {
270
331
  "kind": "javascript-module",
271
332
  "path": "src/components/avatar/avatar.component.js",
@@ -2492,25 +2553,6 @@
2492
2553
  },
2493
2554
  "default": "false"
2494
2555
  },
2495
- {
2496
- "kind": "method",
2497
- "name": "groupTemplate",
2498
- "parameters": [
2499
- {
2500
- "name": "className",
2501
- "description": "html class attribute",
2502
- "type": {
2503
- "text": "string"
2504
- }
2505
- }
2506
- ],
2507
- "description": "Template for a group of form components",
2508
- "return": {
2509
- "type": {
2510
- "text": ""
2511
- }
2512
- }
2513
- },
2514
2556
  {
2515
2557
  "kind": "method",
2516
2558
  "name": "handleLabelClick"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grantcodes/ui",
3
- "version": "2.5.0",
3
+ "version": "2.6.0",
4
4
  "description": "A personal component system built with Lit web components",
5
5
  "type": "module",
6
6
  "main": "src/main.js",
@@ -47,7 +47,7 @@
47
47
  "@lit/react": "^1.0.8",
48
48
  "lit": "^3.3.1",
49
49
  "shiki": "^3.17.1",
50
- "@grantcodes/style-dictionary": "^1.4.0"
50
+ "@grantcodes/style-dictionary": "^1.4.1"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@arcmantle/vite-plugin-import-css-sheet": "^1.0.12",
@@ -33,6 +33,30 @@ export class GrantCodesAppBar extends LitElement {
33
33
  * @type {boolean}
34
34
  */
35
35
  this._mobileMenuOpen = false;
36
+
37
+ /**
38
+ * Close mobile menu when the component crosses the desktop breakpoint.
39
+ * Matches the 768px container query in app-bar.css.
40
+ */
41
+ this._resizeObserver = typeof ResizeObserver !== "undefined"
42
+ ? new ResizeObserver((entries) => {
43
+ for (const entry of entries) {
44
+ if (entry.contentBoxSize[0].inlineSize >= 768 && this._mobileMenuOpen) {
45
+ this._mobileMenuOpen = false;
46
+ }
47
+ }
48
+ })
49
+ : null;
50
+ }
51
+
52
+ connectedCallback() {
53
+ super.connectedCallback();
54
+ this._resizeObserver?.observe(this);
55
+ }
56
+
57
+ disconnectedCallback() {
58
+ super.disconnectedCallback();
59
+ this._resizeObserver?.disconnect();
36
60
  }
37
61
 
38
62
  _toggleMobileMenu() {
@@ -53,13 +77,27 @@ export class GrantCodesAppBar extends LitElement {
53
77
  "app-bar--transparent": this.transparent,
54
78
  });
55
79
 
80
+ const navClasses = classMap({
81
+ "app-bar__nav": true,
82
+ "app-bar__nav--open": this._mobileMenuOpen,
83
+ });
84
+
56
85
  return html`
57
86
  <header class=${classes}>
58
- <div class="app-bar__container">
87
+ <div class="app-bar__bar">
59
88
  <div class="app-bar__logo">
60
89
  <slot name="logo"></slot>
61
90
  </div>
62
91
 
92
+ <!-- Navigation (inline on desktop, overlay on mobile) -->
93
+ <nav
94
+ part="nav"
95
+ class=${navClasses}
96
+ aria-label="Main navigation"
97
+ >
98
+ <slot name="nav"></slot>
99
+ </nav>
100
+
63
101
  <!-- Actions (right side) -->
64
102
  <div class="app-bar__actions">
65
103
  <slot name="actions"></slot>
@@ -75,15 +113,13 @@ export class GrantCodesAppBar extends LitElement {
75
113
  >
76
114
  <span class="app-bar__menu-icon"></span>
77
115
  </button>
78
-
79
- <!-- Navigation (single slot, collapsible on mobile) -->
80
- <nav
81
- class="app-bar__nav ${this._mobileMenuOpen ? "app-bar__nav--mobile-open" : ""}"
82
- aria-label="Main navigation"
83
- >
84
- <slot name="nav"></slot>
85
- </nav>
86
116
  </div>
117
+
118
+ <!-- Mobile overlay backdrop -->
119
+ <div
120
+ class="app-bar__overlay ${this._mobileMenuOpen ? "app-bar__overlay--visible" : ""}"
121
+ @click=${this._toggleMobileMenu}
122
+ ></div>
87
123
  </header>
88
124
  `;
89
125
  }
@@ -13,9 +13,13 @@
13
13
  .app-bar {
14
14
  background-color: var(--g-theme-color-background-default);
15
15
  border-block-end: 1px solid var(--g-theme-color-border-default);
16
+ position: relative;
17
+ z-index: 100;
18
+ }
19
+
20
+ .app-bar--sticky {
16
21
  position: sticky;
17
22
  inset-block-start: 0;
18
- z-index: 100;
19
23
  }
20
24
 
21
25
  .app-bar--transparent {
@@ -24,7 +28,8 @@
24
28
  box-shadow: none;
25
29
  }
26
30
 
27
- .app-bar__container {
31
+ /* Top bar row — always visible */
32
+ .app-bar__bar {
28
33
  display: flex;
29
34
  align-items: center;
30
35
  gap: var(--g-theme-spacing-lg);
@@ -32,7 +37,6 @@
32
37
  padding-block: var(--g-theme-spacing-md);
33
38
  max-inline-size: 1400px;
34
39
  margin-inline: auto;
35
- flex-wrap: wrap;
36
40
  }
37
41
 
38
42
  /* Logo */
@@ -42,39 +46,16 @@
42
46
  flex-shrink: 0;
43
47
  }
44
48
 
45
- /* Navigation */
49
+ /* Navigation — hidden on mobile, shown on desktop */
46
50
  .app-bar__nav {
47
51
  display: none;
48
- flex: 1;
49
- align-items: center;
50
- gap: var(--g-theme-spacing-lg);
51
- order: 5;
52
- inline-size: 100%;
53
- }
54
-
55
- /* Mobile: when menu is open, show nav stacked vertically */
56
- .app-bar__nav--mobile-open {
57
- display: flex;
58
- flex-direction: column;
59
- gap: var(--g-theme-spacing-sm);
60
- padding-inline: var(--g-theme-spacing-md);
61
- padding-block: var(--g-theme-spacing-md);
62
- border-block-start: 1px solid var(--g-theme-color-border-default);
63
- width: 100%;
64
- }
65
-
66
- /* Show nav on larger screens using container queries */
67
- @container app-bar (min-width: 768px) {
68
- .app-bar__nav {
69
- display: flex;
70
- }
71
52
  }
72
53
 
73
54
  /* Actions */
74
55
  .app-bar__actions {
75
56
  display: flex;
76
57
  align-items: center;
77
- gap: var(--g-spacing-12);
58
+ gap: var(--g-theme-spacing-sm);
78
59
  margin-inline-start: auto;
79
60
  }
80
61
 
@@ -84,8 +65,8 @@
84
65
  display: flex;
85
66
  align-items: center;
86
67
  justify-content: center;
87
- inline-size: 2.5rem;
88
- block-size: 2.5rem;
68
+ inline-size: 2.75rem;
69
+ block-size: 2.75rem;
89
70
  padding: var(--g-theme-spacing-sm);
90
71
  border-radius: var(--g-theme-border-radius-md);
91
72
  cursor: pointer;
@@ -97,18 +78,11 @@
97
78
  background-color: var(--g-theme-color-background-subtle-hover);
98
79
  }
99
80
 
100
- /* Hide menu button on larger screens */
101
- @container app-bar (min-width: 768px) {
102
- .app-bar__menu-button {
103
- display: none;
104
- }
105
- }
106
-
107
81
  /* Hamburger Icon */
108
82
  .app-bar__menu-icon {
109
83
  display: block;
110
- inline-size: 1.5rem;
111
- block-size: 1.5rem;
84
+ inline-size: 1.25rem;
85
+ block-size: 1rem;
112
86
  position: relative;
113
87
  }
114
88
 
@@ -120,55 +94,130 @@
120
94
  block-size: 2px;
121
95
  inset-inline-start: 0;
122
96
  background-color: currentColor;
123
- transition: transform 0.2s ease;
97
+ transition: transform 0.2s ease, inset 0.2s ease;
124
98
  }
125
99
 
126
100
  .app-bar__menu-icon::before {
127
- inset-block-start: 0.25rem;
128
- box-shadow: 0 0.5rem 0 currentColor;
101
+ inset-block-start: 0;
102
+ box-shadow: 0 0.4375rem 0 currentColor;
129
103
  }
130
104
 
131
105
  .app-bar__menu-icon::after {
132
- inset-block-end: 0.25rem;
106
+ inset-block-end: 0;
133
107
  }
134
108
 
135
109
  /* Animated hamburger to X */
136
110
  .app-bar__menu-button[aria-expanded="true"] .app-bar__menu-icon::before {
137
- inset-block-start: 0.5rem;
111
+ inset-block-start: calc(50% - 1px);
138
112
  transform: rotate(45deg);
139
113
  box-shadow: none;
140
114
  }
141
115
 
142
116
  .app-bar__menu-button[aria-expanded="true"] .app-bar__menu-icon::after {
143
- inset-block-end: 0.5rem;
117
+ inset-block-end: calc(50% - 1px);
144
118
  transform: rotate(-45deg);
145
119
  }
146
120
 
147
- /* Mobile Navigation */
148
- .app-bar__mobile-nav {
121
+ /*
122
+ * Mobile menu — full-width panel below the app bar.
123
+ * Uses clip-path for a clean slide-down reveal animation.
124
+ */
125
+ .app-bar__nav--open {
149
126
  display: flex;
150
127
  flex-direction: column;
151
- gap: var(--g-theme-spacing-sm);
152
- padding-inline: var(--g-theme-spacing-md);
128
+ gap: var(--g-theme-spacing-xs, 0.25rem);
129
+ position: absolute;
130
+ inset-inline: 0;
131
+ inset-block-start: 100%;
132
+ z-index: 99;
133
+ background-color: var(--g-theme-color-background-default);
134
+ border-block-end: 1px solid var(--g-theme-color-border-default);
153
135
  padding-block: var(--g-theme-spacing-md);
154
- border-block-start: 1px solid var(--g-theme-color-border-default);
155
- animation: slide-down 0.2s ease-out;
136
+ padding-inline: var(--g-theme-spacing-md);
137
+ box-shadow: var(--g-theme-shadow-lg, 0 8px 24px rgba(0, 0, 0, 0.12));
138
+ animation: menu-open 0.25s ease-out;
156
139
  }
157
140
 
158
- /* Desktop: show nav inline and reset mobile styles */
159
- @container app-bar (min-width: 768px) {
160
- .app-bar__container {
161
- flex-wrap: nowrap;
141
+ @keyframes menu-open {
142
+ from {
143
+ opacity: 0;
144
+ transform: translateY(-0.5rem);
145
+ }
146
+ to {
147
+ opacity: 1;
148
+ transform: translateY(0);
149
+ }
150
+ }
151
+
152
+ /* Slotted nav content stacks vertically in mobile menu */
153
+ .app-bar__nav--open ::slotted(ul),
154
+ .app-bar__nav--open ::slotted(div[slot="nav"]) {
155
+ display: flex;
156
+ flex-direction: column;
157
+ gap: var(--g-theme-spacing-xs, 0.25rem);
158
+ margin: 0;
159
+ padding: 0;
160
+ list-style: none;
161
+ }
162
+
163
+ /* Backdrop overlay — covers viewport below app bar when menu is open */
164
+ .app-bar__overlay {
165
+ display: none;
166
+ }
167
+
168
+ .app-bar__overlay--visible {
169
+ display: block;
170
+ position: fixed;
171
+ inset: 0;
172
+ z-index: 98;
173
+ background-color: rgba(0, 0, 0, 0.2);
174
+ animation: overlay-fade 0.2s ease-out;
175
+ }
176
+
177
+ @keyframes overlay-fade {
178
+ from { opacity: 0; }
179
+ to { opacity: 1; }
180
+ }
181
+
182
+ /* Reduced motion preferences */
183
+ @media (prefers-reduced-motion: reduce) {
184
+ .app-bar__menu-icon::before,
185
+ .app-bar__menu-icon::after {
186
+ transition: none;
187
+ }
188
+
189
+ .app-bar__menu-button {
190
+ transition: none;
191
+ }
192
+
193
+ .app-bar__nav--open {
194
+ animation: none;
195
+ }
196
+
197
+ .app-bar__overlay--visible {
198
+ animation: none;
162
199
  }
200
+ }
163
201
 
202
+ /* Desktop: show nav inline, hide hamburger */
203
+ @container app-bar (min-width: 768px) {
164
204
  .app-bar__nav {
165
205
  display: flex;
166
206
  flex-direction: row;
167
- gap: var(--g-theme-spacing-lg);
168
- padding: 0;
207
+ align-items: center;
208
+ gap: var(--g-theme-spacing-xs, 0.25rem);
209
+ flex: 1;
210
+ }
211
+
212
+ /* Reset mobile-open styles at desktop — nav is always inline */
213
+ .app-bar__nav--open {
214
+ position: static;
215
+ background-color: transparent;
169
216
  border: 0;
170
- width: auto;
171
- order: 2;
217
+ padding: 0;
218
+ box-shadow: none;
219
+ animation: none;
220
+ flex-direction: row;
172
221
  }
173
222
 
174
223
  .app-bar__actions {
@@ -176,46 +225,28 @@
176
225
  }
177
226
 
178
227
  .app-bar__menu-button {
179
- order: 4;
180
- }
181
-
182
- /* Ensure mobile-open class doesn't affect desktop */
183
- .app-bar__nav--mobile-open {
184
- display: flex;
228
+ display: none;
185
229
  }
186
- }
187
230
 
188
- @keyframes slide-down {
189
- from {
190
- opacity: 0;
191
- transform: translateY(-0.5rem);
192
- }
193
- to {
194
- opacity: 1;
195
- transform: translateY(0);
231
+ /* Overlay is never visible on desktop */
232
+ .app-bar__overlay--visible {
233
+ display: none;
196
234
  }
197
235
  }
198
236
 
199
- /* Slotted content styling helpers */
200
- ::slotted(a) {
201
- color: var(--g-theme-color-content-default);
202
- text-decoration: none;
203
- padding-block: var(--g-theme-spacing-sm);
204
- padding-inline: var(--g-spacing-12);
205
- border-radius: var(--g-theme-border-radius-md);
206
- transition: all 0.2s ease;
237
+ /* Slotted content styling */
238
+ ::slotted(a[slot="logo"]) {
239
+ color: var(--g-theme-color-content-default) !important;
240
+ text-decoration: none !important;
207
241
  font-family: var(--g-theme-typography-label-font-family);
208
242
  font-weight: var(--g-theme-typography-label-font-weight);
209
243
  }
210
244
 
211
- ::slotted(a:hover) {
212
- color: var(--g-theme-color-content-default);
213
- background-color: var(--g-theme-color-background-subtle-hover);
214
- }
215
-
216
- ::slotted(ul) {
245
+ ::slotted(ul),
246
+ ::slotted(div[slot="nav"]) {
217
247
  display: flex;
218
248
  flex-direction: row;
249
+ gap: var(--g-theme-spacing-xs, 0.25rem);
219
250
  margin: 0;
220
251
  padding: 0;
221
252
  list-style: none;
@@ -1,5 +1,6 @@
1
1
  import { html } from "lit";
2
2
  import "./app-bar.js";
3
+ import "./nav-link.js";
3
4
  import "../button/button.js";
4
5
 
5
6
  const meta = {
@@ -10,19 +11,18 @@ const meta = {
10
11
  export default meta;
11
12
 
12
13
  /**
13
- * Basic app bar with logo and navigation
14
+ * Basic app bar with logo, navigation links, and a sign in action.
15
+ * Nav links use <grantcodes-nav-link> for consistent ghost button styling.
14
16
  */
15
- export const AppBar = {
17
+ export const Default = {
16
18
  render: () => html`
17
19
  <grantcodes-app-bar>
18
- <a slot="logo" href="/" style="font-weight: 700; font-size: 1.25rem; text-decoration: none; color: var(--g-color-brand-purple-900);">
19
- MyApp
20
- </a>
21
- <div slot="nav" style="display: flex; gap: 0.5rem;">
22
- <a href="/">Home</a>
23
- <a href="/about">About</a>
24
- <a href="/features">Features</a>
25
- <a href="/pricing">Pricing</a>
20
+ <a slot="logo" href="/">MyApp</a>
21
+ <div slot="nav">
22
+ <grantcodes-nav-link><a href="/">Home</a></grantcodes-nav-link>
23
+ <grantcodes-nav-link><a href="/about">About</a></grantcodes-nav-link>
24
+ <grantcodes-nav-link><a href="/features">Features</a></grantcodes-nav-link>
25
+ <grantcodes-nav-link><a href="/pricing">Pricing</a></grantcodes-nav-link>
26
26
  </div>
27
27
  <div slot="actions">
28
28
  <grantcodes-button>Sign In</grantcodes-button>
@@ -32,52 +32,90 @@ export const AppBar = {
32
32
  };
33
33
 
34
34
  /**
35
- * Transparent app bar for hero sections
35
+ * Navigation using a <ul> list — matches the real-world pattern from the Astro site.
36
+ * Each <li> wraps a <grantcodes-nav-link> so styling works through the shadow boundary.
37
+ */
38
+ export const WithListNav = {
39
+ render: () => html`
40
+ <grantcodes-app-bar>
41
+ <a slot="logo" href="/">MyApp</a>
42
+ <ul slot="nav">
43
+ <li><grantcodes-nav-link><a href="/docs">Docs</a></grantcodes-nav-link></li>
44
+ <li><grantcodes-nav-link><a href="/blog">Blog</a></grantcodes-nav-link></li>
45
+ <li><grantcodes-nav-link><a href="/changelog">Changelog</a></grantcodes-nav-link></li>
46
+ </ul>
47
+ <div slot="actions">
48
+ <grantcodes-button>Sign In</grantcodes-button>
49
+ </div>
50
+ </grantcodes-app-bar>
51
+ `,
52
+ };
53
+
54
+ /**
55
+ * Sticky app bar that stays at the top of the viewport when scrolling.
56
+ */
57
+ export const Sticky = {
58
+ render: () => html`
59
+ <div style="min-height: 200vh;">
60
+ <grantcodes-app-bar sticky>
61
+ <a slot="logo" href="/">MyApp</a>
62
+ <div slot="nav">
63
+ <grantcodes-nav-link><a href="/">Home</a></grantcodes-nav-link>
64
+ <grantcodes-nav-link><a href="/about">About</a></grantcodes-nav-link>
65
+ <grantcodes-nav-link><a href="/features">Features</a></grantcodes-nav-link>
66
+ <grantcodes-nav-link><a href="/pricing">Pricing</a></grantcodes-nav-link>
67
+ </div>
68
+ <div slot="actions">
69
+ <grantcodes-button>Sign In</grantcodes-button>
70
+ </div>
71
+ </grantcodes-app-bar>
72
+ <p style="padding: 2rem;">
73
+ Scroll down to see the sticky app bar remain at the top of the viewport.
74
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque
75
+ habitant morbi tristique senectus et netus et malesuada fames ac turpis
76
+ egestas.
77
+ </p>
78
+ </div>
79
+ `,
80
+ };
81
+
82
+ /**
83
+ * Transparent app bar for use over hero sections or colored backgrounds.
36
84
  */
37
85
  export const Transparent = {
38
86
  render: () => html`
39
87
  <div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 400px;">
40
88
  <grantcodes-app-bar transparent>
41
- <a slot="logo" href="/" style="font-weight: 700; font-size: 1.25rem; text-decoration: none; color: white;">
42
- MyApp
43
- </a>
44
- <div slot="nav" style="display: flex; gap: 0.5rem;">
45
- <a href="/" style="color: white;">Home</a>
46
- <a href="/about" style="color: white;">About</a>
47
- <a href="/features" style="color: white;">Features</a>
89
+ <a slot="logo" href="/">MyApp</a>
90
+ <div slot="nav">
91
+ <grantcodes-nav-link><a href="/">Home</a></grantcodes-nav-link>
92
+ <grantcodes-nav-link><a href="/about">About</a></grantcodes-nav-link>
93
+ <grantcodes-nav-link><a href="/features">Features</a></grantcodes-nav-link>
48
94
  </div>
49
95
  <div slot="actions">
50
- <grantcodes-button style="--g-theme-color-background-default: white; --g-theme-color-content-default: #667eea;">
51
- Sign Up
52
- </grantcodes-button>
96
+ <grantcodes-button>Sign Up</grantcodes-button>
53
97
  </div>
54
98
  </grantcodes-app-bar>
55
- <div style="padding: 4rem 2rem; text-align: center; color: white;">
56
- <h1 style="font-size: 3rem; margin: 0;">Welcome to MyApp</h1>
57
- <p style="font-size: 1.5rem; margin-top: 1rem;">The transparent app bar blends seamlessly</p>
58
- </div>
59
99
  </div>
60
100
  `,
61
101
  };
62
102
 
63
103
  /**
64
- * App bar with multiple actions
104
+ * App bar with multiple action buttons.
65
105
  */
66
106
  export const WithMultipleActions = {
67
107
  render: () => html`
68
108
  <grantcodes-app-bar>
69
- <a slot="logo" href="/" style="font-weight: 700; font-size: 1.25rem; text-decoration: none; color: var(--g-color-brand-purple-900);">
70
- Dashboard
71
- </a>
72
- <div slot="nav" style="display: flex; gap: 0.5rem;">
73
- <a href="/">Overview</a>
74
- <a href="/analytics">Analytics</a>
75
- <a href="/reports">Reports</a>
109
+ <a slot="logo" href="/">Dashboard</a>
110
+ <div slot="nav">
111
+ <grantcodes-nav-link><a href="/">Overview</a></grantcodes-nav-link>
112
+ <grantcodes-nav-link><a href="/analytics">Analytics</a></grantcodes-nav-link>
113
+ <grantcodes-nav-link><a href="/reports">Reports</a></grantcodes-nav-link>
76
114
  </div>
77
- <div slot="actions" style="display: flex; gap: 0.5rem; align-items: center;">
78
- <grantcodes-button>🔔</grantcodes-button>
79
- <grantcodes-button>⚙️</grantcodes-button>
80
- <grantcodes-button>👤</grantcodes-button>
115
+ <div slot="actions">
116
+ <grantcodes-button>Notifications</grantcodes-button>
117
+ <grantcodes-button>Settings</grantcodes-button>
118
+ <grantcodes-button>Profile</grantcodes-button>
81
119
  </div>
82
120
  </grantcodes-app-bar>
83
121
  `,