@reliability-design/web 1.0.6 → 1.2.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.
Files changed (78) hide show
  1. package/dist/components/rel-accordion/rel-accordion.ts +20 -31
  2. package/dist/components/rel-alert/rel-alert.ts +81 -11
  3. package/dist/components/rel-avatar/rel-avatar.ts +6 -3
  4. package/dist/components/rel-badge/rel-badge.ts +8 -3
  5. package/dist/components/rel-breadcrumb/rel-breadcrumb.ts +6 -6
  6. package/dist/components/rel-button/rel-button.ts +118 -16
  7. package/dist/components/rel-calendar/rel-calendar.ts +16 -9
  8. package/dist/components/rel-card/rel-card.ts +9 -17
  9. package/dist/components/rel-cardmedia/rel-cardmedia.ts +20 -23
  10. package/dist/components/rel-carousel/rel-carousel.ts +596 -469
  11. package/dist/components/rel-checkbox/rel-checkbox.ts +98 -15
  12. package/dist/components/rel-chip/rel-chip.ts +291 -186
  13. package/dist/components/rel-container/rel-container.ts +2 -2
  14. package/dist/components/rel-date-picker/rel-date-picker.ts +23 -19
  15. package/dist/components/rel-divider/rel-divider.ts +12 -3
  16. package/dist/components/rel-drawer/rel-drawer-footer.ts +27 -0
  17. package/dist/components/rel-drawer/rel-drawer.ts +57 -113
  18. package/dist/components/rel-kbd/rel-kbd.ts +94 -118
  19. package/dist/components/rel-layout/rel-layout.ts +49 -58
  20. package/dist/components/rel-menu/rel-menu.ts +359 -327
  21. package/dist/components/rel-menubar/rel-menubar-menu.css +3 -0
  22. package/dist/components/rel-menubar/rel-menubar-menu.ts +2 -1
  23. package/dist/components/rel-menubar/rel-menubar.ts +602 -576
  24. package/dist/components/rel-nav-menu/rel-nav-menu-item.ts +240 -143
  25. package/dist/components/rel-nav-menu/rel-nav-menu.ts +227 -331
  26. package/dist/components/rel-navbar/rel-navbar.ts +13 -0
  27. package/dist/components/rel-otp/rel-otp.ts +22 -25
  28. package/dist/components/rel-pagination/rel-pagination.ts +112 -63
  29. package/dist/components/rel-popover/rel-popover-content.ts +6 -5
  30. package/dist/components/rel-popover/rel-popover.ts +42 -20
  31. package/dist/components/rel-progress/rel-progress.ts +10 -9
  32. package/dist/components/rel-radio/rel-radio.ts +228 -155
  33. package/dist/components/rel-range-picker/rel-range-picker.css +349 -0
  34. package/dist/components/rel-range-picker/rel-range-picker.ts +1079 -0
  35. package/dist/components/rel-resizable/rel-resizable-handle.ts +12 -15
  36. package/dist/components/rel-segmented-button/rel-segmented-button.ts +41 -20
  37. package/dist/components/rel-select/rel-select.ts +112 -27
  38. package/dist/components/rel-sheet/rel-sheet.ts +362 -683
  39. package/dist/components/rel-sidebar/rel-sidebar.ts +13 -5
  40. package/dist/components/rel-slider/rel-slider.ts +74 -29
  41. package/dist/components/rel-snackbar/rel-snackbar.ts +67 -37
  42. package/dist/components/rel-stepper/rel-stepper.ts +43 -31
  43. package/dist/components/rel-switch/rel-switch.ts +26 -12
  44. package/dist/components/rel-tab/rel-tab.ts +57 -37
  45. package/dist/components/rel-table/rel-table-body.ts +5 -0
  46. package/dist/components/rel-table/rel-table-caption.ts +6 -1
  47. package/dist/components/rel-table/rel-table-cell.ts +42 -49
  48. package/dist/components/rel-table/rel-table-footer.ts +5 -0
  49. package/dist/components/rel-table/rel-table-head.ts +13 -1
  50. package/dist/components/rel-table/rel-table-header.ts +5 -0
  51. package/dist/components/rel-table/rel-table-row.ts +7 -3
  52. package/dist/components/rel-table/rel-table.ts +8 -2
  53. package/dist/components/rel-textfield/rel-textfield.ts +153 -44
  54. package/dist/components/rel-toast/rel-toast.ts +56 -22
  55. package/dist/components/rel-tooltip/rel-tooltip.ts +52 -9
  56. package/dist/components/rel-topbar/rel-topbar-actions.ts +24 -0
  57. package/dist/components/rel-topbar/rel-topbar-brand.ts +47 -0
  58. package/dist/components/rel-topbar/rel-topbar-dropdown-item.ts +63 -0
  59. package/dist/components/rel-topbar/rel-topbar-dropdown.ts +28 -0
  60. package/dist/components/rel-topbar/rel-topbar-item.ts +320 -0
  61. package/dist/components/rel-topbar/rel-topbar-mobile-panel.ts +24 -0
  62. package/dist/components/rel-topbar/rel-topbar-profile.ts +222 -0
  63. package/dist/components/rel-topbar/rel-topbar-utilities.ts +24 -0
  64. package/dist/components/rel-topbar/rel-topbar.ts +438 -0
  65. package/dist/index.d.mts +375 -411
  66. package/dist/index.d.ts +375 -411
  67. package/dist/index.js +7587 -7980
  68. package/dist/index.js.map +1 -1
  69. package/dist/index.mjs +7647 -8023
  70. package/dist/index.mjs.map +1 -1
  71. package/dist/rel-menubar-menu-BEEQDAXW.css +3 -0
  72. package/dist/styles/vars-v2.css +525 -0
  73. package/dist/styles/vars.css +79 -27
  74. package/dist/{vars-ITL2K3KO.css → vars-I2PC74XD.css} +79 -27
  75. package/dist/vars-v2-VMGWTFJZ.css +525 -0
  76. package/package.json +3 -1
  77. package/dist/components/rel-quote-page/README.md +0 -166
  78. package/dist/components/rel-quote-page/rel-quote-page.ts +0 -816
