@arclux/arc-ui 1.0.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 (135) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +64 -0
  3. package/package.json +186 -0
  4. package/src/content/accordion-item.js +27 -0
  5. package/src/content/accordion.js +151 -0
  6. package/src/content/animated-number.js +160 -0
  7. package/src/content/aspect-ratio.js +78 -0
  8. package/src/content/avatar-group.js +101 -0
  9. package/src/content/avatar.js +92 -0
  10. package/src/content/badge.js +98 -0
  11. package/src/content/callout.js +141 -0
  12. package/src/content/card.js +75 -0
  13. package/src/content/carousel.js +300 -0
  14. package/src/content/code-block.js +152 -0
  15. package/src/content/collapsible.js +142 -0
  16. package/src/content/color-swatch.js +86 -0
  17. package/src/content/column.js +28 -0
  18. package/src/content/data-table.js +332 -0
  19. package/src/content/divider.js +153 -0
  20. package/src/content/empty-state.js +78 -0
  21. package/src/content/feature-card.js +142 -0
  22. package/src/content/highlight.js +63 -0
  23. package/src/content/icon-library.js +30 -0
  24. package/src/content/icon-registry.js +39 -0
  25. package/src/content/icon.js +95 -0
  26. package/src/content/index.js +44 -0
  27. package/src/content/infinite-scroll.js +144 -0
  28. package/src/content/kbd.js +40 -0
  29. package/src/content/markdown.js +294 -0
  30. package/src/content/marquee.js +166 -0
  31. package/src/content/meter.js +167 -0
  32. package/src/content/scroll-area.js +107 -0
  33. package/src/content/skeleton.js +85 -0
  34. package/src/content/spinner.js +77 -0
  35. package/src/content/stack.js +68 -0
  36. package/src/content/stat.js +72 -0
  37. package/src/content/step.js +22 -0
  38. package/src/content/stepper.js +202 -0
  39. package/src/content/table.js +134 -0
  40. package/src/content/tag.js +156 -0
  41. package/src/content/text.js +111 -0
  42. package/src/content/timeline-item.js +29 -0
  43. package/src/content/timeline.js +170 -0
  44. package/src/content/truncate.js +161 -0
  45. package/src/content/value-card.js +94 -0
  46. package/src/feedback/alert.js +187 -0
  47. package/src/feedback/command-item.js +28 -0
  48. package/src/feedback/command-palette.js +346 -0
  49. package/src/feedback/context-menu.js +299 -0
  50. package/src/feedback/dialog.js +298 -0
  51. package/src/feedback/dropdown-menu.js +259 -0
  52. package/src/feedback/hover-card.js +186 -0
  53. package/src/feedback/index.js +17 -0
  54. package/src/feedback/modal.js +226 -0
  55. package/src/feedback/notification-panel.js +196 -0
  56. package/src/feedback/popover.js +184 -0
  57. package/src/feedback/progress.js +169 -0
  58. package/src/feedback/sheet.js +249 -0
  59. package/src/feedback/toast.js +207 -0
  60. package/src/feedback/tooltip.js +189 -0
  61. package/src/icons/lucide.d.ts +1915 -0
  62. package/src/icons/lucide.js +1915 -0
  63. package/src/icons/phosphor.d.ts +1517 -0
  64. package/src/icons/phosphor.js +1517 -0
  65. package/src/icons/types.d.ts +8 -0
  66. package/src/index.js +9 -0
  67. package/src/input/button.js +127 -0
  68. package/src/input/calendar.js +340 -0
  69. package/src/input/checkbox.js +159 -0
  70. package/src/input/chip.js +120 -0
  71. package/src/input/color-picker.js +461 -0
  72. package/src/input/combobox.js +295 -0
  73. package/src/input/copy-button.js +144 -0
  74. package/src/input/date-picker.js +534 -0
  75. package/src/input/file-upload.js +333 -0
  76. package/src/input/form.js +179 -0
  77. package/src/input/icon-button.js +179 -0
  78. package/src/input/index.js +31 -0
  79. package/src/input/input.js +158 -0
  80. package/src/input/multi-select.js +392 -0
  81. package/src/input/number-input.js +239 -0
  82. package/src/input/otp-input.js +221 -0
  83. package/src/input/pin-input.js +294 -0
  84. package/src/input/radio-group.js +177 -0
  85. package/src/input/radio.js +28 -0
  86. package/src/input/rating.js +195 -0
  87. package/src/input/search.js +371 -0
  88. package/src/input/segmented-control.js +174 -0
  89. package/src/input/select.js +267 -0
  90. package/src/input/slider.js +217 -0
  91. package/src/input/sortable-list.js +345 -0
  92. package/src/input/suggestion.js +26 -0
  93. package/src/input/textarea.js +203 -0
  94. package/src/input/theme-toggle.js +196 -0
  95. package/src/input/toggle.js +166 -0
  96. package/src/layout/app-shell.js +266 -0
  97. package/src/layout/auth-shell.js +153 -0
  98. package/src/layout/container.js +37 -0
  99. package/src/layout/dashboard-grid.js +62 -0
  100. package/src/layout/index.js +15 -0
  101. package/src/layout/page-header.js +100 -0
  102. package/src/layout/page-layout.js +112 -0
  103. package/src/layout/resizable.js +221 -0
  104. package/src/layout/section.js +54 -0
  105. package/src/layout/settings-layout.js +91 -0
  106. package/src/layout/split-pane.js +172 -0
  107. package/src/layout/status-bar.js +84 -0
  108. package/src/layout/toolbar.js +92 -0
  109. package/src/navigation/breadcrumb-item.js +26 -0
  110. package/src/navigation/breadcrumb.js +129 -0
  111. package/src/navigation/drawer.js +183 -0
  112. package/src/navigation/footer.js +99 -0
  113. package/src/navigation/index.js +22 -0
  114. package/src/navigation/link.js +120 -0
  115. package/src/navigation/nav-item.js +46 -0
  116. package/src/navigation/navigation-menu.js +687 -0
  117. package/src/navigation/pagination.js +186 -0
  118. package/src/navigation/scroll-spy.js +198 -0
  119. package/src/navigation/scroll-to-top.js +163 -0
  120. package/src/navigation/sidebar-link.js +28 -0
  121. package/src/navigation/sidebar-section.js +45 -0
  122. package/src/navigation/sidebar.js +336 -0
  123. package/src/navigation/spy-link.js +26 -0
  124. package/src/navigation/tab.js +26 -0
  125. package/src/navigation/tabs.js +202 -0
  126. package/src/navigation/top-bar.js +263 -0
  127. package/src/navigation/tree-item.js +38 -0
  128. package/src/navigation/tree-view.js +255 -0
  129. package/src/shared/index.js +6 -0
  130. package/src/shared/menu-divider.js +9 -0
  131. package/src/shared/menu-item.js +30 -0
  132. package/src/shared/option.js +31 -0
  133. package/src/shared-styles.js +81 -0
  134. package/src/tokens.js +445 -0
  135. package/types/index.d.ts +973 -0
