@reliability-design/web 1.0.3 → 1.0.6

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 (114) hide show
  1. package/dist/components/rel-accordion/README.md +132 -0
  2. package/dist/components/rel-accordion/rel-accordion.ts +43 -16
  3. package/dist/components/rel-alert/README.md +141 -0
  4. package/dist/components/rel-alert/rel-alert.ts +18 -7
  5. package/dist/components/rel-avatar/README.md +119 -0
  6. package/dist/components/rel-badge/README.md +86 -0
  7. package/dist/components/rel-badge/rel-badge.ts +6 -6
  8. package/dist/components/rel-breadcrumb/README.md +102 -0
  9. package/dist/components/rel-breadcrumb/rel-breadcrumb.ts +12 -6
  10. package/dist/components/rel-button/README.md +130 -0
  11. package/dist/components/rel-calendar/README.md +109 -0
  12. package/dist/components/rel-calendar/index.ts +1 -0
  13. package/dist/components/rel-calendar/rel-calendar.ts +467 -0
  14. package/dist/components/rel-card/README.md +94 -0
  15. package/dist/components/rel-card/rel-card.ts +12 -3
  16. package/dist/components/rel-cardmedia/README.md +127 -0
  17. package/dist/components/rel-cardmedia/rel-cardmedia.ts +14 -4
  18. package/dist/components/rel-carousel/README.md +166 -0
  19. package/dist/components/rel-carousel/index.ts +1 -0
  20. package/dist/components/rel-carousel/rel-carousel.ts +469 -0
  21. package/dist/components/rel-chart/README.md +286 -0
  22. package/dist/components/rel-chart/index.ts +1 -0
  23. package/dist/components/rel-chart/rel-chart.ts +736 -0
  24. package/dist/components/rel-checkbox/README.md +77 -0
  25. package/dist/components/rel-checkbox/rel-checkbox.ts +18 -10
  26. package/dist/components/rel-chip/README.md +114 -0
  27. package/dist/components/rel-chip/rel-chip.ts +20 -4
  28. package/dist/components/rel-container/README.md +99 -0
  29. package/dist/components/rel-date-picker/README.md +253 -0
  30. package/dist/components/rel-date-picker/index.ts +1 -0
  31. package/dist/components/rel-date-picker/rel-date-picker.ts +916 -0
  32. package/dist/components/rel-divider/README.md +100 -0
  33. package/dist/components/rel-drawer/README.md +200 -0
  34. package/dist/components/rel-drawer/index.ts +1 -0
  35. package/dist/components/rel-drawer/rel-drawer.ts +621 -0
  36. package/dist/components/rel-kbd/README.md +151 -0
  37. package/dist/components/rel-kbd/rel-kbd.ts +118 -0
  38. package/dist/components/rel-layout/README.md +88 -0
  39. package/dist/components/rel-menu/README.md +151 -0
  40. package/dist/components/rel-menu/rel-menu.ts +18 -10
  41. package/dist/components/rel-menubar/README.md +329 -0
  42. package/dist/components/rel-menubar/index.ts +2 -0
  43. package/dist/components/rel-menubar/rel-menubar-menu.ts +16 -0
  44. package/dist/components/rel-menubar/rel-menubar.ts +576 -0
  45. package/dist/components/rel-nav-menu/README.md +289 -0
  46. package/dist/components/rel-nav-menu/index.ts +3 -0
  47. package/dist/components/rel-nav-menu/rel-nav-menu-item.ts +143 -0
  48. package/dist/components/rel-nav-menu/rel-nav-menu-panel.ts +53 -0
  49. package/dist/components/rel-nav-menu/rel-nav-menu.ts +331 -0
  50. package/dist/components/rel-navbar/README.md +126 -0
  51. package/dist/components/rel-navbar/rel-navbar.ts +91 -0
  52. package/dist/components/rel-otp/README.md +440 -0
  53. package/dist/components/rel-otp/index.ts +1 -0
  54. package/dist/components/rel-otp/rel-otp.ts +504 -0
  55. package/dist/components/rel-pagination/README.md +410 -0
  56. package/dist/components/rel-pagination/index.ts +1 -0
  57. package/dist/components/rel-pagination/rel-pagination.ts +376 -0
  58. package/dist/components/rel-popover/README.md +568 -0
  59. package/dist/components/rel-popover/index.ts +2 -0
  60. package/dist/components/rel-popover/rel-popover-content.ts +55 -0
  61. package/dist/components/rel-popover/rel-popover.ts +327 -0
  62. package/dist/components/rel-progress/README.md +110 -0
  63. package/dist/components/rel-progress/rel-progress.ts +32 -5
  64. package/dist/components/rel-quote-page/README.md +166 -0
  65. package/dist/components/rel-quote-page/rel-quote-page.ts +816 -0
  66. package/dist/components/rel-radio/README.md +120 -0
  67. package/dist/components/rel-radio/rel-radio.ts +13 -5
  68. package/dist/components/rel-resizable/README.md +140 -0
  69. package/dist/components/rel-resizable/index.ts +3 -0
  70. package/dist/components/rel-resizable/rel-resizable-group.ts +374 -0
  71. package/dist/components/rel-resizable/rel-resizable-handle.ts +149 -0
  72. package/dist/components/rel-resizable/rel-resizable-panel.ts +47 -0
  73. package/dist/components/rel-segmented-button/README.md +141 -0
  74. package/dist/components/rel-segmented-button/rel-segmented-button.ts +18 -13
  75. package/dist/components/rel-select/README.md +107 -0
  76. package/dist/components/rel-select/rel-select.ts +14 -14
  77. package/dist/components/rel-sheet/README.md +224 -0
  78. package/dist/components/rel-sheet/rel-sheet.ts +683 -0
  79. package/dist/components/rel-sidebar/README.md +209 -0
  80. package/dist/components/rel-sidebar/rel-sidebar.ts +1158 -0
  81. package/dist/components/rel-slider/README.md +135 -0
  82. package/dist/components/rel-slider/rel-slider.ts +19 -7
  83. package/dist/components/rel-snackbar/README.md +134 -0
  84. package/dist/components/rel-snackbar/rel-snackbar.ts +67 -2
  85. package/dist/components/rel-stepper/README.md +160 -0
  86. package/dist/components/rel-stepper/rel-stepper.ts +6 -6
  87. package/dist/components/rel-switch/README.md +102 -0
  88. package/dist/components/rel-switch/rel-switch.ts +15 -6
  89. package/dist/components/rel-tab/README.md +163 -0
  90. package/dist/components/rel-tab/rel-tab.ts +36 -14
  91. package/dist/components/rel-table/README.md +178 -0
  92. package/dist/components/rel-table/rel-table-body.ts +16 -0
  93. package/dist/components/rel-table/rel-table-caption.ts +22 -0
  94. package/dist/components/rel-table/rel-table-cell.ts +49 -0
  95. package/dist/components/rel-table/rel-table-footer.ts +18 -0
  96. package/dist/components/rel-table/rel-table-head.ts +33 -0
  97. package/dist/components/rel-table/rel-table-header.ts +16 -0
  98. package/dist/components/rel-table/rel-table-row.ts +32 -0
  99. package/dist/components/rel-table/rel-table.ts +47 -0
  100. package/dist/components/rel-textfield/README.md +90 -0
  101. package/dist/components/rel-textfield/rel-textfield.ts +35 -19
  102. package/dist/components/rel-toast/README.md +148 -0
  103. package/dist/components/rel-toast/rel-toast.ts +32 -14
  104. package/dist/components/rel-tooltip/README.md +103 -0
  105. package/dist/components/rel-tooltip/rel-tooltip.ts +9 -9
  106. package/dist/index.d.mts +836 -1
  107. package/dist/index.d.ts +836 -1
  108. package/dist/index.js +10658 -1493
  109. package/dist/index.js.map +1 -1
  110. package/dist/index.mjs +10616 -1499
  111. package/dist/index.mjs.map +1 -1
  112. package/dist/styles/vars.css +293 -183
  113. package/dist/{vars-6ZIUPIU4.css → vars-ITL2K3KO.css} +293 -183
  114. package/package.json +1 -1
