@reliability-design/web 1.0.6 → 1.1.1

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.
Files changed (60) hide show
  1. package/dist/components/rel-accordion/rel-accordion.ts +4 -0
  2. package/dist/components/rel-alert/rel-alert.ts +83 -13
  3. package/dist/components/rel-avatar/rel-avatar.ts +3 -2
  4. package/dist/components/rel-badge/rel-badge.ts +6 -2
  5. package/dist/components/rel-button/rel-button.ts +64 -8
  6. package/dist/components/rel-calendar/rel-calendar.ts +3 -3
  7. package/dist/components/rel-carousel/rel-carousel.ts +10 -11
  8. package/dist/components/rel-checkbox/rel-checkbox.ts +33 -2
  9. package/dist/components/rel-chip/rel-chip.ts +63 -5
  10. package/dist/components/rel-divider/rel-divider.ts +9 -0
  11. package/dist/components/rel-drawer/rel-drawer-footer.ts +29 -0
  12. package/dist/components/rel-drawer/rel-drawer.ts +17 -26
  13. package/dist/components/rel-menu/rel-menu.ts +53 -21
  14. package/dist/components/rel-menubar/rel-menubar.ts +52 -23
  15. package/dist/components/rel-nav-menu/rel-nav-menu-item.ts +240 -143
  16. package/dist/components/rel-nav-menu/rel-nav-menu.ts +227 -331
  17. package/dist/components/rel-navbar/rel-navbar.ts +13 -0
  18. package/dist/components/rel-pagination/rel-pagination.ts +11 -6
  19. package/dist/components/rel-popover/rel-popover.ts +16 -13
  20. package/dist/components/rel-radio/rel-radio.ts +18 -1
  21. package/dist/components/rel-resizable/rel-resizable-handle.ts +4 -8
  22. package/dist/components/rel-select/rel-select.ts +14 -0
  23. package/dist/components/rel-sheet/rel-sheet.ts +7 -6
  24. package/dist/components/rel-sidebar/rel-sidebar.ts +13 -5
  25. package/dist/components/rel-slider/rel-slider.ts +25 -2
  26. package/dist/components/rel-snackbar/rel-snackbar.ts +46 -16
  27. package/dist/components/rel-stepper/rel-stepper.ts +32 -21
  28. package/dist/components/rel-switch/rel-switch.ts +19 -6
  29. package/dist/components/rel-tab/rel-tab.ts +49 -15
  30. package/dist/components/rel-table/rel-table-body.ts +5 -0
  31. package/dist/components/rel-table/rel-table-caption.ts +6 -1
  32. package/dist/components/rel-table/rel-table-cell.ts +42 -49
  33. package/dist/components/rel-table/rel-table-footer.ts +5 -0
  34. package/dist/components/rel-table/rel-table-head.ts +13 -1
  35. package/dist/components/rel-table/rel-table-header.ts +5 -0
  36. package/dist/components/rel-table/rel-table-row.ts +7 -3
  37. package/dist/components/rel-table/rel-table.ts +8 -2
  38. package/dist/components/rel-textfield/rel-textfield.ts +20 -20
  39. package/dist/components/rel-toast/rel-toast.ts +31 -10
  40. package/dist/components/rel-tooltip/rel-tooltip.ts +123 -80
  41. package/dist/components/rel-topbar/rel-topbar-actions.ts +23 -0
  42. package/dist/components/rel-topbar/rel-topbar-brand.ts +46 -0
  43. package/dist/components/rel-topbar/rel-topbar-dropdown-item.ts +33 -0
  44. package/dist/components/rel-topbar/rel-topbar-dropdown.ts +28 -0
  45. package/dist/components/rel-topbar/rel-topbar-item.ts +315 -0
  46. package/dist/components/rel-topbar/rel-topbar-mobile-panel.ts +23 -0
  47. package/dist/components/rel-topbar/rel-topbar-profile.ts +248 -0
  48. package/dist/components/rel-topbar/rel-topbar-utilities.ts +23 -0
  49. package/dist/components/rel-topbar/rel-topbar.ts +329 -0
  50. package/dist/index.d.mts +278 -289
  51. package/dist/index.d.ts +278 -289
  52. package/dist/index.js +4498 -5727
  53. package/dist/index.js.map +1 -1
  54. package/dist/index.mjs +4535 -5756
  55. package/dist/index.mjs.map +1 -1
  56. package/dist/styles/vars.css +346 -294
  57. package/dist/{vars-ITL2K3KO.css → vars-TBB4BMSD.css} +346 -294
  58. package/package.json +2 -1
  59. package/dist/components/rel-quote-page/README.md +0 -166
  60. package/dist/components/rel-quote-page/rel-quote-page.ts +0 -816