@@ -1,143 +1,240 @@
1
- import { LitElement, html, css } from "lit";
2
- import { customElement, property, state } from "lit/decorators.js";
3
-
4
- @customElement("rel-nav-menu-item")
5
- export class RelNavMenuItem extends LitElement {
6
- @property({ type: String }) label = "";
7
- @property({ type: String }) href = "";
8
- @property({ type: String, attribute: "item-id" }) itemId = "";
9
- @property({ type: Boolean, reflect: true }) disabled = false;
10
- @property({ type: String }) icon = "";
11
-
12
- @state() private hasContent = false;
13
-
14
- static styles = css`
15
- :host {
16
- display: inline-block;
17
- }
18
-
19
- .trigger {
20
- display: inline-flex;
21
- align-items: center;
22
- gap: var(--rel-spacing-space-2xs);
23
- padding: var(--rel-spacing-space-xs) var(--rel-spacing-space-md);
24
- font-family: var(--rel-fontFamilies-primary);
25
- font-size: var(--rel-fontSizes-sm);
26
- font-weight: var(--rel-fontWeights-medium);
27
- color: var(--rel-colors-gray-heading);
28
- background: transparent;
29
- border: none;
30
- border-radius: var(--rel-borders-radius-border-radius-200);
31
- cursor: pointer;
32
- transition: all 0.15s ease;
33
- text-decoration: none;
34
- outline: none;
35
- user-select: none;
36
- }
37
-
38
- .trigger:hover:not(:disabled) {
39
- background: var(--rel-surface-secondary, #fafafa);
40
- }
41
-
42
- .trigger:focus-visible {
43
- outline: 2px solid var(--rel-colors-blue-primary);
44
- outline-offset: 2px;
45
- }
46
-
47
- .trigger.active {
48
- background: var(--rel-surface-secondary, #fafafa);
49
- }
50
-
51
- .trigger:disabled {
52
- opacity: 0.5;
53
- cursor: not-allowed;
54
- }
55
-
56
- :host([disabled]) .trigger {
57
- opacity: 0.5;
58
- cursor: not-allowed;
59
- }
60
-
61
- .content {
62
- display: none;
63
- }
64
- `;
65
-
66
- connectedCallback() {
67
- super.connectedCallback();
68
- // Generate item-id from label if not provided
69
- if (!this.itemId && this.label) {
70
- this.itemId = this.label.toLowerCase().replace(/\s+/g, "-");
71
- }
72
- }
73
-
74
- firstUpdated() {
75
- // Check if there's any slotted content
76
- const slot = this.shadowRoot?.querySelector("slot");
77
- if (slot) {
78
- const nodes = slot.assignedNodes({ flatten: true });
79
- this.hasContent = nodes.some(
80
- (node) => node.nodeType === Node.ELEMENT_NODE || node.textContent?.trim()
81
- );
82
- }
83
- }
84
-
85
- private handleSlotChange() {
86
- const slot = this.shadowRoot?.querySelector("slot");
87
- if (slot) {
88
- const nodes = slot.assignedNodes({ flatten: true });
89
- this.hasContent = nodes.some(
90
- (node) => node.nodeType === Node.ELEMENT_NODE || node.textContent?.trim()
91
- );
92
- }
93
- }
94
-
95
- get triggerId() {
96
- return `nav-trigger-${this.itemId}`;
97
- }
98
-
99
- get panelId() {
100
- return `nav-panel-${this.itemId}`;
101
- }
102
-
103
- render() {
104
- const isLink = !!this.href && !this.hasContent;
105
- const tagName = isLink ? "a" : "button";
106
- const attrs = isLink
107
- ? { href: this.href }
108
- : {
109
- type: "button",
110
- "aria-haspopup": this.hasContent ? "menu" : undefined,
111
- "aria-controls": this.hasContent ? this.panelId : undefined,
112
- };
113
-
114
- return html`
115
- ${isLink
116
- ? html`
117
- <a
118
- class="trigger"
119
- href="${this.href}"
120
- id="${this.triggerId}"
121
- ?disabled="${this.disabled}"
122
- >
123
- ${this.label}
124
- </a>
125
- `
126
- : html`
127
- <button
128
- class="trigger"
129
- id="${this.triggerId}"
130
- type="button"
131
- ?disabled="${this.disabled}"
132
- aria-haspopup="${this.hasContent ? "menu" : "false"}"
133
- aria-controls="${this.hasContent ? this.panelId : ""}"
134
- >
135
- ${this.label}
136
- </button>
137
- `}
138
- <div class="content">
139
- <slot @slotchange="${this.handleSlotChange}"></slot>
140
- </div>
141
- `;
142
- }
143
- }
1
+ import { LitElement, html, css } from "lit";
2
+ import { customElement, property } from "lit/decorators.js";
3
+
4
+ @customElement("rel-nav-menu-item")
5
+ export class RelNavMenuItem extends LitElement {
6
+ @property({ type: String }) label = "";
7
+ @property({ type: String }) href = "";
8
+ @property({ type: String, attribute: "item-id" }) itemId = "";
9
+ @property({ type: Boolean, reflect: true }) disabled = false;
10
+ @property({ type: String }) icon = "";
11
+
12
+ /** Promoted from @state so rel-nav-menu can read it as a property. */
13
+ @property({ type: Boolean, reflect: true }) hasContent = false;
14
+
15
+ /** Set by rel-nav-menu to open/close this item's panel. */
16
+ @property({ type: Boolean, reflect: true }) open = false;
17
+
18
+ static styles = css`
19
+ :host {
20
+ display: inline-block;
21
+ }
22
+
23
+ .trigger {
24
+ display: inline-flex;
25
+ align-items: center;
26
+ gap: var(--rel-spacing-space-2xs);
27
+ padding: var(--rel-spacing-space-xs) var(--rel-spacing-space-md);
28
+ font-family: var(--rel-fontFamilies-primary);
29
+ font-size: var(--rel-fontSizes-sm);
30
+ font-weight: var(--rel-fontWeights-medium);
31
+ color: var(--rel-colors-gray-heading);
32
+ background: transparent;
33
+ border: none;
34
+ border-radius: var(--rel-borders-radius-border-radius-200);
35
+ cursor: pointer;
36
+ transition: all 0.15s ease;
37
+ text-decoration: none;
38
+ outline: none;
39
+ user-select: none;
40
+ }
41
+
42
+ .trigger:hover:not(:disabled) {
43
+ background: var(--rel-surface-secondary, #fafafa);
44
+ }
45
+
46
+ .trigger:focus-visible {
47
+ outline: 2px solid var(--rel-colors-blue-primary);
48
+ outline-offset: 2px;
49
+ }
50
+
51
+ /* Active state driven by :host([open]) — no external class manipulation needed */
52
+ :host([open]) .trigger,
53
+ .trigger.active {
54
+ background: var(--rel-surface-secondary, #fafafa);
55
+ }
56
+
57
+ .trigger:disabled {
58
+ opacity: 0.5;
59
+ cursor: not-allowed;
60
+ }
61
+
62
+ :host([disabled]) .trigger {
63
+ opacity: 0.5;
64
+ cursor: not-allowed;
65
+ }
66
+
67
+ /* Panel lives inside the item's own shadow DOM */
68
+ .panel {
69
+ position: fixed;
70
+ min-width: 320px;
71
+ max-width: 600px;
72
+ background: var(--rel-colors-white);
73
+ border: var(--rel-borders-width-stroke-100) solid var(--rel-colors-gray-border);
74
+ border-radius: var(--rel-borders-radius-border-radius-200);
75
+ box-shadow: var(--rel-shadows-shadow-300);
76
+ padding: var(--rel-spacing-space-xs);
77
+ z-index: 1000;
78
+ display: none;
79
+ }
80
+
81
+ .panel.open {
82
+ display: block;
83
+ }
84
+ `;
85
+
86
+ connectedCallback() {
87
+ super.connectedCallback();
88
+ if (!this.itemId && this.label) {
89
+ this.itemId = this.label.toLowerCase().replace(/\s+/g, "-");
90
+ }
91
+ }
92
+
93
+ firstUpdated() {
94
+ this.updateHasContent();
95
+ }
96
+
97
+ updated(changed: Map<string, any>) {
98
+ if (changed.has("open") && this.open) {
99
+ // Wait for paint so the panel has layout dimensions before positioning.
100
+ this.updateComplete.then(() => this.positionPanel());
101
+ }
102
+ }
103
+
104
+ // ── Content detection ──────────────────────────────────────────────────────
105
+
106
+ private updateHasContent() {
107
+ const slot = this.shadowRoot?.querySelector("slot");
108
+ if (slot) {
109
+ const nodes = slot.assignedNodes({ flatten: true });
110
+ this.hasContent = nodes.some(
111
+ (node) => node.nodeType === Node.ELEMENT_NODE || node.textContent?.trim()
112
+ );
113
+ }
114
+ }
115
+
116
+ private handleSlotChange() {
117
+ this.updateHasContent();
118
+ }
119
+
120
+ // ── Panel positioning (moved from rel-nav-menu) ────────────────────────────
121
+
122
+ private positionPanel() {
123
+ const trigger = this.shadowRoot?.querySelector(".trigger") as HTMLElement;
124
+ const panel = this.shadowRoot?.querySelector(".panel") as HTMLElement;
125
+ if (!trigger || !panel) return;
126
+
127
+ const triggerRect = trigger.getBoundingClientRect();
128
+ const panelRect = panel.getBoundingClientRect();
129
+ const viewportWidth = window.innerWidth;
130
+ const viewportHeight = window.innerHeight;
131
+
132
+ let top = triggerRect.bottom + 8;
133
+ let left = triggerRect.left;
134
+
135
+ // Handle right overflow
136
+ if (left + panelRect.width > viewportWidth) {
137
+ left = viewportWidth - panelRect.width - 16;
138
+ }
139
+
140
+ // Handle left overflow
141
+ if (left < 0) left = 16;
142
+
143
+ // Handle bottom overflow — flip above if more space
144
+ if (top + panelRect.height > viewportHeight) {
145
+ const spaceAbove = triggerRect.top;
146
+ const spaceBelow = viewportHeight - triggerRect.bottom;
147
+ if (spaceAbove > spaceBelow && spaceAbove > panelRect.height) {
148
+ top = triggerRect.top - panelRect.height - 8;
149
+ }
150
+ }
151
+
152
+ panel.style.top = `${top}px`;
153
+ panel.style.left = `${left}px`;
154
+ }
155
+
156
+ // ── Events dispatched upward — rel-nav-menu listens via connectedCallback ──
157
+
158
+ private handleTriggerClick() {
159
+ if (this.disabled) return;
160
+ this.dispatchEvent(
161
+ new CustomEvent("rel-nav-item-click", {
162
+ detail: { itemId: this.itemId, hasContent: this.hasContent },
163
+ bubbles: true,
164
+ composed: true,
165
+ })
166
+ );
167
+ }
168
+
169
+ private handleTriggerMouseEnter() {
170
+ if (this.disabled) return;
171
+ this.dispatchEvent(
172
+ new CustomEvent("rel-nav-item-hover", {
173
+ detail: { itemId: this.itemId },
174
+ bubbles: true,
175
+ composed: true,
176
+ })
177
+ );
178
+ }
179
+
180
+ // ── ID helpers ─────────────────────────────────────────────────────────────
181
+
182
+ get triggerId() {
183
+ return `nav-trigger-${this.itemId}`;
184
+ }
185
+
186
+ get panelId() {
187
+ return `nav-panel-${this.itemId}`;
188
+ }
189
+
190
+ // ── Render ─────────────────────────────────────────────────────────────────
191
+
192
+ render() {
193
+ const isLink = !!this.href && !this.hasContent;
194
+
195
+ return html`
196
+ ${isLink
197
+ ? html`
198
+ <a
199
+ class="trigger"
200
+ href="${this.href}"
201
+ id="${this.triggerId}"
202
+ ?disabled="${this.disabled}"
203
+ @click="${this.handleTriggerClick}"
204
+ @mouseenter="${this.handleTriggerMouseEnter}"
205
+ >
206
+ ${this.label}
207
+ </a>
208
+ `
209
+ : html`
210
+ <button
211
+ class="trigger"
212
+ id="${this.triggerId}"
213
+ type="button"
214
+ ?disabled="${this.disabled}"
215
+ aria-haspopup="${this.hasContent ? "menu" : "false"}"
216
+ aria-controls="${this.hasContent ? this.panelId : ""}"
217
+ aria-expanded="${this.open ? "true" : "false"}"
218
+ @click="${this.handleTriggerClick}"
219
+ @mouseenter="${this.handleTriggerMouseEnter}"
220
+ >
221
+ ${this.label}
222
+ </button>
223
+ `}
224
+
225
+ <!--
226
+ Panel rendered inside this shadow root.
227
+ Slot projects the consumer's light-DOM children directly — no cloning.
228
+ rel-nav-menu sets item.open = true/false to show/hide.
229
+ -->
230
+ <div
231
+ class="panel ${this.open ? "open" : ""}"
232
+ id="${this.panelId}"
233
+ role="menu"
234
+ @click="${(e: Event) => e.stopPropagation()}"
235
+ >
236
+ <slot @slotchange="${this.handleSlotChange}"></slot>
237
+ </div>
238
+ `;
239
+ }
240
+ }