@@ -0,0 +1,289 @@
1
+ # rel-nav-menu
2
+
3
+ A horizontal navigation menu component with dropdown panels, perfect for top-level site navigation. Features keyboard navigation, accessible ARIA attributes, and token-driven styling.
4
+
5
+ ## What It Is
6
+
7
+ The navigation menu consists of three custom elements:
8
+ - `<rel-nav-menu>` - Root container that manages navigation state and interactions
9
+ - `<rel-nav-menu-item>` - Individual navigation items (can be links or dropdown triggers)
10
+ - `<rel-nav-menu-panel>` - Styled container for dropdown content
11
+
12
+ ## Basic Usage
13
+
14
+ ```html
15
+ <rel-nav-menu>
16
+ <rel-nav-menu-item label="Features" href="#features"></rel-nav-menu-item>
17
+ <rel-nav-menu-item label="Pricing" href="#pricing"></rel-nav-menu-item>
18
+ <rel-nav-menu-item label="About" href="#about"></rel-nav-menu-item>
19
+ <rel-nav-menu-item label="Contact" href="#contact"></rel-nav-menu-item>
20
+ </rel-nav-menu>
21
+ ```
22
+
23
+ ## Dropdown with Content
24
+
25
+ ```html
26
+ <rel-nav-menu>
27
+ <rel-nav-menu-item label="Getting started">
28
+ <rel-nav-menu-panel>
29
+ <a href="#intro" data-nav-item>
30
+ <div data-title>Introduction</div>
31
+ <div data-desc>Re-usable components built with Tailwind CSS.</div>
32
+ </a>
33
+ <a href="#install" data-nav-item>
34
+ <div data-title>Installation</div>
35
+ <div data-desc>How to install dependencies and structure your app.</div>
36
+ </a>
37
+ <a href="#typography" data-nav-item>
38
+ <div data-title>Typography</div>
39
+ <div data-desc>Styles for headings, paragraphs, lists...</div>
40
+ </a>
41
+ </rel-nav-menu-panel>
42
+ </rel-nav-menu-item>
43
+
44
+ <rel-nav-menu-item label="Components">
45
+ <rel-nav-menu-panel>
46
+ <a href="#accordion" data-nav-item>
47
+ <div data-title>Accordion</div>
48
+ <div data-desc>Vertically stacked interactive headings.</div>
49
+ </a>
50
+ <a href="#alert" data-nav-item>
51
+ <div data-title>Alert Dialog</div>
52
+ <div data-desc>Modal dialog that interrupts the user.</div>
53
+ </a>
54
+ </rel-nav-menu-panel>
55
+ </rel-nav-menu-item>
56
+
57
+ <rel-nav-menu-item label="Docs" href="#docs"></rel-nav-menu-item>
58
+ </rel-nav-menu>
59
+ ```
60
+
61
+ ## Simple Dropdown List
62
+
63
+ For simpler dropdowns without titles and descriptions:
64
+
65
+ ```html
66
+ <rel-nav-menu>
67
+ <rel-nav-menu-item label="Status">
68
+ <rel-nav-menu-panel>
69
+ <a href="#backlog" data-nav-item>Backlog</a>
70
+ <a href="#todo" data-nav-item>To Do</a>
71
+ <a href="#in-progress" data-nav-item>In Progress</a>
72
+ <a href="#done" data-nav-item>Done</a>
73
+ </rel-nav-menu-panel>
74
+ </rel-nav-menu-item>
75
+ </rel-nav-menu>
76
+ ```
77
+
78
+ ## API Reference
79
+
80
+ ### rel-nav-menu
81
+
82
+ Root navigation container.
83
+
84
+ **Attributes:**
85
+ - `open` (string) - ID of currently open item (reflects to attribute)
86
+ - `disabled` (boolean) - Disables all interactions
87
+ - `density` ("comfortable" | "compact") - Spacing density, default: "comfortable"
88
+
89
+ **Events:**
90
+ - `rel-nav-open-change` - Emitted when open state changes
91
+ ```typescript
92
+ detail: { openId: string }
93
+ ```
94
+
95
+ **Example:**
96
+ ```javascript
97
+ const navMenu = document.querySelector('rel-nav-menu');
98
+ navMenu.addEventListener('rel-nav-open-change', (e) => {
99
+ console.log('Open item:', e.detail.openId);
100
+ });
101
+ ```
102
+
103
+ ### rel-nav-menu-item
104
+
105
+ Individual navigation item (link or dropdown trigger).
106
+
107
+ **Attributes:**
108
+ - `label` (string, required) - Text displayed on the trigger
109
+ - `href` (string, optional) - If provided, renders as link (no dropdown)
110
+ - `item-id` (string, optional) - Stable identifier; auto-generated from label if not provided
111
+ - `disabled` (boolean) - Disables this item
112
+ - `icon` (string, optional) - Reserved for future icon support
113
+
114
+ **Behavior:**
115
+ - If `href` is set and no dropdown content → renders as anchor link
116
+ - If dropdown content exists → renders as button with dropdown
117
+ - Auto-generates `item-id` from label if not specified
118
+
119
+ **Slots:**
120
+ - Default slot: dropdown panel content (if any)
121
+
122
+ ### rel-nav-menu-panel
123
+
124
+ Styled container for dropdown content.
125
+
126
+ **Usage:**
127
+ Place inside `<rel-nav-menu-item>` to create dropdown content.
128
+
129
+ **Content Structure:**
130
+ Use data attributes for styling:
131
+ - `data-nav-item` - On anchor/link elements for hover styling
132
+ - `data-title` - For the main title text
133
+ - `data-desc` - For the description text
134
+
135
+ ## Keyboard Navigation
136
+
137
+ Full keyboard accessibility support:
138
+
139
+ | Key | Action |
140
+ |-----|--------|
141
+ | `Tab` / `Shift+Tab` | Navigate through triggers |
142
+ | `ArrowLeft` | Move focus to previous trigger |
143
+ | `ArrowRight` | Move focus to next trigger |
144
+ | `Enter` / `Space` | Open/close focused dropdown (if it has content) |
145
+ | `ArrowDown` | Move focus into open dropdown panel (first focusable element) |
146
+ | `Escape` | Close open dropdown and return focus to trigger |
147
+
148
+ ## Interaction Behavior
149
+
150
+ ### Mouse Interactions
151
+ - **Click** a trigger to toggle its dropdown
152
+ - **Click** another trigger to switch dropdowns
153
+ - **Click outside** to close dropdown
154
+ - **Hover switching**: When a dropdown is open, hovering another trigger switches to it
155
+
156
+ ### Accessibility
157
+ - Root has `role="navigation"`
158
+ - Dropdown triggers have `aria-haspopup="menu"`, `aria-expanded`, and `aria-controls`
159
+ - Panels have matching `id` attributes
160
+ - Disabled items are marked with `aria-disabled`
161
+ - Focus management with visible focus indicators
162
+
163
+ ## Styling Tokens
164
+
165
+ The component uses design tokens from the Reliability Design System:
166
+
167
+ ### Colors
168
+ - `--rel-colors-gray-light` - Nav container background
169
+ - `--rel-colors-gray-background` - Trigger hover/active state, panel item hover
170
+ - `--rel-colors-gray-border` - Borders
171
+ - `--rel-colors-gray-heading` - Text color
172
+ - `--rel-colors-gray-placeholder` - Description text
173
+ - `--rel-colors-white` - Panel background
174
+ - `--rel-colors-blue-primary` - Focus outline
175
+
176
+ ### Typography
177
+ - `--rel-fontFamilies-primary` - Font family (Poppins)
178
+ - `--rel-fontWeights-medium` - Trigger text weight
179
+ - `--rel-fontWeights-semibold` - Panel item title weight
180
+ - `--rel-fontSizes-sm` - Trigger and title text size
181
+ - `--rel-fontSizes-xs` - Description text size
182
+ - `--rel-lineHeights-xs` - Description line height
183
+
184
+ ### Spacing
185
+ - `--rel-spacing-space-3xs` (2px) - Compact spacing
186
+ - `--rel-spacing-space-2xs` (4px) - Container padding, panel gaps
187
+ - `--rel-spacing-space-xs` (8px) - Trigger padding, panel padding
188
+ - `--rel-spacing-space-sm` (12px) - Panel item padding
189
+ - `--rel-spacing-space-md` (16px) - Trigger horizontal padding
190
+
191
+ ### Borders & Effects
192
+ - `--rel-borders-width-stroke-100` (1px) - Border width
193
+ - `--rel-borders-radius-border-radius-100` (2px) - Panel item radius
194
+ - `--rel-borders-radius-border-radius-200` (8px) - Container and panel radius
195
+ - `--rel-shadows-shadow-300` - Panel drop shadow
196
+
197
+ ### Z-Index
198
+ - Dropdown panels: `z-index: 1000`
199
+
200
+ ## Positioning
201
+
202
+ Dropdown panels use fixed positioning with smart collision detection:
203
+ - **Default**: Opens below trigger, start-aligned
204
+ - **Right overflow**: Shifts left to fit viewport
205
+ - **Bottom overflow**: Flips above trigger if more space available
206
+
207
+ ## Complete Example
208
+
209
+ ```html
210
+ <rel-nav-menu id="main-nav">
211
+ <rel-nav-menu-item label="Getting started">
212
+ <rel-nav-menu-panel>
213
+ <a href="#intro" data-nav-item>
214
+ <div data-title>Introduction</div>
215
+ <div data-desc>Re-usable components built using Radix UI and Tailwind CSS.</div>
216
+ </a>
217
+ <a href="#installation" data-nav-item>
218
+ <div data-title>Installation</div>
219
+ <div data-desc>How to install dependencies and structure your app.</div>
220
+ </a>
221
+ <a href="#typography" data-nav-item>
222
+ <div data-title>Typography</div>
223
+ <div data-desc>Styles for headings, paragraphs, lists, and more.</div>
224
+ </a>
225
+ </rel-nav-menu-panel>
226
+ </rel-nav-menu-item>
227
+
228
+ <rel-nav-menu-item label="Components">
229
+ <rel-nav-menu-panel>
230
+ <a href="#accordion" data-nav-item>
231
+ <div data-title>Accordion</div>
232
+ <div data-desc>A vertically stacked set of interactive headings.</div>
233
+ </a>
234
+ <a href="#alert-dialog" data-nav-item>
235
+ <div data-title>Alert Dialog</div>
236
+ <div data-desc>A modal dialog that interrupts the user.</div>
237
+ </a>
238
+ <a href="#avatar" data-nav-item>
239
+ <div data-title>Avatar</div>
240
+ <div data-desc>An image element with a fallback.</div>
241
+ </a>
242
+ </rel-nav-menu-panel>
243
+ </rel-nav-menu-item>
244
+
245
+ <rel-nav-menu-item label="Status">
246
+ <rel-nav-menu-panel>
247
+ <a href="#backlog" data-nav-item>Backlog</a>
248
+ <a href="#todo" data-nav-item>To Do</a>
249
+ <a href="#in-progress" data-nav-item>In Progress</a>
250
+ <a href="#done" data-nav-item>Done</a>
251
+ </rel-nav-menu-panel>
252
+ </rel-nav-menu-item>
253
+
254
+ <rel-nav-menu-item label="Documentation" href="#docs"></rel-nav-menu-item>
255
+ </rel-nav-menu>
256
+
257
+ <script>
258
+ const navMenu = document.getElementById('main-nav');
259
+ navMenu.addEventListener('rel-nav-open-change', (e) => {
260
+ console.log('Navigation state:', e.detail.openId);
261
+ });
262
+ </script>
263
+ ```
264
+
265
+ ## Browser Support
266
+
267
+ Compatible with all modern browsers supporting:
268
+ - Web Components (Custom Elements v1)
269
+ - Shadow DOM
270
+ - ES2020+ features
271
+
272
+ ## Framework Integration
273
+
274
+ Works seamlessly with:
275
+ - Vanilla JavaScript
276
+ - Angular
277
+ - React (via wrapper)
278
+ - Vue
279
+ - Any framework supporting Web Components
280
+
281
+ ## Comparison with Menubar
282
+
283
+ While `rel-menubar` is designed for application menus (File/Edit/View), `rel-nav-menu` is optimized for:
284
+ - **Website navigation** - Top-level site sections
285
+ - **Content-rich dropdowns** - With titles, descriptions, and icons
286
+ - **Flexible layouts** - Horizontal navigation bars
287
+ - **Marketing sites** - Product features, documentation, etc.
288
+
289
+ Use `rel-menubar` for desktop application UIs, use `rel-nav-menu` for website navigation.
@@ -0,0 +1,3 @@
1
+ export * from "./rel-nav-menu";
2
+ export * from "./rel-nav-menu-item";
3
+ export * from "./rel-nav-menu-panel";
@@ -0,0 +1,143 @@
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
+ }
@@ -0,0 +1,53 @@
1
+ import { LitElement, html, css } from "lit";
2
+ import { customElement } from "lit/decorators.js";
3
+
4
+ @customElement("rel-nav-menu-panel")
5
+ export class RelNavMenuPanel extends LitElement {
6
+ static styles = css`
7
+ :host {
8
+ display: block;
9
+ width: 100%;
10
+ }
11
+
12
+ .panel-content {
13
+ display: flex;
14
+ flex-direction: column;
15
+ gap: var(--rel-spacing-space-2xs);
16
+ padding: var(--rel-spacing-space-xs);
17
+ }
18
+
19
+ ::slotted(a[data-nav-item]) {
20
+ display: block;
21
+ padding: var(--rel-spacing-space-sm);
22
+ border-radius: var(--rel-borders-radius-border-radius-100);
23
+ transition: background 0.15s ease;
24
+ text-decoration: none;
25
+ color: inherit;
26
+ }
27
+
28
+ ::slotted(a[data-nav-item]:hover) {
29
+ background: var(--rel-surface-secondary, #fafafa);
30
+ }
31
+
32
+ ::slotted([data-title]) {
33
+ font-size: var(--rel-fontSizes-sm);
34
+ font-weight: var(--rel-fontWeights-semibold);
35
+ color: var(--rel-colors-gray-heading);
36
+ margin-bottom: var(--rel-spacing-space-3xs);
37
+ }
38
+
39
+ ::slotted([data-desc]) {
40
+ font-size: var(--rel-fontSizes-xs);
41
+ color: var(--rel-colors-gray-placeholder);
42
+ line-height: var(--rel-lineHeights-xs);
43
+ }
44
+ `;
45
+
46
+ render() {
47
+ return html`
48
+ <div class="panel-content">
49
+ <slot></slot>
50
+ </div>
51
+ `;
52
+ }
53
+ }