@@ -1,331 +1,227 @@
1
- import { LitElement, html, css } from "lit";
2
- import { customElement, property, state, query } from "lit/decorators.js";
3
- import { RelNavMenuItem } from "./rel-nav-menu-item";
4
-
5
- type DensityType = "comfortable" | "compact";
6
-
7
- @customElement("rel-nav-menu")
8
- export class RelNavMenu extends LitElement {
9
- @property({ type: String, reflect: true }) open = "";
10
- @property({ type: Boolean, reflect: true }) disabled = false;
11
- @property({ type: String }) density: DensityType = "comfortable";
12
-
13
- @state() private items: RelNavMenuItem[] = [];
14
- @state() private focusedIndex = 0;
15
- @state() private hoverSwitchEnabled = false;
16
-
17
- @query(".nav-container") private container!: HTMLElement;
18
-
19
- static styles = css`
20
- :host {
21
- display: block;
22
- font-family: var(--rel-fontFamilies-primary);
23
- }
24
-
25
- .nav-container {
26
- display: flex;
27
- align-items: center;
28
- gap: var(--rel-spacing-space-3xs);
29
- padding: var(--rel-spacing-space-2xs);
30
- background: var(--rel-colors-gray-light);
31
- border-radius: var(--rel-borders-radius-border-radius-200);
32
- border: var(--rel-borders-width-stroke-100) solid var(--rel-colors-gray-border);
33
- }
34
-
35
- .nav-container.compact {
36
- padding: var(--rel-spacing-space-3xs);
37
- gap: 0;
38
- }
39
-
40
- .dropdown-panel {
41
- position: fixed;
42
- min-width: 320px;
43
- max-width: 600px;
44
- background: var(--rel-colors-white);
45
- border: var(--rel-borders-width-stroke-100) solid var(--rel-colors-gray-border);
46
- border-radius: var(--rel-borders-radius-border-radius-200);
47
- box-shadow: var(--rel-shadows-shadow-300);
48
- padding: var(--rel-spacing-space-xs);
49
- z-index: 1000;
50
- display: none;
51
- }
52
-
53
- .dropdown-panel.open {
54
- display: block;
55
- }
56
-
57
- :host([disabled]) .nav-container {
58
- opacity: 0.5;
59
- pointer-events: none;
60
- }
61
- `;
62
-
63
- connectedCallback() {
64
- super.connectedCallback();
65
- this.discoverItems();
66
- document.addEventListener("click", this.handleOutsideClick);
67
- }
68
-
69
- disconnectedCallback() {
70
- super.disconnectedCallback();
71
- document.removeEventListener("click", this.handleOutsideClick);
72
- }
73
-
74
- private discoverItems() {
75
- const slot = this.shadowRoot?.querySelector("slot");
76
- if (slot) {
77
- const nodes = slot.assignedElements() as RelNavMenuItem[];
78
- this.items = nodes.filter((el) => el.tagName === "REL-NAV-MENU-ITEM");
79
- }
80
- }
81
-
82
- private handleSlotChange() {
83
- this.discoverItems();
84
- }
85
-
86
- private handleOutsideClick = (e: MouseEvent) => {
87
- const path = e.composedPath() as HTMLElement[];
88
- const isInside = path.some(
89
- (el) =>
90
- el === this ||
91
- el.classList?.contains("dropdown-panel") ||
92
- el.tagName === "REL-NAV-MENU-ITEM"
93
- );
94
- if (!isInside && this.open) {
95
- this.closePanel();
96
- }
97
- };
98
-
99
- private openPanel(itemId: string) {
100
- if (this.disabled) return;
101
-
102
- const wasOpen = this.open === itemId;
103
- this.open = wasOpen ? "" : itemId;
104
-
105
- if (!wasOpen) {
106
- this.hoverSwitchEnabled = true;
107
- }
108
-
109
- this.dispatchEvent(
110
- new CustomEvent("rel-nav-open-change", {
111
- detail: { openId: this.open },
112
- bubbles: true,
113
- composed: true,
114
- })
115
- );
116
-
117
- if (this.open) {
118
- this.updateComplete.then(() => this.positionPanel(itemId));
119
- }
120
- }
121
-
122
- private closePanel() {
123
- if (this.open) {
124
- this.open = "";
125
- this.hoverSwitchEnabled = false;
126
- this.dispatchEvent(
127
- new CustomEvent("rel-nav-open-change", {
128
- detail: { openId: "" },
129
- bubbles: true,
130
- composed: true,
131
- })
132
- );
133
- }
134
- }
135
-
136
- private positionPanel(itemId: string) {
137
- const item = this.items.find((i) => i.itemId === itemId);
138
- if (!item) return;
139
-
140
- const trigger = item.shadowRoot?.querySelector(".trigger") as HTMLElement;
141
- const panel = this.shadowRoot?.querySelector(
142
- `.dropdown-panel[data-item-id="${itemId}"]`
143
- ) as HTMLElement;
144
-
145
- if (!trigger || !panel) return;
146
-
147
- const triggerRect = trigger.getBoundingClientRect();
148
- const panelRect = panel.getBoundingClientRect();
149
- const viewportWidth = window.innerWidth;
150
- const viewportHeight = window.innerHeight;
151
-
152
- // Default: position below trigger, start-aligned
153
- let top = triggerRect.bottom + 8;
154
- let left = triggerRect.left;
155
-
156
- // Handle right overflow
157
- if (left + panelRect.width > viewportWidth) {
158
- left = viewportWidth - panelRect.width - 16;
159
- }
160
-
161
- // Handle left overflow
162
- if (left < 0) {
163
- left = 16;
164
- }
165
-
166
- // Handle bottom overflow (flip above if needed)
167
- if (top + panelRect.height > viewportHeight) {
168
- const spaceAbove = triggerRect.top;
169
- const spaceBelow = viewportHeight - triggerRect.bottom;
170
-
171
- if (spaceAbove > spaceBelow && spaceAbove > panelRect.height) {
172
- top = triggerRect.top - panelRect.height - 8;
173
- }
174
- }
175
-
176
- panel.style.top = `${top}px`;
177
- panel.style.left = `${left}px`;
178
- }
179
-
180
- private handleItemClick(item: RelNavMenuItem, event: Event) {
181
- if (this.disabled || item.disabled) return;
182
-
183
- // If item has href and no content, let default behavior happen
184
- if (item.href && !this.hasItemContent(item)) {
185
- return;
186
- }
187
-
188
- event.preventDefault();
189
-
190
- // If item has content, toggle panel
191
- if (this.hasItemContent(item)) {
192
- this.openPanel(item.itemId);
193
- }
194
- }
195
-
196
- private handleItemMouseEnter(item: RelNavMenuItem) {
197
- if (this.disabled || item.disabled) return;
198
-
199
- // Hover switching: if a panel is open, hovering another trigger switches to it
200
- if (this.open && this.hoverSwitchEnabled && this.hasItemContent(item)) {
201
- this.openPanel(item.itemId);
202
- }
203
- }
204
-
205
- private handleKeyDown(event: KeyboardEvent) {
206
- if (this.disabled) return;
207
-
208
- const { key } = event;
209
- const focusableItems = this.items.filter((item) => !item.disabled);
210
-
211
- if (key === "ArrowRight") {
212
- event.preventDefault();
213
- this.focusedIndex = Math.min(focusableItems.length - 1, this.focusedIndex + 1);
214
- this.focusItem(this.focusedIndex);
215
- } else if (key === "ArrowLeft") {
216
- event.preventDefault();
217
- this.focusedIndex = Math.max(0, this.focusedIndex - 1);
218
- this.focusItem(this.focusedIndex);
219
- } else if (key === "Enter" || key === " ") {
220
- event.preventDefault();
221
- const item = focusableItems[this.focusedIndex];
222
- if (item && this.hasItemContent(item)) {
223
- this.openPanel(item.itemId);
224
- }
225
- } else if (key === "Escape") {
226
- event.preventDefault();
227
- if (this.open) {
228
- this.closePanel();
229
- const openItem = this.items.find((i) => i.itemId === this.open);
230
- if (openItem) {
231
- const trigger = openItem.shadowRoot?.querySelector(".trigger") as HTMLElement;
232
- trigger?.focus();
233
- }
234
- }
235
- } else if (key === "ArrowDown" && this.open) {
236
- event.preventDefault();
237
- // Move focus into the panel
238
- const panel = this.shadowRoot?.querySelector(
239
- `.dropdown-panel[data-item-id="${this.open}"]`
240
- ) as HTMLElement;
241
- if (panel) {
242
- const firstFocusable = panel.querySelector("a, button") as HTMLElement;
243
- firstFocusable?.focus();
244
- }
245
- }
246
- }
247
-
248
- private focusItem(index: number) {
249
- const focusableItems = this.items.filter((item) => !item.disabled);
250
- const item = focusableItems[index];
251
- if (item) {
252
- const trigger = item.shadowRoot?.querySelector(".trigger") as HTMLElement;
253
- trigger?.focus();
254
- }
255
- }
256
-
257
- private hasItemContent(item: RelNavMenuItem): boolean {
258
- const slot = item.shadowRoot?.querySelector("slot");
259
- if (!slot) return false;
260
- const nodes = slot.assignedNodes({ flatten: true });
261
- return nodes.some(
262
- (node) => node.nodeType === Node.ELEMENT_NODE || node.textContent?.trim()
263
- );
264
- }
265
-
266
- private renderDropdownPanel(item: RelNavMenuItem) {
267
- if (!this.hasItemContent(item)) return null;
268
-
269
- const isOpen = this.open === item.itemId;
270
-
271
- return html`
272
- <div
273
- class="dropdown-panel ${isOpen ? "open" : ""}"
274
- data-item-id="${item.itemId}"
275
- id="${item.panelId}"
276
- role="menu"
277
- @click="${(e: Event) => e.stopPropagation()}"
278
- >
279
- ${this.getItemContent(item)}
280
- </div>
281
- `;
282
- }
283
-
284
- private getItemContent(item: RelNavMenuItem) {
285
- const slot = item.shadowRoot?.querySelector("slot");
286
- if (!slot) return null;
287
-
288
- const nodes = slot.assignedNodes({ flatten: true });
289
- const elements = nodes.filter((node) => node.nodeType === Node.ELEMENT_NODE) as Element[];
290
-
291
- // Clone and return the content
292
- return elements.map((el) => {
293
- const clone = el.cloneNode(true);
294
- return clone;
295
- });
296
- }
297
-
298
- render() {
299
- return html`
300
- <nav
301
- class="nav-container ${this.density === "compact" ? "compact" : ""}"
302
- role="navigation"
303
- @keydown="${this.handleKeyDown}"
304
- >
305
- <slot @slotchange="${this.handleSlotChange}"></slot>
306
- </nav>
307
-
308
- ${this.items.map((item) => {
309
- // Set up click and hover handlers by attaching to the trigger
310
- this.updateComplete.then(() => {
311
- const trigger = item.shadowRoot?.querySelector(".trigger") as HTMLElement;
312
- if (trigger) {
313
- // Remove old listeners if any
314
- trigger.onclick = (e) => this.handleItemClick(item, e);
315
- trigger.onmouseenter = () => this.handleItemMouseEnter(item);
316
-
317
- // Update active state
318
- trigger.classList.toggle("active", this.open === item.itemId);
319
-
320
- // Update ARIA attributes
321
- if (this.hasItemContent(item)) {
322
- trigger.setAttribute("aria-expanded", this.open === item.itemId ? "true" : "false");
323
- }
324
- }
325
- });
326
-
327
- return this.renderDropdownPanel(item);
328
- })}
329
- `;
330
- }
331
- }
1
+ import { LitElement, html, css } from "lit";
2
+ import { customElement, property, state, query } from "lit/decorators.js";
3
+ import { RelNavMenuItem } from "./rel-nav-menu-item";
4
+
5
+ type DensityType = "comfortable" | "compact";
6
+
7
+ @customElement("rel-nav-menu")
8
+ export class RelNavMenu extends LitElement {
9
+ @property({ type: String, reflect: true }) open = "";
10
+ @property({ type: Boolean, reflect: true }) disabled = false;
11
+ @property({ type: String }) density: DensityType = "comfortable";
12
+
13
+ @state() private items: RelNavMenuItem[] = [];
14
+ @state() private focusedIndex = 0;
15
+ @state() private hoverSwitchEnabled = false;
16
+
17
+ @query(".nav-container") private container!: HTMLElement;
18
+
19
+ static styles = css`
20
+ :host {
21
+ display: block;
22
+ font-family: var(--rel-fontFamilies-primary);
23
+ }
24
+
25
+ .nav-container {
26
+ display: flex;
27
+ align-items: center;
28
+ gap: var(--rel-spacing-space-3xs);
29
+ padding: var(--rel-spacing-space-2xs);
30
+ background: var(--rel-colors-gray-light);
31
+ border-radius: var(--rel-borders-radius-border-radius-200);
32
+ border: var(--rel-borders-width-stroke-100) solid var(--rel-colors-gray-border);
33
+ }
34
+
35
+ .nav-container.compact {
36
+ padding: var(--rel-spacing-space-3xs);
37
+ gap: 0;
38
+ }
39
+
40
+ :host([disabled]) .nav-container {
41
+ opacity: 0.5;
42
+ pointer-events: none;
43
+ }
44
+ `;
45
+
46
+ // ── Lifecycle ──────────────────────────────────────────────────────────────
47
+
48
+ connectedCallback() {
49
+ super.connectedCallback();
50
+ this.discoverItems();
51
+ document.addEventListener("click", this.handleOutsideClick);
52
+ // Delegate item interactions via composed events — no shadow DOM mutation.
53
+ this.addEventListener("rel-nav-item-click", this.handleNavItemClick as EventListener);
54
+ this.addEventListener("rel-nav-item-hover", this.handleNavItemHover as EventListener);
55
+ }
56
+
57
+ disconnectedCallback() {
58
+ super.disconnectedCallback();
59
+ document.removeEventListener("click", this.handleOutsideClick);
60
+ this.removeEventListener("rel-nav-item-click", this.handleNavItemClick as EventListener);
61
+ this.removeEventListener("rel-nav-item-hover", this.handleNavItemHover as EventListener);
62
+ }
63
+
64
+ // ── Item discovery ─────────────────────────────────────────────────────────
65
+
66
+ private discoverItems() {
67
+ const slot = this.shadowRoot?.querySelector("slot");
68
+ if (slot) {
69
+ const nodes = slot.assignedElements() as RelNavMenuItem[];
70
+ this.items = nodes.filter((el) => el.tagName === "REL-NAV-MENU-ITEM");
71
+ }
72
+ }
73
+
74
+ private handleSlotChange() {
75
+ this.discoverItems();
76
+ }
77
+
78
+ // ── Outside-click dismissal ────────────────────────────────────────────────
79
+
80
+ private handleOutsideClick = (e: MouseEvent) => {
81
+ const path = e.composedPath() as HTMLElement[];
82
+ const isInside = path.some(
83
+ (el) => el === this || el.tagName === "REL-NAV-MENU-ITEM"
84
+ );
85
+ if (!isInside && this.open) {
86
+ this.closePanel();
87
+ }
88
+ };
89
+
90
+ // ── Delegated item event handlers ──────────────────────────────────────────
91
+
92
+ private handleNavItemClick = (e: Event) => {
93
+ const { itemId, hasContent } = (e as CustomEvent).detail;
94
+ const item = this.items.find((i) => i.itemId === itemId);
95
+ if (!item || this.disabled || item.disabled) return;
96
+ // Plain link with no panel content — let the browser navigate.
97
+ if (item.href && !hasContent) return;
98
+ e.preventDefault();
99
+ if (hasContent) this.openPanel(itemId);
100
+ };
101
+
102
+ private handleNavItemHover = (e: Event) => {
103
+ const { itemId } = (e as CustomEvent).detail;
104
+ const item = this.items.find((i) => i.itemId === itemId);
105
+ if (!item || this.disabled || item.disabled) return;
106
+ if (this.open && this.hoverSwitchEnabled && item.hasContent) {
107
+ this.openPanel(itemId);
108
+ }
109
+ };
110
+
111
+ // ── Panel open/close ───────────────────────────────────────────────────────
112
+
113
+ private openPanel(itemId: string) {
114
+ if (this.disabled) return;
115
+
116
+ // Close the currently open item before switching.
117
+ if (this.open && this.open !== itemId) {
118
+ const prev = this.items.find((i) => i.itemId === this.open);
119
+ if (prev) prev.open = false;
120
+ }
121
+
122
+ const wasOpen = this.open === itemId;
123
+ this.open = wasOpen ? "" : itemId;
124
+
125
+ const item = this.items.find((i) => i.itemId === itemId);
126
+ if (item) item.open = !wasOpen;
127
+
128
+ if (!wasOpen) {
129
+ this.hoverSwitchEnabled = true;
130
+ }
131
+
132
+ this.dispatchEvent(
133
+ new CustomEvent("rel-nav-open-change", {
134
+ detail: { openId: this.open },
135
+ bubbles: true,
136
+ composed: true,
137
+ })
138
+ );
139
+ }
140
+
141
+ private closePanel() {
142
+ if (this.open) {
143
+ const openItem = this.items.find((i) => i.itemId === this.open);
144
+ if (openItem) openItem.open = false;
145
+ this.open = "";
146
+ this.hoverSwitchEnabled = false;
147
+ this.dispatchEvent(
148
+ new CustomEvent("rel-nav-open-change", {
149
+ detail: { openId: "" },
150
+ bubbles: true,
151
+ composed: true,
152
+ })
153
+ );
154
+ }
155
+ }
156
+
157
+ // ── Keyboard navigation ────────────────────────────────────────────────────
158
+
159
+ private handleKeyDown(event: KeyboardEvent) {
160
+ if (this.disabled) return;
161
+
162
+ const { key } = event;
163
+ const focusableItems = this.items.filter((item) => !item.disabled);
164
+
165
+ if (key === "ArrowRight") {
166
+ event.preventDefault();
167
+ this.focusedIndex = Math.min(focusableItems.length - 1, this.focusedIndex + 1);
168
+ this.focusItem(this.focusedIndex);
169
+ } else if (key === "ArrowLeft") {
170
+ event.preventDefault();
171
+ this.focusedIndex = Math.max(0, this.focusedIndex - 1);
172
+ this.focusItem(this.focusedIndex);
173
+ } else if (key === "Enter" || key === " ") {
174
+ event.preventDefault();
175
+ const item = focusableItems[this.focusedIndex];
176
+ if (item && item.hasContent) {
177
+ this.openPanel(item.itemId);
178
+ }
179
+ } else if (key === "Escape") {
180
+ event.preventDefault();
181
+ if (this.open) {
182
+ // Capture before closePanel() clears this.open.
183
+ const openItemId = this.open;
184
+ this.closePanel();
185
+ const openItem = this.items.find((i) => i.itemId === openItemId);
186
+ if (openItem) {
187
+ const trigger = openItem.shadowRoot?.querySelector(".trigger") as HTMLElement;
188
+ trigger?.focus();
189
+ }
190
+ }
191
+ } else if (key === "ArrowDown" && this.open) {
192
+ event.preventDefault();
193
+ // Move focus into the open panel (now inside the item's shadow root).
194
+ const openItem = this.items.find((i) => i.itemId === this.open);
195
+ if (openItem) {
196
+ const panel = openItem.shadowRoot?.querySelector(".panel") as HTMLElement;
197
+ if (panel) {
198
+ const firstFocusable = panel.querySelector("a, button") as HTMLElement;
199
+ firstFocusable?.focus();
200
+ }
201
+ }
202
+ }
203
+ }
204
+
205
+ private focusItem(index: number) {
206
+ const focusableItems = this.items.filter((item) => !item.disabled);
207
+ const item = focusableItems[index];
208
+ if (item) {
209
+ const trigger = item.shadowRoot?.querySelector(".trigger") as HTMLElement;
210
+ trigger?.focus();
211
+ }
212
+ }
213
+
214
+ // ── Render ─────────────────────────────────────────────────────────────────
215
+
216
+ render() {
217
+ return html`
218
+ <nav
219
+ class="nav-container ${this.density === "compact" ? "compact" : ""}"
220
+ role="navigation"
221
+ @keydown="${this.handleKeyDown}"
222
+ >
223
+ <slot @slotchange="${this.handleSlotChange}"></slot>
224
+ </nav>
225
+ `;
226
+ }
227
+ }
@@ -1,8 +1,21 @@
1
1
  import { LitElement, html, css } from "lit";