@@ -0,0 +1,371 @@
1
+ import { LitElement, html, css } from 'lit';
2
+ import { tokenStyles } from '../shared-styles.js';
3
+ import './suggestion.js';
4
+
5
+ export class ArcSearch extends LitElement {
6
+ static properties = {
7
+ value: { type: String },
8
+ placeholder: { type: String },
9
+ label: { type: String },
10
+ disabled: { type: Boolean, reflect: true },
11
+ loading: { type: Boolean, reflect: true },
12
+ _open: { state: true },
13
+ _activeIndex: { state: true },
14
+ _suggestions: { state: true },
15
+ };
16
+
17
+ static styles = [
18
+ tokenStyles,
19
+ css`
20
+ :host {
21
+ display: block;
22
+ position: relative;
23
+ font-family: var(--font-body);
24
+ }
25
+
26
+ :host([disabled]) {
27
+ opacity: 0.5;
28
+ pointer-events: none;
29
+ }
30
+
31
+ .search__label {
32
+ display: block;
33
+ font-size: var(--text-xs);
34
+ font-weight: 600;
35
+ color: var(--text-secondary);
36
+ margin-bottom: var(--space-xs);
37
+ letter-spacing: 0.5px;
38
+ }
39
+
40
+ .search__wrapper {
41
+ position: relative;
42
+ display: flex;
43
+ align-items: center;
44
+ }
45
+
46
+ .search__icon {
47
+ position: absolute;
48
+ left: var(--space-sm);
49
+ display: flex;
50
+ align-items: center;
51
+ justify-content: center;
52
+ width: 18px;
53
+ height: 18px;
54
+ color: var(--text-muted);
55
+ pointer-events: none;
56
+ }
57
+
58
+ .search__input {
59
+ width: 100%;
60
+ box-sizing: border-box;
61
+ font-family: var(--font-body);
62
+ font-size: var(--text-sm);
63
+ color: var(--text-primary);
64
+ background: var(--bg-card);
65
+ border: 1px solid var(--border-default);
66
+ border-radius: var(--radius-md);
67
+ padding: var(--space-sm) var(--space-lg) var(--space-sm) calc(var(--space-sm) + 26px);
68
+ outline: none;
69
+ transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
70
+ }
71
+
72
+ .search__input::placeholder {
73
+ color: var(--text-muted);
74
+ }
75
+
76
+ .search__input:focus {
77
+ outline: none;
78
+ border-color: rgba(var(--accent-primary-rgb), 0.4);
79
+ box-shadow: var(--focus-glow);
80
+ }
81
+
82
+ .search__clear {
83
+ position: absolute;
84
+ right: var(--space-sm);
85
+ display: flex;
86
+ align-items: center;
87
+ justify-content: center;
88
+ width: 24px;
89
+ height: 24px;
90
+ border: none;
91
+ background: none;
92
+ color: var(--text-muted);
93
+ cursor: pointer;
94
+ border-radius: var(--radius-full);
95
+ font-size: var(--text-md);
96
+ padding: 0;
97
+ transition: color var(--transition-fast), background var(--transition-fast);
98
+ }
99
+
100
+ .search__clear:hover {
101
+ color: var(--text-primary);
102
+ background: rgba(var(--accent-primary-rgb), 0.1);
103
+ }
104
+
105
+ .search__clear:focus-visible {
106
+ outline: none;
107
+ box-shadow: var(--focus-glow);
108
+ }
109
+
110
+ .search__spinner {
111
+ position: absolute;
112
+ right: var(--space-sm);
113
+ width: 18px;
114
+ height: 18px;
115
+ border: 2px solid var(--border-default);
116
+ border-top-color: var(--accent-primary);
117
+ border-radius: var(--radius-full);
118
+ animation: spin 0.7s linear infinite;
119
+ }
120
+
121
+ @keyframes spin {
122
+ to { transform: rotate(360deg); }
123
+ }
124
+
125
+ .search__suggestions {
126
+ position: absolute;
127
+ top: calc(100% + 4px);
128
+ left: 0;
129
+ right: 0;
130
+ max-height: 220px;
131
+ overflow-y: auto;
132
+ background: var(--bg-card);
133
+ border: 1px solid var(--border-default);
134
+ border-radius: var(--radius-md);
135
+ box-shadow: var(--shadow-overlay);
136
+ z-index: 1000;
137
+ padding: var(--space-xs) 0;
138
+ display: none;
139
+ }
140
+
141
+ .search__suggestions--open {
142
+ display: block;
143
+ }
144
+
145
+ .search__suggestion {
146
+ display: block;
147
+ width: 100%;
148
+ text-align: left;
149
+ font-family: var(--font-body);
150
+ font-size: var(--text-sm);
151
+ color: var(--text-primary);
152
+ background: none;
153
+ border: none;
154
+ padding: var(--space-sm) var(--space-md);
155
+ cursor: pointer;
156
+ transition: background var(--transition-fast);
157
+ }
158
+
159
+ .search__suggestion:hover,
160
+ .search__suggestion--active {
161
+ background: rgba(var(--accent-primary-rgb), 0.1);
162
+ }
163
+
164
+ .search__suggestion:focus-visible {
165
+ outline: none;
166
+ box-shadow: var(--focus-glow);
167
+ }
168
+
169
+ .search__slot-host { display: none; }
170
+
171
+ @media (prefers-reduced-motion: reduce) {
172
+ :host *,
173
+ :host *::before,
174
+ :host *::after {
175
+ animation-duration: 0.01ms !important;
176
+ animation-iteration-count: 1 !important;
177
+ transition-duration: 0.01ms !important;
178
+ }
179
+ }
180
+ `,
181
+ ];
182
+
183
+ constructor() {
184
+ super();
185
+ this.value = '';
186
+ this.placeholder = 'Search...';
187
+ this.label = '';
188
+ this.disabled = false;
189
+ this.loading = false;
190
+ this._open = false;
191
+ this._activeIndex = -1;
192
+ this._suggestions = [];
193
+ this._onDocClick = this._onDocClick.bind(this);
194
+ }
195
+
196
+ connectedCallback() {
197
+ super.connectedCallback();
198
+ document.addEventListener('click', this._onDocClick, true);
199
+ }
200
+
201
+ disconnectedCallback() {
202
+ super.disconnectedCallback();
203
+ document.removeEventListener('click', this._onDocClick, true);
204
+ }
205
+
206
+ _onSlotChange(e) {
207
+ this._suggestions = e.target.assignedElements({ flatten: true })
208
+ .filter(el => el.tagName === 'ARC-SUGGESTION');
209
+ }
210
+
211
+ _onDocClick(e) {
212
+ if (!e.composedPath().includes(this)) {
213
+ this._open = false;
214
+ }
215
+ }
216
+
217
+ get _hasSuggestions() {
218
+ return this._suggestions.length > 0;
219
+ }
220
+
221
+ get _normalizedSuggestions() {
222
+ return this._suggestions.map(s => ({
223
+ label: s.label,
224
+ value: s.value || s.label,
225
+ }));
226
+ }
227
+
228
+ _onInput(e) {
229
+ this.value = e.target.value;
230
+ this._activeIndex = -1;
231
+ if (this._hasSuggestions) this._open = true;
232
+
233
+ this.dispatchEvent(new CustomEvent('arc-input', {
234
+ detail: { value: this.value },
235
+ bubbles: true,
236
+ composed: true,
237
+ }));
238
+ }
239
+
240
+ _onFocus() {
241
+ if (this._hasSuggestions) this._open = true;
242
+ }
243
+
244
+ _clear() {
245
+ this.value = '';
246
+ this._open = false;
247
+ this._activeIndex = -1;
248
+
249
+ this.dispatchEvent(new CustomEvent('arc-clear', {
250
+ bubbles: true,
251
+ composed: true,
252
+ }));
253
+
254
+ this.shadowRoot.querySelector('.search__input')?.focus();
255
+ }
256
+
257
+ _submit() {
258
+ this.dispatchEvent(new CustomEvent('arc-change', {
259
+ detail: { value: this.value },
260
+ bubbles: true,
261
+ composed: true,
262
+ }));
263
+ }
264
+
265
+ _selectSuggestion(item) {
266
+ this.value = item.label || item.value;
267
+ this._open = false;
268
+ this._activeIndex = -1;
269
+
270
+ this.dispatchEvent(new CustomEvent('arc-select', {
271
+ detail: { value: item },
272
+ bubbles: true,
273
+ composed: true,
274
+ }));
275
+ }
276
+
277
+ _onKeyDown(e) {
278
+ const items = this._normalizedSuggestions;
279
+
280
+ switch (e.key) {
281
+ case 'ArrowDown':
282
+ if (!this._open && this._hasSuggestions) { this._open = true; return; }
283
+ e.preventDefault();
284
+ this._activeIndex = Math.min(this._activeIndex + 1, items.length - 1);
285
+ break;
286
+ case 'ArrowUp':
287
+ e.preventDefault();
288
+ this._activeIndex = Math.max(this._activeIndex - 1, 0);
289
+ break;
290
+ case 'Enter':
291
+ e.preventDefault();
292
+ if (this._activeIndex >= 0 && items[this._activeIndex]) {
293
+ this._selectSuggestion(items[this._activeIndex]);
294
+ } else {
295
+ this._submit();
296
+ }
297
+ break;
298
+ case 'Escape':
299
+ if (this._open) {
300
+ this._open = false;
301
+ this._activeIndex = -1;
302
+ }
303
+ break;
304
+ }
305
+ }
306
+
307
+ render() {
308
+ const items = this._normalizedSuggestions;
309
+ const showSuggestions = this._open && items.length > 0;
310
+
311
+ return html`
312
+ <div class="search__slot-host">
313
+ <slot @slotchange=${this._onSlotChange}></slot>
314
+ </div>
315
+ ${this.label ? html`<label class="search__label" part="label">${this.label}</label>` : ''}
316
+ <div class="search__wrapper" part="wrapper">
317
+ <span class="search__icon" aria-hidden="true" part="icon">
318
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
319
+ <circle cx="7" cy="7" r="5" stroke="currentColor" stroke-width="1.5"/>
320
+ <path d="M11 11L14 14" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
321
+ </svg>
322
+ </span>
323
+
324
+ <input
325
+ class="search__input"
326
+ type="text"
327
+ role="searchbox"
328
+ .value=${this.value}
329
+ placeholder=${this.placeholder}
330
+ ?disabled=${this.disabled}
331
+ aria-label=${this.label || this.placeholder}
332
+ aria-expanded=${this._hasSuggestions ? String(this._open) : undefined}
333
+ @input=${this._onInput}
334
+ @focus=${this._onFocus}
335
+ @keydown=${this._onKeyDown}
336
+ part="input"
337
+ />
338
+
339
+ ${this.loading ? html`
340
+ <span class="search__spinner" part="spinner" aria-label="Loading"></span>
341
+ ` : this.value ? html`
342
+ <button
343
+ class="search__clear"
344
+ @click=${this._clear}
345
+ aria-label="Clear search"
346
+ tabindex="-1"
347
+ part="clear"
348
+ >&times;</button>
349
+ ` : ''}
350
+
351
+ <div
352
+ class="search__suggestions ${showSuggestions ? 'search__suggestions--open' : ''}"
353
+ role="listbox"
354
+ part="suggestions"
355
+ >
356
+ ${items.map((item, i) => html`
357
+ <button
358
+ class="search__suggestion ${i === this._activeIndex ? 'search__suggestion--active' : ''}"
359
+ role="option"
360
+ aria-selected=${i === this._activeIndex ? 'true' : 'false'}
361
+ @click=${() => this._selectSuggestion(item)}
362
+ part="suggestion"
363
+ >${item.label || item.value}</button>
364
+ `)}
365
+ </div>
366
+ </div>
367
+ `;
368
+ }
369
+ }
370
+
371
+ customElements.define('arc-search', ArcSearch);
@@ -0,0 +1,174 @@
1
+ import { LitElement, html, css } from 'lit';
2
+ import { tokenStyles } from '../shared-styles.js';
3
+
4
+ export class ArcSegmentedControl extends LitElement {
5
+ static properties = {
6
+ value: { type: String, reflect: true },
7
+ disabled: { type: Boolean, reflect: true },
8
+ _options: { state: true },
9
+ };
10
+
11
+ static styles = [
12
+ tokenStyles,
13
+ css`
14
+ :host { display: inline-flex; }
15
+ :host([disabled]) { pointer-events: none; opacity: 0.4; }
16
+
17
+ .segmented {
18
+ display: inline-flex;
19
+ align-items: center;
20
+ background: var(--bg-surface);
21
+ border: 1px solid var(--border-default);
22
+ border-radius: var(--radius-md);
23
+ padding: 3px; /* cosmetic inset for pill container */
24
+ gap: 2px; /* cosmetic micro-spacing */
25
+ box-sizing: border-box;
26
+ }
27
+
28
+ .segmented__option {
29
+ display: inline-flex;
30
+ align-items: center;
31
+ justify-content: center;
32
+ padding: var(--touch-pad) var(--space-md);
33
+ min-height: var(--touch-min);
34
+ font-family: var(--font-accent);
35
+ font-size: var(--text-xs);
36
+ font-weight: 600;
37
+ letter-spacing: 1px;
38
+ text-transform: uppercase;
39
+ color: var(--text-muted);
40
+ background: transparent;
41
+ border: 1px solid transparent;
42
+ border-radius: calc(var(--radius-md) - 2px);
43
+ cursor: pointer;
44
+ transition:
45
+ background var(--transition-base),
46
+ color var(--transition-base),
47
+ border-color var(--transition-base),
48
+ box-shadow var(--transition-base);
49
+ white-space: nowrap;
50
+ user-select: none;
51
+ line-height: 1.4;
52
+ }
53
+
54
+ .segmented__option:hover:not(.is-active) {
55
+ color: var(--text-primary);
56
+ background: var(--bg-hover);
57
+ }
58
+
59
+ .segmented__option.is-active {
60
+ background: var(--accent-primary);
61
+ color: var(--bg-deep);
62
+ border-color: var(--accent-primary);
63
+ box-shadow: 0 0 12px rgba(var(--accent-primary-rgb), 0.4);
64
+ }
65
+
66
+ .segmented__option:focus-visible {
67
+ outline: none;
68
+ box-shadow: var(--focus-glow);
69
+ }
70
+
71
+ .segmented__option.is-active:focus-visible {
72
+ box-shadow: var(--focus-glow), 0 0 12px rgba(var(--accent-primary-rgb), 0.4);
73
+ }
74
+
75
+ .segmented__slot-host { display: none; }
76
+
77
+ @media (prefers-reduced-motion: reduce) {
78
+ .segmented__option { transition: none; }
79
+ }
80
+ `,
81
+ ];
82
+
83
+ constructor() {
84
+ super();
85
+ this.value = '';
86
+ this.disabled = false;
87
+ this._options = [];
88
+ }
89
+
90
+ _onSlotChange(e) {
91
+ this._options = e.target.assignedElements({ flatten: true })
92
+ .filter(el => el.tagName === 'ARC-OPTION');
93
+ // Auto-select first if no value set
94
+ if (!this.value && this._options.length > 0) {
95
+ this.value = this._options[0].getAttribute('value') || '';
96
+ }
97
+ }
98
+
99
+ _select(optionValue) {
100
+ if (this.disabled || optionValue === this.value) return;
101
+ this.value = optionValue;
102
+ this.dispatchEvent(new CustomEvent('arc-change', {
103
+ detail: { value: this.value },
104
+ bubbles: true,
105
+ composed: true,
106
+ }));
107
+ }
108
+
109
+ _handleKeydown(e, index) {
110
+ let nextIndex = index;
111
+
112
+ if (e.key === 'ArrowRight' || e.key === 'ArrowDown') {
113
+ e.preventDefault();
114
+ nextIndex = (index + 1) % this._options.length;
115
+ } else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') {
116
+ e.preventDefault();
117
+ nextIndex = (index - 1 + this._options.length) % this._options.length;
118
+ } else if (e.key === 'Enter' || e.key === ' ') {
119
+ e.preventDefault();
120
+ const val = this._options[index]?.getAttribute('value') || '';
121
+ this._select(val);
122
+ return;
123
+ } else if (e.key === 'Home') {
124
+ e.preventDefault();
125
+ nextIndex = 0;
126
+ } else if (e.key === 'End') {
127
+ e.preventDefault();
128
+ nextIndex = this._options.length - 1;
129
+ } else {
130
+ return;
131
+ }
132
+
133
+ const val = this._options[nextIndex]?.getAttribute('value') || '';
134
+ this._select(val);
135
+ this.updateComplete.then(() => {
136
+ const buttons = this.shadowRoot.querySelectorAll('.segmented__option');
137
+ buttons[nextIndex]?.focus();
138
+ });
139
+ }
140
+
141
+ render() {
142
+ return html`
143
+ <div class="segmented__slot-host">
144
+ <slot @slotchange=${this._onSlotChange}></slot>
145
+ </div>
146
+ <div
147
+ class="segmented"
148
+ role="radiogroup"
149
+ aria-disabled=${this.disabled ? 'true' : 'false'}
150
+ part="control"
151
+ >
152
+ ${this._options.map((opt, i) => {
153
+ const val = opt.getAttribute('value') || '';
154
+ const label = opt.textContent?.trim() || val;
155
+ const isActive = val === this.value;
156
+ return html`
157
+ <button
158
+ class="segmented__option ${isActive ? 'is-active' : ''}"
159
+ role="radio"
160
+ aria-checked=${isActive ? 'true' : 'false'}
161
+ tabindex=${isActive ? '0' : '-1'}
162
+ ?disabled=${this.disabled}
163
+ @click=${() => this._select(val)}
164
+ @keydown=${(e) => this._handleKeydown(e, i)}
165
+ part="option"
166
+ >${label}</button>
167
+ `;
168
+ })}
169
+ </div>
170
+ `;
171
+ }
172
+ }
173
+
174
+ customElements.define('arc-segmented-control', ArcSegmentedControl);