2
2
  import { customElement, property } from "lit/decorators.js";
3
3
 
4
+ /**
5
+ * @deprecated rel-navbar is deprecated and will be removed in a future release.
6
+ * Use rel-topbar and its sub-components instead:
7
+ * rel-topbar, rel-topbar-brand, rel-topbar-actions, rel-topbar-utilities,
8
+ * rel-topbar-item, rel-topbar-dropdown, rel-topbar-dropdown-item
9
+ */
4
10
  @customElement("rel-navbar")
5
11
  export class RelNavbar extends LitElement {
12
+ constructor() {
13
+ super();
14
+ console.warn(
15
+ "[rel-navbar] rel-navbar is deprecated. Use rel-topbar instead."
16
+ );
17
+ }
18
+
6
19
  @property({ type: Boolean, reflect: true })
7
20
  sticky = false;
8
21
 
@@ -9,7 +9,7 @@ type PageItem = { type: "page"; value: number } | { type: "ellipsis" } | { type:
9
9
  export class RelPagination extends LitElement {
10
10
  @property({ type: Number }) page?: number;
11
11
  @property({ type: Number }) defaultPage = 1;
12
- @property({ type: Number }) totalPages!: number;
12
+ @property({ type: Number }) totalPages = 0;
13
13
  @property({ type: Number }) siblingCount = 1;
14
14
  @property({ type: Number }) boundaryCount = 1;
15
15
  @property({ type: Boolean, reflect: true }) disabled = false;
@@ -87,8 +87,8 @@ export class RelPagination extends LitElement {
87
87
 
88
88
  button[aria-current="page"],
89
89
  a[aria-current="page"] {
90
- background: var(--rel-colors-gray-heading);
91
- color: var(--rel-colors-white);
90
+ background: var(--rel-color-bg-selected);
91
+ color: var(--rel-color-text-primary);
92
92
  border-color: var(--rel-colors-gray-heading);
93
93
  font-weight: var(--rel-fontWeights-semibold);
94
94
  }
@@ -222,6 +222,11 @@ export class RelPagination extends LitElement {
222
222
  );
223
223
  }
224
224
 
225
+ private getHref(page: number): string {
226
+ if (!this.hrefTemplate) return "#";
227
+ return this.hrefTemplate.replace(/\{page\}/, String(page));
228
+ }
229
+
225
230
  private handleKeyDown(event: KeyboardEvent, callback: () => void) {
226
231
  if (event.key === "Enter" || event.key === " ") {
227
232
  event.preventDefault();
@@ -258,7 +263,7 @@ export class RelPagination extends LitElement {
258
263
  const targetPage = current - 1;
259
264
 
260
265
  if (useLinks) {
261
- const href = disabled ? "#" : this.hrefTemplate.replace("{page}", String(targetPage));
266
+ const href = disabled ? "#" : this.getHref(targetPage);
262
267
  return html`
263
268
  <a
264
269
  href="${href}"
@@ -295,7 +300,7 @@ export class RelPagination extends LitElement {
295
300
  const targetPage = current + 1;
296
301
 
297
302
  if (useLinks) {
298
- const href = disabled ? "#" : this.hrefTemplate.replace("{page}", String(targetPage));
303
+ const href = disabled ? "#" : this.getHref(targetPage);
299
304
  return html`
300
305
  <a
301
306
  href="${href}"
@@ -332,7 +337,7 @@ export class RelPagination extends LitElement {
332
337
  const isCurrent = pageNum === current;
333
338
 
334
339
  if (useLinks) {
335
- const href = this.hrefTemplate.replace("{page}", String(pageNum));
340
+ const href = this.getHref(pageNum);
336
341
  return html`
337
342
  <a
338
343
  href="${href}"