@santi020k/lumen-elements 0.3.0 → 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.
package/dist/define.js CHANGED
@@ -1,4358 +1 @@
1
- /* eslint-disable complexity, @typescript-eslint/no-non-null-assertion */
2
- import { coerceThemeBuilderExportFormat, coerceThemeBuilderMode, coerceThemeBuilderScheme, composeClassName, createThemeBuilderTokens, exportThemeBuilderValue, getLumenRichTextShortcut, getVirtualRange, isLumenRichTextToggleCommand, lumenComponentNames, normalizeThemeBuilderHex, parseThemeCss, renderLumenIconSvg, scoreThemeContrast, tuneThemeContrast } from '@santi020k/lumen-core';
3
- const registry = new Set();
4
- const appliedClassNames = new WeakMap();
5
- const focusableSelector = [
6
- 'a[href]',
7
- 'button:not([disabled])',
8
- 'input:not([disabled])',
9
- 'select:not([disabled])',
10
- 'textarea:not([disabled])',
11
- '[tabindex]:not([tabindex="-1"])'
12
- ].join(',');
13
- // cspell:ignore spinbutton
14
- const fieldControlSelector = [
15
- 'input:not([type="hidden"])',
16
- 'select',
17
- 'textarea',
18
- '[contenteditable="true"]',
19
- '[role="combobox"]',
20
- '[role="listbox"]',
21
- '[role="spinbutton"]',
22
- '[role="textbox"]'
23
- ].join(',');
24
- const fieldDescriptionSelector = '[data-ui-field-hint], [data-ui-field-error], .ui-field__hint, .ui-field__error';
25
- const fieldErrorSelector = '[data-ui-field-error], .ui-field__error';
26
- const richTextEditorSelector = '[data-ui-rich-text-editor]';
27
- const richTextEditorCommandSelector = '[data-ui-editor-command]';
28
- const richTextEditorContentSelector = '[data-ui-rich-text-editable], [contenteditable="true"]';
29
- const scheduleSelector = '[data-ui-schedule]';
30
- const scheduleEventSelector = '[data-ui-schedule-event]';
31
- const scheduleSlotSelector = '[data-ui-schedule-slot]';
32
- const resizableSelector = '[data-ui-resizable]';
33
- const resizableHandleSelector = '[data-ui-resizable-handle]';
34
- const resizableHandleTemplateSelector = '[data-ui-resizable-handle-template]';
35
- const contextMenuSelector = '[data-ui-context-menu]';
36
- const contextMenuTriggerSelector = '[data-ui-context-menu-trigger]';
37
- const dateRangePickerSelector = '[data-ui-date-range-picker]';
38
- const dateRangePickerInputSelector = 'input[type="date"]';
39
- const inputOtpSelector = '[data-ui-input-otp], lumen-input-otp';
40
- const inputOtpNativeSelector = '[data-ui-input-otp-native]';
41
- const inputOtpSegmentSelector = '[data-ui-input-otp-segment]';
42
- const inputOtpSegmentsSelector = '[data-ui-input-otp-segments]';
43
- const calendarSelector = '[data-ui-calendar], lumen-calendar';
44
- const calendarInputSelector = '[data-ui-calendar-input]';
45
- const calendarLabelSelector = '[data-ui-calendar-label]';
46
- const calendarGridSelector = '[data-ui-calendar-grid]';
47
- const calendarDaySelector = '[data-ui-calendar-day]';
48
- const datePickerSelector = '[data-ui-date-picker], lumen-date-picker';
49
- const datePickerNativeSelector = '[data-ui-date-picker-native]';
50
- const datePickerControlSelector = '[data-ui-date-picker-control]';
51
- const datePickerTriggerSelector = '[data-ui-date-picker-trigger]';
52
- const datePickerValueSelector = '[data-ui-date-picker-value]';
53
- const datePickerPopoverSelector = '[data-ui-date-picker-popover]';
54
- const formControlSelector = [
55
- 'input:not([type="hidden"])',
56
- 'select',
57
- 'textarea'
58
- ].join(',');
59
- const selectOptionSelector = '[data-ui-select-option]';
60
- const defaultToastDuration = 5000;
61
- const defaultToastMax = 5;
62
- const toastCloseDelay = 240;
63
- const validityMessageAttributes = [
64
- ['valueMissing', 'data-error-required'],
65
- ['typeMismatch', 'data-error-type'],
66
- ['patternMismatch', 'data-error-pattern'],
67
- ['tooShort', 'data-error-too-short'],
68
- ['tooLong', 'data-error-too-long'],
69
- ['rangeUnderflow', 'data-error-min'],
70
- ['rangeOverflow', 'data-error-max'],
71
- ['stepMismatch', 'data-error-step'],
72
- ['badInput', 'data-error-bad-input'],
73
- ['customError', 'data-error-custom']
74
- ];
75
- const toastTimers = new WeakMap();
76
- const mergeClassNames = (...classNames) => composeClassName(...classNames).split(/\s+/).filter(Boolean);
77
- const glassAttributeClasses = (className) => ({
78
- glass: {
79
- strong: `${className} ui-glass-strong`,
80
- subtle: `${className} ui-glass-subtle`,
81
- true: className
82
- },
83
- surface: { glass: className }
84
- });
85
- const elementConfigs = {
86
- Accordion: {
87
- attributeClasses: {
88
- variant: { flush: 'ui-accordion--flush' }
89
- },
90
- baseClassName: 'ui-accordion',
91
- defaults: { variant: 'default' },
92
- tagName: 'lumen-accordion'
93
- },
94
- Alert: {
95
- attributeClasses: {
96
- glass: { strong: 'ui-alert--glass ui-glass-strong', subtle: 'ui-alert--glass ui-glass-subtle', true: 'ui-alert--glass' },
97
- variant: {
98
- destructive: 'ui-alert--destructive',
99
- success: 'ui-alert--success',
100
- warning: 'ui-alert--warning'
101
- }
102
- },
103
- baseClassName: 'ui-alert',
104
- defaults: { variant: 'default' },
105
- tagName: 'lumen-alert'
106
- },
107
- AlertDialog: {
108
- attributeClasses: {
109
- glass: { strong: 'ui-dialog--glass ui-glass-strong', subtle: 'ui-dialog--glass ui-glass-subtle', true: 'ui-dialog--glass' },
110
- surface: { glass: 'ui-dialog--glass' }
111
- },
112
- baseClassName: 'ui-dialog ui-alert-dialog',
113
- defaults: { 'data-ui-alert-dialog': '', surface: 'default' },
114
- tagName: 'lumen-alert-dialog'
115
- },
116
- Agenda: { attributeClasses: glassAttributeClasses('ui-agenda--glass'), baseClassName: 'ui-agenda', tagName: 'lumen-agenda' },
117
- AspectRatio: { baseClassName: 'ui-aspect-ratio', tagName: 'lumen-aspect-ratio' },
118
- Attachment: { attributeClasses: glassAttributeClasses('ui-attachment--glass'), baseClassName: 'ui-attachment', tagName: 'lumen-attachment' },
119
- Autocomplete: { baseClassName: 'ui-input ui-autocomplete', defaults: { role: 'combobox', type: 'search' }, tagName: 'lumen-autocomplete' },
120
- Avatar: { baseClassName: 'ui-avatar', tagName: 'lumen-avatar' },
121
- BackToTop: { baseClassName: 'ui-back-to-top', tagName: 'lumen-back-to-top' },
122
- Badge: {
123
- attributeClasses: {
124
- variant: {
125
- default: 'ui-badge--default',
126
- destructive: 'ui-badge--destructive',
127
- outline: 'ui-badge--outline',
128
- secondary: 'ui-badge--secondary',
129
- success: 'ui-badge--success',
130
- warning: 'ui-badge--warning'
131
- }
132
- },
133
- baseClassName: 'ui-badge',
134
- defaults: { variant: 'default' },
135
- tagName: 'lumen-badge'
136
- },
137
- Breadcrumb: { baseClassName: 'ui-breadcrumb', defaults: { 'aria-label': 'Breadcrumb' }, tagName: 'lumen-breadcrumb' },
138
- Bubble: {
139
- attributeClasses: { from: { user: 'ui-bubble--user' }, ...glassAttributeClasses('ui-bubble--glass') },
140
- baseClassName: 'ui-bubble',
141
- defaults: { from: 'assistant' },
142
- tagName: 'lumen-bubble'
143
- },
144
- Button: {
145
- attributeClasses: {
146
- variant: {
147
- default: 'ui-button--default',
148
- destructive: 'ui-button--destructive',
149
- ghost: 'ui-button--ghost',
150
- link: 'ui-button--link',
151
- outline: 'ui-button--outline',
152
- secondary: 'ui-button--secondary'
153
- },
154
- size: {
155
- default: 'ui-button--default-size',
156
- icon: 'ui-button--icon',
157
- lg: 'ui-button--lg',
158
- sm: 'ui-button--sm'
159
- },
160
- disabled: { true: 'ui-button--disabled' },
161
- loading: { true: 'ui-button--loading' }
162
- },
163
- baseClassName: 'ui-button',
164
- defaults: { role: 'button', size: 'default', tabindex: '0', variant: 'default' },
165
- role: 'button',
166
- tagName: 'lumen-button'
167
- },
168
- ButtonGroup: { baseClassName: 'ui-button-group', tagName: 'lumen-button-group' },
169
- Calendar: { attributeClasses: glassAttributeClasses('ui-calendar--glass'), baseClassName: 'ui-calendar', defaults: { 'data-ui-calendar': '' }, tagName: 'lumen-calendar' },
170
- Callout: { baseClassName: 'ui-callout', tagName: 'lumen-callout' },
171
- Card: {
172
- attributeClasses: {
173
- glass: {
174
- strong: 'ui-card--glass ui-glass-strong',
175
- subtle: 'ui-card--glass ui-glass-subtle',
176
- true: 'ui-card--glass'
177
- },
178
- variant: {
179
- glass: 'ui-card--glass',
180
- interactive: 'ui-card--interactive',
181
- muted: 'ui-card--muted',
182
- unstyled: 'ui-card--unstyled'
183
- }
184
- },
185
- baseClassName: 'ui-card',
186
- defaults: { variant: 'default' },
187
- tagName: 'lumen-card'
188
- },
189
- Carousel: { attributeClasses: glassAttributeClasses('ui-carousel--glass'), baseClassName: 'ui-carousel', defaults: { 'data-ui-carousel': '' }, tagName: 'lumen-carousel' },
190
- Chart: { attributeClasses: glassAttributeClasses('ui-chart--glass'), baseClassName: 'ui-chart', tagName: 'lumen-chart' },
191
- Checkbox: { baseClassName: 'ui-checkbox', defaults: { type: 'checkbox' }, tagName: 'lumen-checkbox' },
192
- Collapsible: { baseClassName: 'ui-collapsible', defaults: { 'data-ui-collapsible': '' }, tagName: 'lumen-collapsible' },
193
- Code: {
194
- attributeClasses: {
195
- variant: {
196
- block: 'ui-code--block',
197
- inline: 'ui-code--inline'
198
- },
199
- wrap: {
200
- true: 'ui-code--wrap'
201
- }
202
- },
203
- baseClassName: 'ui-code',
204
- defaults: { 'data-code-theme': 'auto', variant: 'inline' },
205
- tagName: 'lumen-code'
206
- },
207
- CodeTabs: {
208
- baseClassName: 'ui-code-tabs',
209
- defaults: { 'data-ui-tabs': '' },
210
- tagName: 'lumen-code-tabs'
211
- },
212
- Combobox: { baseClassName: 'ui-combobox', defaults: { 'data-ui-combobox': '' }, tagName: 'lumen-combobox' },
213
- Command: { attributeClasses: glassAttributeClasses('ui-command--glass'), baseClassName: 'ui-command', defaults: { 'data-ui-command': '' }, tagName: 'lumen-command' },
214
- ColorPicker: { baseClassName: 'ui-color-picker', defaults: { type: 'color' }, tagName: 'lumen-color-picker' },
215
- ContextMenu: {
216
- attributeClasses: {
217
- glass: { strong: 'ui-menu--glass ui-glass-strong', subtle: 'ui-menu--glass ui-glass-subtle', true: 'ui-menu--glass' },
218
- surface: { glass: 'ui-menu--glass' }
219
- },
220
- baseClassName: 'ui-menu',
221
- defaults: { 'data-ui-context-menu': '', role: 'menu', surface: 'default' },
222
- tagName: 'lumen-context-menu'
223
- },
224
- DataTable: { attributeClasses: glassAttributeClasses('ui-data-table--glass'), baseClassName: 'ui-data-table', defaults: { 'data-ui-datatable': '' }, tagName: 'lumen-data-table' },
225
- DatePicker: {
226
- attributeClasses: glassAttributeClasses('ui-date-picker-field--glass'),
227
- baseClassName: 'ui-input ui-date-picker',
228
- defaults: { type: 'date' },
229
- tagName: 'lumen-date-picker'
230
- },
231
- DateRangePicker: { baseClassName: 'ui-date-range-picker', defaults: { 'data-ui-date-range-picker': '' }, tagName: 'lumen-date-range-picker' },
232
- Dialog: {
233
- attributeClasses: {
234
- glass: { strong: 'ui-dialog--glass ui-glass-strong', subtle: 'ui-dialog--glass ui-glass-subtle', true: 'ui-dialog--glass' },
235
- layout: { fullscreen: 'ui-dialog--fullscreen' },
236
- surface: { glass: 'ui-dialog--glass' }
237
- },
238
- baseClassName: 'ui-dialog',
239
- defaults: { 'data-ui-dialog': '', layout: 'centered', surface: 'default' },
240
- tagName: 'lumen-dialog'
241
- },
242
- Direction: { baseClassName: 'ui-direction', defaults: { dir: 'ltr' }, tagName: 'lumen-direction' },
243
- Drawer: {
244
- attributeClasses: {
245
- glass: { strong: 'ui-drawer--glass ui-glass-strong', subtle: 'ui-drawer--glass ui-glass-subtle', true: 'ui-drawer--glass' },
246
- surface: { glass: 'ui-drawer--glass' }
247
- },
248
- baseClassName: 'ui-drawer',
249
- defaults: { 'data-ui-drawer': '', surface: 'default' },
250
- tagName: 'lumen-drawer'
251
- },
252
- DropdownMenu: {
253
- attributeClasses: {
254
- glass: { strong: 'ui-menu--glass ui-glass-strong', subtle: 'ui-menu--glass ui-glass-subtle', true: 'ui-menu--glass' },
255
- surface: { glass: 'ui-menu--glass' }
256
- },
257
- baseClassName: 'ui-menu',
258
- defaults: { 'data-ui-dropdown-menu': '', surface: 'default' },
259
- tagName: 'lumen-dropdown-menu'
260
- },
261
- Empty: { attributeClasses: glassAttributeClasses('ui-empty--glass'), baseClassName: 'ui-empty', tagName: 'lumen-empty' },
262
- Eyebrow: { baseClassName: 'ui-eyebrow', tagName: 'lumen-eyebrow' },
263
- Field: { attributeClasses: glassAttributeClasses('ui-field--glass'), baseClassName: 'ui-field', defaults: { 'data-ui-field': '' }, tagName: 'lumen-field' },
264
- FloatingBadge: { baseClassName: 'ui-floating-badge', tagName: 'lumen-floating-badge' },
265
- FormattedDate: { baseClassName: 'ui-formatted-date', tagName: 'lumen-formatted-date' },
266
- HoverCard: {
267
- attributeClasses: {
268
- glass: { strong: 'ui-hover-card--glass ui-glass-strong', subtle: 'ui-hover-card--glass ui-glass-subtle', true: 'ui-hover-card--glass' },
269
- surface: { glass: 'ui-hover-card--glass' }
270
- },
271
- baseClassName: 'ui-hover-card',
272
- defaults: { 'data-ui-hover-card': '', surface: 'default' },
273
- tagName: 'lumen-hover-card'
274
- },
275
- Icon: {
276
- attributeClasses: {
277
- size: {
278
- lg: 'ui-icon--lg',
279
- sm: 'ui-icon--sm',
280
- xl: 'ui-icon--xl'
281
- }
282
- },
283
- baseClassName: 'ui-icon',
284
- defaults: { size: 'default' },
285
- tagName: 'lumen-icon'
286
- },
287
- Image: {
288
- attributeClasses: {
289
- 'invert-on-dark': { true: 'ui-image--invert-dark' }
290
- },
291
- baseClassName: 'ui-image',
292
- tagName: 'lumen-image'
293
- },
294
- Input: { attributeClasses: { size: { lg: 'ui-input--lg', sm: 'ui-input--sm' } }, baseClassName: 'ui-input', defaults: { type: 'text' }, tagName: 'lumen-input' },
295
- InputGroup: { baseClassName: 'ui-input-group', tagName: 'lumen-input-group' },
296
- InputOTP: { baseClassName: 'ui-input-otp-field', defaults: { 'data-ui-input-otp': '', 'data-ui-input-otp-length': '6' }, tagName: 'lumen-input-otp' },
297
- NumberField: { baseClassName: 'ui-input ui-number-field', defaults: { type: 'number' }, tagName: 'lumen-number-field' },
298
- Item: { attributeClasses: glassAttributeClasses('ui-item--glass'), baseClassName: 'ui-item', tagName: 'lumen-item' },
299
- Kbd: { baseClassName: 'ui-kbd', tagName: 'lumen-kbd' },
300
- Label: { baseClassName: 'ui-label', tagName: 'lumen-label' },
301
- Link: { attributeClasses: { variant: { inherit: 'ui-link--inherit' } }, baseClassName: 'ui-link', tagName: 'lumen-link' },
302
- Marker: {
303
- attributeClasses: {
304
- variant: {
305
- danger: 'ui-marker--danger',
306
- success: 'ui-marker--success',
307
- warning: 'ui-marker--warning'
308
- }
309
- },
310
- baseClassName: 'ui-marker',
311
- defaults: { variant: 'default' },
312
- tagName: 'lumen-marker'
313
- },
314
- Menubar: {
315
- attributeClasses: {
316
- glass: { strong: 'ui-menubar--glass ui-glass-strong', subtle: 'ui-menubar--glass ui-glass-subtle', true: 'ui-menubar--glass' },
317
- surface: { glass: 'ui-menubar--glass' }
318
- },
319
- baseClassName: 'ui-menubar',
320
- defaults: { 'data-ui-menubar': '', surface: 'default' },
321
- tagName: 'lumen-menubar'
322
- },
323
- Message: {
324
- attributeClasses: {
325
- from: {
326
- assistant: 'ui-message--assistant',
327
- user: 'ui-message--user'
328
- }
329
- },
330
- baseClassName: 'ui-message',
331
- defaults: { from: 'assistant' },
332
- tagName: 'lumen-message'
333
- },
334
- MessageScroller: { attributeClasses: glassAttributeClasses('ui-message-scroller--glass'), baseClassName: 'ui-message-scroller', tagName: 'lumen-message-scroller' },
335
- NativeSelect: { attributeClasses: { size: { lg: 'ui-select--lg', sm: 'ui-select--sm' } }, baseClassName: 'ui-select', tagName: 'lumen-native-select' },
336
- NavigationMenu: {
337
- attributeClasses: {
338
- glass: { strong: 'ui-navigation-menu--glass ui-glass-strong', subtle: 'ui-navigation-menu--glass ui-glass-subtle', true: 'ui-navigation-menu--glass' },
339
- surface: { glass: 'ui-navigation-menu--glass' },
340
- variant: { unstyled: 'ui-navigation-menu--unstyled' }
341
- },
342
- baseClassName: 'ui-navigation-menu',
343
- defaults: { 'data-ui-navigation-menu': '', surface: 'default' },
344
- tagName: 'lumen-navigation-menu'
345
- },
346
- Pagination: { baseClassName: 'ui-pagination', defaults: { 'aria-label': 'Pagination' }, tagName: 'lumen-pagination' },
347
- PhoneInput: { baseClassName: 'ui-phone-input ui-input-group', tagName: 'lumen-phone-input' },
348
- Pill: { baseClassName: 'ui-pill', tagName: 'lumen-pill' },
349
- Popover: {
350
- attributeClasses: {
351
- glass: { strong: 'ui-popover--glass ui-glass-strong', subtle: 'ui-popover--glass ui-glass-subtle', true: 'ui-popover--glass' },
352
- surface: { glass: 'ui-popover--glass' }
353
- },
354
- baseClassName: 'ui-popover',
355
- defaults: { 'data-ui-popover': '', surface: 'default' },
356
- tagName: 'lumen-popover'
357
- },
358
- Progress: { baseClassName: 'ui-progress', defaults: { role: 'progressbar' }, tagName: 'lumen-progress' },
359
- Prose: { baseClassName: 'ui-prose', tagName: 'lumen-prose' },
360
- RadioGroup: { baseClassName: 'ui-radio-group', defaults: { 'data-ui-radio-group': '' }, tagName: 'lumen-radio-group' },
361
- Resizable: {
362
- attributeClasses: { 'data-orientation': { vertical: 'ui-resizable--vertical' } },
363
- baseClassName: 'ui-resizable',
364
- defaults: { 'data-orientation': 'horizontal', 'data-ui-resizable': '', 'data-ui-resizable-reset': 'true' },
365
- tagName: 'lumen-resizable'
366
- },
367
- RichTextEditor: { attributeClasses: glassAttributeClasses('ui-rich-text-editor--glass'), baseClassName: 'ui-rich-text-editor', defaults: { 'data-ui-rich-text-editor': '' }, tagName: 'lumen-rich-text-editor' },
368
- ScrollArea: { attributeClasses: glassAttributeClasses('ui-scroll-area--glass'), baseClassName: 'ui-scroll-area', tagName: 'lumen-scroll-area' },
369
- Schedule: { attributeClasses: glassAttributeClasses('ui-schedule--glass'), baseClassName: 'ui-schedule', defaults: { 'data-ui-schedule': '' }, tagName: 'lumen-schedule' },
370
- SearchField: { baseClassName: 'ui-input ui-search-field', defaults: { type: 'search' }, tagName: 'lumen-search-field' },
371
- Select: {
372
- attributeClasses: {
373
- ...glassAttributeClasses('ui-select-field--glass'),
374
- size: { lg: 'ui-select--lg', sm: 'ui-select--sm' }
375
- },
376
- baseClassName: 'ui-select',
377
- tagName: 'lumen-select'
378
- },
379
- Separator: {
380
- attributeClasses: {
381
- orientation: {
382
- horizontal: 'ui-separator--horizontal',
383
- vertical: 'ui-separator--vertical'
384
- }
385
- },
386
- baseClassName: 'ui-separator',
387
- defaults: { orientation: 'horizontal' },
388
- tagName: 'lumen-separator'
389
- },
390
- Sheet: {
391
- attributeClasses: {
392
- glass: { strong: 'ui-sheet--glass ui-glass-strong', subtle: 'ui-sheet--glass ui-glass-subtle', true: 'ui-sheet--glass' },
393
- surface: { glass: 'ui-sheet--glass' }
394
- },
395
- baseClassName: 'ui-sheet',
396
- defaults: { 'data-ui-sheet': '', surface: 'default' },
397
- tagName: 'lumen-sheet'
398
- },
399
- Sidebar: {
400
- attributeClasses: {
401
- glass: { strong: 'ui-sidebar--glass ui-glass-strong', subtle: 'ui-sidebar--glass ui-glass-subtle', true: 'ui-sidebar--glass' },
402
- surface: { glass: 'ui-sidebar--glass' },
403
- variant: { unstyled: 'ui-sidebar--unstyled' }
404
- },
405
- baseClassName: 'ui-sidebar',
406
- defaults: { surface: 'default' },
407
- tagName: 'lumen-sidebar'
408
- },
409
- Skeleton: { baseClassName: 'ui-skeleton', tagName: 'lumen-skeleton' },
410
- SkipLink: { baseClassName: 'ui-skip-link', tagName: 'lumen-skip-link' },
411
- Slider: { baseClassName: 'ui-slider', defaults: { type: 'range' }, tagName: 'lumen-slider' },
412
- Sonner: { baseClassName: 'ui-sonner', defaults: { 'data-ui-sonner': '' }, tagName: 'lumen-sonner' },
413
- Spinner: { baseClassName: 'ui-spinner', tagName: 'lumen-spinner' },
414
- Switch: { baseClassName: 'ui-switch', defaults: { role: 'switch', type: 'checkbox' }, tagName: 'lumen-switch' },
415
- Table: { attributeClasses: glassAttributeClasses('ui-table-wrap--glass'), baseClassName: 'ui-table-wrap', tagName: 'lumen-table' },
416
- Tabs: { attributeClasses: glassAttributeClasses('ui-tabs--glass'), baseClassName: 'ui-tabs', defaults: { 'data-ui-tabs': '' }, tagName: 'lumen-tabs' },
417
- TagGroup: { baseClassName: 'ui-tag-group', defaults: { role: 'list' }, tagName: 'lumen-tag-group' },
418
- Textarea: { baseClassName: 'ui-textarea', defaults: { rows: '4' }, tagName: 'lumen-textarea' },
419
- ThemeBuilder: { attributeClasses: glassAttributeClasses('ui-theme-builder--glass'), baseClassName: 'ui-theme-builder', defaults: { 'data-ui-theme-builder': '' }, tagName: 'lumen-theme-builder' },
420
- ThemeToggle: { baseClassName: 'ui-theme-toggle', tagName: 'lumen-theme-toggle' },
421
- TimeField: { baseClassName: 'ui-input ui-time-field', defaults: { type: 'time' }, tagName: 'lumen-time-field' },
422
- Toast: {
423
- attributeClasses: {
424
- glass: {
425
- true: 'ui-toast--glass'
426
- },
427
- surface: {
428
- glass: 'ui-toast--glass'
429
- },
430
- variant: {
431
- destructive: 'ui-toast--destructive',
432
- success: 'ui-toast--success',
433
- warning: 'ui-toast--warning'
434
- }
435
- },
436
- baseClassName: 'ui-toast',
437
- defaults: { surface: 'default', variant: 'default' },
438
- tagName: 'lumen-toast'
439
- },
440
- Toggle: {
441
- baseClassName: 'ui-toggle',
442
- defaults: { 'aria-pressed': 'false', 'data-ui-toggle': '', role: 'button', tabindex: '0' },
443
- role: 'button',
444
- tagName: 'lumen-toggle'
445
- },
446
- ToggleGroup: { baseClassName: 'ui-toggle-group', defaults: { 'data-ui-toggle-group': '' }, tagName: 'lumen-toggle-group' },
447
- Tooltip: { baseClassName: 'ui-tooltip', tagName: 'lumen-tooltip' },
448
- Tree: { attributeClasses: glassAttributeClasses('ui-tree--glass'), baseClassName: 'ui-tree', defaults: { role: 'tree' }, tagName: 'lumen-tree' },
449
- TreeGrid: { attributeClasses: glassAttributeClasses('ui-tree-grid--glass'), baseClassName: 'ui-tree-grid', defaults: { role: 'treegrid' }, tagName: 'lumen-tree-grid' },
450
- Typography: { baseClassName: 'ui-typography', tagName: 'lumen-typography' },
451
- VirtualList: { attributeClasses: glassAttributeClasses('ui-virtual-list--glass'), baseClassName: 'ui-virtual-list', defaults: { 'data-ui-virtual-list': '' }, tagName: 'lumen-virtual-list' },
452
- LanguageToggle: { baseClassName: 'ui-language-toggle', tagName: 'lumen-language-toggle' },
453
- Particles: { baseClassName: 'ui-particles', tagName: 'lumen-particles' },
454
- AnimatedNumber: {
455
- attributeClasses: {
456
- duration: {
457
- fast: 'ui-motion-duration-fast',
458
- slow: 'ui-motion-duration-slow',
459
- standard: 'ui-motion-duration-standard'
460
- }
461
- },
462
- baseClassName: 'ui-animated-number',
463
- defaults: { duration: 'slow', from: '0' },
464
- tagName: 'lumen-animated-number'
465
- },
466
- RevealGroup: {
467
- attributeClasses: {
468
- animation: {
469
- fade: 'ui-reveal-group-fade',
470
- scale: 'ui-reveal-group-scale',
471
- 'slide-up': 'ui-reveal-group-slide-up'
472
- },
473
- duration: {
474
- fast: 'ui-motion-duration-fast',
475
- slow: 'ui-motion-duration-slow',
476
- standard: 'ui-motion-duration-standard'
477
- }
478
- },
479
- baseClassName: 'ui-reveal-group',
480
- defaults: { animation: 'slide-up', duration: 'slow', once: 'true', threshold: '0.15' },
481
- tagName: 'lumen-reveal-group'
482
- },
483
- ScrollReveal: {
484
- attributeClasses: {
485
- animation: {
486
- fade: 'ui-scroll-reveal-fade',
487
- scale: 'ui-scroll-reveal-scale',
488
- 'slide-up': 'ui-scroll-reveal-slide-up'
489
- },
490
- duration: {
491
- fast: 'ui-motion-duration-fast',
492
- slow: 'ui-motion-duration-slow',
493
- standard: 'ui-motion-duration-standard'
494
- }
495
- },
496
- baseClassName: 'ui-scroll-reveal',
497
- defaults: { animation: 'fade', duration: 'slow', once: 'true', threshold: '0.15' },
498
- tagName: 'lumen-scroll-reveal'
499
- },
500
- Stat: { baseClassName: 'ui-stat', tagName: 'lumen-stat' },
501
- Meter: { baseClassName: 'ui-meter', tagName: 'lumen-meter' },
502
- Note: {
503
- attributeClasses: {
504
- 'border-position': {
505
- left: 'ui-note--border-left',
506
- none: 'ui-note--border-none',
507
- right: 'ui-note--border-right'
508
- }
509
- },
510
- baseClassName: 'ui-note',
511
- defaults: { 'border-position': 'left' },
512
- tagName: 'lumen-note'
513
- },
514
- Rating: { baseClassName: 'ui-rating', tagName: 'lumen-rating' },
515
- Timeline: { baseClassName: 'ui-timeline', tagName: 'lumen-timeline' },
516
- AnimatedLogo: { baseClassName: 'ui-animated-logo', tagName: 'lumen-animated-logo' },
517
- AnimatedPortrait: { baseClassName: 'ui-animated-portrait', tagName: 'lumen-animated-portrait' },
518
- ButtonLink: {
519
- attributeClasses: {
520
- shape: { icon: 'ui-button-link--icon' },
521
- variant: { unstyled: 'ui-button-link--unstyled' }
522
- },
523
- baseClassName: 'ui-button-link',
524
- tagName: 'lumen-button-link'
525
- },
526
- CoverImage: {
527
- attributeClasses: { hover: { true: 'ui-cover-image--hover' } },
528
- baseClassName: 'ui-cover-image',
529
- tagName: 'lumen-cover-image'
530
- },
531
- GradientDivider: { baseClassName: 'ui-gradient-divider', tagName: 'lumen-gradient-divider' },
532
- Stepper: {
533
- attributeClasses: { orientation: { vertical: 'ui-stepper--vertical' } },
534
- baseClassName: 'ui-stepper',
535
- defaults: { orientation: 'horizontal' },
536
- tagName: 'lumen-stepper'
537
- },
538
- FileUpload: { baseClassName: 'ui-file-upload', defaults: { 'data-ui-file-upload': '' }, tagName: 'lumen-file-upload' },
539
- Tour: { baseClassName: 'ui-tour', defaults: { 'data-ui-tour': '' }, tagName: 'lumen-tour' },
540
- Anchor: { baseClassName: 'ui-anchor', defaults: { 'aria-label': 'On this page', 'data-ui-anchor': '' }, tagName: 'lumen-anchor' },
541
- Segmented: {
542
- attributeClasses: { size: { lg: 'ui-segmented--lg', sm: 'ui-segmented--sm' } },
543
- baseClassName: 'ui-segmented',
544
- defaults: { role: 'group' },
545
- tagName: 'lumen-segmented'
546
- },
547
- Toolbar: {
548
- attributeClasses: { orientation: { vertical: 'ui-toolbar--vertical' } },
549
- baseClassName: 'ui-toolbar',
550
- defaults: { 'aria-label': 'Toolbar', 'data-ui-toolbar': '', orientation: 'horizontal', role: 'toolbar' },
551
- tagName: 'lumen-toolbar'
552
- },
553
- Descriptions: { baseClassName: 'ui-descriptions', tagName: 'lumen-descriptions' },
554
- Popconfirm: { baseClassName: 'ui-popover ui-popconfirm', defaults: { 'data-ui-popconfirm': '', 'data-ui-popover': '' }, tagName: 'lumen-popconfirm' },
555
- Transfer: { baseClassName: 'ui-transfer', defaults: { 'data-ui-transfer': '' }, tagName: 'lumen-transfer' },
556
- Cascader: { baseClassName: 'ui-cascader', defaults: { 'data-ui-cascader': '' }, tagName: 'lumen-cascader' },
557
- TreeSelect: { baseClassName: 'ui-tree-select', defaults: { 'data-ui-tree-select': '' }, tagName: 'lumen-tree-select' },
558
- Mentions: { baseClassName: 'ui-mentions', defaults: { 'data-ui-mentions': '' }, tagName: 'lumen-mentions' },
559
- QRCode: { baseClassName: 'ui-qr-code', tagName: 'lumen-qr-code' },
560
- Watermark: { baseClassName: 'ui-watermark', defaults: { 'data-ui-watermark': '' }, tagName: 'lumen-watermark' },
561
- Affix: {
562
- attributeClasses: { position: { bottom: 'ui-affix--bottom' } },
563
- baseClassName: 'ui-affix',
564
- defaults: { position: 'top' },
565
- tagName: 'lumen-affix'
566
- },
567
- SpeedDial: {
568
- attributeClasses: {
569
- direction: {
570
- down: 'ui-speed-dial--down',
571
- left: 'ui-speed-dial--left',
572
- right: 'ui-speed-dial--right',
573
- up: 'ui-speed-dial--up'
574
- }
575
- },
576
- baseClassName: 'ui-speed-dial',
577
- defaults: { 'data-ui-speed-dial': '', direction: 'up' },
578
- tagName: 'lumen-speed-dial'
579
- }
580
- };
581
- const observedAttributeNames = [
582
- 'animation',
583
- 'border-position',
584
- 'decimals',
585
- 'delay',
586
- 'decorative',
587
- 'direction',
588
- 'disabled',
589
- 'duration',
590
- 'from',
591
- 'glass',
592
- 'hover',
593
- 'label',
594
- 'locale',
595
- 'name',
596
- 'orientation',
597
- 'position',
598
- 'prefix',
599
- 'pressed',
600
- 'shape',
601
- 'size',
602
- 'surface',
603
- 'stagger',
604
- 'suffix',
605
- 'threshold',
606
- 'value',
607
- 'variant'
608
- ];
609
- const hasDocument = () => typeof document !== 'undefined';
610
- const parseMotionDuration = (value) => {
611
- const parsedDuration = Number.parseFloat(value);
612
- if (!Number.isFinite(parsedDuration))
613
- return 300;
614
- return value.endsWith('ms') ? parsedDuration : parsedDuration * 1000;
615
- };
616
- const createId = (prefix) => {
617
- if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {
618
- return `${prefix}-${crypto.randomUUID()}`;
619
- }
620
- return `${prefix}-${Math.random().toString(36).slice(2)}`;
621
- };
622
- const isElementVisible = (element) => {
623
- if (typeof element.checkVisibility === 'function') {
624
- return element.checkVisibility();
625
- }
626
- return element.offsetParent !== null || element.getClientRects().length > 0;
627
- };
628
- const getFocusable = (root) => {
629
- if (!root)
630
- return [];
631
- return [...root.querySelectorAll(focusableSelector)]
632
- .filter(element => !element.hasAttribute('hidden') && isElementVisible(element));
633
- };
634
- const getOwnedTarget = (event) => event.target instanceof Node ? event.target : null;
635
- const getScopedElements = (scope, selector) => {
636
- const elements = [...scope.querySelectorAll(selector)];
637
- if (scope instanceof Element && scope.matches(selector)) {
638
- elements.unshift(scope);
639
- }
640
- return elements;
641
- };
642
- const getClosestScopedElement = (scope, selector) => scope instanceof Element ? scope.closest(selector) : null;
643
- const isNativeFormControl = (element) => element instanceof HTMLInputElement ||
644
- element instanceof HTMLSelectElement ||
645
- element instanceof HTMLTextAreaElement;
646
- const getFieldControl = (root) => {
647
- const controlId = root.dataset.uiFieldControl;
648
- if (controlId && hasDocument()) {
649
- const control = document.getElementById(controlId);
650
- if (control instanceof HTMLElement)
651
- return control;
652
- }
653
- return root.querySelector(fieldControlSelector);
654
- };
655
- const getFieldDescriptionId = (element) => {
656
- if (!element.id) {
657
- element.id = createId('ui-field-description');
658
- }
659
- return element.id;
660
- };
661
- const getFieldRoot = (control) => control.closest('.ui-field, [data-ui-field]');
662
- const getValidationMessage = (control, field) => {
663
- for (const [validityKey, attributeName] of validityMessageAttributes) {
664
- if (!control.validity[validityKey])
665
- continue;
666
- return control.getAttribute(attributeName) ??
667
- field?.getAttribute(attributeName) ??
668
- control.validationMessage;
669
- }
670
- return control.validationMessage;
671
- };
672
- const setFieldValidity = (control, invalid, message = '') => {
673
- const field = getFieldRoot(control);
674
- if (invalid) {
675
- control.setAttribute('aria-invalid', 'true');
676
- control.dataset.uiValidationInvalid = 'true';
677
- }
678
- else if (control.dataset.uiValidationInvalid === 'true') {
679
- control.removeAttribute('aria-invalid');
680
- delete control.dataset.uiValidationInvalid;
681
- }
682
- if (!field)
683
- return;
684
- field.dataset.invalid = String(invalid);
685
- for (const error of field.querySelectorAll(fieldErrorSelector)) {
686
- error.dataset.uiValidationErrorBound = 'true';
687
- error.hidden = !invalid;
688
- error.textContent = invalid ? message : '';
689
- }
690
- };
691
- const validateControl = (control, form) => {
692
- form.dispatchEvent(new CustomEvent('ui:validate', {
693
- bubbles: true,
694
- detail: { control, form, value: control.value }
695
- }));
696
- const invalid = !control.validity.valid;
697
- const message = invalid ? getValidationMessage(control, getFieldRoot(control)) : '';
698
- setFieldValidity(control, invalid, message);
699
- return !invalid;
700
- };
701
- const getFormControls = (form) => [...form.querySelectorAll(formControlSelector)]
702
- .filter(control => control.form === form && !control.disabled);
703
- const validateForm = (form) => getFormControls(form).filter(control => !validateControl(control, form));
704
- const initLumenFields = (scope) => {
705
- for (const root of getScopedElements(scope, '.ui-field, [data-ui-field]')) {
706
- if (root.dataset.uiFieldBound === 'true')
707
- continue;
708
- const control = getFieldControl(root);
709
- if (!control)
710
- continue;
711
- root.dataset.uiFieldBound = 'true';
712
- const existingIds = control.getAttribute('aria-describedby')?.trim().split(/\s+/) ?? [];
713
- const configuredIds = root.dataset.uiFieldDescribedby?.trim().split(/\s+/) ?? [];
714
- const descriptionIds = [...root.querySelectorAll(fieldDescriptionSelector)]
715
- .map(element => getFieldDescriptionId(element));
716
- const describedBy = [...new Set([...existingIds, ...configuredIds, ...descriptionIds].filter(Boolean))];
717
- if (describedBy.length) {
718
- control.setAttribute('aria-describedby', describedBy.join(' '));
719
- }
720
- }
721
- };
722
- const initLumenForms = (scope) => {
723
- for (const form of getScopedElements(scope, 'form[data-ui-form]')) {
724
- if (form.dataset.uiFormBound === 'true')
725
- continue;
726
- form.dataset.uiFormBound = 'true';
727
- form.noValidate = true;
728
- form.addEventListener('focusout', event => {
729
- if (!isNativeFormControl(event.target) || event.target.form !== form)
730
- return;
731
- const valid = validateControl(event.target, form);
732
- form.dispatchEvent(new CustomEvent(valid ? 'ui:valid' : 'ui:invalid', {
733
- bubbles: true,
734
- detail: valid
735
- ? { control: event.target, form }
736
- : { control: event.target, controls: [event.target], form }
737
- }));
738
- });
739
- form.addEventListener('submit', event => {
740
- const invalidControls = validateForm(form);
741
- if (invalidControls.length) {
742
- event.preventDefault();
743
- const firstInvalid = invalidControls[0];
744
- if (!firstInvalid)
745
- return;
746
- form.dispatchEvent(new CustomEvent('ui:invalid', {
747
- bubbles: true,
748
- detail: { control: firstInvalid, controls: invalidControls, form }
749
- }));
750
- firstInvalid.focus({ preventScroll: true });
751
- firstInvalid.reportValidity();
752
- return;
753
- }
754
- form.dispatchEvent(new CustomEvent('ui:valid', {
755
- bubbles: true,
756
- detail: { controls: getFormControls(form), form }
757
- }));
758
- });
759
- }
760
- };
761
- export const enhanceLumenForms = (scope = document) => {
762
- initLumenFields(scope);
763
- initLumenForms(scope);
764
- };
765
- const installFormController = () => {
766
- if (!hasDocument() || document.documentElement.dataset.uiElementsFormsBound === 'true')
767
- return;
768
- document.documentElement.dataset.uiElementsFormsBound = 'true';
769
- enhanceLumenForms(document);
770
- if (typeof MutationObserver === 'undefined')
771
- return;
772
- const observer = new MutationObserver(mutations => {
773
- for (const mutation of mutations) {
774
- for (const node of mutation.addedNodes) {
775
- if (node instanceof Element || node instanceof DocumentFragment) {
776
- enhanceLumenForms(node);
777
- }
778
- }
779
- }
780
- });
781
- observer.observe(document.documentElement, { childList: true, subtree: true });
782
- };
783
- const getRichTextCommandValue = (control) => {
784
- if (control.dataset.uiEditorValue !== undefined)
785
- return control.dataset.uiEditorValue;
786
- if (control instanceof HTMLInputElement
787
- || control instanceof HTMLSelectElement
788
- || control instanceof HTMLTextAreaElement)
789
- return control.value;
790
- return undefined;
791
- };
792
- const syncRichTextCommandStates = (root) => {
793
- const commandDocument = document;
794
- for (const control of root.querySelectorAll(richTextEditorCommandSelector)) {
795
- const command = control.dataset.uiEditorCommand ?? '';
796
- const value = getRichTextCommandValue(control);
797
- let active = false;
798
- if (isLumenRichTextToggleCommand(command)) {
799
- active = commandDocument.queryCommandState?.(command) ?? false;
800
- control.setAttribute('aria-pressed', String(active));
801
- }
802
- else if (command === 'formatBlock' && value) {
803
- const currentValue = commandDocument.queryCommandValue?.(command)
804
- .replaceAll(/[<>]/g, '')
805
- .toLowerCase();
806
- active = currentValue === value.replaceAll(/[<>]/g, '').toLowerCase();
807
- }
808
- control.dataset.state = active ? 'on' : 'off';
809
- }
810
- };
811
- const dispatchRichTextChange = (root) => {
812
- const editable = root.querySelector(richTextEditorContentSelector);
813
- if (!editable)
814
- return;
815
- const detail = {
816
- html: editable.innerHTML,
817
- text: editable.textContent
818
- };
819
- root.dispatchEvent(new CustomEvent('ui:editor-change', {
820
- bubbles: true,
821
- detail
822
- }));
823
- };
824
- const executeRichTextCommand = (root, command, value) => {
825
- if (!command)
826
- return false;
827
- const commandDocument = document;
828
- let executed = false;
829
- if (typeof commandDocument.execCommand === 'function') {
830
- executed = value === undefined
831
- ? commandDocument.execCommand(command)
832
- : commandDocument.execCommand(command, false, value);
833
- }
834
- const detail = {
835
- command,
836
- executed,
837
- ...(value === undefined ? {} : { value })
838
- };
839
- root.dispatchEvent(new CustomEvent('ui:editor-command', {
840
- bubbles: true,
841
- detail
842
- }));
843
- syncRichTextCommandStates(root);
844
- dispatchRichTextChange(root);
845
- return executed;
846
- };
847
- const initRichTextEditors = (scope) => {
848
- const closestRoot = getClosestScopedElement(scope, richTextEditorSelector);
849
- const roots = getScopedElements(scope, richTextEditorSelector);
850
- if (closestRoot instanceof HTMLElement && !roots.includes(closestRoot)) {
851
- roots.unshift(closestRoot);
852
- }
853
- for (const root of roots) {
854
- if (root.dataset.uiEditorBound === 'true')
855
- continue;
856
- root.dataset.uiEditorBound = 'true';
857
- for (const control of root.querySelectorAll(richTextEditorCommandSelector)) {
858
- control.dataset.uiEditorCommandBound = 'true';
859
- const execute = () => {
860
- executeRichTextCommand(root, control.dataset.uiEditorCommand ?? '', getRichTextCommandValue(control));
861
- };
862
- if (control instanceof HTMLSelectElement)
863
- control.addEventListener('change', execute);
864
- else
865
- control.addEventListener('click', execute);
866
- }
867
- root.addEventListener('keydown', event => {
868
- if (!(event.target instanceof HTMLElement)
869
- || !event.target.closest(richTextEditorContentSelector))
870
- return;
871
- const command = getLumenRichTextShortcut(event);
872
- if (!command)
873
- return;
874
- event.preventDefault();
875
- executeRichTextCommand(root, command);
876
- });
877
- root.addEventListener('input', event => {
878
- if (!(event.target instanceof HTMLElement)
879
- || !event.target.closest(richTextEditorContentSelector))
880
- return;
881
- syncRichTextCommandStates(root);
882
- dispatchRichTextChange(root);
883
- });
884
- root.addEventListener('keyup', () => { syncRichTextCommandStates(root); });
885
- root.addEventListener('mouseup', () => { syncRichTextCommandStates(root); });
886
- syncRichTextCommandStates(root);
887
- }
888
- };
889
- export const enhanceLumenRichTextEditors = (scope = document) => {
890
- initRichTextEditors(scope);
891
- };
892
- const installRichTextEditorController = () => {
893
- if (!hasDocument() || document.documentElement.dataset.uiElementsRichTextEditorsBound === 'true')
894
- return;
895
- document.documentElement.dataset.uiElementsRichTextEditorsBound = 'true';
896
- enhanceLumenRichTextEditors(document);
897
- if (typeof MutationObserver === 'undefined')
898
- return;
899
- const observer = new MutationObserver(mutations => {
900
- for (const mutation of mutations) {
901
- for (const node of mutation.addedNodes) {
902
- if (node instanceof Element || node instanceof DocumentFragment) {
903
- enhanceLumenRichTextEditors(node);
904
- }
905
- }
906
- }
907
- });
908
- observer.observe(document.documentElement, { childList: true, subtree: true });
909
- };
910
- const getScheduleTransferValue = (event) => event.id || event.textContent.trim();
911
- const initSchedules = (scope) => {
912
- const closestRoot = getClosestScopedElement(scope, scheduleSelector);
913
- const roots = getScopedElements(scope, scheduleSelector);
914
- if (closestRoot instanceof HTMLElement && !roots.includes(closestRoot)) {
915
- roots.unshift(closestRoot);
916
- }
917
- for (const root of roots) {
918
- root.dataset.uiScheduleBound = 'true';
919
- for (const scheduleEvent of root.querySelectorAll(scheduleEventSelector)) {
920
- if (scheduleEvent.dataset.uiScheduleEventBound === 'true')
921
- continue;
922
- scheduleEvent.dataset.uiScheduleEventBound = 'true';
923
- scheduleEvent.draggable = scheduleEvent.draggable || scheduleEvent.dataset.uiDraggable === 'true';
924
- scheduleEvent.addEventListener('dragstart', event => {
925
- event.dataTransfer?.setData('text/plain', getScheduleTransferValue(scheduleEvent));
926
- root.dataset.uiDragging = 'true';
927
- });
928
- scheduleEvent.addEventListener('dragend', () => {
929
- delete root.dataset.uiDragging;
930
- });
931
- }
932
- for (const slot of root.querySelectorAll(scheduleSlotSelector)) {
933
- if (slot.dataset.uiScheduleSlotBound === 'true')
934
- continue;
935
- slot.dataset.uiScheduleSlotBound = 'true';
936
- slot.addEventListener('dragover', event => {
937
- event.preventDefault();
938
- slot.dataset.state = 'drag-over';
939
- });
940
- slot.addEventListener('dragleave', () => {
941
- delete slot.dataset.state;
942
- });
943
- slot.addEventListener('drop', event => {
944
- event.preventDefault();
945
- delete slot.dataset.state;
946
- const draggedId = event.dataTransfer?.getData('text/plain');
947
- const dragged = draggedId ? document.getElementById(draggedId) : null;
948
- if (dragged instanceof HTMLElement) {
949
- slot.append(dragged);
950
- }
951
- root.dispatchEvent(new CustomEvent('ui:schedule-change', {
952
- bubbles: true,
953
- detail: {
954
- ...(draggedId ? { eventId: draggedId } : {}),
955
- ...(slot.dataset.uiScheduleSlot ? { slot: slot.dataset.uiScheduleSlot } : {})
956
- }
957
- }));
958
- });
959
- }
960
- }
961
- };
962
- export const enhanceLumenSchedules = (scope = document) => {
963
- initSchedules(scope);
964
- };
965
- const installScheduleController = () => {
966
- if (!hasDocument() || document.documentElement.dataset.uiElementsSchedulesBound === 'true')
967
- return;
968
- document.documentElement.dataset.uiElementsSchedulesBound = 'true';
969
- enhanceLumenSchedules(document);
970
- if (typeof MutationObserver === 'undefined')
971
- return;
972
- const observer = new MutationObserver(mutations => {
973
- for (const mutation of mutations) {
974
- for (const node of mutation.addedNodes) {
975
- if (node instanceof Element || node instanceof DocumentFragment) {
976
- enhanceLumenSchedules(node);
977
- }
978
- }
979
- }
980
- });
981
- observer.observe(document.documentElement, { childList: true, subtree: true });
982
- };
983
- /* cspell:ignore valuenow */
984
- /* eslint-disable @stylistic/padding-line-between-statements -- Resizable mirrors Astro's compact pane sizing runtime. */
985
- const parseResizableNumberList = (value, count, fallback) => {
986
- const values = (value ?? '')
987
- .split(',')
988
- .map(item => Number.parseFloat(item.trim()))
989
- .filter(Number.isFinite);
990
- return Array.from({ length: count }, (_, index) => values[index] ?? values[0] ?? fallback);
991
- };
992
- const normalizeResizableSizes = (sizes, count) => {
993
- const fallbackSize = 100 / Math.max(1, count);
994
- const usableSizes = Array.from({ length: count }, (_, index) => {
995
- const size = sizes[index] ?? fallbackSize;
996
- return Number.isFinite(size) && size > 0 ? size : fallbackSize;
997
- });
998
- const total = usableSizes.reduce((sum, size) => sum + size, 0);
999
- if (total <= 0)
1000
- return Array.from({ length: count }, () => fallbackSize);
1001
- return usableSizes.map(size => (size / total) * 100);
1002
- };
1003
- const getResizablePanes = (root) => [...root.children].filter((child) => child instanceof HTMLElement &&
1004
- !child.hasAttribute('data-ui-resizable-handle') &&
1005
- !child.hasAttribute('data-ui-resizable-handle-template'));
1006
- const applyResizableSizes = (root, panes, handles, sizes, minSizes, maxSizes) => {
1007
- for (const [index, pane] of panes.entries()) {
1008
- pane.dataset.uiResizablePanel = '';
1009
- pane.style.setProperty('--ui-resizable-size', `${sizes[index] ?? 0}%`);
1010
- }
1011
- for (const handle of handles) {
1012
- const index = Number.parseInt(handle.dataset.index ?? '0', 10);
1013
- handle.setAttribute('aria-valuemin', String(Math.round(minSizes[index] ?? 0)));
1014
- handle.setAttribute('aria-valuemax', String(Math.round(maxSizes[index] ?? 100)));
1015
- handle.setAttribute('aria-valuenow', String(Math.round(sizes[index] ?? 0)));
1016
- }
1017
- };
1018
- const resizeResizablePair = (sizes, minSizes, maxSizes, index, nextSize) => {
1019
- const nextIndex = index + 1;
1020
- const total = (sizes[index] ?? 0) + (sizes[nextIndex] ?? 0);
1021
- const min = Math.max(minSizes[index] ?? 0, total - (maxSizes[nextIndex] ?? 100));
1022
- const max = Math.min(maxSizes[index] ?? 100, total - (minSizes[nextIndex] ?? 0));
1023
- const paneSize = Math.min(max, Math.max(min, nextSize));
1024
- sizes[index] = paneSize;
1025
- sizes[nextIndex] = total - paneSize;
1026
- };
1027
- const createResizableHandle = (root, index, separatorOrientation) => {
1028
- const template = root.querySelector(`:scope > ${resizableHandleTemplateSelector}`);
1029
- const handleFromTemplate = template?.content
1030
- .querySelector(resizableHandleSelector)
1031
- ?.cloneNode(true);
1032
- const handle = handleFromTemplate instanceof HTMLButtonElement
1033
- ? handleFromTemplate
1034
- : document.createElement('button');
1035
- handle.type = 'button';
1036
- handle.className = 'ui-resizable__handle';
1037
- handle.dataset.uiResizableHandle = '';
1038
- handle.dataset.index = String(index);
1039
- handle.tabIndex = 0;
1040
- handle.setAttribute('aria-label', `Resize panel ${index + 1}`);
1041
- handle.setAttribute('role', 'separator');
1042
- handle.setAttribute('aria-orientation', separatorOrientation);
1043
- return handle;
1044
- };
1045
- const initResizableGroups = (scope) => {
1046
- const closestRoot = getClosestScopedElement(scope, resizableSelector);
1047
- const roots = getScopedElements(scope, resizableSelector);
1048
- if (closestRoot instanceof HTMLElement && !roots.includes(closestRoot)) {
1049
- roots.unshift(closestRoot);
1050
- }
1051
- for (const root of roots) {
1052
- if (root.dataset.uiBound === 'true')
1053
- continue;
1054
- if (root.getAttribute('direction') === 'vertical') {
1055
- root.dataset.orientation = 'vertical';
1056
- }
1057
- const panes = getResizablePanes(root);
1058
- if (panes.length < 2)
1059
- continue;
1060
- root.dataset.uiBound = 'true';
1061
- root.dataset.uiResizableEnhanced = 'true';
1062
- root.classList.toggle('ui-resizable--vertical', root.dataset.orientation === 'vertical');
1063
- const direction = root.dataset.orientation === 'vertical' ? 'vertical' : 'horizontal';
1064
- const separatorOrientation = direction === 'horizontal' ? 'vertical' : 'horizontal';
1065
- const axis = direction === 'horizontal' ? 'clientX' : 'clientY';
1066
- const sizeProperty = direction === 'horizontal' ? 'width' : 'height';
1067
- const minSizes = parseResizableNumberList(root.dataset.uiResizableMinSize, panes.length, 12);
1068
- const maxSizes = parseResizableNumberList(root.dataset.uiResizableMaxSize, panes.length, 88);
1069
- const initialSizes = normalizeResizableSizes(parseResizableNumberList(root.dataset.uiResizableDefaultSizes, panes.length, 100 / panes.length), panes.length);
1070
- let sizes = [...initialSizes];
1071
- const handles = [];
1072
- for (const [index, pane] of panes.entries()) {
1073
- pane.dataset.uiResizablePanel = '';
1074
- if (index >= panes.length - 1)
1075
- continue;
1076
- const existingHandle = pane.nextElementSibling instanceof HTMLElement &&
1077
- pane.nextElementSibling.matches(resizableHandleSelector)
1078
- ? pane.nextElementSibling
1079
- : null;
1080
- const handle = existingHandle ?? createResizableHandle(root, index, separatorOrientation);
1081
- if (!existingHandle) {
1082
- pane.after(handle);
1083
- }
1084
- handles.push(handle);
1085
- let startPosition = 0;
1086
- let startSize = 0;
1087
- let containerSize = 1;
1088
- const applySizes = () => {
1089
- applyResizableSizes(root, panes, handles, sizes, minSizes, maxSizes);
1090
- };
1091
- const resizePair = (nextSize) => {
1092
- resizeResizablePair(sizes, minSizes, maxSizes, index, nextSize);
1093
- applySizes();
1094
- };
1095
- handle.addEventListener('pointerdown', event => {
1096
- if (event.button !== 0)
1097
- return;
1098
- event.preventDefault();
1099
- startPosition = event[axis];
1100
- startSize = sizes[index] ?? 0;
1101
- containerSize = Math.max(1, root.getBoundingClientRect()[sizeProperty]);
1102
- root.dataset.resizing = 'true';
1103
- handle.dataset.active = 'true';
1104
- handle.setPointerCapture(event.pointerId);
1105
- });
1106
- handle.addEventListener('pointermove', event => {
1107
- if (handle.dataset.active !== 'true')
1108
- return;
1109
- const delta = ((event[axis] - startPosition) / containerSize) * 100;
1110
- resizePair(startSize + delta);
1111
- });
1112
- handle.addEventListener('pointerup', event => {
1113
- if (handle.dataset.active !== 'true')
1114
- return;
1115
- delete handle.dataset.active;
1116
- delete root.dataset.resizing;
1117
- handle.releasePointerCapture(event.pointerId);
1118
- });
1119
- handle.addEventListener('dblclick', () => {
1120
- if (root.dataset.uiResizableReset !== 'true')
1121
- return;
1122
- sizes = [...initialSizes];
1123
- applySizes();
1124
- });
1125
- handle.addEventListener('keydown', event => {
1126
- const step = event.shiftKey ? 10 : 2;
1127
- const keyDeltas = direction === 'horizontal'
1128
- ? { ArrowLeft: -step, ArrowRight: step }
1129
- : { ArrowDown: step, ArrowUp: -step };
1130
- if (event.key === 'Home') {
1131
- event.preventDefault();
1132
- resizePair(minSizes[index] ?? 0);
1133
- return;
1134
- }
1135
- if (event.key === 'End') {
1136
- event.preventDefault();
1137
- resizePair(maxSizes[index] ?? 100);
1138
- return;
1139
- }
1140
- const delta = keyDeltas[event.key];
1141
- if (delta === undefined)
1142
- return;
1143
- event.preventDefault();
1144
- resizePair((sizes[index] ?? 0) + delta);
1145
- });
1146
- }
1147
- applyResizableSizes(root, panes, handles, sizes, minSizes, maxSizes);
1148
- }
1149
- };
1150
- export const enhanceLumenResizable = (scope = document) => {
1151
- initResizableGroups(scope);
1152
- };
1153
- const installResizableController = () => {
1154
- if (!hasDocument() || document.documentElement.dataset.uiElementsResizableBound === 'true')
1155
- return;
1156
- document.documentElement.dataset.uiElementsResizableBound = 'true';
1157
- enhanceLumenResizable(document);
1158
- if (typeof MutationObserver === 'undefined')
1159
- return;
1160
- const observer = new MutationObserver(mutations => {
1161
- for (const mutation of mutations) {
1162
- for (const node of mutation.addedNodes) {
1163
- if (node instanceof Element || node instanceof DocumentFragment) {
1164
- enhanceLumenResizable(node);
1165
- }
1166
- }
1167
- }
1168
- });
1169
- observer.observe(document.documentElement, { childList: true, subtree: true });
1170
- };
1171
- /* eslint-enable @stylistic/padding-line-between-statements */
1172
- const getLoopedIndex = (key, currentIndex, itemCount, forwardKeys) => {
1173
- const lastIndex = itemCount - 1;
1174
- if (key === 'Home')
1175
- return 0;
1176
- if (key === 'End')
1177
- return lastIndex;
1178
- if (forwardKeys.includes(key))
1179
- return (currentIndex + 1) % itemCount;
1180
- return (currentIndex - 1 + itemCount) % itemCount;
1181
- };
1182
- const syncDateRangePicker = (root) => {
1183
- const inputs = [...root.querySelectorAll(dateRangePickerInputSelector)];
1184
- const start = inputs[0];
1185
- const end = inputs.at(-1);
1186
- if (!start || !end || start === end)
1187
- return;
1188
- const datePickers = root.querySelectorAll(datePickerSelector);
1189
- datePickers[0]?.setAttribute('data-range-part', 'start');
1190
- datePickers[datePickers.length - 1]?.setAttribute('data-range-part', 'end');
1191
- if (start.value) {
1192
- end.min = start.value;
1193
- }
1194
- else {
1195
- end.removeAttribute('min');
1196
- }
1197
- if (end.value) {
1198
- start.max = end.value;
1199
- }
1200
- else {
1201
- start.removeAttribute('max');
1202
- }
1203
- if (start.value && end.value && end.value < start.value) {
1204
- end.value = start.value;
1205
- end.dispatchEvent(new Event('change', { bubbles: true }));
1206
- }
1207
- let rangeState = 'empty';
1208
- if (start.value && end.value) {
1209
- rangeState = 'complete';
1210
- }
1211
- else if (start.value) {
1212
- rangeState = 'selecting-end';
1213
- }
1214
- root.dataset.rangeState = rangeState;
1215
- };
1216
- const initDateRangePickers = (scope) => {
1217
- const closestRoot = getClosestScopedElement(scope, dateRangePickerSelector);
1218
- const roots = getScopedElements(scope, dateRangePickerSelector);
1219
- if (closestRoot instanceof HTMLElement && !roots.includes(closestRoot)) {
1220
- roots.unshift(closestRoot);
1221
- }
1222
- for (const root of roots) {
1223
- for (const input of root.querySelectorAll(dateRangePickerInputSelector)) {
1224
- if (input.dataset.uiDateRangeInputBound === 'true')
1225
- continue;
1226
- input.dataset.uiDateRangeInputBound = 'true';
1227
- input.addEventListener('change', () => {
1228
- syncDateRangePicker(root);
1229
- });
1230
- }
1231
- syncDateRangePicker(root);
1232
- }
1233
- };
1234
- /* eslint-disable unicorn/consistent-function-scoping -- DatePicker callbacks intentionally close over each picker instance. */
1235
- const initDatePickers = (scope) => {
1236
- const closestRoot = getClosestScopedElement(scope, datePickerSelector);
1237
- const roots = getScopedElements(scope, datePickerSelector);
1238
- if (closestRoot instanceof HTMLElement && !roots.includes(closestRoot)) {
1239
- roots.unshift(closestRoot);
1240
- }
1241
- for (const root of roots) {
1242
- if (root.dataset.uiBound === 'true')
1243
- continue;
1244
- const native = root.querySelector(datePickerNativeSelector);
1245
- const control = root.querySelector(datePickerControlSelector);
1246
- const trigger = root.querySelector(datePickerTriggerSelector);
1247
- const valueEl = root.querySelector(datePickerValueSelector);
1248
- const popover = root.querySelector(datePickerPopoverSelector);
1249
- const calendar = root.querySelector(calendarSelector);
1250
- if (!native || !control || !trigger || !popover)
1251
- continue;
1252
- root.dataset.uiBound = 'true';
1253
- native.dataset.uiEnhanced = 'true';
1254
- control.hidden = false;
1255
- const closePopover = () => {
1256
- popover.hidden = true;
1257
- popover.dataset.state = 'closed';
1258
- trigger.setAttribute('aria-expanded', 'false');
1259
- // eslint-disable-next-line no-use-before-define -- the paired callbacks reference each other.
1260
- document.removeEventListener('click', handleOutsideClick);
1261
- };
1262
- const handleOutsideClick = (event) => {
1263
- if (!(event.target instanceof Node))
1264
- return;
1265
- if (!popover.contains(event.target) && !trigger.contains(event.target)) {
1266
- closePopover();
1267
- }
1268
- };
1269
- const openPopover = () => {
1270
- if (calendar) {
1271
- if (native.min)
1272
- calendar.dataset.uiCalendarMin = native.min;
1273
- else
1274
- delete calendar.dataset.uiCalendarMin;
1275
- if (native.max)
1276
- calendar.dataset.uiCalendarMax = native.max;
1277
- else
1278
- delete calendar.dataset.uiCalendarMax;
1279
- }
1280
- popover.hidden = false;
1281
- popover.dataset.state = 'open';
1282
- trigger.setAttribute('aria-expanded', 'true');
1283
- globalThis.setTimeout(() => {
1284
- document.addEventListener('click', handleOutsideClick);
1285
- });
1286
- };
1287
- trigger.addEventListener('click', () => {
1288
- if (popover.hidden) {
1289
- openPopover();
1290
- }
1291
- else {
1292
- closePopover();
1293
- }
1294
- });
1295
- popover.addEventListener('change', event => {
1296
- const target = event.target;
1297
- if (target instanceof HTMLInputElement && target.hasAttribute('data-ui-calendar-input')) {
1298
- const newDate = target.value;
1299
- native.value = newDate;
1300
- if (valueEl)
1301
- valueEl.textContent = newDate || 'mm/dd/yyyy';
1302
- native.dispatchEvent(new Event('change', { bubbles: true, cancelable: true }));
1303
- closePopover();
1304
- }
1305
- });
1306
- }
1307
- };
1308
- /* eslint-enable unicorn/consistent-function-scoping */
1309
- export const enhanceLumenDateRangePickers = (scope = document) => {
1310
- initDateRangePickers(scope);
1311
- };
1312
- const installDateRangePickerController = () => {
1313
- if (!hasDocument() || document.documentElement.dataset.uiElementsDateRangePickersBound === 'true')
1314
- return;
1315
- document.documentElement.dataset.uiElementsDateRangePickersBound = 'true';
1316
- enhanceLumenDateRangePickers(document);
1317
- if (typeof MutationObserver === 'undefined')
1318
- return;
1319
- const observer = new MutationObserver(mutations => {
1320
- for (const mutation of mutations) {
1321
- for (const node of mutation.addedNodes) {
1322
- if (node instanceof Element || node instanceof DocumentFragment) {
1323
- enhanceLumenDateRangePickers(node);
1324
- }
1325
- }
1326
- }
1327
- });
1328
- observer.observe(document.documentElement, { childList: true, subtree: true });
1329
- };
1330
- export const enhanceLumenDatePickers = (scope = document) => {
1331
- initDatePickers(scope);
1332
- };
1333
- const installDatePickerController = () => {
1334
- if (!hasDocument() || document.documentElement.dataset.uiElementsDatePickersBound === 'true')
1335
- return;
1336
- document.documentElement.dataset.uiElementsDatePickersBound = 'true';
1337
- enhanceLumenDatePickers(document);
1338
- if (typeof MutationObserver === 'undefined')
1339
- return;
1340
- const observer = new MutationObserver(mutations => {
1341
- for (const mutation of mutations) {
1342
- for (const node of mutation.addedNodes) {
1343
- if (node instanceof Element || node instanceof DocumentFragment) {
1344
- enhanceLumenDatePickers(node);
1345
- }
1346
- }
1347
- }
1348
- });
1349
- observer.observe(document.documentElement, { childList: true, subtree: true });
1350
- };
1351
- /* eslint-disable @stylistic/padding-line-between-statements, unicorn/consistent-function-scoping -- InputOTP mirrors Astro's compact DOM synchronization runtime. */
1352
- const defaultInputOtpLength = 6;
1353
- const defaultInputOtpPattern = '[0-9]*';
1354
- const normalizeInputOtpLength = (value) => Math.max(1, Number.parseInt(value ?? '', 10) || defaultInputOtpLength);
1355
- const getInputOtpLength = (root) => normalizeInputOtpLength(root.getAttribute('length') ?? root.getAttribute('maxlength') ?? root.dataset.uiInputOtpLength);
1356
- const sanitizeInputOtpValue = (input, value, length) => {
1357
- const numericOnly = input.inputMode === 'numeric' || input.getAttribute('pattern') === defaultInputOtpPattern;
1358
- const normalized = numericOnly ? value.replaceAll(/\D/g, '') : value.replaceAll(/\s/g, '');
1359
- return normalized.slice(0, length);
1360
- };
1361
- const createInputOtpSegment = (index) => {
1362
- const segment = document.createElement('button');
1363
- const char = document.createElement('span');
1364
- segment.ariaHidden = 'true';
1365
- segment.className = 'ui-input-otp__segment';
1366
- segment.dataset.index = String(index);
1367
- segment.dataset.uiInputOtpSegment = '';
1368
- segment.tabIndex = -1;
1369
- segment.type = 'button';
1370
- char.dataset.uiInputOtpChar = '';
1371
- char.textContent = '\u00a0';
1372
- segment.append(char);
1373
- return segment;
1374
- };
1375
- const copyInputOtpAttribute = (root, input, name) => {
1376
- if (!root.hasAttribute(name) || input.hasAttribute(name))
1377
- return;
1378
- input.setAttribute(name, root.getAttribute(name) ?? '');
1379
- };
1380
- const ensureInputOtpNativeInput = (root, length) => {
1381
- let input = root.querySelector(inputOtpNativeSelector);
1382
- const created = !input;
1383
- if (!input) {
1384
- input = document.createElement('input');
1385
- root.prepend(input);
1386
- }
1387
- input.classList.add('ui-input-otp', 'ui-input-otp__native');
1388
- input.dataset.uiInputOtpNative = '';
1389
- if (!input.hasAttribute('autocomplete')) {
1390
- input.setAttribute('autocomplete', root.getAttribute('autocomplete') ?? 'one-time-code');
1391
- }
1392
- if (!input.hasAttribute('inputmode')) {
1393
- input.setAttribute('inputmode', root.getAttribute('inputmode') ?? 'numeric');
1394
- }
1395
- if (!input.hasAttribute('maxlength')) {
1396
- input.setAttribute('maxlength', root.getAttribute('maxlength') ?? root.getAttribute('length') ?? String(length));
1397
- }
1398
- if (!input.hasAttribute('pattern')) {
1399
- input.setAttribute('pattern', root.getAttribute('pattern') ?? defaultInputOtpPattern);
1400
- }
1401
- if (!input.hasAttribute('type')) {
1402
- input.setAttribute('type', 'text');
1403
- }
1404
- for (const name of ['aria-describedby', 'aria-label', 'name', 'placeholder']) {
1405
- copyInputOtpAttribute(root, input, name);
1406
- }
1407
- input.disabled = root.hasAttribute('disabled') || input.disabled;
1408
- input.required = root.hasAttribute('required') || input.required;
1409
- if (root.hasAttribute('aria-invalid') && !input.hasAttribute('aria-invalid')) {
1410
- input.setAttribute('aria-invalid', root.getAttribute('aria-invalid') ?? 'true');
1411
- }
1412
- if (created && root.hasAttribute('value')) {
1413
- input.value = root.getAttribute('value') ?? '';
1414
- }
1415
- return input;
1416
- };
1417
- const ensureInputOtpSegmentsRoot = (root) => {
1418
- let segmentsRoot = root.querySelector(inputOtpSegmentsSelector);
1419
- if (!segmentsRoot) {
1420
- segmentsRoot = document.createElement('div');
1421
- root.append(segmentsRoot);
1422
- }
1423
- segmentsRoot.classList.add('ui-input-otp__segments');
1424
- segmentsRoot.dataset.uiInputOtpSegments = '';
1425
- return segmentsRoot;
1426
- };
1427
- const ensureInputOtpSegments = (segmentsRoot, length) => {
1428
- const segments = [...segmentsRoot.querySelectorAll(inputOtpSegmentSelector)];
1429
- for (let index = segments.length; index < length; index += 1) {
1430
- const segment = createInputOtpSegment(index);
1431
- segmentsRoot.append(segment);
1432
- segments.push(segment);
1433
- }
1434
- for (const segment of segments.splice(length)) {
1435
- segment.remove();
1436
- }
1437
- for (const [index, segment] of segments.entries()) {
1438
- segment.classList.add('ui-input-otp__segment');
1439
- segment.dataset.index = String(index);
1440
- segment.dataset.uiInputOtpSegment = '';
1441
- segment.setAttribute('aria-hidden', 'true');
1442
- segment.tabIndex = -1;
1443
- segment.type = 'button';
1444
- if (!segment.querySelector('[data-ui-input-otp-char]')) {
1445
- const char = document.createElement('span');
1446
- char.dataset.uiInputOtpChar = '';
1447
- segment.append(char);
1448
- }
1449
- }
1450
- return segments;
1451
- };
1452
- const syncInputOtpSegments = (root, input, segments, length) => {
1453
- const value = sanitizeInputOtpValue(input, input.value, length);
1454
- if (input.value !== value) {
1455
- input.value = value;
1456
- }
1457
- const activeIndex = Math.min(length - 1, Math.max(0, input.selectionStart ?? value.length));
1458
- root.dataset.disabled = input.disabled ? 'true' : 'false';
1459
- root.dataset.invalid = input.getAttribute('aria-invalid') === 'true' ? 'true' : 'false';
1460
- for (const [index, segment] of segments.entries()) {
1461
- const char = segment.querySelector('[data-ui-input-otp-char]');
1462
- segment.disabled = input.disabled;
1463
- segment.dataset.active = String(document.activeElement === input && index === activeIndex);
1464
- if (char) {
1465
- char.textContent = value[index] ?? '\u00a0';
1466
- }
1467
- }
1468
- };
1469
- const initInputOtpFields = (scope) => {
1470
- const closestRoot = getClosestScopedElement(scope, inputOtpSelector);
1471
- const roots = getScopedElements(scope, inputOtpSelector);
1472
- if (closestRoot instanceof HTMLElement && !roots.includes(closestRoot)) {
1473
- roots.unshift(closestRoot);
1474
- }
1475
- for (const root of roots) {
1476
- if (root.dataset.uiBound === 'true')
1477
- continue;
1478
- const length = getInputOtpLength(root);
1479
- const input = ensureInputOtpNativeInput(root, length);
1480
- const segmentsRoot = ensureInputOtpSegmentsRoot(root);
1481
- const segments = ensureInputOtpSegments(segmentsRoot, length);
1482
- root.dataset.uiBound = 'true';
1483
- root.dataset.uiInputOtpLength = String(length);
1484
- input.dataset.uiEnhanced = 'true';
1485
- segmentsRoot.hidden = false;
1486
- const syncSegments = () => {
1487
- syncInputOtpSegments(root, input, segments, length);
1488
- };
1489
- const setSelection = (index) => {
1490
- const position = Math.min(input.value.length, Math.max(0, index));
1491
- input.focus({ preventScroll: true });
1492
- input.setSelectionRange(position, position);
1493
- syncSegments();
1494
- };
1495
- const setValue = (value) => {
1496
- input.value = sanitizeInputOtpValue(input, value, length);
1497
- input.setSelectionRange(input.value.length, input.value.length);
1498
- input.dispatchEvent(new Event('input', { bubbles: true }));
1499
- input.dispatchEvent(new Event('change', { bubbles: true }));
1500
- syncSegments();
1501
- };
1502
- syncSegments();
1503
- input.addEventListener('input', syncSegments);
1504
- input.addEventListener('change', syncSegments);
1505
- input.addEventListener('focus', syncSegments);
1506
- input.addEventListener('blur', syncSegments);
1507
- input.addEventListener('click', syncSegments);
1508
- input.addEventListener('keyup', syncSegments);
1509
- input.addEventListener('keydown', event => {
1510
- if (event.key === 'ArrowLeft') {
1511
- event.preventDefault();
1512
- setSelection((input.selectionStart ?? input.value.length) - 1);
1513
- return;
1514
- }
1515
- if (event.key === 'ArrowRight') {
1516
- event.preventDefault();
1517
- setSelection((input.selectionStart ?? input.value.length) + 1);
1518
- return;
1519
- }
1520
- if (event.key === 'Home') {
1521
- event.preventDefault();
1522
- setSelection(0);
1523
- return;
1524
- }
1525
- if (event.key === 'End') {
1526
- event.preventDefault();
1527
- setSelection(input.value.length);
1528
- }
1529
- });
1530
- input.addEventListener('paste', event => {
1531
- const pasted = event.clipboardData?.getData('text') ?? '';
1532
- if (!pasted)
1533
- return;
1534
- event.preventDefault();
1535
- setValue(pasted);
1536
- });
1537
- input.form?.addEventListener('reset', () => {
1538
- globalThis.setTimeout(syncSegments);
1539
- });
1540
- for (const [index, segment] of segments.entries()) {
1541
- segment.addEventListener('click', () => {
1542
- setSelection(index);
1543
- });
1544
- }
1545
- }
1546
- };
1547
- export const enhanceLumenInputOTPs = (scope = document) => {
1548
- initInputOtpFields(scope);
1549
- };
1550
- const installInputOtpController = () => {
1551
- if (!hasDocument() || document.documentElement.dataset.uiElementsInputOtpBound === 'true')
1552
- return;
1553
- document.documentElement.dataset.uiElementsInputOtpBound = 'true';
1554
- enhanceLumenInputOTPs(document);
1555
- if (typeof MutationObserver === 'undefined')
1556
- return;
1557
- const observer = new MutationObserver(mutations => {
1558
- for (const mutation of mutations) {
1559
- for (const node of mutation.addedNodes) {
1560
- if (node instanceof Element || node instanceof DocumentFragment) {
1561
- enhanceLumenInputOTPs(node);
1562
- }
1563
- }
1564
- }
1565
- });
1566
- observer.observe(document.documentElement, { childList: true, subtree: true });
1567
- };
1568
- /* eslint-enable @stylistic/padding-line-between-statements, unicorn/consistent-function-scoping */
1569
- /* cspell:ignore lsaquo rsaquo */
1570
- /* eslint-disable @stylistic/padding-line-between-statements -- Calendar mirrors Astro's UTC date grid runtime. */
1571
- const calendarDatePattern = /^\d{4}-\d{2}-\d{2}$/;
1572
- const calendarMonthPattern = /^\d{4}-\d{2}$/;
1573
- const parseCalendarDate = (value) => {
1574
- if (!value || !calendarDatePattern.test(value))
1575
- return null;
1576
- const [year = Number.NaN, month = Number.NaN, day = Number.NaN] = value.split('-').map(Number);
1577
- const date = new Date(Date.UTC(year, month - 1, day));
1578
- return date.getUTCFullYear() === year &&
1579
- date.getUTCMonth() === month - 1 &&
1580
- date.getUTCDate() === day
1581
- ? date
1582
- : null;
1583
- };
1584
- const parseCalendarMonth = (value) => {
1585
- if (!value || !calendarMonthPattern.test(value))
1586
- return null;
1587
- const [year = Number.NaN, month = Number.NaN] = value.split('-').map(Number);
1588
- const date = new Date(Date.UTC(year, month - 1, 1));
1589
- return date.getUTCFullYear() === year && date.getUTCMonth() === month - 1 ? date : null;
1590
- };
1591
- const formatCalendarDate = (date) => date.toISOString().slice(0, 10);
1592
- const formatCalendarMonth = (date) => date.toISOString().slice(0, 7);
1593
- const addCalendarDays = (date, days) => new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate() + days));
1594
- const getCalendarDaysInMonth = (date) => new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth() + 1, 0)).getUTCDate();
1595
- const addCalendarMonths = (date, months) => {
1596
- const targetMonth = new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth() + months, 1));
1597
- return new Date(Date.UTC(targetMonth.getUTCFullYear(), targetMonth.getUTCMonth(), Math.min(date.getUTCDate(), getCalendarDaysInMonth(targetMonth))));
1598
- };
1599
- const compareCalendarDates = (date, other) => other ? formatCalendarDate(date).localeCompare(formatCalendarDate(other)) : 0;
1600
- const getCalendarToday = () => {
1601
- const today = new Date();
1602
- return new Date(Date.UTC(today.getFullYear(), today.getMonth(), today.getDate()));
1603
- };
1604
- const getCalendarGridStart = (month) => addCalendarDays(month, -((month.getUTCDay() + 6) % 7));
1605
- const getCalendarLocale = () => document.documentElement.lang || navigator.language || 'en';
1606
- const isCalendarDateDisabled = (root, date, min, max) => root.dataset.disabled === 'true' ||
1607
- compareCalendarDates(date, min) < 0 ||
1608
- compareCalendarDates(date, max) > 0;
1609
- const clampCalendarDate = (date, min, max) => {
1610
- if (min && compareCalendarDates(date, min) < 0)
1611
- return min;
1612
- if (max && compareCalendarDates(date, max) > 0)
1613
- return max;
1614
- return date;
1615
- };
1616
- const getCalendarFocusDate = (root, month, min, max, requestedDate) => {
1617
- const selectedDate = parseCalendarDate(root.dataset.uiCalendarValue);
1618
- const today = getCalendarToday();
1619
- const candidates = [requestedDate, selectedDate, today, month];
1620
- for (const candidate of candidates) {
1621
- if (candidate &&
1622
- formatCalendarMonth(candidate) === formatCalendarMonth(month) &&
1623
- !isCalendarDateDisabled(root, candidate, min, max)) {
1624
- return candidate;
1625
- }
1626
- }
1627
- for (let index = 0; index < getCalendarDaysInMonth(month); index += 1) {
1628
- const date = addCalendarDays(month, index);
1629
- if (!isCalendarDateDisabled(root, date, min, max))
1630
- return date;
1631
- }
1632
- return month;
1633
- };
1634
- const ensureCalendarStructure = (root) => {
1635
- root.id ||= createId('ui-calendar');
1636
- const labelId = `${root.id}-label`;
1637
- const selectedDate = parseCalendarDate(root.getAttribute('value') ?? root.dataset.uiCalendarValue);
1638
- const minDate = parseCalendarDate(root.getAttribute('min') ?? root.dataset.uiCalendarMin);
1639
- const maxDate = parseCalendarDate(root.getAttribute('max') ?? root.dataset.uiCalendarMax);
1640
- const monthDate = parseCalendarMonth(root.getAttribute('month') ?? root.dataset.uiCalendarMonth) ??
1641
- (selectedDate ? new Date(Date.UTC(selectedDate.getUTCFullYear(), selectedDate.getUTCMonth(), 1)) : null) ??
1642
- new Date(Date.UTC(getCalendarToday().getUTCFullYear(), getCalendarToday().getUTCMonth(), 1));
1643
- let input = root.querySelector(calendarInputSelector);
1644
- root.dataset.uiCalendarInitialMonth ??= formatCalendarMonth(monthDate);
1645
- root.dataset.uiCalendarMonth ||= formatCalendarMonth(monthDate);
1646
- if (minDate)
1647
- root.dataset.uiCalendarMin = formatCalendarDate(minDate);
1648
- if (maxDate)
1649
- root.dataset.uiCalendarMax = formatCalendarDate(maxDate);
1650
- if (selectedDate)
1651
- root.dataset.uiCalendarValue = formatCalendarDate(selectedDate);
1652
- if (root.hasAttribute('disabled'))
1653
- root.dataset.disabled = 'true';
1654
- if (!input) {
1655
- input = document.createElement('input');
1656
- input.type = 'hidden';
1657
- input.dataset.uiCalendarInput = '';
1658
- root.prepend(input);
1659
- }
1660
- input.disabled = root.dataset.disabled === 'true';
1661
- input.value = root.dataset.uiCalendarValue ?? '';
1662
- if (root.hasAttribute('name') && !input.name) {
1663
- input.name = root.getAttribute('name') ?? '';
1664
- }
1665
- if (!root.querySelector('[data-ui-calendar-prev]')) {
1666
- const header = document.createElement('div');
1667
- const previous = document.createElement('button');
1668
- const label = document.createElement('strong');
1669
- const next = document.createElement('button');
1670
- header.className = 'ui-calendar__header';
1671
- previous.type = 'button';
1672
- previous.className = 'ui-calendar__nav';
1673
- previous.dataset.uiCalendarPrev = '';
1674
- previous.setAttribute('aria-label', 'Previous month');
1675
- previous.innerHTML = '<span aria-hidden="true">&lsaquo;</span>';
1676
- label.className = 'ui-calendar__label';
1677
- label.dataset.uiCalendarLabel = '';
1678
- label.id = labelId;
1679
- next.type = 'button';
1680
- next.className = 'ui-calendar__nav';
1681
- next.dataset.uiCalendarNext = '';
1682
- next.setAttribute('aria-label', 'Next month');
1683
- next.innerHTML = '<span aria-hidden="true">&rsaquo;</span>';
1684
- header.append(previous, label, next);
1685
- input.after(header);
1686
- }
1687
- const label = root.querySelector(calendarLabelSelector);
1688
- if (label) {
1689
- label.id ||= labelId;
1690
- }
1691
- if (!root.querySelector(calendarGridSelector)) {
1692
- const table = document.createElement('table');
1693
- table.className = 'ui-calendar__grid';
1694
- table.dataset.uiCalendarGrid = '';
1695
- table.role = 'grid';
1696
- table.setAttribute('aria-labelledby', label?.id ?? labelId);
1697
- root.append(table);
1698
- }
1699
- };
1700
- const syncCalendarNavigation = (root, month, min, max) => {
1701
- const previous = root.querySelector('[data-ui-calendar-prev]');
1702
- const next = root.querySelector('[data-ui-calendar-next]');
1703
- const disabled = root.dataset.disabled === 'true';
1704
- const previousMonthLastDay = addCalendarDays(month, -1);
1705
- const nextMonthFirstDay = addCalendarMonths(month, 1);
1706
- if (previous)
1707
- previous.disabled = disabled || compareCalendarDates(previousMonthLastDay, min) < 0;
1708
- if (next)
1709
- next.disabled = disabled || compareCalendarDates(nextMonthFirstDay, max) > 0;
1710
- };
1711
- const renderCalendar = (root, requestedFocusDate, shouldFocus = false) => {
1712
- const label = root.querySelector(calendarLabelSelector);
1713
- const grid = root.querySelector(calendarGridSelector);
1714
- if (!label || !grid)
1715
- return;
1716
- const locale = getCalendarLocale();
1717
- const min = parseCalendarDate(root.dataset.uiCalendarMin);
1718
- const max = parseCalendarDate(root.dataset.uiCalendarMax);
1719
- const selectedDate = parseCalendarDate(root.dataset.uiCalendarValue);
1720
- const todayIso = formatCalendarDate(getCalendarToday());
1721
- const month = parseCalendarMonth(root.dataset.uiCalendarMonth) ??
1722
- (selectedDate ? new Date(Date.UTC(selectedDate.getUTCFullYear(), selectedDate.getUTCMonth(), 1)) : null) ??
1723
- getCalendarToday();
1724
- const visibleMonth = new Date(Date.UTC(month.getUTCFullYear(), month.getUTCMonth(), 1));
1725
- const focusDate = getCalendarFocusDate(root, visibleMonth, min, max, requestedFocusDate);
1726
- const focusIso = formatCalendarDate(focusDate);
1727
- const selectedIso = selectedDate ? formatCalendarDate(selectedDate) : '';
1728
- const monthLabel = new Intl.DateTimeFormat(locale, { month: 'long', timeZone: 'UTC', year: 'numeric' }).format(visibleMonth);
1729
- const dayLabel = new Intl.DateTimeFormat(locale, { day: 'numeric', month: 'long', timeZone: 'UTC', weekday: 'long', year: 'numeric' });
1730
- const weekdayLabel = new Intl.DateTimeFormat(locale, { timeZone: 'UTC', weekday: 'short' });
1731
- const header = document.createElement('thead');
1732
- const headerRow = document.createElement('tr');
1733
- const body = document.createElement('tbody');
1734
- const firstCell = getCalendarGridStart(visibleMonth);
1735
- root.dataset.uiCalendarMonth = formatCalendarMonth(visibleMonth);
1736
- label.textContent = monthLabel;
1737
- syncCalendarNavigation(root, visibleMonth, min, max);
1738
- headerRow.role = 'row';
1739
- for (let index = 0; index < 7; index += 1) {
1740
- const cell = document.createElement('th');
1741
- cell.scope = 'col';
1742
- cell.role = 'columnheader';
1743
- cell.textContent = weekdayLabel.format(new Date(Date.UTC(2026, 0, 5 + index)));
1744
- headerRow.append(cell);
1745
- }
1746
- header.append(headerRow);
1747
- for (let rowIndex = 0; rowIndex < 6; rowIndex += 1) {
1748
- const row = document.createElement('tr');
1749
- row.role = 'row';
1750
- for (let columnIndex = 0; columnIndex < 7; columnIndex += 1) {
1751
- const date = addCalendarDays(firstCell, rowIndex * 7 + columnIndex);
1752
- const dateIso = formatCalendarDate(date);
1753
- const cell = document.createElement('td');
1754
- const unavailable = isCalendarDateDisabled(root, date, min, max);
1755
- cell.role = 'gridcell';
1756
- cell.tabIndex = !unavailable && dateIso === focusIso ? 0 : -1;
1757
- cell.textContent = String(date.getUTCDate());
1758
- cell.dataset.date = dateIso;
1759
- cell.dataset.uiCalendarDay = '';
1760
- cell.setAttribute('aria-label', dayLabel.format(date));
1761
- cell.setAttribute('aria-selected', String(selectedIso === dateIso));
1762
- if (unavailable)
1763
- cell.setAttribute('aria-disabled', 'true');
1764
- if (formatCalendarMonth(date) !== formatCalendarMonth(visibleMonth))
1765
- cell.dataset.outside = 'true';
1766
- if (dateIso === todayIso)
1767
- cell.dataset.today = 'true';
1768
- if (selectedIso === dateIso)
1769
- cell.dataset.selected = 'true';
1770
- row.append(cell);
1771
- }
1772
- body.append(row);
1773
- }
1774
- grid.replaceChildren(header, body);
1775
- if (shouldFocus) {
1776
- root.querySelector(`${calendarDaySelector}[data-date="${focusIso}"]`)?.focus({ preventScroll: true });
1777
- }
1778
- };
1779
- const selectCalendarDate = (root, date) => {
1780
- const input = root.querySelector(calendarInputSelector);
1781
- if (!input || root.dataset.disabled === 'true')
1782
- return;
1783
- const min = parseCalendarDate(root.dataset.uiCalendarMin);
1784
- const max = parseCalendarDate(root.dataset.uiCalendarMax);
1785
- const nextDate = clampCalendarDate(date, min, max);
1786
- if (isCalendarDateDisabled(root, nextDate, min, max))
1787
- return;
1788
- input.value = formatCalendarDate(nextDate);
1789
- root.dataset.uiCalendarValue = input.value;
1790
- root.dataset.uiCalendarMonth = formatCalendarMonth(nextDate);
1791
- input.dispatchEvent(new Event('input', { bubbles: true }));
1792
- input.dispatchEvent(new Event('change', { bubbles: true }));
1793
- renderCalendar(root, nextDate, true);
1794
- };
1795
- const focusCalendarDate = (root, date) => {
1796
- const min = parseCalendarDate(root.dataset.uiCalendarMin);
1797
- const max = parseCalendarDate(root.dataset.uiCalendarMax);
1798
- const nextDate = clampCalendarDate(date, min, max);
1799
- root.dataset.uiCalendarMonth = formatCalendarMonth(nextDate);
1800
- renderCalendar(root, nextDate, true);
1801
- };
1802
- const moveCalendarFocus = (root, currentDate, key) => {
1803
- const column = (currentDate.getUTCDay() + 6) % 7;
1804
- const keyOffsets = {
1805
- ArrowDown: 7,
1806
- ArrowLeft: -1,
1807
- ArrowRight: 1,
1808
- ArrowUp: -7,
1809
- End: 6 - column,
1810
- Home: -column
1811
- };
1812
- if (key === 'PageDown' || key === 'PageUp') {
1813
- focusCalendarDate(root, addCalendarMonths(currentDate, key === 'PageDown' ? 1 : -1));
1814
- return;
1815
- }
1816
- const offset = keyOffsets[key];
1817
- if (offset !== undefined) {
1818
- focusCalendarDate(root, addCalendarDays(currentDate, offset));
1819
- }
1820
- };
1821
- const initCalendars = (scope) => {
1822
- const closestRoot = getClosestScopedElement(scope, calendarSelector);
1823
- const roots = getScopedElements(scope, calendarSelector);
1824
- if (closestRoot instanceof HTMLElement && !roots.includes(closestRoot)) {
1825
- roots.unshift(closestRoot);
1826
- }
1827
- for (const root of roots) {
1828
- if (root.dataset.uiBound === 'true')
1829
- continue;
1830
- ensureCalendarStructure(root);
1831
- const input = root.querySelector(calendarInputSelector);
1832
- if (!input)
1833
- continue;
1834
- root.dataset.uiBound = 'true';
1835
- renderCalendar(root);
1836
- root.querySelector('[data-ui-calendar-prev]')?.addEventListener('click', () => {
1837
- const month = parseCalendarMonth(root.dataset.uiCalendarMonth);
1838
- if (!month)
1839
- return;
1840
- const nextMonth = addCalendarMonths(month, -1);
1841
- root.dataset.uiCalendarMonth = formatCalendarMonth(nextMonth);
1842
- renderCalendar(root, nextMonth, true);
1843
- });
1844
- root.querySelector('[data-ui-calendar-next]')?.addEventListener('click', () => {
1845
- const month = parseCalendarMonth(root.dataset.uiCalendarMonth);
1846
- if (!month)
1847
- return;
1848
- const nextMonth = addCalendarMonths(month, 1);
1849
- root.dataset.uiCalendarMonth = formatCalendarMonth(nextMonth);
1850
- renderCalendar(root, nextMonth, true);
1851
- });
1852
- root.addEventListener('click', event => {
1853
- const target = event.target;
1854
- if (!(target instanceof Element))
1855
- return;
1856
- const cell = target.closest(calendarDaySelector);
1857
- if (!cell || !root.contains(cell) || cell.getAttribute('aria-disabled') === 'true')
1858
- return;
1859
- const date = parseCalendarDate(cell.dataset.date);
1860
- if (date)
1861
- selectCalendarDate(root, date);
1862
- });
1863
- root.addEventListener('keydown', event => {
1864
- const target = event.target;
1865
- if (!(target instanceof HTMLElement) || !target.hasAttribute('data-ui-calendar-day'))
1866
- return;
1867
- const date = parseCalendarDate(target.dataset.date);
1868
- if (!date)
1869
- return;
1870
- if (event.key === 'Enter' || event.key === ' ') {
1871
- event.preventDefault();
1872
- selectCalendarDate(root, date);
1873
- return;
1874
- }
1875
- if (event.key !== 'ArrowDown' &&
1876
- event.key !== 'ArrowLeft' &&
1877
- event.key !== 'ArrowRight' &&
1878
- event.key !== 'ArrowUp' &&
1879
- event.key !== 'End' &&
1880
- event.key !== 'Home' &&
1881
- event.key !== 'PageDown' &&
1882
- event.key !== 'PageUp') {
1883
- return;
1884
- }
1885
- event.preventDefault();
1886
- moveCalendarFocus(root, date, event.key);
1887
- });
1888
- input.form?.addEventListener('reset', () => {
1889
- globalThis.setTimeout(() => {
1890
- root.dataset.uiCalendarValue = input.value;
1891
- root.dataset.uiCalendarMonth = root.dataset.uiCalendarInitialMonth ?? root.dataset.uiCalendarMonth;
1892
- renderCalendar(root);
1893
- });
1894
- });
1895
- }
1896
- };
1897
- export const enhanceLumenCalendars = (scope = document) => {
1898
- initCalendars(scope);
1899
- };
1900
- const installCalendarController = () => {
1901
- if (!hasDocument() || document.documentElement.dataset.uiElementsCalendarsBound === 'true')
1902
- return;
1903
- document.documentElement.dataset.uiElementsCalendarsBound = 'true';
1904
- enhanceLumenCalendars(document);
1905
- if (typeof MutationObserver === 'undefined')
1906
- return;
1907
- const observer = new MutationObserver(mutations => {
1908
- for (const mutation of mutations) {
1909
- for (const node of mutation.addedNodes) {
1910
- if (node instanceof Element || node instanceof DocumentFragment) {
1911
- enhanceLumenCalendars(node);
1912
- }
1913
- }
1914
- }
1915
- });
1916
- observer.observe(document.documentElement, { childList: true, subtree: true });
1917
- };
1918
- /* eslint-enable @stylistic/padding-line-between-statements */
1919
- const closeContextMenu = (menu) => {
1920
- if (menu.dataset.state !== 'open')
1921
- return;
1922
- menu.dataset.state = 'closed';
1923
- menu.hidden = true;
1924
- };
1925
- const closeOpenContextMenus = (except) => {
1926
- if (!hasDocument())
1927
- return;
1928
- for (const menu of document.querySelectorAll(`${contextMenuSelector}[data-state="open"]`)) {
1929
- if (menu !== except) {
1930
- closeContextMenu(menu);
1931
- }
1932
- }
1933
- };
1934
- const openContextMenuAt = (menu, x, y) => {
1935
- closeOpenContextMenus(menu);
1936
- menu.hidden = false;
1937
- menu.style.position = 'fixed';
1938
- menu.style.zIndex = '60';
1939
- menu.dataset.state = 'open';
1940
- const rect = menu.getBoundingClientRect();
1941
- const left = Math.max(8, Math.min(x, window.innerWidth - rect.width - 8));
1942
- const top = Math.max(8, Math.min(y, window.innerHeight - rect.height - 8));
1943
- menu.style.left = `${left}px`;
1944
- menu.style.top = `${top}px`;
1945
- getFocusable(menu)[0]?.focus();
1946
- };
1947
- const initContextMenus = (scope) => {
1948
- for (const trigger of getScopedElements(scope, contextMenuTriggerSelector)) {
1949
- if (trigger.dataset.uiContextMenuBound === 'true')
1950
- continue;
1951
- const menuId = trigger.getAttribute('data-ui-context-menu-trigger');
1952
- const menu = menuId && hasDocument() ? document.getElementById(menuId) : null;
1953
- if (!(menu instanceof HTMLElement))
1954
- continue;
1955
- trigger.dataset.uiContextMenuBound = 'true';
1956
- menu.hidden = true;
1957
- menu.dataset.state = 'closed';
1958
- trigger.addEventListener('contextmenu', event => {
1959
- event.preventDefault();
1960
- openContextMenuAt(menu, event.clientX, event.clientY);
1961
- });
1962
- trigger.addEventListener('keydown', event => {
1963
- if (event.key !== 'ContextMenu' && !(event.shiftKey && event.key === 'F10'))
1964
- return;
1965
- event.preventDefault();
1966
- const rect = trigger.getBoundingClientRect();
1967
- openContextMenuAt(menu, rect.left + 16, rect.top + 16);
1968
- });
1969
- if (menu.dataset.uiContextMenuMenuBound === 'true')
1970
- continue;
1971
- menu.dataset.uiContextMenuMenuBound = 'true';
1972
- menu.addEventListener('keydown', event => {
1973
- if (event.key === 'Escape') {
1974
- event.preventDefault();
1975
- closeContextMenu(menu);
1976
- trigger.focus({ preventScroll: true });
1977
- return;
1978
- }
1979
- if (!['ArrowDown', 'ArrowUp', 'End', 'Home'].includes(event.key))
1980
- return;
1981
- const items = getFocusable(menu);
1982
- if (items.length === 0)
1983
- return;
1984
- event.preventDefault();
1985
- const currentIndex = items.indexOf(document.activeElement);
1986
- items[getLoopedIndex(event.key, currentIndex, items.length, ['ArrowDown'])]?.focus();
1987
- });
1988
- menu.addEventListener('click', event => {
1989
- if (event.target instanceof HTMLElement && event.target.closest('[role="menuitem"]')) {
1990
- closeContextMenu(menu);
1991
- }
1992
- });
1993
- }
1994
- };
1995
- export const enhanceLumenContextMenus = (scope = document) => {
1996
- initContextMenus(scope);
1997
- };
1998
- const installContextMenuController = () => {
1999
- if (!hasDocument() || document.documentElement.dataset.uiElementsContextMenusBound === 'true')
2000
- return;
2001
- document.documentElement.dataset.uiElementsContextMenusBound = 'true';
2002
- enhanceLumenContextMenus(document);
2003
- document.addEventListener('pointerdown', event => {
2004
- const target = getOwnedTarget(event);
2005
- if (!target)
2006
- return;
2007
- for (const menu of document.querySelectorAll(`${contextMenuSelector}[data-state="open"]`)) {
2008
- if (!menu.contains(target)) {
2009
- closeContextMenu(menu);
2010
- }
2011
- }
2012
- });
2013
- document.addEventListener('keydown', event => {
2014
- if (event.key === 'Escape') {
2015
- closeOpenContextMenus();
2016
- }
2017
- });
2018
- if (typeof MutationObserver === 'undefined')
2019
- return;
2020
- const observer = new MutationObserver(mutations => {
2021
- for (const mutation of mutations) {
2022
- for (const node of mutation.addedNodes) {
2023
- if (node instanceof Element || node instanceof DocumentFragment) {
2024
- enhanceLumenContextMenus(node);
2025
- }
2026
- }
2027
- }
2028
- });
2029
- observer.observe(document.documentElement, { childList: true, subtree: true });
2030
- };
2031
- const getDataTableSortValue = (cell) => {
2032
- if (!cell)
2033
- return '';
2034
- return cell.dataset.sortValue ?? cell.textContent.trim();
2035
- };
2036
- const compareDataTableValues = (value, other, sortType) => {
2037
- const numericValue = Number(value.replaceAll(',', ''));
2038
- const numericOther = Number(other.replaceAll(',', ''));
2039
- const useNumeric = sortType === 'number' || (sortType !== 'string' &&
2040
- value.trim() !== '' &&
2041
- other.trim() !== '' &&
2042
- Number.isFinite(numericValue) &&
2043
- Number.isFinite(numericOther));
2044
- if (useNumeric) {
2045
- return numericValue - numericOther;
2046
- }
2047
- return value.localeCompare(other, undefined, { numeric: true, sensitivity: 'base' });
2048
- };
2049
- const getDataTableRows = (table) => [...(table.tBodies[0]?.rows ?? [])];
2050
- const getDataTableRowValue = (row, index) => row.dataset.value || row.id || String(index);
2051
- const getNextDataTableSortDirection = (currentColumn, columnIndex, currentDirection) => {
2052
- if (currentColumn !== String(columnIndex) || currentDirection === 'none')
2053
- return 'ascending';
2054
- if (currentDirection === 'ascending')
2055
- return 'descending';
2056
- return 'none';
2057
- };
2058
- const getControlledPanel = (trigger) => {
2059
- const controls = trigger.getAttribute('aria-controls');
2060
- if (controls && hasDocument()) {
2061
- return document.getElementById(controls);
2062
- }
2063
- return trigger.nextElementSibling instanceof HTMLElement ? trigger.nextElementSibling : null;
2064
- };
2065
- const setDisclosureOpen = (trigger, panel, open) => {
2066
- trigger.setAttribute('aria-expanded', String(open));
2067
- panel.hidden = !open;
2068
- panel.dataset.state = open ? 'open' : 'closed';
2069
- };
2070
- const isPrintableKey = (event) => event.key.length === 1 && !event.altKey && !event.ctrlKey && !event.metaKey;
2071
- const escapeCssIdentifier = (value) => {
2072
- if (typeof CSS !== 'undefined' && typeof CSS.escape === 'function') {
2073
- return CSS.escape(value);
2074
- }
2075
- return value.replaceAll(/["#.:?[\\\]]/g, '\\$&');
2076
- };
2077
- const isToastPlacement = (placement) => placement === 'top-left' ||
2078
- placement === 'top-center' ||
2079
- placement === 'top-right' ||
2080
- placement === 'bottom-left' ||
2081
- placement === 'bottom-center' ||
2082
- placement === 'bottom-right';
2083
- const getToastPlacement = (placement) => isToastPlacement(placement) ? placement : 'bottom-right';
2084
- const getToastVariantClass = (variant) => {
2085
- if (variant === 'success')
2086
- return 'ui-toast--success';
2087
- if (variant === 'warning')
2088
- return 'ui-toast--warning';
2089
- if (variant === 'destructive')
2090
- return 'ui-toast--destructive';
2091
- return false;
2092
- };
2093
- const normalizeToastViewport = (viewport, placement) => {
2094
- viewport.classList.add('ui-sonner');
2095
- viewport.dataset.uiSonner = '';
2096
- viewport.dataset.placement = getToastPlacement(placement ?? viewport.dataset.placement);
2097
- viewport.setAttribute('aria-live', viewport.getAttribute('aria-live') ?? 'polite');
2098
- viewport.setAttribute('aria-atomic', viewport.getAttribute('aria-atomic') ?? 'false');
2099
- viewport.setAttribute('aria-label', viewport.getAttribute('aria-label') ?? 'Notifications');
2100
- };
2101
- const getToastViewport = (placement) => {
2102
- if (!hasDocument())
2103
- return null;
2104
- const resolvedPlacement = getToastPlacement(placement);
2105
- const shouldUseAnyViewport = placement === undefined;
2106
- const existing = document.querySelector(`[data-ui-sonner][data-placement="${resolvedPlacement}"]`) ??
2107
- (shouldUseAnyViewport ? document.querySelector('[data-ui-sonner]') : null);
2108
- if (existing) {
2109
- normalizeToastViewport(existing, existing.dataset.placement ?? resolvedPlacement);
2110
- return existing;
2111
- }
2112
- const tagName = typeof customElements !== 'undefined' && customElements.get('lumen-sonner')
2113
- ? 'lumen-sonner'
2114
- : 'div';
2115
- const viewport = document.createElement(tagName);
2116
- normalizeToastViewport(viewport, resolvedPlacement);
2117
- document.body.append(viewport);
2118
- return viewport;
2119
- };
2120
- const clearToastTimer = (toast) => {
2121
- const timer = toastTimers.get(toast);
2122
- if (!timer)
2123
- return;
2124
- if (timer.timer) {
2125
- globalThis.clearTimeout(timer.timer);
2126
- }
2127
- timer.cleanup?.();
2128
- toastTimers.delete(toast);
2129
- };
2130
- const dismissToastElement = (toast) => {
2131
- clearToastTimer(toast);
2132
- toast.dataset.state = 'closed';
2133
- globalThis.setTimeout(() => { toast.remove(); }, toastCloseDelay);
2134
- };
2135
- const scheduleToastDismiss = (toast, duration) => {
2136
- clearToastTimer(toast);
2137
- if (!Number.isFinite(duration) || duration <= 0)
2138
- return;
2139
- const timerState = {
2140
- cleanup: undefined,
2141
- remaining: duration,
2142
- startedAt: Date.now(),
2143
- timer: undefined
2144
- };
2145
- const start = () => {
2146
- timerState.startedAt = Date.now();
2147
- timerState.timer = globalThis.setTimeout(() => { dismissToastElement(toast); }, timerState.remaining);
2148
- };
2149
- const pause = () => {
2150
- if (timerState.timer) {
2151
- globalThis.clearTimeout(timerState.timer);
2152
- }
2153
- timerState.remaining = Math.max(0, timerState.remaining - (Date.now() - timerState.startedAt));
2154
- };
2155
- const resume = () => {
2156
- if (timerState.remaining > 0)
2157
- start();
2158
- };
2159
- timerState.cleanup = () => {
2160
- toast.removeEventListener('mouseenter', pause);
2161
- toast.removeEventListener('mouseleave', resume);
2162
- toast.removeEventListener('focusin', pause);
2163
- toast.removeEventListener('focusout', resume);
2164
- };
2165
- toast.addEventListener('mouseenter', pause);
2166
- toast.addEventListener('mouseleave', resume);
2167
- toast.addEventListener('focusin', pause);
2168
- toast.addEventListener('focusout', resume);
2169
- toastTimers.set(toast, timerState);
2170
- start();
2171
- };
2172
- const setToastContent = (toast, detail) => {
2173
- const title = detail.title ?? toast.dataset.title ?? 'Notification';
2174
- const description = detail.description ?? toast.dataset.description ?? '';
2175
- const variant = detail.variant ?? toast.dataset.variant ?? 'default';
2176
- const variantClass = getToastVariantClass(variant);
2177
- toast.className = variantClass ? `ui-toast ${variantClass}` : 'ui-toast';
2178
- toast.dataset.uiToast = '';
2179
- toast.dataset.variant = variant;
2180
- toast.dataset.title = title;
2181
- toast.dataset.description = description;
2182
- toast.setAttribute('variant', variant);
2183
- toast.setAttribute('role', variant === 'destructive' ? 'alert' : 'status');
2184
- toast.setAttribute('aria-live', variant === 'destructive' ? 'assertive' : 'polite');
2185
- toast.replaceChildren();
2186
- const body = document.createElement('div');
2187
- const heading = document.createElement('strong');
2188
- body.className = 'ui-toast__body';
2189
- heading.textContent = title;
2190
- body.append(heading);
2191
- if (description) {
2192
- const text = document.createElement('p');
2193
- text.textContent = description;
2194
- body.append(text);
2195
- }
2196
- toast.append(body);
2197
- if (detail.action?.label) {
2198
- const action = document.createElement('button');
2199
- action.className = 'ui-button ui-button--secondary ui-button--sm ui-toast__action';
2200
- action.type = 'button';
2201
- action.textContent = detail.action.label;
2202
- action.addEventListener('click', event => {
2203
- detail.action?.onClick?.(event, toast);
2204
- toast.dispatchEvent(new CustomEvent(detail.action?.event ?? 'ui:toast-action', {
2205
- bubbles: true,
2206
- detail: { id: toast.id, value: detail.action?.value }
2207
- }));
2208
- dismissToastElement(toast);
2209
- });
2210
- toast.append(action);
2211
- }
2212
- const dismiss = document.createElement('button');
2213
- dismiss.className = 'ui-toast__dismiss';
2214
- dismiss.type = 'button';
2215
- dismiss.setAttribute('aria-label', 'Dismiss notification');
2216
- dismiss.textContent = 'Dismiss';
2217
- dismiss.addEventListener('click', () => { dismissToastElement(toast); });
2218
- toast.append(dismiss);
2219
- };
2220
- export const LumenToast = {
2221
- create(detail) {
2222
- const viewport = getToastViewport(detail.placement);
2223
- if (!viewport)
2224
- return detail.id ?? createId('ui-toast');
2225
- const id = detail.id ?? createId('ui-toast');
2226
- const duration = detail.duration ?? defaultToastDuration;
2227
- const max = detail.max ?? Number(viewport.dataset.uiToastMax ?? defaultToastMax);
2228
- const existingToast = document.getElementById(id);
2229
- if (existingToast instanceof HTMLElement && existingToast.hasAttribute('data-ui-toast')) {
2230
- existingToast.dataset.state = 'open';
2231
- setToastContent(existingToast, detail);
2232
- viewport.append(existingToast);
2233
- scheduleToastDismiss(existingToast, duration);
2234
- return id;
2235
- }
2236
- const tagName = typeof customElements !== 'undefined' && customElements.get('lumen-toast')
2237
- ? 'lumen-toast'
2238
- : 'aside';
2239
- const toast = document.createElement(tagName);
2240
- toast.id = id;
2241
- toast.dataset.state = 'open';
2242
- toast.addEventListener('keydown', event => {
2243
- if (event.key !== 'Escape')
2244
- return;
2245
- event.preventDefault();
2246
- dismissToastElement(toast);
2247
- });
2248
- setToastContent(toast, detail);
2249
- viewport.append(toast);
2250
- scheduleToastDismiss(toast, duration);
2251
- const toasts = [...viewport.querySelectorAll('[data-ui-toast]')];
2252
- for (const staleToast of toasts.slice(0, Math.max(0, toasts.length - max))) {
2253
- dismissToastElement(staleToast);
2254
- }
2255
- return id;
2256
- },
2257
- dismiss(id) {
2258
- if (!hasDocument())
2259
- return;
2260
- const selector = id ? `#${escapeCssIdentifier(id)}` : '[data-ui-toast]';
2261
- for (const toast of document.querySelectorAll(selector)) {
2262
- if (toast.hasAttribute('data-ui-toast')) {
2263
- dismissToastElement(toast);
2264
- }
2265
- }
2266
- },
2267
- update(id, detail) {
2268
- if (!hasDocument())
2269
- return;
2270
- const toast = document.getElementById(id);
2271
- if (!(toast instanceof HTMLElement) || !toast.hasAttribute('data-ui-toast'))
2272
- return;
2273
- setToastContent(toast, { ...detail, id });
2274
- if (detail.duration !== undefined) {
2275
- scheduleToastDismiss(toast, detail.duration);
2276
- }
2277
- }
2278
- };
2279
- const installToastController = () => {
2280
- if (!hasDocument() || document.documentElement.dataset.uiElementsToastsBound === 'true')
2281
- return;
2282
- document.documentElement.dataset.uiElementsToastsBound = 'true';
2283
- globalThis.LumenToast = LumenToast;
2284
- for (const viewport of document.querySelectorAll('[data-ui-sonner]')) {
2285
- normalizeToastViewport(viewport);
2286
- }
2287
- document.addEventListener('ui:toast', event => {
2288
- LumenToast.create(event instanceof CustomEvent ? event.detail : {});
2289
- });
2290
- document.addEventListener('ui:toast-update', event => {
2291
- const detail = event instanceof CustomEvent ? event.detail : {};
2292
- if (detail.id) {
2293
- LumenToast.update(detail.id, detail);
2294
- }
2295
- });
2296
- document.addEventListener('ui:toast-dismiss', event => {
2297
- const detail = event instanceof CustomEvent ? event.detail : {};
2298
- LumenToast.dismiss(detail.id);
2299
- });
2300
- };
2301
- export class LumenElement extends HTMLElement {
2302
- static config;
2303
- static get observedAttributes() {
2304
- return observedAttributeNames;
2305
- }
2306
- connectedCallback() {
2307
- this.applyDefaults();
2308
- this.applyClassNames();
2309
- }
2310
- disconnectedCallback() {
2311
- /* Subclasses clean up behavior listeners when needed. */
2312
- }
2313
- attributeChangedCallback() {
2314
- this.applyClassNames();
2315
- }
2316
- get config() {
2317
- return this.constructor.config;
2318
- }
2319
- applyDefaults() {
2320
- for (const [name, value] of Object.entries(this.config.defaults ?? {})) {
2321
- if (!this.hasAttribute(name)) {
2322
- this.setAttribute(name, value);
2323
- }
2324
- }
2325
- if (this.config.role && !this.hasAttribute('role')) {
2326
- this.setAttribute('role', this.config.role);
2327
- }
2328
- }
2329
- applyClassNames() {
2330
- const previousClassNames = appliedClassNames.get(this) ?? [];
2331
- for (const className of previousClassNames) {
2332
- this.classList.remove(className);
2333
- }
2334
- const classNames = mergeClassNames(this.config.baseClassName);
2335
- for (const [attributeName, classMap] of Object.entries(this.config.attributeClasses ?? {})) {
2336
- const attributeValue = this.hasAttribute(attributeName)
2337
- ? this.getAttribute(attributeName) || 'true'
2338
- : this.config.defaults?.[attributeName];
2339
- const className = attributeValue ? classMap[attributeValue] : undefined;
2340
- if (className) {
2341
- classNames.push(...mergeClassNames(className));
2342
- }
2343
- }
2344
- this.classList.add(...classNames);
2345
- appliedClassNames.set(this, classNames);
2346
- }
2347
- }
2348
- class LumenIconBehaviorElement extends LumenElement {
2349
- connectedCallback() {
2350
- super.connectedCallback();
2351
- this.renderIcon();
2352
- }
2353
- attributeChangedCallback() {
2354
- super.attributeChangedCallback();
2355
- this.renderIcon();
2356
- }
2357
- renderIcon() {
2358
- const name = this.getAttribute('name');
2359
- const label = this.getAttribute('label') ?? this.getAttribute('aria-label');
2360
- const isDecorative = this.hasAttribute('decorative') || !label;
2361
- if (name) {
2362
- const svg = renderLumenIconSvg(name);
2363
- if (svg !== this.innerHTML) {
2364
- this.innerHTML = svg;
2365
- }
2366
- }
2367
- if (isDecorative) {
2368
- this.setAttribute('aria-hidden', 'true');
2369
- this.removeAttribute('aria-label');
2370
- this.removeAttribute('role');
2371
- }
2372
- else {
2373
- this.removeAttribute('aria-hidden');
2374
- this.setAttribute('aria-label', label);
2375
- this.setAttribute('role', 'img');
2376
- }
2377
- }
2378
- }
2379
- class LumenDialogBehaviorElement extends LumenElement {
2380
- abortController;
2381
- lastTrigger;
2382
- connectedCallback() {
2383
- super.connectedCallback();
2384
- if (!hasDocument())
2385
- return;
2386
- this.abortController?.abort();
2387
- this.abortController = new AbortController();
2388
- this.setupDialog(this.abortController.signal);
2389
- }
2390
- disconnectedCallback() {
2391
- this.abortController?.abort();
2392
- this.abortController = undefined;
2393
- }
2394
- show(trigger) {
2395
- this.openDialog(trigger);
2396
- }
2397
- close() {
2398
- this.closeDialog();
2399
- }
2400
- get isAlertDialog() {
2401
- return this.hasAttribute('data-ui-alert-dialog') || this.tagName.toLowerCase() === 'lumen-alert-dialog';
2402
- }
2403
- get nativeDialog() {
2404
- const dialog = this.querySelector('dialog');
2405
- return dialog instanceof HTMLDialogElement ? dialog : null;
2406
- }
2407
- get dialogRoot() {
2408
- return this.nativeDialog ?? this;
2409
- }
2410
- setupDialog(signal) {
2411
- const dialog = this.dialogRoot;
2412
- const initiallyOpen = this.hasAttribute('open') || this.nativeDialog?.open === true;
2413
- dialog.setAttribute('aria-modal', 'true');
2414
- dialog.setAttribute('role', this.isAlertDialog ? 'alertdialog' : 'dialog');
2415
- if (!this.nativeDialog) {
2416
- this.hidden = !initiallyOpen;
2417
- this.dataset.state = initiallyOpen ? 'open' : 'closed';
2418
- }
2419
- this.nativeDialog?.addEventListener('click', event => {
2420
- if (event.target === this.nativeDialog && !this.isAlertDialog) {
2421
- this.closeDialog();
2422
- }
2423
- }, { signal });
2424
- this.nativeDialog?.addEventListener('close', () => { this.returnFocus(); }, { signal });
2425
- this.addEventListener('click', event => {
2426
- const target = getOwnedTarget(event);
2427
- const closeButton = target instanceof Element
2428
- ? target.closest('[data-ui-dialog-close], [data-ui-alert-dialog-close]')
2429
- : null;
2430
- if (closeButton) {
2431
- this.closeDialog();
2432
- }
2433
- }, { signal });
2434
- this.addEventListener('keydown', event => {
2435
- if (event.key === 'Escape') {
2436
- event.preventDefault();
2437
- this.closeDialog();
2438
- return;
2439
- }
2440
- if (event.key !== 'Tab')
2441
- return;
2442
- this.trapFocus(event);
2443
- }, { signal });
2444
- document.addEventListener('click', event => {
2445
- const target = getOwnedTarget(event);
2446
- const trigger = target instanceof Element
2447
- ? target.closest('[data-ui-dialog-trigger], [data-ui-alert-dialog-trigger]')
2448
- : null;
2449
- const targetId = trigger?.dataset.uiDialogTrigger ?? trigger?.dataset.uiAlertDialogTrigger;
2450
- if (!trigger || targetId !== this.id)
2451
- return;
2452
- this.openDialog(trigger);
2453
- }, { signal });
2454
- document.addEventListener('pointerdown', event => {
2455
- if (!this.isOpen() || this.isAlertDialog)
2456
- return;
2457
- const target = getOwnedTarget(event);
2458
- if (!target || this.contains(target))
2459
- return;
2460
- this.closeDialog();
2461
- }, { signal });
2462
- }
2463
- isOpen() {
2464
- return this.nativeDialog?.open === true || this.hasAttribute('open') || this.dataset.state === 'open';
2465
- }
2466
- openDialog(trigger) {
2467
- if (trigger) {
2468
- if (!trigger.id) {
2469
- trigger.id = createId('ui-trigger');
2470
- }
2471
- this.lastTrigger = trigger;
2472
- }
2473
- const dialog = this.nativeDialog;
2474
- if (dialog) {
2475
- if (typeof dialog.showModal === 'function' && !dialog.open) {
2476
- dialog.showModal();
2477
- }
2478
- else {
2479
- dialog.setAttribute('open', '');
2480
- }
2481
- }
2482
- else {
2483
- this.hidden = false;
2484
- this.setAttribute('open', '');
2485
- this.dataset.state = 'open';
2486
- }
2487
- getFocusable(this.dialogRoot)[0]?.focus({ preventScroll: true });
2488
- }
2489
- closeDialog() {
2490
- const dialog = this.nativeDialog;
2491
- if (dialog?.open) {
2492
- dialog.close();
2493
- return;
2494
- }
2495
- if (!dialog) {
2496
- this.hidden = true;
2497
- this.removeAttribute('open');
2498
- this.dataset.state = 'closed';
2499
- this.returnFocus();
2500
- }
2501
- }
2502
- returnFocus() {
2503
- this.lastTrigger?.focus({ preventScroll: true });
2504
- }
2505
- trapFocus(event) {
2506
- const focusable = getFocusable(this.dialogRoot);
2507
- if (!focusable.length)
2508
- return;
2509
- const first = focusable[0];
2510
- const last = focusable.at(-1);
2511
- if (!first || !last)
2512
- return;
2513
- if (event.shiftKey && document.activeElement === first) {
2514
- event.preventDefault();
2515
- last.focus();
2516
- return;
2517
- }
2518
- if (!event.shiftKey && document.activeElement === last) {
2519
- event.preventDefault();
2520
- first.focus();
2521
- }
2522
- }
2523
- }
2524
- class LumenDisclosureBehaviorElement extends LumenElement {
2525
- abortController;
2526
- connectedCallback() {
2527
- super.connectedCallback();
2528
- if (!hasDocument())
2529
- return;
2530
- this.abortController?.abort();
2531
- this.abortController = new AbortController();
2532
- this.setupDisclosure(this.abortController.signal);
2533
- }
2534
- disconnectedCallback() {
2535
- this.abortController?.abort();
2536
- this.abortController = undefined;
2537
- }
2538
- setupDisclosure(signal) {
2539
- const trigger = this.querySelector('[data-ui-trigger]');
2540
- if (!trigger)
2541
- return;
2542
- const panel = getControlledPanel(trigger);
2543
- if (!panel)
2544
- return;
2545
- trigger.setAttribute('aria-haspopup', trigger.getAttribute('aria-haspopup') ?? 'menu');
2546
- setDisclosureOpen(trigger, panel, trigger.getAttribute('aria-expanded') === 'true');
2547
- const close = () => { setDisclosureOpen(trigger, panel, false); };
2548
- const open = () => { setDisclosureOpen(trigger, panel, true); };
2549
- trigger.addEventListener('click', () => {
2550
- setDisclosureOpen(trigger, panel, trigger.getAttribute('aria-expanded') !== 'true');
2551
- }, { signal });
2552
- trigger.addEventListener('keydown', event => {
2553
- if (event.key !== 'ArrowDown' && event.key !== 'Enter' && event.key !== ' ')
2554
- return;
2555
- event.preventDefault();
2556
- open();
2557
- getFocusable(panel)[0]?.focus();
2558
- }, { signal });
2559
- panel.addEventListener('keydown', event => {
2560
- if (event.key === 'Escape') {
2561
- event.preventDefault();
2562
- close();
2563
- trigger.focus({ preventScroll: true });
2564
- return;
2565
- }
2566
- const keys = ['ArrowDown', 'ArrowUp', 'Home', 'End'];
2567
- if (!keys.includes(event.key))
2568
- return;
2569
- const items = getFocusable(panel);
2570
- if (!items.length)
2571
- return;
2572
- event.preventDefault();
2573
- const currentIndex = items.indexOf(document.activeElement);
2574
- const nextItem = items[getLoopedIndex(event.key, Math.max(0, currentIndex), items.length, ['ArrowDown'])];
2575
- nextItem?.focus();
2576
- }, { signal });
2577
- document.addEventListener('pointerdown', event => {
2578
- if (trigger.getAttribute('aria-expanded') !== 'true')
2579
- return;
2580
- const target = getOwnedTarget(event);
2581
- if (!target || this.contains(target) || panel.contains(target))
2582
- return;
2583
- close();
2584
- }, { signal });
2585
- }
2586
- }
2587
- class LumenTabsBehaviorElement extends LumenElement {
2588
- abortController;
2589
- connectedCallback() {
2590
- super.connectedCallback();
2591
- if (!hasDocument())
2592
- return;
2593
- this.abortController?.abort();
2594
- this.abortController = new AbortController();
2595
- this.setupTabs(this.abortController.signal);
2596
- }
2597
- disconnectedCallback() {
2598
- this.abortController?.abort();
2599
- this.abortController = undefined;
2600
- }
2601
- setupTabs(signal) {
2602
- const tabs = [...this.querySelectorAll('[role="tab"]')];
2603
- const panels = [...this.querySelectorAll('[role="tabpanel"]')];
2604
- if (!tabs.length || !panels.length)
2605
- return;
2606
- const activate = (tab) => {
2607
- for (const item of tabs) {
2608
- const selected = item === tab;
2609
- const panelId = item.getAttribute('aria-controls');
2610
- const panel = panelId ? document.getElementById(panelId) : null;
2611
- item.setAttribute('aria-selected', String(selected));
2612
- item.tabIndex = selected ? 0 : -1;
2613
- if (panel) {
2614
- panel.hidden = !selected;
2615
- }
2616
- }
2617
- };
2618
- activate(tabs.find(tab => tab.getAttribute('aria-selected') === 'true') ?? tabs[0]);
2619
- for (const tab of tabs) {
2620
- tab.addEventListener('click', () => { activate(tab); }, { signal });
2621
- tab.addEventListener('keydown', event => {
2622
- const keys = ['ArrowLeft', 'ArrowRight', 'Home', 'End'];
2623
- if (!keys.includes(event.key))
2624
- return;
2625
- event.preventDefault();
2626
- const currentIndex = tabs.indexOf(tab);
2627
- const nextTab = tabs[getLoopedIndex(event.key, Math.max(0, currentIndex), tabs.length, ['ArrowRight'])];
2628
- if (nextTab) {
2629
- activate(nextTab);
2630
- nextTab.focus();
2631
- }
2632
- }, { signal });
2633
- }
2634
- }
2635
- }
2636
- class LumenSelectBehaviorElement extends LumenElement {
2637
- abortController;
2638
- typeahead = '';
2639
- typeaheadTimer;
2640
- connectedCallback() {
2641
- super.connectedCallback();
2642
- if (!hasDocument())
2643
- return;
2644
- this.dataset.uiSelect = '';
2645
- this.abortController?.abort();
2646
- this.abortController = new AbortController();
2647
- this.setupSelect(this.abortController.signal);
2648
- }
2649
- disconnectedCallback() {
2650
- this.abortController?.abort();
2651
- this.abortController = undefined;
2652
- if (this.typeaheadTimer) {
2653
- globalThis.clearTimeout(this.typeaheadTimer);
2654
- this.typeaheadTimer = undefined;
2655
- }
2656
- }
2657
- setupSelect(signal) {
2658
- const select = this.ensureNativeSelect();
2659
- const control = this.ensureControl(select);
2660
- const trigger = control.querySelector('[data-ui-select-trigger]');
2661
- const listbox = control.querySelector('[data-ui-select-list]');
2662
- if (!trigger || !listbox)
2663
- return;
2664
- this.renderOptions(select, listbox);
2665
- control.hidden = false;
2666
- select.dataset.uiEnhanced = 'true';
2667
- select.dataset.uiSelectNative = '';
2668
- select.tabIndex = -1;
2669
- select.setAttribute('aria-hidden', 'true');
2670
- trigger.disabled = select.disabled;
2671
- trigger.setAttribute('aria-haspopup', 'listbox');
2672
- trigger.setAttribute('role', 'combobox');
2673
- for (const attribute of ['aria-label', 'aria-labelledby', 'aria-describedby', 'aria-invalid']) {
2674
- const value = select.getAttribute(attribute);
2675
- if (value) {
2676
- trigger.setAttribute(attribute, value);
2677
- }
2678
- }
2679
- if (select.required) {
2680
- trigger.setAttribute('aria-required', 'true');
2681
- }
2682
- if (!trigger.hasAttribute('aria-label') && !trigger.hasAttribute('aria-labelledby')) {
2683
- const label = [...select.labels].find(item => item.textContent.trim());
2684
- if (label?.textContent) {
2685
- trigger.setAttribute('aria-label', label.textContent.trim());
2686
- }
2687
- }
2688
- for (const label of select.labels) {
2689
- label.addEventListener('click', event => {
2690
- event.preventDefault();
2691
- trigger.focus({ preventScroll: true });
2692
- }, { signal });
2693
- }
2694
- this.syncValue(select, trigger);
2695
- this.closeSelect(trigger, listbox);
2696
- trigger.addEventListener('click', () => {
2697
- if (trigger.getAttribute('aria-expanded') === 'true') {
2698
- this.closeSelect(trigger, listbox);
2699
- }
2700
- else {
2701
- this.openSelect(trigger, listbox);
2702
- }
2703
- }, { signal });
2704
- trigger.addEventListener('keydown', event => {
2705
- if (this.handleTypeahead(event))
2706
- return;
2707
- if (event.key === 'Escape') {
2708
- this.closeSelect(trigger, listbox);
2709
- return;
2710
- }
2711
- const keys = ['ArrowDown', 'ArrowUp', 'Home', 'End', 'Enter', ' '];
2712
- if (!keys.includes(event.key))
2713
- return;
2714
- event.preventDefault();
2715
- this.openSelect(trigger, listbox);
2716
- if (event.key === 'Enter' || event.key === ' ') {
2717
- (this.getSelectedItem() ?? this.getEnabledItems()[0])?.focus();
2718
- return;
2719
- }
2720
- this.focusOption(event.key);
2721
- }, { signal });
2722
- select.addEventListener('change', () => { this.syncValue(select, trigger); }, { signal });
2723
- select.form?.addEventListener('reset', () => {
2724
- globalThis.setTimeout(() => { this.syncValue(select, trigger); });
2725
- }, { signal });
2726
- for (const item of this.getItems()) {
2727
- item.tabIndex = -1;
2728
- item.addEventListener('click', () => { this.selectOption(select, trigger, listbox, item); }, { signal });
2729
- item.addEventListener('keydown', event => {
2730
- if (this.handleTypeahead(event, item))
2731
- return;
2732
- if (event.key === 'Escape') {
2733
- this.closeSelect(trigger, listbox);
2734
- trigger.focus({ preventScroll: true });
2735
- return;
2736
- }
2737
- if (event.key === 'Enter' || event.key === ' ') {
2738
- event.preventDefault();
2739
- this.selectOption(select, trigger, listbox, item);
2740
- return;
2741
- }
2742
- const keys = ['ArrowDown', 'ArrowUp', 'Home', 'End'];
2743
- if (!keys.includes(event.key))
2744
- return;
2745
- event.preventDefault();
2746
- this.focusOption(event.key, item);
2747
- }, { signal });
2748
- }
2749
- document.addEventListener('pointerdown', event => {
2750
- if (trigger.getAttribute('aria-expanded') !== 'true')
2751
- return;
2752
- const target = getOwnedTarget(event);
2753
- if (!target || this.contains(target))
2754
- return;
2755
- this.closeSelect(trigger, listbox);
2756
- }, { signal });
2757
- }
2758
- ensureNativeSelect() {
2759
- const existing = this.querySelector('[data-ui-select-native], select');
2760
- if (existing)
2761
- return existing;
2762
- const select = document.createElement('select');
2763
- const directOptions = [...this.children].filter((child) => child instanceof HTMLOptionElement);
2764
- select.className = 'ui-select ui-select__native';
2765
- select.dataset.uiSelectNative = '';
2766
- for (const attribute of ['id', 'name', 'required', 'disabled', 'value']) {
2767
- const value = this.getAttribute(attribute);
2768
- if (value !== null) {
2769
- select.setAttribute(attribute, value);
2770
- }
2771
- }
2772
- for (const option of directOptions) {
2773
- select.append(option);
2774
- }
2775
- this.prepend(select);
2776
- return select;
2777
- }
2778
- ensureControl(select) {
2779
- const existing = this.querySelector('[data-ui-select-control]');
2780
- if (existing)
2781
- return existing;
2782
- const control = document.createElement('div');
2783
- const trigger = document.createElement('button');
2784
- const value = document.createElement('span');
2785
- const listbox = document.createElement('div');
2786
- const selectId = select.id || createId('ui-select');
2787
- select.id = selectId;
2788
- control.className = 'ui-select__control';
2789
- control.dataset.uiSelectControl = '';
2790
- control.hidden = true;
2791
- trigger.className = 'ui-select ui-select__trigger';
2792
- trigger.dataset.uiSelectTrigger = '';
2793
- trigger.id = `${selectId}-trigger`;
2794
- trigger.type = 'button';
2795
- trigger.setAttribute('aria-controls', `${selectId}-listbox`);
2796
- trigger.setAttribute('aria-expanded', 'false');
2797
- trigger.setAttribute('aria-haspopup', 'listbox');
2798
- value.dataset.uiSelectValue = '';
2799
- listbox.className = 'ui-select__list';
2800
- listbox.dataset.uiSelectList = '';
2801
- listbox.dataset.state = 'closed';
2802
- listbox.hidden = true;
2803
- listbox.id = `${selectId}-listbox`;
2804
- listbox.setAttribute('role', 'listbox');
2805
- trigger.append(value);
2806
- control.append(trigger, listbox);
2807
- select.after(control);
2808
- return control;
2809
- }
2810
- renderOptions(select, listbox) {
2811
- const items = [...select.options]
2812
- .filter(option => !option.hasAttribute('data-ui-select-placeholder'))
2813
- .map(option => {
2814
- const item = document.createElement('button');
2815
- item.type = 'button';
2816
- item.setAttribute('role', 'option');
2817
- item.dataset.uiSelectOption = '';
2818
- item.dataset.value = option.value;
2819
- item.textContent = option.label;
2820
- if (option.disabled) {
2821
- item.disabled = true;
2822
- item.setAttribute('aria-disabled', 'true');
2823
- }
2824
- return item;
2825
- });
2826
- listbox.replaceChildren(...items);
2827
- }
2828
- syncValue(select, trigger) {
2829
- const value = this.querySelector('[data-ui-select-value]');
2830
- if (!value)
2831
- return;
2832
- const selectedOption = select.selectedOptions[0];
2833
- const placeholder = select.querySelector('[data-ui-select-placeholder]');
2834
- const hasSelection = Boolean(selectedOption && !selectedOption.hasAttribute('data-ui-select-placeholder'));
2835
- const selectedLabel = hasSelection && selectedOption ? selectedOption.label : '';
2836
- value.textContent = hasSelection
2837
- ? selectedLabel
2838
- : placeholder?.textContent.trim() || 'Select an option';
2839
- this.dataset.placeholder = hasSelection ? 'false' : 'true';
2840
- trigger.setAttribute('aria-expanded', trigger.getAttribute('aria-expanded') ?? 'false');
2841
- for (const item of this.getItems()) {
2842
- item.setAttribute('aria-selected', String(hasSelection && item.dataset.value === select.value));
2843
- }
2844
- }
2845
- openSelect(trigger, listbox) {
2846
- trigger.setAttribute('aria-expanded', 'true');
2847
- listbox.hidden = false;
2848
- listbox.dataset.state = 'open';
2849
- }
2850
- closeSelect(trigger, listbox) {
2851
- trigger.setAttribute('aria-expanded', 'false');
2852
- listbox.hidden = true;
2853
- listbox.dataset.state = 'closed';
2854
- }
2855
- getItems() {
2856
- return [...this.querySelectorAll(selectOptionSelector)];
2857
- }
2858
- getEnabledItems() {
2859
- return this.getItems().filter(item => !item.hasAttribute('disabled') && item.getAttribute('aria-disabled') !== 'true');
2860
- }
2861
- getSelectedItem() {
2862
- return this.getEnabledItems().find(item => item.getAttribute('aria-selected') === 'true');
2863
- }
2864
- selectOption(select, trigger, listbox, item) {
2865
- if (item.hasAttribute('disabled') || item.getAttribute('aria-disabled') === 'true')
2866
- return;
2867
- select.value = item.dataset.value ?? '';
2868
- select.dispatchEvent(new Event('input', { bubbles: true }));
2869
- select.dispatchEvent(new Event('change', { bubbles: true }));
2870
- this.syncValue(select, trigger);
2871
- this.closeSelect(trigger, listbox);
2872
- trigger.focus({ preventScroll: true });
2873
- }
2874
- focusOption(key, currentItem) {
2875
- const items = this.getEnabledItems();
2876
- if (!items.length)
2877
- return;
2878
- const current = currentItem ?? this.getSelectedItem() ?? items[0];
2879
- if (!current)
2880
- return;
2881
- const currentIndex = items.indexOf(current);
2882
- const nextItem = items[getLoopedIndex(key, Math.max(0, currentIndex), items.length, ['ArrowDown'])];
2883
- nextItem?.focus();
2884
- }
2885
- handleTypeahead(event, currentItem) {
2886
- if (!isPrintableKey(event))
2887
- return false;
2888
- event.preventDefault();
2889
- this.typeahead += event.key.toLowerCase();
2890
- if (this.typeaheadTimer) {
2891
- globalThis.clearTimeout(this.typeaheadTimer);
2892
- }
2893
- this.typeaheadTimer = globalThis.setTimeout(() => {
2894
- this.typeahead = '';
2895
- }, 700);
2896
- const trigger = this.querySelector('[data-ui-select-trigger]');
2897
- const listbox = this.querySelector('[data-ui-select-list]');
2898
- if (trigger && listbox) {
2899
- this.openSelect(trigger, listbox);
2900
- }
2901
- this.focusTypeaheadOption(currentItem);
2902
- return true;
2903
- }
2904
- focusTypeaheadOption(currentItem) {
2905
- const items = this.getEnabledItems();
2906
- if (!items.length || !this.typeahead)
2907
- return;
2908
- const current = currentItem ?? this.getSelectedItem() ?? items[0];
2909
- if (!current)
2910
- return;
2911
- const currentIndex = items.indexOf(current);
2912
- const startIndex = Math.max(0, currentIndex + 1);
2913
- const orderedItems = [...items.slice(startIndex), ...items.slice(0, startIndex)];
2914
- const nextItem = orderedItems.find(item => item.textContent.trim().toLowerCase().startsWith(this.typeahead));
2915
- nextItem?.focus();
2916
- }
2917
- }
2918
- class LumenDataTableBehaviorElement extends LumenElement {
2919
- abortController;
2920
- connectedCallback() {
2921
- super.connectedCallback();
2922
- if (!hasDocument())
2923
- return;
2924
- if (this.hasAttribute('selectable') && this.dataset.uiDatatableSelectable !== 'true') {
2925
- this.dataset.uiDatatableSelectable = 'true';
2926
- }
2927
- if (this.hasAttribute('name') && !this.dataset.uiDatatableName) {
2928
- this.dataset.uiDatatableName = this.getAttribute('name') ?? '';
2929
- }
2930
- this.abortController?.abort();
2931
- this.abortController = new AbortController();
2932
- this.setupDataTable(this.abortController.signal);
2933
- }
2934
- disconnectedCallback() {
2935
- this.abortController?.abort();
2936
- this.abortController = undefined;
2937
- }
2938
- setupDataTable(signal) {
2939
- const table = this.querySelector('table');
2940
- if (!table)
2941
- return;
2942
- this.setupSelection(table, signal);
2943
- this.setupSorting(table, signal);
2944
- }
2945
- setupSorting(table, signal) {
2946
- const body = table.tBodies[0];
2947
- if (!body)
2948
- return;
2949
- for (const [index, row] of [...body.rows].entries()) {
2950
- row.dataset.uiDatatableIndex = row.dataset.uiDatatableIndex ?? String(index);
2951
- }
2952
- const headers = [...table.querySelectorAll('thead th')].filter(header => header.dataset.uiDatatableSortable === 'true' ||
2953
- header.dataset.sortable === 'true' ||
2954
- header.hasAttribute('data-sortable'));
2955
- for (const header of headers) {
2956
- const row = header.parentElement;
2957
- const columnIndex = row ? [...row.children].indexOf(header) : -1;
2958
- if (columnIndex < 0)
2959
- continue;
2960
- header.dataset.uiDatatableColumn = String(columnIndex);
2961
- header.setAttribute('aria-sort', header.getAttribute('aria-sort') ?? 'none');
2962
- const button = this.ensureSortButton(header);
2963
- button.addEventListener('click', () => {
2964
- const nextDirection = getNextDataTableSortDirection(this.dataset.uiDatatableSortColumn, columnIndex, header.getAttribute('aria-sort'));
2965
- this.updateSort(table, header, nextDirection);
2966
- this.sortRows(table, header, columnIndex, nextDirection);
2967
- }, { signal });
2968
- }
2969
- }
2970
- ensureSortButton(header) {
2971
- const existing = header.querySelector('[data-ui-datatable-sort]');
2972
- if (existing)
2973
- return existing;
2974
- const button = document.createElement('button');
2975
- button.type = 'button';
2976
- button.className = 'ui-data-table__sort';
2977
- button.dataset.uiDatatableSort = '';
2978
- while (header.firstChild) {
2979
- button.append(header.firstChild);
2980
- }
2981
- header.append(button);
2982
- return button;
2983
- }
2984
- updateSort(table, header, direction) {
2985
- for (const item of table.querySelectorAll('thead th[aria-sort]')) {
2986
- item.setAttribute('aria-sort', item === header ? direction : 'none');
2987
- item.dataset.sort = item === header ? direction : 'none';
2988
- }
2989
- this.dataset.uiDatatableSortDirection = direction;
2990
- if (direction === 'none') {
2991
- delete this.dataset.uiDatatableSortColumn;
2992
- }
2993
- else {
2994
- this.dataset.uiDatatableSortColumn = header.dataset.uiDatatableColumn ?? '';
2995
- }
2996
- }
2997
- sortRows(table, header, columnIndex, direction) {
2998
- const body = table.tBodies[0];
2999
- if (!body)
3000
- return;
3001
- const rows = [...body.rows];
3002
- const sortType = header.dataset.uiDatatableSortType;
3003
- rows.sort((row, other) => {
3004
- if (direction === 'none') {
3005
- return Number(row.dataset.uiDatatableIndex ?? '0') - Number(other.dataset.uiDatatableIndex ?? '0');
3006
- }
3007
- const result = compareDataTableValues(getDataTableSortValue(row.cells[columnIndex]), getDataTableSortValue(other.cells[columnIndex]), sortType);
3008
- return (direction === 'ascending' ? result : -result) ||
3009
- Number(row.dataset.uiDatatableIndex ?? '0') - Number(other.dataset.uiDatatableIndex ?? '0');
3010
- });
3011
- for (const row of rows) {
3012
- body.append(row);
3013
- }
3014
- }
3015
- setupSelection(table, signal) {
3016
- const selectable = this.dataset.uiDatatableSelectable === 'true' || this.hasAttribute('selectable');
3017
- if (!selectable)
3018
- return;
3019
- const headRow = table.tHead?.rows[0];
3020
- const body = table.tBodies[0];
3021
- if (!headRow || !body)
3022
- return;
3023
- const selectAll = this.ensureSelectAll(headRow);
3024
- for (const [index, row] of getDataTableRows(table).entries()) {
3025
- const checkbox = this.ensureRowSelect(row, index);
3026
- checkbox.addEventListener('change', () => { this.syncSelection(table, selectAll, true); }, { signal });
3027
- }
3028
- selectAll.addEventListener('change', () => {
3029
- for (const checkbox of table.querySelectorAll('[data-ui-datatable-row-select]')) {
3030
- checkbox.checked = selectAll.checked;
3031
- }
3032
- this.syncSelection(table, selectAll, true);
3033
- }, { signal });
3034
- this.closest('form')?.addEventListener('reset', () => {
3035
- globalThis.setTimeout(() => { this.syncSelection(table, selectAll, true); });
3036
- }, { signal });
3037
- this.syncSelection(table, selectAll);
3038
- }
3039
- ensureSelectAll(headRow) {
3040
- const existing = headRow.querySelector('[data-ui-datatable-select-all]');
3041
- if (existing)
3042
- return existing;
3043
- const headerCell = document.createElement('th');
3044
- const selectAll = document.createElement('input');
3045
- headerCell.className = 'ui-data-table__selection';
3046
- headerCell.scope = 'col';
3047
- selectAll.type = 'checkbox';
3048
- selectAll.className = 'ui-data-table__checkbox';
3049
- selectAll.dataset.uiDatatableSelectAll = '';
3050
- selectAll.setAttribute('aria-label', 'Select all rows');
3051
- headerCell.append(selectAll);
3052
- headRow.prepend(headerCell);
3053
- return selectAll;
3054
- }
3055
- ensureRowSelect(row, index) {
3056
- const existing = row.querySelector('[data-ui-datatable-row-select]');
3057
- row.dataset.uiDatatableRow = '';
3058
- row.dataset.value = getDataTableRowValue(row, index);
3059
- if (existing)
3060
- return existing;
3061
- const cell = document.createElement('td');
3062
- const checkbox = document.createElement('input');
3063
- const selected = row.dataset.state === 'selected' || row.getAttribute('aria-selected') === 'true';
3064
- cell.className = 'ui-data-table__selection';
3065
- checkbox.type = 'checkbox';
3066
- checkbox.className = 'ui-data-table__checkbox';
3067
- checkbox.dataset.uiDatatableRowSelect = '';
3068
- checkbox.checked = selected;
3069
- checkbox.defaultChecked = selected;
3070
- checkbox.setAttribute('aria-label', `Select row ${index + 1}`);
3071
- cell.append(checkbox);
3072
- row.prepend(cell);
3073
- return checkbox;
3074
- }
3075
- syncSelection(table, selectAll, dispatch = false) {
3076
- const rows = getDataTableRows(table);
3077
- const selectedValues = [];
3078
- for (const [index, row] of rows.entries()) {
3079
- const checkbox = row.querySelector('[data-ui-datatable-row-select]');
3080
- const selected = checkbox?.checked === true;
3081
- row.setAttribute('aria-selected', String(selected));
3082
- if (selected) {
3083
- row.dataset.state = 'selected';
3084
- selectedValues.push(getDataTableRowValue(row, index));
3085
- }
3086
- else {
3087
- delete row.dataset.state;
3088
- }
3089
- }
3090
- selectAll.checked = rows.length > 0 && selectedValues.length === rows.length;
3091
- selectAll.indeterminate = selectedValues.length > 0 && selectedValues.length < rows.length;
3092
- this.syncSelectionInputs(selectedValues);
3093
- if (dispatch) {
3094
- const detail = { values: selectedValues };
3095
- this.dispatchEvent(new CustomEvent('ui:data-table-selection-change', { bubbles: true, detail }));
3096
- // Deprecated compatibility event. Remove in Lumen 1.0.
3097
- this.dispatchEvent(new CustomEvent('ui:datatable-selection-change', { bubbles: true, detail }));
3098
- }
3099
- }
3100
- syncSelectionInputs(selectedValues) {
3101
- const name = this.dataset.uiDatatableName;
3102
- let inputs = this.querySelector('[data-ui-datatable-inputs]');
3103
- if (name) {
3104
- if (!inputs) {
3105
- inputs = document.createElement('div');
3106
- inputs.hidden = true;
3107
- inputs.dataset.uiDatatableInputs = '';
3108
- this.append(inputs);
3109
- }
3110
- inputs.replaceChildren(...selectedValues.map(value => {
3111
- const input = document.createElement('input');
3112
- input.type = 'hidden';
3113
- input.name = name;
3114
- input.value = value;
3115
- return input;
3116
- }));
3117
- }
3118
- else {
3119
- inputs?.replaceChildren();
3120
- }
3121
- }
3122
- }
3123
- class LumenVirtualListBehaviorElement extends LumenElement {
3124
- abortController;
3125
- connectedCallback() {
3126
- super.connectedCallback();
3127
- if (!hasDocument())
3128
- return;
3129
- this.abortController?.abort();
3130
- this.abortController = new AbortController();
3131
- this.setupVirtualList(this.abortController.signal);
3132
- }
3133
- disconnectedCallback() {
3134
- this.abortController?.abort();
3135
- this.abortController = undefined;
3136
- }
3137
- setupVirtualList(signal) {
3138
- const items = [...this.children].filter((child) => child instanceof HTMLElement);
3139
- if (!items.length)
3140
- return;
3141
- const update = () => {
3142
- const overscan = this.getNumberAttribute('data-ui-overscan', 'overscan', 4, 0);
3143
- const itemSize = this.getNumberAttribute('data-ui-item-size', 'item-size', 44);
3144
- const range = getVirtualRange(this.scrollTop, this.clientHeight, itemSize, items.length, overscan);
3145
- for (const [index, item] of items.entries()) {
3146
- item.hidden = index < range.startIndex || index > range.endIndex;
3147
- }
3148
- this.dispatchEvent(new CustomEvent('ui:virtual-list-range', {
3149
- bubbles: true,
3150
- detail: range
3151
- }));
3152
- };
3153
- this.addEventListener('scroll', update, { passive: true, signal });
3154
- update();
3155
- }
3156
- getNumberAttribute(dataAttribute, attribute, fallback, minimum = 1) {
3157
- const value = Number(this.getAttribute(dataAttribute) ?? this.getAttribute(attribute) ?? fallback);
3158
- return Number.isFinite(value) && value >= minimum ? value : fallback;
3159
- }
3160
- }
3161
- class LumenThemeBuilderBehaviorElement extends LumenElement {
3162
- abortController;
3163
- currentExportFormat = 'css';
3164
- currentExportValue = '';
3165
- currentScheme = 'light';
3166
- currentTokens = null;
3167
- connectedCallback() {
3168
- super.connectedCallback();
3169
- if (!hasDocument())
3170
- return;
3171
- this.abortController?.abort();
3172
- this.abortController = new AbortController();
3173
- this.setupThemeBuilder(this.abortController.signal);
3174
- }
3175
- disconnectedCallback() {
3176
- this.abortController?.abort();
3177
- this.abortController = undefined;
3178
- }
3179
- setupThemeBuilder(signal) {
3180
- const brandHue = this.querySelector('[data-ui-theme-brand-hue], [data-ui-theme-hue]');
3181
- const brandHueNumber = this.querySelector('[data-ui-theme-brand-hue-number]');
3182
- const accentHue = this.querySelector('[data-ui-theme-accent-hue]');
3183
- const accentHueNumber = this.querySelector('[data-ui-theme-accent-hue-number]');
3184
- const primaryColor = this.querySelector('[data-ui-theme-primary-color]');
3185
- const primaryHex = this.querySelector('[data-ui-theme-primary-hex]');
3186
- const secondaryColor = this.querySelector('[data-ui-theme-secondary-color]');
3187
- const secondaryHex = this.querySelector('[data-ui-theme-secondary-hex]');
3188
- const exportButton = this.querySelector('[data-ui-theme-export]');
3189
- const output = this.querySelector('[data-ui-theme-output]');
3190
- const exportFormatButtons = [...this.querySelectorAll('[data-ui-theme-export-format]')];
3191
- const modeButtons = [...this.querySelectorAll('[data-ui-theme-mode]')];
3192
- const schemeButtons = [...this.querySelectorAll('[data-ui-theme-scheme]')];
3193
- const importButton = this.querySelector('[data-ui-theme-import]');
3194
- const checkContrastButton = this.querySelector('[data-ui-theme-check-contrast]');
3195
- const scoreElement = this.querySelector('[data-ui-theme-contrast-score]');
3196
- const statusElement = this.querySelector('[data-ui-theme-contrast-status]');
3197
- this.currentExportFormat = coerceThemeBuilderExportFormat(this.getButtonValue(exportFormatButtons, 'data-ui-theme-export-format', 'css'));
3198
- this.currentScheme = coerceThemeBuilderScheme(this.getButtonValue(schemeButtons, 'data-ui-theme-scheme', this.getDefaultScheme()));
3199
- const updateContrastUi = (tokens) => {
3200
- if (!scoreElement && !statusElement)
3201
- return;
3202
- const score = scoreThemeContrast(tokens, 'ink', 'canvas');
3203
- if (scoreElement)
3204
- scoreElement.textContent = String(score.ratio);
3205
- if (statusElement) {
3206
- statusElement.textContent = score.wcagAA ? 'Passes WCAG AA' : 'Fails WCAG AA';
3207
- statusElement.dataset.status = score.wcagAA ? 'pass' : 'fail';
3208
- }
3209
- };
3210
- const update = (dispatch = true) => {
3211
- const result = createThemeBuilderTokens({
3212
- accentHue: accentHue?.value ?? accentHueNumber?.value ?? this.getAttribute('data-ui-theme-accent-hue') ?? null,
3213
- hue: brandHue?.value ?? brandHueNumber?.value ?? this.getAttribute('data-ui-theme-brand-hue') ?? this.getAttribute('data-ui-theme-hue') ?? null,
3214
- mode: this.getButtonValue(modeButtons, 'data-ui-theme-mode', 'generated'),
3215
- primaryColor: primaryHex?.value ?? primaryColor?.value ?? null,
3216
- scheme: this.currentScheme,
3217
- secondaryColor: secondaryHex?.value ?? secondaryColor?.value ?? null
3218
- });
3219
- this.currentScheme = result.scheme;
3220
- this.currentTokens = result.tokens;
3221
- const target = this.getTarget();
3222
- if (target) {
3223
- this.applyTokens(target, result.tokens, result.scheme);
3224
- }
3225
- this.writeExport(output);
3226
- updateContrastUi(result.tokens);
3227
- if (dispatch) {
3228
- this.dispatchEvent(new CustomEvent('ui:theme-change', {
3229
- bubbles: true,
3230
- detail: result
3231
- }));
3232
- }
3233
- };
3234
- this.bindHueInputs(brandHue, brandHueNumber, update, signal);
3235
- this.bindHueInputs(accentHue, accentHueNumber, update, signal);
3236
- this.bindHexInputs(primaryColor, primaryHex, update, signal);
3237
- this.bindHexInputs(secondaryColor, secondaryHex, update, signal);
3238
- for (const button of exportFormatButtons) {
3239
- button.addEventListener('click', () => {
3240
- this.currentExportFormat = coerceThemeBuilderExportFormat(button.getAttribute('data-ui-theme-export-format'));
3241
- this.setPressedState(exportFormatButtons, 'data-ui-theme-export-format', this.currentExportFormat);
3242
- this.writeExport(output);
3243
- }, { signal });
3244
- }
3245
- for (const button of modeButtons) {
3246
- button.addEventListener('click', () => {
3247
- this.setPressedState(modeButtons, 'data-ui-theme-mode', coerceThemeBuilderMode(button.getAttribute('data-ui-theme-mode')));
3248
- update();
3249
- }, { signal });
3250
- }
3251
- for (const button of schemeButtons) {
3252
- button.addEventListener('click', () => {
3253
- this.currentScheme = coerceThemeBuilderScheme(button.getAttribute('data-ui-theme-scheme'));
3254
- this.setPressedState(schemeButtons, 'data-ui-theme-scheme', this.currentScheme);
3255
- update();
3256
- }, { signal });
3257
- }
3258
- exportButton?.addEventListener('click', () => {
3259
- if (this.currentTokens) {
3260
- this.writeExport(output);
3261
- }
3262
- else {
3263
- update(false);
3264
- }
3265
- const value = output?.value || this.currentExportValue;
3266
- navigator.clipboard.writeText(value).catch(() => null);
3267
- this.dispatchEvent(new CustomEvent('ui:theme-export', {
3268
- bubbles: true,
3269
- detail: {
3270
- css: this.currentExportFormat === 'css' ? value : undefined,
3271
- format: this.currentExportFormat,
3272
- tokens: this.currentTokens,
3273
- value
3274
- }
3275
- }));
3276
- }, { signal });
3277
- importButton?.addEventListener('click', () => {
3278
- const value = output?.value || '';
3279
- if (!value)
3280
- return;
3281
- const parsed = parseThemeCss(value);
3282
- if (Object.keys(parsed).length === 0)
3283
- return;
3284
- this.currentTokens = parsed;
3285
- const target = this.getTarget();
3286
- if (target) {
3287
- this.applyTokens(target, this.currentTokens, this.currentScheme);
3288
- }
3289
- this.writeExport(output);
3290
- updateContrastUi(this.currentTokens);
3291
- this.dispatchEvent(new CustomEvent('ui:theme-change', {
3292
- bubbles: true,
3293
- detail: {
3294
- accentHue: 0,
3295
- hue: 0,
3296
- mode: 'manual',
3297
- scheme: this.currentScheme,
3298
- tokens: this.currentTokens
3299
- }
3300
- }));
3301
- }, { signal });
3302
- checkContrastButton?.addEventListener('click', () => {
3303
- if (!this.currentTokens)
3304
- return;
3305
- this.currentTokens = tuneThemeContrast(this.currentTokens, 'ink', 'canvas');
3306
- const target = this.getTarget();
3307
- if (target) {
3308
- this.applyTokens(target, this.currentTokens, this.currentScheme);
3309
- }
3310
- this.writeExport(output);
3311
- updateContrastUi(this.currentTokens);
3312
- this.dispatchEvent(new CustomEvent('ui:theme-change', {
3313
- bubbles: true,
3314
- detail: {
3315
- accentHue: 0,
3316
- hue: 0,
3317
- mode: 'manual',
3318
- scheme: this.currentScheme,
3319
- tokens: this.currentTokens
3320
- }
3321
- }));
3322
- }, { signal });
3323
- update(false);
3324
- }
3325
- getDefaultScheme() {
3326
- return document.documentElement.dataset.theme?.includes('dark') ? 'dark' : 'light';
3327
- }
3328
- getTarget() {
3329
- const selector = this.dataset.uiThemeTarget;
3330
- if (!selector)
3331
- return document.documentElement;
3332
- try {
3333
- return document.querySelector(selector);
3334
- }
3335
- catch {
3336
- return null;
3337
- }
3338
- }
3339
- getButtonValue(buttons, attribute, fallback) {
3340
- const activeButton = buttons.find(button => button.getAttribute('aria-selected') === 'true' ||
3341
- button.getAttribute('aria-pressed') === 'true');
3342
- return activeButton?.getAttribute(attribute) ?? this.getAttribute(attribute) ?? fallback;
3343
- }
3344
- setPressedState(buttons, attribute, value) {
3345
- for (const button of buttons) {
3346
- const isPressed = button.getAttribute(attribute) === value;
3347
- if (button.hasAttribute('aria-pressed')) {
3348
- button.setAttribute('aria-pressed', String(isPressed));
3349
- }
3350
- button.classList.toggle('ui-button--secondary', isPressed);
3351
- button.classList.toggle('ui-button--outline', !isPressed);
3352
- }
3353
- }
3354
- bindHueInputs(range, number, onChange, signal) {
3355
- const sync = (source, target) => {
3356
- if (target) {
3357
- target.value = source.value;
3358
- }
3359
- onChange();
3360
- };
3361
- range?.addEventListener('input', () => { sync(range, number); }, { signal });
3362
- number?.addEventListener('input', () => { sync(number, range); }, { signal });
3363
- }
3364
- bindHexInputs(color, text, onChange, signal) {
3365
- color?.addEventListener('input', () => {
3366
- if (text) {
3367
- text.value = color.value;
3368
- text.removeAttribute('aria-invalid');
3369
- }
3370
- onChange();
3371
- }, { signal });
3372
- text?.addEventListener('input', () => {
3373
- const normalized = normalizeThemeBuilderHex(text.value);
3374
- if (normalized) {
3375
- if (color)
3376
- color.value = normalized;
3377
- text.removeAttribute('aria-invalid');
3378
- onChange();
3379
- }
3380
- else {
3381
- text.setAttribute('aria-invalid', 'true');
3382
- }
3383
- }, { signal });
3384
- }
3385
- applyTokens(target, tokens, scheme) {
3386
- target.style.colorScheme = scheme;
3387
- for (const [token, value] of Object.entries(tokens)) {
3388
- target.style.setProperty(`--${token}`, value);
3389
- }
3390
- }
3391
- writeExport(output) {
3392
- if (!this.currentTokens)
3393
- return;
3394
- this.currentExportValue = exportThemeBuilderValue(this.currentTokens, this.currentScheme, this.currentExportFormat);
3395
- if (output) {
3396
- output.value = this.currentExportValue;
3397
- }
3398
- }
3399
- }
3400
- class LumenTooltipBehaviorElement extends LumenElement {
3401
- abortController;
3402
- showTimer;
3403
- connectedCallback() {
3404
- super.connectedCallback();
3405
- if (!hasDocument())
3406
- return;
3407
- this.abortController?.abort();
3408
- this.abortController = new AbortController();
3409
- this.setupTooltip(this.abortController.signal);
3410
- }
3411
- disconnectedCallback() {
3412
- this.abortController?.abort();
3413
- this.abortController = undefined;
3414
- this.clearTimer();
3415
- }
3416
- setupTooltip(signal) {
3417
- const tip = this.querySelector('[role="tooltip"]');
3418
- const trigger = this.querySelector('[data-ui-tooltip-trigger], [data-ui-trigger], button, a[href], input:not([type="hidden"]), select, textarea, [tabindex]:not([tabindex="-1"])');
3419
- if (!tip)
3420
- return;
3421
- if (trigger && !trigger.closest('[role="tooltip"]')) {
3422
- if (!tip.id) {
3423
- tip.id = createId('ui-tooltip');
3424
- }
3425
- const describedBy = new Set((trigger.getAttribute('aria-describedby') ?? '').split(/\s+/).filter(Boolean));
3426
- describedBy.add(tip.id);
3427
- trigger.setAttribute('aria-describedby', [...describedBy].join(' '));
3428
- }
3429
- const show = (delay) => {
3430
- this.clearTimer();
3431
- this.showTimer = globalThis.setTimeout(() => {
3432
- tip.style.removeProperty('visibility');
3433
- }, delay);
3434
- };
3435
- const hide = () => {
3436
- this.clearTimer();
3437
- tip.style.visibility = 'hidden';
3438
- };
3439
- this.addEventListener('mouseenter', () => { show(250); }, { signal });
3440
- this.addEventListener('mouseleave', hide, { signal });
3441
- this.addEventListener('focusin', () => { show(0); }, { signal });
3442
- this.addEventListener('focusout', hide, { signal });
3443
- this.addEventListener('keydown', event => {
3444
- if (event.key === 'Escape') {
3445
- hide();
3446
- }
3447
- }, { signal });
3448
- }
3449
- clearTimer() {
3450
- if (!this.showTimer)
3451
- return;
3452
- globalThis.clearTimeout(this.showTimer);
3453
- this.showTimer = undefined;
3454
- }
3455
- }
3456
- class LumenSonnerBehaviorElement extends LumenElement {
3457
- connectedCallback() {
3458
- super.connectedCallback();
3459
- normalizeToastViewport(this);
3460
- installToastController();
3461
- }
3462
- }
3463
- class LumenToastBehaviorElement extends LumenElement {
3464
- abortController;
3465
- connectedCallback() {
3466
- super.connectedCallback();
3467
- this.dataset.uiToast = '';
3468
- this.setAttribute('role', this.getAttribute('role') ?? (this.getAttribute('variant') === 'destructive' ? 'alert' : 'status'));
3469
- this.setAttribute('aria-live', this.getAttribute('aria-live') ?? (this.getAttribute('variant') === 'destructive' ? 'assertive' : 'polite'));
3470
- this.abortController?.abort();
3471
- this.abortController = new AbortController();
3472
- this.addEventListener('keydown', event => {
3473
- if (event.key !== 'Escape')
3474
- return;
3475
- event.preventDefault();
3476
- dismissToastElement(this);
3477
- }, { signal: this.abortController.signal });
3478
- }
3479
- disconnectedCallback() {
3480
- this.abortController?.abort();
3481
- this.abortController = undefined;
3482
- clearToastTimer(this);
3483
- }
3484
- }
3485
- class LumenFileUploadBehaviorElement extends LumenElement {
3486
- abortController;
3487
- connectedCallback() {
3488
- super.connectedCallback();
3489
- this.abortController?.abort();
3490
- this.abortController = new AbortController();
3491
- const input = this.querySelector('[data-ui-file-upload-input]');
3492
- if (!input)
3493
- return;
3494
- const files = this.querySelector('[data-ui-file-upload-files]');
3495
- const renderFiles = () => {
3496
- const selectedFiles = input.files ? [...input.files] : [];
3497
- this.dataset.state = selectedFiles.length > 0 ? 'selected' : 'idle';
3498
- if (!files)
3499
- return;
3500
- if (selectedFiles.length === 1) {
3501
- files.textContent = selectedFiles[0]?.name ?? '';
3502
- }
3503
- else {
3504
- files.textContent = selectedFiles.length > 1
3505
- ? `${selectedFiles.length} files selected`
3506
- : '';
3507
- }
3508
- };
3509
- input.addEventListener('change', renderFiles, { signal: this.abortController.signal });
3510
- this.addEventListener('dragover', event => {
3511
- if (input.disabled)
3512
- return;
3513
- event.preventDefault();
3514
- this.dataset.state = 'drag-over';
3515
- }, { signal: this.abortController.signal });
3516
- this.addEventListener('dragleave', event => {
3517
- if (event.relatedTarget instanceof Node && this.contains(event.relatedTarget))
3518
- return;
3519
- this.dataset.state = input.files?.length ? 'selected' : 'idle';
3520
- }, { signal: this.abortController.signal });
3521
- this.addEventListener('drop', event => {
3522
- if (input.disabled)
3523
- return;
3524
- event.preventDefault();
3525
- if (event.dataTransfer) {
3526
- input.files = event.dataTransfer.files;
3527
- input.dispatchEvent(new Event('change', { bubbles: true }));
3528
- }
3529
- }, { signal: this.abortController.signal });
3530
- renderFiles();
3531
- }
3532
- disconnectedCallback() {
3533
- this.abortController?.abort();
3534
- this.abortController = undefined;
3535
- }
3536
- }
3537
- class LumenAnchorBehaviorElement extends LumenElement {
3538
- observer;
3539
- connectedCallback() {
3540
- super.connectedCallback();
3541
- this.observer?.disconnect();
3542
- if (typeof IntersectionObserver === 'undefined')
3543
- return;
3544
- const links = [...this.querySelectorAll('a[href^="#"]')];
3545
- const byId = new Map();
3546
- const targets = [];
3547
- for (const link of links) {
3548
- const id = decodeURIComponent(link.getAttribute('href')?.slice(1) ?? '');
3549
- const target = id ? document.getElementById(id) : null;
3550
- if (target) {
3551
- byId.set(id, link);
3552
- targets.push(target);
3553
- }
3554
- }
3555
- if (!targets.length)
3556
- return;
3557
- this.observer = new IntersectionObserver(entries => {
3558
- const visibleEntry = entries.find(entry => entry.isIntersecting);
3559
- if (!visibleEntry)
3560
- return;
3561
- for (const link of links) {
3562
- link.dataset.active = 'false';
3563
- }
3564
- const active = byId.get(visibleEntry.target.id);
3565
- if (active)
3566
- active.dataset.active = 'true';
3567
- }, { rootMargin: '0px 0px -70% 0px', threshold: 0 });
3568
- for (const target of targets) {
3569
- this.observer.observe(target);
3570
- }
3571
- }
3572
- disconnectedCallback() {
3573
- this.observer?.disconnect();
3574
- this.observer = undefined;
3575
- }
3576
- }
3577
- class LumenTourBehaviorElement extends LumenElement {
3578
- abortController;
3579
- opener = null;
3580
- connectedCallback() {
3581
- super.connectedCallback();
3582
- this.abortController?.abort();
3583
- this.abortController = new AbortController();
3584
- const popover = this.querySelector('[data-ui-tour-popover]');
3585
- const steps = [...this.querySelectorAll('[data-ui-tour-step]')];
3586
- if (!popover || !steps.length)
3587
- return;
3588
- let index = 0;
3589
- const positionStep = () => {
3590
- const step = steps[index];
3591
- if (!step)
3592
- return;
3593
- for (const [stepIndex, node] of steps.entries()) {
3594
- node.hidden = stepIndex !== index;
3595
- }
3596
- const target = step.dataset.target
3597
- ? document.querySelector(step.dataset.target)
3598
- : null;
3599
- if (target) {
3600
- const rect = target.getBoundingClientRect();
3601
- popover.style.top = `${rect.bottom + 8}px`;
3602
- popover.style.left = `${rect.left}px`;
3603
- }
3604
- };
3605
- const open = () => {
3606
- this.hidden = false;
3607
- index = 0;
3608
- positionStep();
3609
- };
3610
- const close = () => {
3611
- this.hidden = true;
3612
- };
3613
- this.addEventListener('click', event => {
3614
- const target = event.target;
3615
- if (!(target instanceof HTMLElement))
3616
- return;
3617
- if (target.closest('[data-ui-tour-next]')) {
3618
- if (index < steps.length - 1) {
3619
- index += 1;
3620
- positionStep();
3621
- }
3622
- else {
3623
- close();
3624
- }
3625
- }
3626
- else if (target.closest('[data-ui-tour-prev]')) {
3627
- if (index > 0) {
3628
- index -= 1;
3629
- positionStep();
3630
- }
3631
- }
3632
- else if (target.closest('[data-ui-tour-close]') || target.hasAttribute('data-ui-tour-backdrop')) {
3633
- close();
3634
- }
3635
- }, { signal: this.abortController.signal });
3636
- this.opener = this.id
3637
- ? document.querySelector(`[data-ui-tour-open="#${this.id}"]`)
3638
- : null;
3639
- this.opener?.addEventListener('click', open, { signal: this.abortController.signal });
3640
- const lumenWindow = window;
3641
- lumenWindow.LumenTours ??= {};
3642
- if (this.id)
3643
- lumenWindow.LumenTours[this.id] = open;
3644
- }
3645
- disconnectedCallback() {
3646
- this.abortController?.abort();
3647
- this.abortController = undefined;
3648
- this.opener = null;
3649
- const lumenWindow = window;
3650
- if (this.id && lumenWindow.LumenTours)
3651
- Reflect.deleteProperty(lumenWindow.LumenTours, this.id);
3652
- }
3653
- }
3654
- class LumenTransferBehaviorElement extends LumenElement {
3655
- abortController;
3656
- connectedCallback() {
3657
- super.connectedCallback();
3658
- this.abortController?.abort();
3659
- this.abortController = new AbortController();
3660
- const lists = new Map();
3661
- for (const list of this.querySelectorAll('[data-ui-transfer-list]')) {
3662
- if (list.dataset.side)
3663
- lists.set(list.dataset.side, list);
3664
- }
3665
- const move = (fromSide, toSide) => {
3666
- const from = lists.get(fromSide);
3667
- const to = lists.get(toSide);
3668
- if (!from || !to)
3669
- return;
3670
- const moved = [];
3671
- for (const checkbox of from.querySelectorAll('[data-ui-transfer-item]')) {
3672
- if (!checkbox.checked)
3673
- continue;
3674
- const item = checkbox.closest('.ui-transfer__item');
3675
- if (item) {
3676
- checkbox.checked = false;
3677
- to.append(item);
3678
- moved.push(checkbox.value);
3679
- }
3680
- }
3681
- if (moved.length) {
3682
- this.dispatchEvent(new CustomEvent('ui:transfer-change', {
3683
- bubbles: true,
3684
- detail: { from: fromSide, to: toSide, values: moved }
3685
- }));
3686
- }
3687
- };
3688
- for (const button of this.querySelectorAll('[data-ui-transfer-move]')) {
3689
- button.addEventListener('click', () => {
3690
- if (button.dataset.uiTransferMove === 'target') {
3691
- move('source', 'target');
3692
- }
3693
- else if (button.dataset.uiTransferMove === 'source') {
3694
- move('target', 'source');
3695
- }
3696
- }, { signal: this.abortController.signal });
3697
- }
3698
- }
3699
- disconnectedCallback() {
3700
- this.abortController?.abort();
3701
- this.abortController = undefined;
3702
- }
3703
- }
3704
- class LumenMentionsBehaviorElement extends LumenElement {
3705
- abortController;
3706
- closeTimer;
3707
- connectedCallback() {
3708
- super.connectedCallback();
3709
- this.abortController?.abort();
3710
- this.abortController = new AbortController();
3711
- const input = this.querySelector('[data-ui-mentions-input]');
3712
- const list = this.querySelector('[data-ui-mentions-list]');
3713
- if (!input || !list)
3714
- return;
3715
- const trigger = this.dataset.uiMentionsTrigger ?? '@';
3716
- const escapedTrigger = trigger.replaceAll(/[.*+?^${}()|[\]\\]/g, '\\$&');
3717
- const options = [...list.querySelectorAll('[data-ui-mentions-option]')];
3718
- const close = () => {
3719
- list.hidden = true;
3720
- };
3721
- const filter = () => {
3722
- const caret = input.selectionStart;
3723
- const match = new RegExp(`${escapedTrigger}(\\w*)$`).exec(input.value.slice(0, caret));
3724
- if (!match) {
3725
- close();
3726
- return;
3727
- }
3728
- const query = (match[1] ?? '').toLowerCase();
3729
- let visibleCount = 0;
3730
- for (const option of options) {
3731
- const visible = (option.dataset.value ?? '').toLowerCase().startsWith(query);
3732
- option.hidden = !visible;
3733
- if (visible)
3734
- visibleCount += 1;
3735
- }
3736
- list.hidden = visibleCount === 0;
3737
- };
3738
- const insert = (value) => {
3739
- const caret = input.selectionStart;
3740
- const before = input.value.slice(0, caret)
3741
- .replace(new RegExp(`${escapedTrigger}\\w*$`), `${trigger}${value} `);
3742
- input.value = before + input.value.slice(caret);
3743
- input.focus();
3744
- input.setSelectionRange(before.length, before.length);
3745
- close();
3746
- input.dispatchEvent(new Event('input', { bubbles: true }));
3747
- };
3748
- input.addEventListener('input', filter, { signal: this.abortController.signal });
3749
- input.addEventListener('keyup', filter, { signal: this.abortController.signal });
3750
- input.addEventListener('blur', () => {
3751
- this.closeTimer = globalThis.setTimeout(close, 120);
3752
- }, { signal: this.abortController.signal });
3753
- for (const option of options) {
3754
- option.addEventListener('mousedown', event => {
3755
- event.preventDefault();
3756
- insert(option.dataset.value ?? '');
3757
- }, { signal: this.abortController.signal });
3758
- }
3759
- }
3760
- disconnectedCallback() {
3761
- this.abortController?.abort();
3762
- this.abortController = undefined;
3763
- if (this.closeTimer)
3764
- globalThis.clearTimeout(this.closeTimer);
3765
- this.closeTimer = undefined;
3766
- }
3767
- }
3768
- const setupSelectionDisclosure = (root, signal, rovingPanel = true) => {
3769
- const trigger = root.querySelector('[data-ui-trigger]');
3770
- const panel = root.querySelector('[data-ui-panel]');
3771
- if (!trigger || !panel)
3772
- return undefined;
3773
- const close = () => { setDisclosureOpen(trigger, panel, false); };
3774
- setDisclosureOpen(trigger, panel, trigger.getAttribute('aria-expanded') === 'true');
3775
- trigger.addEventListener('click', () => {
3776
- setDisclosureOpen(trigger, panel, trigger.getAttribute('aria-expanded') !== 'true');
3777
- }, { signal });
3778
- trigger.addEventListener('keydown', event => {
3779
- if (!['ArrowDown', 'Enter', ' '].includes(event.key))
3780
- return;
3781
- event.preventDefault();
3782
- setDisclosureOpen(trigger, panel, true);
3783
- getFocusable(panel)[0]?.focus();
3784
- }, { signal });
3785
- panel.addEventListener('keydown', event => {
3786
- if (event.key === 'Escape') {
3787
- event.preventDefault();
3788
- close();
3789
- trigger.focus({ preventScroll: true });
3790
- return;
3791
- }
3792
- if (!rovingPanel || !['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key))
3793
- return;
3794
- const items = getFocusable(panel);
3795
- if (!items.length)
3796
- return;
3797
- event.preventDefault();
3798
- const currentIndex = Math.max(0, items.indexOf(document.activeElement));
3799
- items[getLoopedIndex(event.key, currentIndex, items.length, ['ArrowDown'])]?.focus();
3800
- }, { signal });
3801
- document.addEventListener('pointerdown', event => {
3802
- const target = getOwnedTarget(event);
3803
- if (!target || root.contains(target))
3804
- return;
3805
- close();
3806
- }, { signal });
3807
- return { close, panel, trigger };
3808
- };
3809
- class LumenCascaderBehaviorElement extends LumenElement {
3810
- abortController;
3811
- connectedCallback() {
3812
- super.connectedCallback();
3813
- this.abortController?.abort();
3814
- this.abortController = new AbortController();
3815
- const disclosure = setupSelectionDisclosure(this, this.abortController.signal, false);
3816
- if (!disclosure)
3817
- return;
3818
- const valueLabel = this.querySelector('[data-ui-cascader-value]');
3819
- const input = this.querySelector('[data-ui-cascader-input]');
3820
- const columns = [...this.querySelectorAll('.ui-cascader__column')];
3821
- for (const option of this.querySelectorAll('[data-ui-cascader-option]')) {
3822
- option.addEventListener('click', () => {
3823
- const column = option.closest('.ui-cascader__column');
3824
- if (column) {
3825
- const columnIndex = columns.indexOf(column);
3826
- for (const descendant of columns.slice(columnIndex + 1)) {
3827
- descendant.hidden = true;
3828
- for (const descendantOption of descendant.querySelectorAll('[data-ui-cascader-option]')) {
3829
- descendantOption.dataset.active = 'false';
3830
- descendantOption.setAttribute('aria-selected', 'false');
3831
- }
3832
- }
3833
- for (const sibling of column.querySelectorAll('[data-ui-cascader-option]')) {
3834
- sibling.dataset.active = 'false';
3835
- sibling.setAttribute('aria-selected', 'false');
3836
- }
3837
- }
3838
- option.dataset.active = 'true';
3839
- option.setAttribute('aria-selected', 'true');
3840
- const next = option.dataset.uiCascaderNext
3841
- ? this.querySelector(option.dataset.uiCascaderNext)
3842
- : null;
3843
- if (next) {
3844
- next.hidden = false;
3845
- return;
3846
- }
3847
- const value = option.dataset.value ?? option.textContent.trim();
3848
- if (valueLabel)
3849
- valueLabel.textContent = option.dataset.label ?? option.textContent.trim();
3850
- if (input)
3851
- input.value = value;
3852
- disclosure.close();
3853
- this.dispatchEvent(new CustomEvent('ui:cascader-change', { bubbles: true, detail: { value } }));
3854
- }, { signal: this.abortController.signal });
3855
- }
3856
- disclosure.panel.addEventListener('keydown', event => {
3857
- const target = event.target;
3858
- if (!(target instanceof HTMLElement))
3859
- return;
3860
- const option = target.closest('[data-ui-cascader-option]');
3861
- const column = option?.closest('.ui-cascader__column');
3862
- if (!option || !column)
3863
- return;
3864
- const columnIndex = columns.indexOf(column);
3865
- const options = [...column.querySelectorAll('[data-ui-cascader-option]')];
3866
- if (['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key)) {
3867
- event.preventDefault();
3868
- options[getLoopedIndex(event.key, options.indexOf(option), options.length, ['ArrowDown'])]?.focus();
3869
- }
3870
- else if (event.key === 'ArrowRight') {
3871
- const next = option.dataset.uiCascaderNext
3872
- ? this.querySelector(option.dataset.uiCascaderNext)
3873
- : null;
3874
- if (next) {
3875
- event.preventDefault();
3876
- option.click();
3877
- next.querySelector('[data-ui-cascader-option]')?.focus();
3878
- }
3879
- }
3880
- else if (event.key === 'ArrowLeft' && columnIndex > 0) {
3881
- event.preventDefault();
3882
- for (const descendant of columns.slice(columnIndex))
3883
- descendant.hidden = true;
3884
- columns.slice(0, columnIndex).reverse().find(candidate => !candidate.hidden)
3885
- ?.querySelector('[data-ui-cascader-option][data-active="true"]')
3886
- ?.focus();
3887
- }
3888
- }, { signal: this.abortController.signal });
3889
- }
3890
- disconnectedCallback() {
3891
- this.abortController?.abort();
3892
- this.abortController = undefined;
3893
- }
3894
- }
3895
- class LumenTreeSelectBehaviorElement extends LumenElement {
3896
- abortController;
3897
- connectedCallback() {
3898
- super.connectedCallback();
3899
- this.abortController?.abort();
3900
- this.abortController = new AbortController();
3901
- const disclosure = setupSelectionDisclosure(this, this.abortController.signal);
3902
- if (!disclosure)
3903
- return;
3904
- const valueLabel = this.querySelector('[data-ui-tree-select-value]');
3905
- const input = this.querySelector('[data-ui-tree-select-input]');
3906
- for (const item of this.querySelectorAll('[data-ui-panel] [data-value]')) {
3907
- item.addEventListener('click', () => {
3908
- const value = item.dataset.value ?? '';
3909
- if (valueLabel)
3910
- valueLabel.textContent = item.textContent.trim();
3911
- if (input)
3912
- input.value = value;
3913
- disclosure.close();
3914
- this.dispatchEvent(new CustomEvent('ui:tree-select-change', { bubbles: true, detail: { value } }));
3915
- }, { signal: this.abortController.signal });
3916
- }
3917
- }
3918
- disconnectedCallback() {
3919
- this.abortController?.abort();
3920
- this.abortController = undefined;
3921
- }
3922
- }
3923
- class LumenBackToTopBehaviorElement extends LumenElement {
3924
- connectedCallback() {
3925
- super.connectedCallback();
3926
- this.addEventListener('click', () => {
3927
- window.scrollTo({ top: 0, behavior: 'smooth' });
3928
- });
3929
- }
3930
- }
3931
- class LumenLanguageToggleBehaviorElement extends LumenElement {
3932
- connectedCallback() {
3933
- super.connectedCallback();
3934
- this.addEventListener('click', () => {
3935
- window.dispatchEvent(new CustomEvent('language-change'));
3936
- });
3937
- }
3938
- }
3939
- class LumenParticlesBehaviorElement extends LumenElement {
3940
- connectedCallback() {
3941
- super.connectedCallback();
3942
- if (!hasDocument())
3943
- return;
3944
- if (window.matchMedia('(prefers-reduced-motion: reduce)').matches)
3945
- return;
3946
- if (this.children.length > 0)
3947
- return;
3948
- const densityConfig = { low: 15, medium: 25, high: 40 };
3949
- const density = (this.getAttribute('data-ui-particles') || 'medium');
3950
- const count = densityConfig[density];
3951
- for (let i = 0; i < count; i++) {
3952
- const el = document.createElement('div');
3953
- const size = Math.random() * 12 + 8;
3954
- const left = Math.random() * 100;
3955
- const top = Math.random() * 100;
3956
- const delay = Math.random() * 8;
3957
- const duration = 20 + Math.random() * 15;
3958
- el.style.cssText = `
3959
- position: absolute;
3960
- left: ${left}%;
3961
- top: ${top}%;
3962
- width: ${size}px;
3963
- height: ${size}px;
3964
- border-radius: 50%;
3965
- background: var(--ui-surface-strong, currentColor);
3966
- opacity: 0.1;
3967
- animation: ui-particle-drift ${duration}s ease-in-out ${delay}s infinite;
3968
- `;
3969
- this.appendChild(el);
3970
- }
3971
- }
3972
- }
3973
- class LumenRatingBehaviorElement extends LumenElement {
3974
- connectedCallback() {
3975
- super.connectedCallback();
3976
- this.addEventListener('click', (e) => {
3977
- if (this.getAttribute('data-readonly') === 'true')
3978
- return;
3979
- const button = e.target.closest('.ui-rating__star');
3980
- if (!button)
3981
- return;
3982
- const stars = [...this.querySelectorAll('.ui-rating__star')];
3983
- const index = stars.indexOf(button);
3984
- if (index === -1)
3985
- return;
3986
- const newValue = index + 1;
3987
- this.setAttribute('data-value', newValue.toString());
3988
- for (const [i, star] of stars.entries()) {
3989
- star.setAttribute('data-active', i < newValue ? 'true' : 'false');
3990
- }
3991
- this.dispatchEvent(new CustomEvent('change', { detail: { value: newValue } }));
3992
- });
3993
- }
3994
- }
3995
- class LumenScrollRevealBehaviorElement extends LumenElement {
3996
- observer;
3997
- connectedCallback() {
3998
- super.connectedCallback();
3999
- if (!hasDocument())
4000
- return;
4001
- this.dataset.uiScrollRevealBound = 'true';
4002
- const delay = Math.max(0, Number(this.getAttribute('delay')) || 0);
4003
- this.style.setProperty('--ui-reveal-delay', `${delay}ms`);
4004
- if (window.matchMedia('(prefers-reduced-motion: reduce)').matches
4005
- || typeof IntersectionObserver === 'undefined') {
4006
- this.classList.add('is-revealed');
4007
- return;
4008
- }
4009
- const once = this.getAttribute('once') !== 'false';
4010
- const threshold = Math.min(1, Math.max(0, Number(this.getAttribute('threshold')) || 0));
4011
- this.observer = new IntersectionObserver((entries) => {
4012
- for (const entry of entries) {
4013
- entry.target.classList.toggle('is-revealed', entry.isIntersecting);
4014
- if (entry.isIntersecting && once) {
4015
- this.observer?.unobserve(entry.target);
4016
- }
4017
- }
4018
- }, { threshold });
4019
- this.observer.observe(this);
4020
- }
4021
- disconnectedCallback() {
4022
- this.observer?.disconnect();
4023
- this.observer = undefined;
4024
- }
4025
- }
4026
- class LumenRevealGroupBehaviorElement extends LumenScrollRevealBehaviorElement {
4027
- connectedCallback() {
4028
- super.connectedCallback();
4029
- const stagger = Math.max(0, Number(this.getAttribute('stagger')) || 80);
4030
- this.style.setProperty('--ui-reveal-stagger', `${stagger}ms`);
4031
- for (const [index, child] of [...this.children].entries()) {
4032
- if (child instanceof HTMLElement) {
4033
- child.style.setProperty('--ui-reveal-index', String(index));
4034
- }
4035
- }
4036
- }
4037
- }
4038
- class LumenAnimatedNumberBehaviorElement extends LumenElement {
4039
- animationFrame;
4040
- observer;
4041
- connectedCallback() {
4042
- super.connectedCallback();
4043
- this.animateValue();
4044
- }
4045
- attributeChangedCallback() {
4046
- super.attributeChangedCallback();
4047
- if (this.isConnected)
4048
- this.animateValue();
4049
- }
4050
- disconnectedCallback() {
4051
- this.observer?.disconnect();
4052
- if (this.animationFrame !== undefined)
4053
- cancelAnimationFrame(this.animationFrame);
4054
- }
4055
- animateValue() {
4056
- if (!hasDocument())
4057
- return;
4058
- this.observer?.disconnect();
4059
- if (this.animationFrame !== undefined)
4060
- cancelAnimationFrame(this.animationFrame);
4061
- const from = Number(this.getAttribute('from'));
4062
- const value = Number(this.getAttribute('value'));
4063
- if (!Number.isFinite(from) || !Number.isFinite(value))
4064
- return;
4065
- const decimals = Math.max(0, Math.min(20, Number(this.getAttribute('decimals')) || 0));
4066
- const prefix = this.getAttribute('prefix') ?? '';
4067
- const suffix = this.getAttribute('suffix') ?? '';
4068
- const formatter = new Intl.NumberFormat(this.getAttribute('locale') || undefined, {
4069
- maximumFractionDigits: decimals,
4070
- minimumFractionDigits: decimals
4071
- });
4072
- const format = (current) => `${prefix}${formatter.format(current)}${suffix}`;
4073
- const finalValue = format(value);
4074
- this.setAttribute('aria-label', finalValue);
4075
- if (window.matchMedia('(prefers-reduced-motion: reduce)').matches
4076
- || typeof IntersectionObserver === 'undefined') {
4077
- this.textContent = finalValue;
4078
- return;
4079
- }
4080
- this.textContent = format(from);
4081
- this.observer = new IntersectionObserver(entries => {
4082
- if (!entries.some(entry => entry.isIntersecting))
4083
- return;
4084
- this.observer?.disconnect();
4085
- const durationValue = getComputedStyle(this).getPropertyValue('--ui-motion-duration').trim();
4086
- const duration = parseMotionDuration(durationValue);
4087
- const startedAt = performance.now();
4088
- const update = (now) => {
4089
- const progress = Math.min(1, (now - startedAt) / Math.max(1, duration));
4090
- const eased = 1 - Math.pow(1 - progress, 3);
4091
- this.textContent = format(from + ((value - from) * eased));
4092
- if (progress < 1) {
4093
- this.animationFrame = requestAnimationFrame(update);
4094
- }
4095
- else {
4096
- this.textContent = finalValue;
4097
- }
4098
- };
4099
- this.animationFrame = requestAnimationFrame(update);
4100
- }, { threshold: 0.15 });
4101
- this.observer.observe(this);
4102
- }
4103
- }
4104
- class LumenThemeToggleBehaviorElement extends LumenElement {
4105
- #isAnimating = false;
4106
- connectedCallback() {
4107
- super.connectedCallback();
4108
- this.setAttribute('role', 'switch');
4109
- this.setAttribute('aria-checked', String(this.#rootInDarkMode()));
4110
- this.addEventListener('click', () => {
4111
- if (this.#isAnimating)
4112
- return;
4113
- const isDark = this.#rootInDarkMode();
4114
- const newTheme = isDark ? 'light' : 'dark';
4115
- const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
4116
- if (prefersReducedMotion) {
4117
- this.#dispatchChange(newTheme);
4118
- return;
4119
- }
4120
- this.#circularReveal(isDark, newTheme);
4121
- });
4122
- }
4123
- #rootInDarkMode() {
4124
- const doc = document.documentElement;
4125
- return doc.getAttribute('data-theme') === 'dark' || doc.classList.contains('dark');
4126
- }
4127
- #dispatchChange(newTheme) {
4128
- const doc = document.documentElement;
4129
- doc.setAttribute('data-theme', newTheme);
4130
- if (newTheme === 'dark') {
4131
- doc.classList.add('dark');
4132
- }
4133
- else {
4134
- doc.classList.remove('dark');
4135
- }
4136
- localStorage.setItem('theme', newTheme);
4137
- window.dispatchEvent(new CustomEvent('theme-change', { detail: newTheme }));
4138
- this.setAttribute('aria-checked', String(this.#rootInDarkMode()));
4139
- }
4140
- #circularReveal(isDark, newTheme) {
4141
- const isTouchDevice = window.matchMedia('(hover: none) and (pointer: coarse)').matches;
4142
- if (isTouchDevice) {
4143
- this.#dispatchChange(newTheme);
4144
- return;
4145
- }
4146
- this.#isAnimating = true;
4147
- const rect = this.getBoundingClientRect();
4148
- const x = Math.round(rect.left + rect.width / 2);
4149
- const y = Math.round(rect.top + rect.height / 2);
4150
- const maxRadius = Math.hypot(Math.max(x, window.innerWidth - x), Math.max(y, window.innerHeight - y));
4151
- const oldBg = isDark ? 'hsl(277 20% 10%)' : 'hsl(268 20% 98%)';
4152
- const overlay = document.createElement('div');
4153
- overlay.setAttribute('aria-hidden', 'true');
4154
- Object.assign(overlay.style, {
4155
- position: 'fixed',
4156
- inset: '0',
4157
- zIndex: '99999',
4158
- pointerEvents: 'none',
4159
- backgroundColor: oldBg,
4160
- clipPath: `circle(${maxRadius}px at ${x}px ${y}px)`,
4161
- willChange: 'clip-path',
4162
- });
4163
- document.body.appendChild(overlay);
4164
- this.#dispatchChange(newTheme);
4165
- requestAnimationFrame(() => {
4166
- requestAnimationFrame(() => {
4167
- overlay.style.transition = 'clip-path 580ms cubic-bezier(0.4, 0, 0.2, 1)';
4168
- overlay.style.clipPath = `circle(0px at ${x}px ${y}px)`;
4169
- const done = () => {
4170
- overlay.remove();
4171
- this.#isAnimating = false;
4172
- };
4173
- overlay.addEventListener('transitionend', done, { once: true });
4174
- setTimeout(done, 750);
4175
- });
4176
- });
4177
- }
4178
- }
4179
- const createLumenElementClass = (config) => class extends LumenElement {
4180
- static config = config;
4181
- };
4182
- const createLumenBehaviorElementClass = (BaseElement, config) => class extends BaseElement {
4183
- static config = config;
4184
- };
4185
- const behaviorElementClasses = {
4186
- AlertDialog: LumenDialogBehaviorElement,
4187
- Anchor: LumenAnchorBehaviorElement,
4188
- AnimatedNumber: LumenAnimatedNumberBehaviorElement,
4189
- BackToTop: LumenBackToTopBehaviorElement,
4190
- Cascader: LumenCascaderBehaviorElement,
4191
- CodeTabs: LumenTabsBehaviorElement,
4192
- DataTable: LumenDataTableBehaviorElement,
4193
- Dialog: LumenDialogBehaviorElement,
4194
- DropdownMenu: LumenDisclosureBehaviorElement,
4195
- FileUpload: LumenFileUploadBehaviorElement,
4196
- Icon: LumenIconBehaviorElement,
4197
- LanguageToggle: LumenLanguageToggleBehaviorElement,
4198
- Mentions: LumenMentionsBehaviorElement,
4199
- Particles: LumenParticlesBehaviorElement,
4200
- Popover: LumenDisclosureBehaviorElement,
4201
- Rating: LumenRatingBehaviorElement,
4202
- RevealGroup: LumenRevealGroupBehaviorElement,
4203
- ScrollReveal: LumenScrollRevealBehaviorElement,
4204
- Select: LumenSelectBehaviorElement,
4205
- Sonner: LumenSonnerBehaviorElement,
4206
- Tabs: LumenTabsBehaviorElement,
4207
- ThemeBuilder: LumenThemeBuilderBehaviorElement,
4208
- ThemeToggle: LumenThemeToggleBehaviorElement,
4209
- Toast: LumenToastBehaviorElement,
4210
- Tour: LumenTourBehaviorElement,
4211
- Transfer: LumenTransferBehaviorElement,
4212
- TreeSelect: LumenTreeSelectBehaviorElement,
4213
- Tooltip: LumenTooltipBehaviorElement,
4214
- VirtualList: LumenVirtualListBehaviorElement
4215
- };
4216
- const elementClasses = Object.fromEntries(lumenComponentNames.map(componentName => {
4217
- const behaviorClass = behaviorElementClasses[componentName];
4218
- if (behaviorClass) {
4219
- return [componentName, createLumenBehaviorElementClass(behaviorClass, elementConfigs[componentName])];
4220
- }
4221
- return [componentName, createLumenElementClass(elementConfigs[componentName])];
4222
- }));
4223
- const elementDefinitions = lumenComponentNames.map(componentName => {
4224
- const config = elementConfigs[componentName];
4225
- return [config.tagName, elementClasses[componentName]];
4226
- });
4227
- export const enhanceLumenElements = (scope = document) => {
4228
- enhanceLumenDateRangePickers(scope);
4229
- enhanceLumenDatePickers(scope);
4230
- enhanceLumenInputOTPs(scope);
4231
- initLumenFields(scope);
4232
- initLumenForms(scope);
4233
- };
4234
- export const defineLumenElements = (customElementsRegistry = typeof customElements === 'undefined'
4235
- ? undefined
4236
- : customElements) => {
4237
- if (!customElementsRegistry)
4238
- return;
4239
- for (const [name, element] of elementDefinitions) {
4240
- if (!registry.has(name) && !customElementsRegistry.get(name)) {
4241
- customElementsRegistry.define(name, element);
4242
- registry.add(name);
4243
- }
4244
- }
4245
- installToastController();
4246
- installFormController();
4247
- installRichTextEditorController();
4248
- installScheduleController();
4249
- installResizableController();
4250
- installContextMenuController();
4251
- installDateRangePickerController();
4252
- installDatePickerController();
4253
- installInputOtpController();
4254
- installCalendarController();
4255
- };
4256
- export const installLumenControllers = () => {
4257
- installDateRangePickerController();
4258
- installDatePickerController();
4259
- installInputOtpController();
4260
- };
4261
- export const lumenElementDefinitions = elementDefinitions;
4262
- export const LumenAccordionElement = elementClasses.Accordion;
4263
- export const LumenAlertElement = elementClasses.Alert;
4264
- export const LumenAlertDialogElement = elementClasses.AlertDialog;
4265
- export const LumenAgendaElement = elementClasses.Agenda;
4266
- export const LumenAspectRatioElement = elementClasses.AspectRatio;
4267
- export const LumenAttachmentElement = elementClasses.Attachment;
4268
- export const LumenAutocompleteElement = elementClasses.Autocomplete;
4269
- export const LumenAvatarElement = elementClasses.Avatar;
4270
- export const LumenBadgeElement = elementClasses.Badge;
4271
- export const LumenBreadcrumbElement = elementClasses.Breadcrumb;
4272
- export const LumenBubbleElement = elementClasses.Bubble;
4273
- export const LumenButtonElement = elementClasses.Button;
4274
- export const LumenButtonGroupElement = elementClasses.ButtonGroup;
4275
- export const LumenCalendarElement = elementClasses.Calendar;
4276
- export const LumenCardElement = elementClasses.Card;
4277
- export const LumenCarouselElement = elementClasses.Carousel;
4278
- export const LumenChartElement = elementClasses.Chart;
4279
- export const LumenCheckboxElement = elementClasses.Checkbox;
4280
- export const LumenCollapsibleElement = elementClasses.Collapsible;
4281
- export const LumenCodeElement = elementClasses.Code;
4282
- export const LumenCodeTabsElement = elementClasses.CodeTabs;
4283
- export const LumenComboboxElement = elementClasses.Combobox;
4284
- export const LumenCommandElement = elementClasses.Command;
4285
- export const LumenColorPickerElement = elementClasses.ColorPicker;
4286
- export const LumenContextMenuElement = elementClasses.ContextMenu;
4287
- export const LumenDataTableElement = elementClasses.DataTable;
4288
- export const LumenDatePickerElement = elementClasses.DatePicker;
4289
- export const LumenDateRangePickerElement = elementClasses.DateRangePicker;
4290
- export const LumenDialogElement = elementClasses.Dialog;
4291
- export const LumenDirectionElement = elementClasses.Direction;
4292
- export const LumenDrawerElement = elementClasses.Drawer;
4293
- export const LumenDropdownMenuElement = elementClasses.DropdownMenu;
4294
- export const LumenEmptyElement = elementClasses.Empty;
4295
- export const LumenFieldElement = elementClasses.Field;
4296
- export const LumenHoverCardElement = elementClasses.HoverCard;
4297
- export const LumenIconElement = elementClasses.Icon;
4298
- export const LumenInputElement = elementClasses.Input;
4299
- export const LumenInputGroupElement = elementClasses.InputGroup;
4300
- export const LumenInputOTPElement = elementClasses.InputOTP;
4301
- export const LumenNumberFieldElement = elementClasses.NumberField;
4302
- export const LumenItemElement = elementClasses.Item;
4303
- export const LumenKbdElement = elementClasses.Kbd;
4304
- export const LumenLabelElement = elementClasses.Label;
4305
- export const LumenMarkerElement = elementClasses.Marker;
4306
- export const LumenMenubarElement = elementClasses.Menubar;
4307
- export const LumenMessageElement = elementClasses.Message;
4308
- export const LumenMessageScrollerElement = elementClasses.MessageScroller;
4309
- export const LumenNativeSelectElement = elementClasses.NativeSelect;
4310
- export const LumenNavigationMenuElement = elementClasses.NavigationMenu;
4311
- export const LumenPaginationElement = elementClasses.Pagination;
4312
- export const LumenPhoneInputElement = elementClasses.PhoneInput;
4313
- export const LumenPopoverElement = elementClasses.Popover;
4314
- export const LumenProgressElement = elementClasses.Progress;
4315
- export const LumenRadioGroupElement = elementClasses.RadioGroup;
4316
- export const LumenResizableElement = elementClasses.Resizable;
4317
- export const LumenRichTextEditorElement = elementClasses.RichTextEditor;
4318
- export const LumenScrollAreaElement = elementClasses.ScrollArea;
4319
- export const LumenScheduleElement = elementClasses.Schedule;
4320
- export const LumenSearchFieldElement = elementClasses.SearchField;
4321
- export const LumenSelectElement = elementClasses.Select;
4322
- export const LumenSeparatorElement = elementClasses.Separator;
4323
- export const LumenSheetElement = elementClasses.Sheet;
4324
- export const LumenSidebarElement = elementClasses.Sidebar;
4325
- export const LumenSkeletonElement = elementClasses.Skeleton;
4326
- export const LumenSliderElement = elementClasses.Slider;
4327
- export const LumenSonnerElement = elementClasses.Sonner;
4328
- export const LumenSpinnerElement = elementClasses.Spinner;
4329
- export const LumenSwitchElement = elementClasses.Switch;
4330
- export const LumenTableElement = elementClasses.Table;
4331
- export const LumenTabsElement = elementClasses.Tabs;
4332
- export const LumenTagGroupElement = elementClasses.TagGroup;
4333
- export const LumenTextareaElement = elementClasses.Textarea;
4334
- export const LumenThemeBuilderElement = elementClasses.ThemeBuilder;
4335
- export const LumenTimeFieldElement = elementClasses.TimeField;
4336
- export const LumenToastElement = elementClasses.Toast;
4337
- export const LumenToggleElement = elementClasses.Toggle;
4338
- export const LumenToggleGroupElement = elementClasses.ToggleGroup;
4339
- export const LumenTooltipElement = elementClasses.Tooltip;
4340
- export const LumenTreeElement = elementClasses.Tree;
4341
- export const LumenTreeGridElement = elementClasses.TreeGrid;
4342
- export const LumenTypographyElement = elementClasses.Typography;
4343
- export const LumenVirtualListElement = elementClasses.VirtualList;
4344
- export const LumenLanguageToggleElement = elementClasses.LanguageToggle;
4345
- export const LumenParticlesElement = elementClasses.Particles;
4346
- export const LumenAnimatedNumberElement = elementClasses.AnimatedNumber;
4347
- export const LumenRevealGroupElement = elementClasses.RevealGroup;
4348
- export const LumenScrollRevealElement = elementClasses.ScrollReveal;
4349
- export const LumenStatElement = elementClasses.Stat;
4350
- export const LumenMeterElement = elementClasses.Meter;
4351
- export const LumenNoteElement = elementClasses.Note;
4352
- export const LumenRatingElement = elementClasses.Rating;
4353
- export const LumenTimelineElement = elementClasses.Timeline;
4354
- export const LumenAnimatedLogoElement = elementClasses.AnimatedLogo;
4355
- export const LumenAnimatedPortraitElement = elementClasses.AnimatedPortrait;
4356
- export const LumenButtonLinkElement = elementClasses.ButtonLink;
4357
- export const LumenCoverImageElement = elementClasses.CoverImage;
4358
- export const LumenGradientDividerElement = elementClasses.GradientDivider;
1
+ import{alignLumenChartSeries as Ht,coerceThemeBuilderExportFormat as Ne,coerceThemeBuilderMode as Ot,coerceThemeBuilderScheme as we,composeClassName as Vt,createLumenBarGeometry as zt,createLumenLineGeometry as Te,createLumenPieGeometry as Ut,createThemeBuilderTokens as jt,exportThemeBuilderValue as Gt,getLumenChartCategories as Yt,getLumenChartDomain as Kt,getLumenChartTicks as De,getLumenRichTextShortcut as Wt,getVirtualRange as Zt,hasLumenChartData as Me,hasLumenPieData as Xt,isLumenRichTextToggleCommand as Jt,lumenChartTones as ce,lumenComponentNames as Ie,normalizeThemeBuilderHex as Qt,parseThemeCss as ea,renderLumenIconSvg as ta,resolveLumenChartTone as de,scaleLumenChartValue as ee,scoreThemeContrast as aa,tuneThemeContrast as na}from"@santi020k/lumen-core";const Be=new Set,Fe=new WeakMap,sa=["a[href]","button:not([disabled])","input:not([disabled])","select:not([disabled])","textarea:not([disabled])",'[tabindex]:not([tabindex="-1"])'].join(","),ra=['input:not([type="hidden"])',"select","textarea",'[contenteditable="true"]','[role="combobox"]','[role="listbox"]','[role="spinbutton"]','[role="textbox"]'].join(","),ia="[data-ui-field-hint], [data-ui-field-error], .ui-field__hint, .ui-field__error",oa="[data-ui-field-error], .ui-field__error",$e="[data-ui-rich-text-editor]",qe="[data-ui-editor-command]",me='[data-ui-rich-text-editable], [contenteditable="true"]',_e="[data-ui-schedule]",la="[data-ui-schedule-event]",ua="[data-ui-schedule-slot]",Pe="[data-ui-resizable]",Re="[data-ui-resizable-handle]",ca="[data-ui-resizable-handle-template]",He="[data-ui-context-menu]",da="[data-ui-context-menu-trigger]",Oe="[data-ui-date-range-picker]",Ve='input[type="date"]',ze="[data-ui-input-otp], lumen-input-otp",ma="[data-ui-input-otp-native]",ha="[data-ui-input-otp-segment]",ba="[data-ui-input-otp-segments]",he="[data-ui-calendar], lumen-calendar",be="[data-ui-calendar-input]",Ue="[data-ui-calendar-label]",je="[data-ui-calendar-grid]",Ge="[data-ui-calendar-day]",pe="[data-ui-date-picker], lumen-date-picker",pa="[data-ui-date-picker-native]",ga="[data-ui-date-picker-control]",fa="[data-ui-date-picker-trigger]",Ca="[data-ui-date-picker-value]",va="[data-ui-date-picker-popover]",xa=['input:not([type="hidden"])',"select","textarea"].join(","),Ea="[data-ui-select-option]",ya=5e3,Aa=5,Sa=240,La=[["valueMissing","data-error-required"],["typeMismatch","data-error-type"],["patternMismatch","data-error-pattern"],["tooShort","data-error-too-short"],["tooLong","data-error-too-long"],["rangeUnderflow","data-error-min"],["rangeOverflow","data-error-max"],["stepMismatch","data-error-step"],["badInput","data-error-bad-input"],["customError","data-error-custom"]],ge=new WeakMap,Ye=(...a)=>Vt(...a).split(/\s+/).filter(Boolean),A=a=>({glass:{strong:`${a} ui-glass-strong`,subtle:`${a} ui-glass-subtle`,true:a}}),fe={Accordion:{attributeClasses:{variant:{flush:"ui-accordion--flush"}},baseClassName:"ui-accordion",defaults:{variant:"default"},tagName:"lumen-accordion"},Alert:{attributeClasses:{glass:{strong:"ui-alert--glass ui-glass-strong",subtle:"ui-alert--glass ui-glass-subtle",true:"ui-alert--glass"},variant:{destructive:"ui-alert--destructive",success:"ui-alert--success",warning:"ui-alert--warning"}},baseClassName:"ui-alert",defaults:{variant:"default"},tagName:"lumen-alert"},AlertDialog:{attributeClasses:{glass:{strong:"ui-dialog--glass ui-glass-strong",subtle:"ui-dialog--glass ui-glass-subtle",true:"ui-dialog--glass"}},baseClassName:"ui-dialog ui-alert-dialog",defaults:{"data-ui-alert-dialog":""},tagName:"lumen-alert-dialog"},Agenda:{attributeClasses:A("ui-agenda--glass"),baseClassName:"ui-agenda",tagName:"lumen-agenda"},AspectRatio:{baseClassName:"ui-aspect-ratio",tagName:"lumen-aspect-ratio"},Attachment:{attributeClasses:A("ui-attachment--glass"),baseClassName:"ui-attachment",tagName:"lumen-attachment"},Autocomplete:{baseClassName:"ui-input ui-autocomplete",defaults:{role:"combobox",type:"search"},tagName:"lumen-autocomplete"},Avatar:{baseClassName:"ui-avatar",tagName:"lumen-avatar"},BackToTop:{baseClassName:"ui-back-to-top",tagName:"lumen-back-to-top"},Badge:{attributeClasses:{variant:{default:"ui-badge--default",destructive:"ui-badge--destructive",outline:"ui-badge--outline",secondary:"ui-badge--secondary",success:"ui-badge--success",warning:"ui-badge--warning"}},baseClassName:"ui-badge",defaults:{variant:"default"},tagName:"lumen-badge"},BarChart:{attributeClasses:{...A("ui-chart--glass"),presentation:{bare:"ui-chart--bare"}},baseClassName:"ui-chart ui-bar-chart",defaults:{layout:"grouped",orientation:"vertical"},role:"figure",tagName:"lumen-bar-chart"},Breadcrumb:{baseClassName:"ui-breadcrumb",defaults:{"aria-label":"Breadcrumb"},tagName:"lumen-breadcrumb"},Bubble:{attributeClasses:{from:{user:"ui-bubble--user"},...A("ui-bubble--glass")},baseClassName:"ui-bubble",defaults:{from:"assistant"},tagName:"lumen-bubble"},Button:{attributeClasses:{variant:{default:"ui-button--default",destructive:"ui-button--destructive",ghost:"ui-button--ghost",link:"ui-button--link",outline:"ui-button--outline",secondary:"ui-button--secondary"},size:{default:"ui-button--default-size",icon:"ui-button--icon",lg:"ui-button--lg",sm:"ui-button--sm"},disabled:{true:"ui-button--disabled"},loading:{true:"ui-button--loading"}},baseClassName:"ui-button",defaults:{"data-slot":"button",role:"button",size:"default",tabindex:"0",variant:"default"},role:"button",tagName:"lumen-button"},ButtonGroup:{baseClassName:"ui-button-group",tagName:"lumen-button-group"},Calendar:{attributeClasses:A("ui-calendar--glass"),baseClassName:"ui-calendar",defaults:{"data-ui-calendar":""},tagName:"lumen-calendar"},Callout:{baseClassName:"ui-callout",tagName:"lumen-callout"},Card:{attributeClasses:{glass:{strong:"ui-card--glass ui-glass-strong",subtle:"ui-card--glass ui-glass-subtle",true:"ui-card--glass"},variant:{glass:"ui-card--glass",interactive:"ui-card--interactive",muted:"ui-card--muted",unstyled:"ui-card--unstyled"}},baseClassName:"ui-card",defaults:{"data-slot":"card",variant:"default"},tagName:"lumen-card"},CardContent:{baseClassName:"ui-card__content",defaults:{"data-slot":"card-content"},tagName:"lumen-card-content"},CardDescription:{baseClassName:"ui-card__description",defaults:{"data-slot":"card-description"},tagName:"lumen-card-description"},CardFooter:{baseClassName:"ui-card__footer",defaults:{"data-slot":"card-footer"},tagName:"lumen-card-footer"},CardHeader:{baseClassName:"ui-card__header",defaults:{"data-slot":"card-header"},tagName:"lumen-card-header"},CardTitle:{baseClassName:"ui-card__title",defaults:{"data-slot":"card-title"},tagName:"lumen-card-title"},Carousel:{attributeClasses:A("ui-carousel--glass"),baseClassName:"ui-carousel",defaults:{"data-ui-carousel":""},tagName:"lumen-carousel"},Chart:{attributeClasses:{...A("ui-chart--glass"),presentation:{bare:"ui-chart--bare"}},baseClassName:"ui-chart",tagName:"lumen-chart"},Checkbox:{baseClassName:"ui-checkbox",defaults:{type:"checkbox"},tagName:"lumen-checkbox"},CheckboxGroup:{attributeClasses:{orientation:{horizontal:"ui-checkbox-group--horizontal",vertical:"ui-checkbox-group--vertical"}},baseClassName:"ui-checkbox-group",defaults:{"data-ui-checkbox-group":"",orientation:"vertical",role:"group"},tagName:"lumen-checkbox-group"},Collapsible:{baseClassName:"ui-collapsible",defaults:{"data-ui-collapsible":""},tagName:"lumen-collapsible"},Code:{attributeClasses:{variant:{block:"ui-code--block",inline:"ui-code--inline"},wrap:{true:"ui-code--wrap"}},baseClassName:"ui-code",defaults:{"data-code-theme":"auto","data-slot":"code",variant:"inline"},tagName:"lumen-code"},CodeTabs:{baseClassName:"ui-code-tabs",defaults:{"data-slot":"code-tabs","data-ui-tabs":""},tagName:"lumen-code-tabs"},Combobox:{baseClassName:"ui-combobox",defaults:{"data-ui-combobox":""},tagName:"lumen-combobox"},Container:{attributeClasses:{size:{full:"ui-container--full",lg:"ui-container--lg",md:"ui-container--md",sm:"ui-container--sm"}},baseClassName:"ui-container",defaults:{"data-ui-container":"",size:"lg"},tagName:"lumen-container"},CopyButton:{baseClassName:"ui-button ui-button--outline ui-copy-button",defaults:{"aria-label":"Copy to clipboard","data-state":"idle","data-ui-copy-button":"",role:"button",tabindex:"0"},tagName:"lumen-copy-button"},Command:{attributeClasses:A("ui-command--glass"),baseClassName:"ui-command",defaults:{"data-ui-command":""},tagName:"lumen-command"},ColorPicker:{baseClassName:"ui-color-picker",defaults:{type:"color"},tagName:"lumen-color-picker"},ContextMenu:{attributeClasses:{glass:{strong:"ui-menu--glass ui-glass-strong",subtle:"ui-menu--glass ui-glass-subtle",true:"ui-menu--glass"}},baseClassName:"ui-menu",defaults:{"data-ui-context-menu":"",role:"menu"},tagName:"lumen-context-menu"},DataTable:{attributeClasses:A("ui-data-table--glass"),baseClassName:"ui-data-table",defaults:{"data-ui-datatable":""},tagName:"lumen-data-table"},DatePicker:{attributeClasses:A("ui-date-picker-field--glass"),baseClassName:"ui-input ui-date-picker",defaults:{type:"date"},tagName:"lumen-date-picker"},DateRangePicker:{baseClassName:"ui-date-range-picker",defaults:{"data-ui-date-range-picker":""},tagName:"lumen-date-range-picker"},Dialog:{attributeClasses:{glass:{strong:"ui-dialog--glass ui-glass-strong",subtle:"ui-dialog--glass ui-glass-subtle",true:"ui-dialog--glass"},layout:{fullscreen:"ui-dialog--fullscreen"}},baseClassName:"ui-dialog",defaults:{"data-ui-dialog":"",layout:"centered"},tagName:"lumen-dialog"},Direction:{baseClassName:"ui-direction",defaults:{dir:"ltr"},tagName:"lumen-direction"},Drawer:{attributeClasses:{glass:{strong:"ui-drawer--glass ui-glass-strong",subtle:"ui-drawer--glass ui-glass-subtle",true:"ui-drawer--glass"}},baseClassName:"ui-drawer",defaults:{"data-ui-drawer":""},tagName:"lumen-drawer"},DropdownMenu:{attributeClasses:{glass:{strong:"ui-menu--glass ui-glass-strong",subtle:"ui-menu--glass ui-glass-subtle",true:"ui-menu--glass"}},baseClassName:"ui-menu",defaults:{"data-ui-dropdown-menu":""},tagName:"lumen-dropdown-menu"},Empty:{attributeClasses:A("ui-empty--glass"),baseClassName:"ui-empty",tagName:"lumen-empty"},ErrorSummary:{baseClassName:"ui-error-summary",defaults:{"data-ui-error-summary":"",tabindex:"-1"},tagName:"lumen-error-summary"},Eyebrow:{baseClassName:"ui-eyebrow",tagName:"lumen-eyebrow"},Field:{attributeClasses:A("ui-field--glass"),baseClassName:"ui-field",defaults:{"data-ui-field":""},tagName:"lumen-field"},FieldError:{baseClassName:"ui-field-error",defaults:{"data-ui-field-error":""},tagName:"lumen-field-error"},FloatingBadge:{baseClassName:"ui-floating-badge",tagName:"lumen-floating-badge"},Form:{baseClassName:"ui-form",defaults:{"data-ui-form":""},tagName:"lumen-form"},FormattedDate:{baseClassName:"ui-formatted-date",tagName:"lumen-formatted-date"},Grid:{attributeClasses:{columns:{1:"ui-grid--columns-1",2:"ui-grid--columns-2",3:"ui-grid--columns-3",4:"ui-grid--columns-4",6:"ui-grid--columns-6",12:"ui-grid--columns-12",auto:"ui-grid--columns-auto"},gap:{lg:"ui-grid--gap-lg",md:"ui-grid--gap-md",none:"ui-grid--gap-none",sm:"ui-grid--gap-sm",xl:"ui-grid--gap-xl"}},baseClassName:"ui-grid",defaults:{"data-ui-grid":"",columns:"auto",gap:"md"},tagName:"lumen-grid"},HoverCard:{attributeClasses:{glass:{strong:"ui-hover-card--glass ui-glass-strong",subtle:"ui-hover-card--glass ui-glass-subtle",true:"ui-hover-card--glass"}},baseClassName:"ui-hover-card",defaults:{"data-ui-hover-card":""},tagName:"lumen-hover-card"},Icon:{attributeClasses:{size:{lg:"ui-icon--lg",sm:"ui-icon--sm",xl:"ui-icon--xl"}},baseClassName:"ui-icon",defaults:{size:"default"},tagName:"lumen-icon"},Image:{attributeClasses:{"invert-on-dark":{true:"ui-image--invert-dark"}},baseClassName:"ui-image",tagName:"lumen-image"},Input:{attributeClasses:{size:{lg:"ui-input--lg",sm:"ui-input--sm"}},baseClassName:"ui-input",defaults:{type:"text"},tagName:"lumen-input"},InputGroup:{baseClassName:"ui-input-group",tagName:"lumen-input-group"},InputOTP:{baseClassName:"ui-input-otp-field",defaults:{"data-ui-input-otp":"","data-ui-input-otp-length":"6"},tagName:"lumen-input-otp"},NumberField:{baseClassName:"ui-input ui-number-field",defaults:{type:"number"},tagName:"lumen-number-field"},Item:{attributeClasses:A("ui-item--glass"),baseClassName:"ui-item",defaults:{"data-slot":"item"},tagName:"lumen-item"},Kbd:{baseClassName:"ui-kbd",tagName:"lumen-kbd"},Label:{baseClassName:"ui-label",tagName:"lumen-label"},Link:{attributeClasses:{variant:{inherit:"ui-link--inherit"}},baseClassName:"ui-link",defaults:{"data-slot":"link"},tagName:"lumen-link"},LineChart:{attributeClasses:{...A("ui-chart--glass"),presentation:{bare:"ui-chart--bare"}},baseClassName:"ui-chart ui-line-chart",role:"figure",tagName:"lumen-line-chart"},ListBox:{baseClassName:"ui-list-box",defaults:{"data-ui-list-box":""},tagName:"lumen-list-box"},Marker:{attributeClasses:{variant:{danger:"ui-marker--danger",success:"ui-marker--success",warning:"ui-marker--warning"}},baseClassName:"ui-marker",defaults:{variant:"default"},tagName:"lumen-marker"},Menubar:{attributeClasses:{glass:{strong:"ui-menubar--glass ui-glass-strong",subtle:"ui-menubar--glass ui-glass-subtle",true:"ui-menubar--glass"}},baseClassName:"ui-menubar",defaults:{"data-ui-menubar":""},tagName:"lumen-menubar"},PieChart:{attributeClasses:{...A("ui-chart--glass"),variant:{donut:"ui-pie-chart--donut",pie:"ui-pie-chart--pie"}},baseClassName:"ui-chart ui-pie-chart",defaults:{variant:"donut"},role:"figure",tagName:"lumen-pie-chart"},Message:{attributeClasses:{from:{assistant:"ui-message--assistant",user:"ui-message--user"}},baseClassName:"ui-message",defaults:{from:"assistant"},tagName:"lumen-message"},MessageScroller:{attributeClasses:A("ui-message-scroller--glass"),baseClassName:"ui-message-scroller",tagName:"lumen-message-scroller"},NativeSelect:{attributeClasses:{size:{lg:"ui-select--lg",sm:"ui-select--sm"}},baseClassName:"ui-select",tagName:"lumen-native-select"},NavigationMenu:{attributeClasses:{glass:{strong:"ui-navigation-menu--glass ui-glass-strong",subtle:"ui-navigation-menu--glass ui-glass-subtle",true:"ui-navigation-menu--glass"},variant:{unstyled:"ui-navigation-menu--unstyled"}},baseClassName:"ui-navigation-menu",defaults:{"data-slot":"navigation-menu","data-ui-navigation-menu":""},tagName:"lumen-navigation-menu"},Pagination:{baseClassName:"ui-pagination",defaults:{"aria-label":"Pagination"},tagName:"lumen-pagination"},PasswordField:{baseClassName:"ui-password-field",defaults:{"data-ui-password-field":""},tagName:"lumen-password-field"},PhoneInput:{baseClassName:"ui-phone-input ui-input-group",tagName:"lumen-phone-input"},Pill:{attributeClasses:{variant:{brand:"ui-pill--brand",outline:"ui-pill--outline"}},baseClassName:"ui-pill",defaults:{variant:"neutral"},tagName:"lumen-pill"},Popover:{attributeClasses:{glass:{strong:"ui-popover--glass ui-glass-strong",subtle:"ui-popover--glass ui-glass-subtle",true:"ui-popover--glass"}},baseClassName:"ui-popover",defaults:{"data-ui-popover":""},tagName:"lumen-popover"},Progress:{baseClassName:"ui-progress",defaults:{"aria-valuemax":"100","aria-valuemin":"0","aria-valuenow":"0","data-ui-progress":"",max:"100",role:"progressbar",value:"0"},tagName:"lumen-progress"},Prose:{baseClassName:"ui-prose",tagName:"lumen-prose"},RadioGroup:{baseClassName:"ui-radio-group",defaults:{"data-ui-radio-group":""},tagName:"lumen-radio-group"},Resizable:{attributeClasses:{"data-orientation":{vertical:"ui-resizable--vertical"}},baseClassName:"ui-resizable",defaults:{"data-orientation":"horizontal","data-ui-resizable":"","data-ui-resizable-reset":"true"},tagName:"lumen-resizable"},RichTextEditor:{attributeClasses:A("ui-rich-text-editor--glass"),baseClassName:"ui-rich-text-editor",defaults:{"data-ui-rich-text-editor":""},tagName:"lumen-rich-text-editor"},ScrollArea:{attributeClasses:A("ui-scroll-area--glass"),baseClassName:"ui-scroll-area",tagName:"lumen-scroll-area"},ScrollProgress:{attributeClasses:{position:{bottom:"ui-scroll-progress--bottom"}},baseClassName:"ui-scroll-progress",defaults:{"aria-label":"Reading progress","aria-valuemax":"100","aria-valuemin":"0","aria-valuenow":"0","data-ui-scroll-progress":"",position:"top",role:"progressbar"},tagName:"lumen-scroll-progress"},Schedule:{attributeClasses:A("ui-schedule--glass"),baseClassName:"ui-schedule",defaults:{"data-ui-schedule":""},tagName:"lumen-schedule"},SearchField:{baseClassName:"ui-input ui-search-field",defaults:{type:"search"},tagName:"lumen-search-field"},Select:{attributeClasses:{...A("ui-select-field--glass"),size:{lg:"ui-select--lg",sm:"ui-select--sm"}},baseClassName:"ui-select",tagName:"lumen-select"},Separator:{attributeClasses:{orientation:{horizontal:"ui-separator--horizontal",vertical:"ui-separator--vertical"}},baseClassName:"ui-separator",defaults:{orientation:"horizontal"},tagName:"lumen-separator"},Sheet:{attributeClasses:{glass:{strong:"ui-sheet--glass ui-glass-strong",subtle:"ui-sheet--glass ui-glass-subtle",true:"ui-sheet--glass"}},baseClassName:"ui-sheet",defaults:{"data-ui-sheet":""},tagName:"lumen-sheet"},Sidebar:{attributeClasses:{glass:{strong:"ui-sidebar--glass ui-glass-strong",subtle:"ui-sidebar--glass ui-glass-subtle",true:"ui-sidebar--glass"},variant:{unstyled:"ui-sidebar--unstyled"}},baseClassName:"ui-sidebar",defaults:{"data-slot":"sidebar"},tagName:"lumen-sidebar"},Skeleton:{baseClassName:"ui-skeleton",tagName:"lumen-skeleton"},SkipLink:{baseClassName:"ui-skip-link",tagName:"lumen-skip-link"},Slider:{baseClassName:"ui-slider",defaults:{type:"range"},tagName:"lumen-slider"},Sonner:{baseClassName:"ui-sonner",defaults:{"data-ui-sonner":""},tagName:"lumen-sonner"},Sparkline:{baseClassName:"ui-sparkline",tagName:"lumen-sparkline"},Spinner:{baseClassName:"ui-spinner",tagName:"lumen-spinner"},Switch:{baseClassName:"ui-switch",defaults:{role:"switch",type:"checkbox"},tagName:"lumen-switch"},Table:{attributeClasses:A("ui-table-wrap--glass"),baseClassName:"ui-table-wrap",defaults:{"data-slot":"table"},tagName:"lumen-table"},Tabs:{attributeClasses:A("ui-tabs--glass"),baseClassName:"ui-tabs",defaults:{"data-ui-tabs":""},tagName:"lumen-tabs"},TagGroup:{baseClassName:"ui-tag-group",defaults:{role:"list"},tagName:"lumen-tag-group"},Textarea:{baseClassName:"ui-textarea",defaults:{rows:"4"},tagName:"lumen-textarea"},ThemeBuilder:{attributeClasses:A("ui-theme-builder--glass"),baseClassName:"ui-theme-builder",defaults:{"data-ui-theme-builder":""},tagName:"lumen-theme-builder"},ThemeToggle:{baseClassName:"ui-theme-toggle",defaults:{"data-slot":"theme-toggle"},tagName:"lumen-theme-toggle"},TimeField:{baseClassName:"ui-input ui-time-field",defaults:{type:"time"},tagName:"lumen-time-field"},Toast:{attributeClasses:{glass:{true:"ui-toast--glass"},variant:{destructive:"ui-toast--destructive",success:"ui-toast--success",warning:"ui-toast--warning"}},baseClassName:"ui-toast",defaults:{variant:"default"},tagName:"lumen-toast"},Toggle:{baseClassName:"ui-toggle",defaults:{"aria-pressed":"false","data-ui-toggle":"",role:"button",tabindex:"0"},role:"button",tagName:"lumen-toggle"},ToggleGroup:{baseClassName:"ui-toggle-group",defaults:{"data-ui-toggle-group":""},tagName:"lumen-toggle-group"},Tooltip:{baseClassName:"ui-tooltip",tagName:"lumen-tooltip"},Tree:{attributeClasses:A("ui-tree--glass"),baseClassName:"ui-tree",defaults:{role:"tree"},tagName:"lumen-tree"},TreeGrid:{attributeClasses:A("ui-tree-grid--glass"),baseClassName:"ui-tree-grid",defaults:{role:"treegrid"},tagName:"lumen-tree-grid"},Typography:{baseClassName:"ui-typography",tagName:"lumen-typography"},VirtualList:{attributeClasses:A("ui-virtual-list--glass"),baseClassName:"ui-virtual-list",defaults:{"data-ui-virtual-list":""},tagName:"lumen-virtual-list"},VisuallyHidden:{baseClassName:"ui-visually-hidden",defaults:{"data-ui-visually-hidden":""},tagName:"lumen-visually-hidden"},LanguageToggle:{baseClassName:"ui-language-toggle",tagName:"lumen-language-toggle"},Particles:{baseClassName:"ui-particles",tagName:"lumen-particles"},AnimatedNumber:{attributeClasses:{duration:{fast:"ui-motion-duration-fast",slow:"ui-motion-duration-slow",standard:"ui-motion-duration-standard"}},baseClassName:"ui-animated-number",defaults:{duration:"slow",from:"0"},tagName:"lumen-animated-number"},RevealGroup:{attributeClasses:{animation:{fade:"ui-reveal-group-fade",scale:"ui-reveal-group-scale","slide-up":"ui-reveal-group-slide-up"},duration:{fast:"ui-motion-duration-fast",slow:"ui-motion-duration-slow",standard:"ui-motion-duration-standard"}},baseClassName:"ui-reveal-group",defaults:{animation:"slide-up",duration:"slow",once:"true",threshold:"0.15"},tagName:"lumen-reveal-group"},ScrollReveal:{attributeClasses:{animation:{fade:"ui-scroll-reveal-fade",scale:"ui-scroll-reveal-scale","slide-up":"ui-scroll-reveal-slide-up"},duration:{fast:"ui-motion-duration-fast",slow:"ui-motion-duration-slow",standard:"ui-motion-duration-standard"}},baseClassName:"ui-scroll-reveal",defaults:{animation:"fade",duration:"slow",once:"true",threshold:"0.15"},tagName:"lumen-scroll-reveal"},Stat:{attributeClasses:{variant:{accent:"ui-stat--accent",bare:"ui-stat--bare",glass:"ui-stat--glass"}},baseClassName:"ui-stat",defaults:{"data-slot":"stat",variant:"default"},tagName:"lumen-stat"},StatDescription:{baseClassName:"ui-stat-description",defaults:{"data-slot":"stat-description"},tagName:"lumen-stat-description"},StatIcon:{baseClassName:"ui-stat-icon",defaults:{"data-slot":"stat-icon"},tagName:"lumen-stat-icon"},StatLabel:{baseClassName:"ui-stat-label",defaults:{"data-slot":"stat-label"},tagName:"lumen-stat-label"},StatTrend:{attributeClasses:{tone:{danger:"ui-stat-trend--danger",neutral:"ui-stat-trend--neutral",success:"ui-stat-trend--success",warning:"ui-stat-trend--warning"}},baseClassName:"ui-stat-trend",defaults:{"data-slot":"stat-trend",tone:"neutral"},tagName:"lumen-stat-trend"},StatValue:{baseClassName:"ui-stat-value",defaults:{"data-slot":"stat-value"},tagName:"lumen-stat-value"},Stack:{attributeClasses:{direction:{horizontal:"ui-stack--horizontal",vertical:"ui-stack--vertical"},gap:{lg:"ui-stack--gap-lg",md:"ui-stack--gap-md",none:"ui-stack--gap-none",sm:"ui-stack--gap-sm",xl:"ui-stack--gap-xl"}},baseClassName:"ui-stack",defaults:{"data-ui-stack":"",direction:"vertical",gap:"md"},tagName:"lumen-stack"},Meter:{baseClassName:"ui-meter",tagName:"lumen-meter"},Note:{attributeClasses:{"border-position":{left:"ui-note--border-left",none:"ui-note--border-none",right:"ui-note--border-right"}},baseClassName:"ui-note",defaults:{"border-position":"left"},tagName:"lumen-note"},Rating:{baseClassName:"ui-rating",tagName:"lumen-rating"},Timeline:{baseClassName:"ui-timeline",tagName:"lumen-timeline"},AnimatedLogo:{baseClassName:"ui-animated-logo",tagName:"lumen-animated-logo"},AnimatedPortrait:{baseClassName:"ui-animated-portrait",tagName:"lumen-animated-portrait"},ButtonLink:{attributeClasses:{shape:{icon:"ui-button-link--icon"},variant:{unstyled:"ui-button-link--unstyled"}},baseClassName:"ui-button-link",defaults:{"data-slot":"button-link"},tagName:"lumen-button-link"},CoverImage:{attributeClasses:{hover:{true:"ui-cover-image--hover"}},baseClassName:"ui-cover-image",tagName:"lumen-cover-image"},GradientDivider:{baseClassName:"ui-gradient-divider",tagName:"lumen-gradient-divider"},Stepper:{attributeClasses:{orientation:{vertical:"ui-stepper--vertical"}},baseClassName:"ui-stepper",defaults:{orientation:"horizontal"},tagName:"lumen-stepper"},FileUpload:{baseClassName:"ui-file-upload",defaults:{"data-ui-file-upload":""},tagName:"lumen-file-upload"},Tour:{baseClassName:"ui-tour",defaults:{"data-ui-tour":""},tagName:"lumen-tour"},Anchor:{baseClassName:"ui-anchor",defaults:{"aria-label":"On this page","activation-offset":"96","data-ui-anchor":"","data-ui-anchor-offset":"96"},tagName:"lumen-anchor"},Segmented:{attributeClasses:{size:{lg:"ui-segmented--lg",sm:"ui-segmented--sm"}},baseClassName:"ui-segmented",defaults:{role:"group"},tagName:"lumen-segmented"},Toolbar:{attributeClasses:{orientation:{vertical:"ui-toolbar--vertical"}},baseClassName:"ui-toolbar",defaults:{"aria-label":"Toolbar","data-ui-toolbar":"",orientation:"horizontal",role:"toolbar"},tagName:"lumen-toolbar"},Descriptions:{baseClassName:"ui-descriptions",tagName:"lumen-descriptions"},Popconfirm:{baseClassName:"ui-popover ui-popconfirm",defaults:{"data-ui-popconfirm":"","data-ui-popover":""},tagName:"lumen-popconfirm"},Transfer:{baseClassName:"ui-transfer",defaults:{"data-ui-transfer":""},tagName:"lumen-transfer"},Cascader:{baseClassName:"ui-cascader",defaults:{"data-ui-cascader":""},tagName:"lumen-cascader"},TreeSelect:{baseClassName:"ui-tree-select",defaults:{"data-ui-tree-select":""},tagName:"lumen-tree-select"},Mentions:{baseClassName:"ui-mentions",defaults:{"data-ui-mentions":""},tagName:"lumen-mentions"},QRCode:{baseClassName:"ui-qr-code",tagName:"lumen-qr-code"},Watermark:{baseClassName:"ui-watermark",defaults:{"data-ui-watermark":""},tagName:"lumen-watermark"},Affix:{attributeClasses:{position:{bottom:"ui-affix--bottom"}},baseClassName:"ui-affix",defaults:{position:"top"},tagName:"lumen-affix"},SpeedDial:{attributeClasses:{direction:{down:"ui-speed-dial--down",left:"ui-speed-dial--left",right:"ui-speed-dial--right",up:"ui-speed-dial--up"}},baseClassName:"ui-speed-dial",defaults:{"data-ui-speed-dial":"",direction:"up"},tagName:"lumen-speed-dial"}},ka=["activation-offset","animation","area","autocomplete","border-position","caption","center-label","center-value","checked","columns","decimals","delay","decorative","direction","disabled","duration","from","form","gap","glass","heading","hover","label","locale","layout","markers","max","maxlength","min","minlength","multiple","name","orientation","pattern","position","placeholder","readonly","required","rows","prefix","pressed","reference-value","series","shape","show-endpoint","show-legend","show-table","size","surface","stagger","step","suffix","threshold","tone","type","value","values","variant"],x=()=>typeof document<"u",Na=a=>{const e=Number.parseFloat(a);return Number.isFinite(e)?a.endsWith("ms")?e:e*1e3:300},R=a=>typeof crypto<"u"&&typeof crypto.randomUUID=="function"?`${a}-${crypto.randomUUID()}`:`${a}-${Math.random().toString(36).slice(2)}`,wa=a=>typeof a.checkVisibility=="function"?a.checkVisibility():a.offsetParent!==null||a.getClientRects().length>0,H=a=>a?[...a.querySelectorAll(sa)].filter(e=>!e.hasAttribute("hidden")&&wa(e)):[],z=a=>a.target instanceof Node?a.target:null,F=(a,e)=>{const t=[...a.querySelectorAll(e)];return a instanceof Element&&a.matches(e)&&t.unshift(a),t},U=(a,e)=>a instanceof Element?a.closest(e):null,Ta=a=>a instanceof HTMLInputElement||a instanceof HTMLSelectElement||a instanceof HTMLTextAreaElement,Da=a=>{const e=a.dataset.uiFieldControl;if(e&&x()){const t=document.getElementById(e);if(t instanceof HTMLElement)return t}return a.querySelector(ra)},Ma=a=>(a.id||(a.id=R("ui-field-description")),a.id),Ke=a=>a.closest(".ui-field, [data-ui-field]"),Ia=(a,e)=>{for(const[t,n]of La)if(a.validity[t])return a.getAttribute(n)??e?.getAttribute(n)??a.validationMessage;return a.validationMessage},Ba=(a,e,t="")=>{const n=Ke(a);if(e?(a.setAttribute("aria-invalid","true"),a.dataset.uiValidationInvalid="true"):a.dataset.uiValidationInvalid==="true"&&(a.removeAttribute("aria-invalid"),delete a.dataset.uiValidationInvalid),!!n){n.dataset.invalid=String(e);for(const s of n.querySelectorAll(oa))s.dataset.uiValidationErrorBound="true",s.hidden=!e,s.textContent=e?t:""}},We=(a,e)=>{e.dispatchEvent(new CustomEvent("ui:validate",{bubbles:!0,detail:{control:a,form:e,value:a.value}}));const t=!a.validity.valid,n=t?Ia(a,Ke(a)):"";return Ba(a,t,n),!t},Ze=a=>[...a.querySelectorAll(xa)].filter(e=>e.form===a&&!e.disabled),Fa=a=>Ze(a).filter(e=>!We(e,a)),Xe=a=>{for(const e of F(a,".ui-field, [data-ui-field]")){if(e.dataset.uiFieldBound==="true")continue;const t=Da(e);if(!t)continue;e.dataset.uiFieldBound="true";const n=t.getAttribute("aria-describedby")?.trim().split(/\s+/)??[],s=e.dataset.uiFieldDescribedby?.trim().split(/\s+/)??[],r=[...e.querySelectorAll(ia)].map(o=>Ma(o)),i=[...new Set([...n,...s,...r].filter(Boolean))];i.length&&t.setAttribute("aria-describedby",i.join(" "))}},Je=a=>{for(const e of F(a,"form[data-ui-form]")){if(e.dataset.uiFormBound==="true")continue;e.dataset.uiFormBound="true",e.noValidate=!0;const t=n=>{e.dataset.status=n,n==="submitting"?e.setAttribute("aria-busy","true"):e.removeAttribute("aria-busy")};e.addEventListener("click",n=>{const s=n.target;if(!(s instanceof Element))return;const r=s.closest('[data-ui-error-summary] a[href^="#"]'),i=r?.hash.slice(1),o=i?document.getElementById(i):null;!r||!(o instanceof HTMLElement)||!e.contains(o)||(n.preventDefault(),o.focus({preventScroll:!0}),o.scrollIntoView({behavior:"smooth",block:"center"}))}),e.addEventListener("focusout",n=>{if(!Ta(n.target)||n.target.form!==e)return;const s=We(n.target,e);e.dispatchEvent(new CustomEvent(s?"ui:valid":"ui:invalid",{bubbles:!0,detail:s?{control:n.target,form:e}:{control:n.target,controls:[n.target],form:e}}))}),e.addEventListener("submit",n=>{if(e.dataset.status==="submitting"){n.preventDefault();return}const s=Fa(e);if(s.length){n.preventDefault(),t("error");const r=s[0],i=e.querySelector("[data-ui-error-summary]:not([hidden])");if(!r)return;e.dispatchEvent(new CustomEvent("ui:invalid",{bubbles:!0,detail:{control:r,controls:s,form:e}})),i?i.focus({preventScroll:!0}):(r.focus({preventScroll:!0}),r.reportValidity());return}e.dispatchEvent(new CustomEvent("ui:valid",{bubbles:!0,detail:{controls:Ze(e),form:e}})),t("submitting"),queueMicrotask(()=>{n.defaultPrevented&&t("idle")})}),e.addEventListener("reset",()=>{t("idle")})}},Qe=(a=document)=>{for(const e of F(a,"lumen-password-field, [data-ui-password-field]")){if(e.dataset.uiPasswordBound==="true")continue;let t=e.querySelector('input[data-ui-password-input], input[type="password"]');if(!t&&e.localName==="lumen-password-field"){t=document.createElement("input"),t.className="ui-input",t.dataset.uiPasswordInput="",t.type="password";for(const u of["autocomplete","disabled","form","id","maxlength","minlength","name","pattern","placeholder","readonly","required","value"]){const h=e.getAttribute(u);h!==null&&t.setAttribute(u,h)}e.append(t)}if(!t)continue;let n=e.querySelector("[data-ui-password-toggle]");n||(n=document.createElement("button"),n.className="ui-button ui-button--ghost ui-button--icon",n.dataset.uiPasswordToggle="",n.type="button",n.innerHTML='<span aria-hidden="true">Show</span>',e.append(n)),e.dataset.uiPasswordBound="true";const s=e.dataset.showLabel??"Show password",r=e.dataset.hideLabel??"Hide password",i=n.querySelector("span"),o=u=>{t.type=u?"text":"password",n.setAttribute("aria-controls",t.id),n.setAttribute("aria-label",u?r:s),n.setAttribute("aria-pressed",String(u)),i&&(i.textContent=u?"Hide":"Show")};n.addEventListener("click",()=>{o(t.type==="password"),t.focus({preventScroll:!0})}),t.form?.addEventListener("reset",()=>{o(!1)});const l=t.form;if(l&&typeof MutationObserver<"u"){const u=()=>{l.dataset.status==="success"&&o(!1)};new MutationObserver(u).observe(l,{attributeFilter:["data-status"],attributes:!0}),u()}o(!1)}},et=a=>[...a.selectedOptions].map(e=>e.value),$a=(a,e,t,n)=>{const s=t.get(e);if(s)return s;const r=document.createElement("div"),i=document.createElement("div"),o=`${n.id||"ui-list-box"}-group-${t.size}`;return r.setAttribute("aria-labelledby",o),r.setAttribute("role","group"),i.className="ui-list-box__section",i.id=o,i.textContent=e.label,r.append(i),t.set(e,r),a.append(r),r},tt=(a=document)=>{for(const e of F(a,"lumen-list-box, [data-ui-list-box]")){if(e.dataset.uiListBoxBound==="true")continue;let t=e.querySelector("[data-ui-list-box-native], select");if(!t&&e.localName==="lumen-list-box"){t=document.createElement("select"),t.dataset.uiListBoxNative="";for(const b of["disabled","form","id","multiple","name","required","size"]){const p=e.getAttribute(b);p!==null&&t.setAttribute(b,p)}const m=[...e.children].filter(b=>b instanceof HTMLOptionElement||b instanceof HTMLOptGroupElement);t.append(...m),e.prepend(t)}if(!t)continue;t.dataset.uiListBoxNative="",t.dataset.uiListBoxEnhanced="true";const n=e.hasAttribute("loading")||e.dataset.loading==="true";n&&(t.disabled=!0);let s=e.querySelector("[data-ui-list-box-list]");if(!s){s=document.createElement("div"),s.className="ui-list-box__list",s.dataset.uiListBoxList="",s.setAttribute("role","listbox"),s.tabIndex=t.disabled?-1:0,s.toggleAttribute("aria-multiselectable",t.multiple);const m=new Map;for(const b of t.options){const p=document.createElement("div");p.className="ui-list-box__option",p.dataset.uiListBoxOption="",p.dataset.value=b.value,p.textContent=b.textContent,p.setAttribute("role","option"),b.disabled&&p.setAttribute("aria-disabled","true");const S=b.parentElement;S instanceof HTMLOptGroupElement?$a(s,S,m,t).append(p):s.append(p)}e.append(s)}const r=[...s.querySelectorAll("[data-ui-list-box-option]")];if(s.toggleAttribute("aria-busy",n),!r.length){const m=document.createElement("div");m.className=n?"ui-list-box__status":"ui-list-box__empty",m.setAttribute("role",n?"status":"option"),n||m.setAttribute("aria-disabled","true"),m.textContent=n?e.getAttribute("loading-message")??"Loading options":e.getAttribute("empty-message")??"No options available",s.append(m),e.dataset.uiListBoxBound="true";continue}e.dataset.uiListBoxBound="true";let i=Math.max(0,r.findIndex(m=>m.getAttribute("aria-disabled")!=="true")),o="",l;const u=()=>{r.forEach((b,p)=>{b.id||=`${t.id||"ui-list-box"}-option-${p}`,b.dataset.active=p===i?"true":"false"});const m=r[i];m&&s.setAttribute("aria-activedescendant",m.id)},h=()=>{const m=new Set(et(t));r.forEach(b=>{b.setAttribute("aria-selected",String(m.has(b.dataset.value??"")))})},d=m=>{const b=r[m];if(!b||b.getAttribute("aria-disabled")==="true"||t.disabled)return;const p=[...t.options].find(S=>S.value===b.dataset.value);p&&(t.multiple?p.selected=!p.selected:t.value=p.value,h(),t.dispatchEvent(new Event("input",{bubbles:!0,composed:!0})),t.dispatchEvent(new Event("change",{bubbles:!0,composed:!0})),e.dispatchEvent(new CustomEvent("ui:list-box-change",{bubbles:!0,composed:!0,detail:{values:et(t)}})))},g=m=>{let b=i;for(const p of r)if(b=(b+m+r.length)%r.length,r[b]?.getAttribute("aria-disabled")!=="true"){i=b,u(),e.dataset.selectionFollowsFocus==="true"&&d(i);return}};s.addEventListener("keydown",m=>{if(m.key==="ArrowDown")m.preventDefault(),g(1);else if(m.key==="ArrowUp")m.preventDefault(),g(-1);else if(m.key==="Home")m.preventDefault(),i=Math.max(0,r.findIndex(b=>b.getAttribute("aria-disabled")!=="true")),u(),e.dataset.selectionFollowsFocus==="true"&&d(i);else if(m.key==="End"){m.preventDefault();for(let b=r.length-1;b>=0;b-=1)if(r[b]?.getAttribute("aria-disabled")!=="true"){i=b;break}u(),e.dataset.selectionFollowsFocus==="true"&&d(i)}else if(m.key==="Enter"||m.key===" ")m.preventDefault(),d(i);else if(m.key.length===1&&!m.ctrlKey&&!m.metaKey&&!m.altKey){o+=m.key.toLowerCase(),l&&globalThis.clearTimeout(l),l=globalThis.setTimeout(()=>{o=""},700);const b=r.findIndex(p=>p.getAttribute("aria-disabled")!=="true"&&p.textContent.trim().toLowerCase().startsWith(o));b>=0&&(i=b,u(),e.dataset.selectionFollowsFocus==="true"&&d(i))}}),r.forEach((m,b)=>{m.addEventListener("click",()=>{i=b,u(),d(b)})}),t.addEventListener("change",h),t.form?.addEventListener("reset",()=>{globalThis.setTimeout(()=>{h(),i=Math.max(0,r.findIndex(m=>m.getAttribute("aria-selected")==="true")),u()})}),h(),u()}},at=(a=document)=>{Xe(a),Je(a)},qa=()=>{if(!x()||document.documentElement.dataset.uiElementsFormsBound==="true"||(document.documentElement.dataset.uiElementsFormsBound="true",at(document),typeof MutationObserver>"u"))return;new MutationObserver(e=>{for(const t of e)for(const n of t.addedNodes)(n instanceof Element||n instanceof DocumentFragment)&&at(n)}).observe(document.documentElement,{childList:!0,subtree:!0})},nt=a=>{if(a.dataset.uiEditorValue!==void 0)return a.dataset.uiEditorValue;if(a instanceof HTMLInputElement||a instanceof HTMLSelectElement||a instanceof HTMLTextAreaElement)return a.value},X=a=>{const e=document;for(const t of a.querySelectorAll(qe)){const n=t.dataset.uiEditorCommand??"",s=nt(t);let r=!1;Jt(n)?(r=e.queryCommandState?.(n)??!1,t.setAttribute("aria-pressed",String(r))):n==="formatBlock"&&s&&(r=e.queryCommandValue?.(n).replaceAll(/[<>]/g,"").toLowerCase()===s.replaceAll(/[<>]/g,"").toLowerCase()),t.dataset.state=r?"on":"off"}},st=a=>{const e=a.querySelector(me);if(!e)return;const t={html:e.innerHTML,text:e.textContent};a.dispatchEvent(new CustomEvent("ui:editor-change",{bubbles:!0,detail:t}))},rt=(a,e,t)=>{if(!e)return!1;const n=document;let s=!1;typeof n.execCommand=="function"&&(s=t===void 0?n.execCommand(e):n.execCommand(e,!1,t));const r={command:e,executed:s,...t===void 0?{}:{value:t}};return a.dispatchEvent(new CustomEvent("ui:editor-command",{bubbles:!0,detail:r})),X(a),st(a),s},_a=a=>{const e=U(a,$e),t=F(a,$e);e instanceof HTMLElement&&!t.includes(e)&&t.unshift(e);for(const n of t)if(n.dataset.uiEditorBound!=="true"){n.dataset.uiEditorBound="true";for(const s of n.querySelectorAll(qe)){s.dataset.uiEditorCommandBound="true";const r=()=>{rt(n,s.dataset.uiEditorCommand??"",nt(s))};s instanceof HTMLSelectElement?s.addEventListener("change",r):s.addEventListener("click",r)}n.addEventListener("keydown",s=>{if(!(s.target instanceof HTMLElement)||!s.target.closest(me))return;const r=Wt(s);r&&(s.preventDefault(),rt(n,r))}),n.addEventListener("input",s=>{!(s.target instanceof HTMLElement)||!s.target.closest(me)||(X(n),st(n))}),n.addEventListener("keyup",()=>{X(n)}),n.addEventListener("mouseup",()=>{X(n)}),X(n)}},it=(a=document)=>{_a(a)},Pa=()=>{if(!x()||document.documentElement.dataset.uiElementsRichTextEditorsBound==="true"||(document.documentElement.dataset.uiElementsRichTextEditorsBound="true",it(document),typeof MutationObserver>"u"))return;new MutationObserver(e=>{for(const t of e)for(const n of t.addedNodes)(n instanceof Element||n instanceof DocumentFragment)&&it(n)}).observe(document.documentElement,{childList:!0,subtree:!0})},Ra=a=>a.id||a.textContent.trim(),Ha=a=>{const e=U(a,_e),t=F(a,_e);e instanceof HTMLElement&&!t.includes(e)&&t.unshift(e);for(const n of t){n.dataset.uiScheduleBound="true";for(const s of n.querySelectorAll(la))s.dataset.uiScheduleEventBound!=="true"&&(s.dataset.uiScheduleEventBound="true",s.draggable=s.draggable||s.dataset.uiDraggable==="true",s.addEventListener("dragstart",r=>{r.dataTransfer?.setData("text/plain",Ra(s)),n.dataset.uiDragging="true"}),s.addEventListener("dragend",()=>{delete n.dataset.uiDragging}));for(const s of n.querySelectorAll(ua))s.dataset.uiScheduleSlotBound!=="true"&&(s.dataset.uiScheduleSlotBound="true",s.addEventListener("dragover",r=>{r.preventDefault(),s.dataset.state="drag-over"}),s.addEventListener("dragleave",()=>{delete s.dataset.state}),s.addEventListener("drop",r=>{r.preventDefault(),delete s.dataset.state;const i=r.dataTransfer?.getData("text/plain"),o=i?document.getElementById(i):null;o instanceof HTMLElement&&s.append(o),n.dispatchEvent(new CustomEvent("ui:schedule-change",{bubbles:!0,detail:{...i?{eventId:i}:{},...s.dataset.uiScheduleSlot?{slot:s.dataset.uiScheduleSlot}:{}}}))}))}},ot=(a=document)=>{Ha(a)},Oa=()=>{if(!x()||document.documentElement.dataset.uiElementsSchedulesBound==="true"||(document.documentElement.dataset.uiElementsSchedulesBound="true",ot(document),typeof MutationObserver>"u"))return;new MutationObserver(e=>{for(const t of e)for(const n of t.addedNodes)(n instanceof Element||n instanceof DocumentFragment)&&ot(n)}).observe(document.documentElement,{childList:!0,subtree:!0})},Ce=(a,e,t)=>{const n=(a??"").split(",").map(s=>Number.parseFloat(s.trim())).filter(Number.isFinite);return Array.from({length:e},(s,r)=>n[r]??n[0]??t)},Va=(a,e)=>{const t=100/Math.max(1,e),n=Array.from({length:e},(r,i)=>{const o=a[i]??t;return Number.isFinite(o)&&o>0?o:t}),s=n.reduce((r,i)=>r+i,0);return s<=0?Array.from({length:e},()=>t):n.map(r=>r/s*100)},za=a=>[...a.children].filter(e=>e instanceof HTMLElement&&!e.hasAttribute("data-ui-resizable-handle")&&!e.hasAttribute("data-ui-resizable-handle-template")),lt=(a,e,t,n,s,r)=>{for(const[i,o]of e.entries())o.dataset.uiResizablePanel="",o.style.setProperty("--ui-resizable-size",`${n[i]??0}%`);for(const i of t){const o=Number.parseInt(i.dataset.index??"0",10);i.setAttribute("aria-valuemin",String(Math.round(s[o]??0))),i.setAttribute("aria-valuemax",String(Math.round(r[o]??100))),i.setAttribute("aria-valuenow",String(Math.round(n[o]??0)))}},Ua=(a,e,t,n,s)=>{const r=n+1,i=(a[n]??0)+(a[r]??0),o=Math.max(e[n]??0,i-(t[r]??100)),l=Math.min(t[n]??100,i-(e[r]??0)),u=Math.min(l,Math.max(o,s));a[n]=u,a[r]=i-u},ja=(a,e,t)=>{const s=a.querySelector(`:scope > ${ca}`)?.content.querySelector(Re)?.cloneNode(!0),r=s instanceof HTMLButtonElement?s:document.createElement("button");return r.type="button",r.className="ui-resizable__handle",r.dataset.uiResizableHandle="",r.dataset.index=String(e),r.tabIndex=0,r.setAttribute("aria-label",`Resize panel ${e+1}`),r.setAttribute("role","separator"),r.setAttribute("aria-orientation",t),r},Ga=a=>{const e=U(a,Pe),t=F(a,Pe);e instanceof HTMLElement&&!t.includes(e)&&t.unshift(e);for(const n of t){if(n.dataset.uiBound==="true")continue;n.getAttribute("direction")==="vertical"&&(n.dataset.orientation="vertical");const s=za(n);if(s.length<2)continue;n.dataset.uiBound="true",n.dataset.uiResizableEnhanced="true",n.classList.toggle("ui-resizable--vertical",n.dataset.orientation==="vertical");const r=n.dataset.orientation==="vertical"?"vertical":"horizontal",i=r==="horizontal"?"vertical":"horizontal",o=r==="horizontal"?"clientX":"clientY",l=r==="horizontal"?"width":"height",u=Ce(n.dataset.uiResizableMinSize,s.length,12),h=Ce(n.dataset.uiResizableMaxSize,s.length,88),d=Va(Ce(n.dataset.uiResizableDefaultSizes,s.length,100/s.length),s.length);let g=[...d];const m=[];for(const[b,p]of s.entries()){if(p.dataset.uiResizablePanel="",b>=s.length-1)continue;const S=p.nextElementSibling instanceof HTMLElement&&p.nextElementSibling.matches(Re)?p.nextElementSibling:null,y=S??ja(n,b,i);S||p.after(y),m.push(y);let D=0,w=0,M=1;const v=()=>{lt(n,s,m,g,u,h)},E=f=>{Ua(g,u,h,b,f),v()};y.addEventListener("pointerdown",f=>{f.button===0&&(f.preventDefault(),D=f[o],w=g[b]??0,M=Math.max(1,n.getBoundingClientRect()[l]),n.dataset.resizing="true",y.dataset.active="true",y.setPointerCapture(f.pointerId))}),y.addEventListener("pointermove",f=>{if(y.dataset.active!=="true")return;const B=(f[o]-D)/M*100;E(w+B)}),y.addEventListener("pointerup",f=>{y.dataset.active==="true"&&(delete y.dataset.active,delete n.dataset.resizing,y.releasePointerCapture(f.pointerId))}),y.addEventListener("dblclick",()=>{n.dataset.uiResizableReset==="true"&&(g=[...d],v())}),y.addEventListener("keydown",f=>{const B=f.shiftKey?10:2,L=r==="horizontal"?{ArrowLeft:-B,ArrowRight:B}:{ArrowDown:B,ArrowUp:-B};if(f.key==="Home"){f.preventDefault(),E(u[b]??0);return}if(f.key==="End"){f.preventDefault(),E(h[b]??100);return}const N=L[f.key];N!==void 0&&(f.preventDefault(),E((g[b]??0)+N))})}lt(n,s,m,g,u,h)}},ut=(a=document)=>{Ga(a)},Ya=()=>{if(!x()||document.documentElement.dataset.uiElementsResizableBound==="true"||(document.documentElement.dataset.uiElementsResizableBound="true",ut(document),typeof MutationObserver>"u"))return;new MutationObserver(e=>{for(const t of e)for(const n of t.addedNodes)(n instanceof Element||n instanceof DocumentFragment)&&ut(n)}).observe(document.documentElement,{childList:!0,subtree:!0})},j=(a,e,t,n)=>{const s=t-1;return a==="Home"?0:a==="End"?s:n.includes(a)?(e+1)%t:(e-1+t)%t},ct=a=>{const e=[...a.querySelectorAll(Ve)],t=e[0],n=e.at(-1);if(!t||!n||t===n)return;const s=a.querySelectorAll(pe);s[0]?.setAttribute("data-range-part","start"),s[s.length-1]?.setAttribute("data-range-part","end"),t.value?n.min=t.value:n.removeAttribute("min"),n.value?t.max=n.value:t.removeAttribute("max"),t.value&&n.value&&n.value<t.value&&(n.value=t.value,n.dispatchEvent(new Event("change",{bubbles:!0})));let r="empty";t.value&&n.value?r="complete":t.value&&(r="selecting-end"),a.dataset.rangeState=r},Ka=a=>{const e=U(a,Oe),t=F(a,Oe);e instanceof HTMLElement&&!t.includes(e)&&t.unshift(e);for(const n of t){for(const s of n.querySelectorAll(Ve))s.dataset.uiDateRangeInputBound!=="true"&&(s.dataset.uiDateRangeInputBound="true",s.addEventListener("change",()=>{ct(n)}));ct(n)}},Wa=a=>{const e=U(a,pe),t=F(a,pe);e instanceof HTMLElement&&!t.includes(e)&&t.unshift(e);for(const n of t){if(n.dataset.uiBound==="true")continue;const s=n.querySelector(pa),r=n.querySelector(ga),i=n.querySelector(fa),o=n.querySelector(Ca),l=n.querySelector(va),u=n.querySelector(he);if(!s||!r||!i||!l)continue;n.dataset.uiBound="true",s.dataset.uiEnhanced="true",r.hidden=!1;const h=()=>{l.hidden=!0,l.dataset.state="closed",i.setAttribute("aria-expanded","false"),document.removeEventListener("click",d)},d=m=>{m.target instanceof Node&&!l.contains(m.target)&&!i.contains(m.target)&&h()},g=()=>{u&&(s.min?u.dataset.uiCalendarMin=s.min:delete u.dataset.uiCalendarMin,s.max?u.dataset.uiCalendarMax=s.max:delete u.dataset.uiCalendarMax),l.hidden=!1,l.dataset.state="open",i.setAttribute("aria-expanded","true"),globalThis.setTimeout(()=>{document.addEventListener("click",d)})};i.addEventListener("click",()=>{l.hidden?g():h()}),l.addEventListener("change",m=>{const b=m.target;if(b instanceof HTMLInputElement&&b.hasAttribute("data-ui-calendar-input")){const p=b.value;s.value=p,o&&(o.textContent=p||"mm/dd/yyyy"),s.dispatchEvent(new Event("change",{bubbles:!0,cancelable:!0})),h()}})}},ve=(a=document)=>{Ka(a)},dt=()=>{if(!x()||document.documentElement.dataset.uiElementsDateRangePickersBound==="true"||(document.documentElement.dataset.uiElementsDateRangePickersBound="true",ve(document),typeof MutationObserver>"u"))return;new MutationObserver(e=>{for(const t of e)for(const n of t.addedNodes)(n instanceof Element||n instanceof DocumentFragment)&&ve(n)}).observe(document.documentElement,{childList:!0,subtree:!0})},xe=(a=document)=>{Wa(a)},mt=()=>{if(!x()||document.documentElement.dataset.uiElementsDatePickersBound==="true"||(document.documentElement.dataset.uiElementsDatePickersBound="true",xe(document),typeof MutationObserver>"u"))return;new MutationObserver(e=>{for(const t of e)for(const n of t.addedNodes)(n instanceof Element||n instanceof DocumentFragment)&&xe(n)}).observe(document.documentElement,{childList:!0,subtree:!0})},Za=6,ht="[0-9]*",Xa=a=>Math.max(1,Number.parseInt(a??"",10)||Za),Ja=a=>Xa(a.getAttribute("length")??a.getAttribute("maxlength")??a.dataset.uiInputOtpLength),bt=(a,e,t)=>(a.inputMode==="numeric"||a.getAttribute("pattern")===ht?e.replaceAll(/\D/g,""):e.replaceAll(/\s/g,"")).slice(0,t),Qa=a=>{const e=document.createElement("button"),t=document.createElement("span");return e.ariaHidden="true",e.className="ui-input-otp__segment",e.dataset.index=String(a),e.dataset.uiInputOtpSegment="",e.tabIndex=-1,e.type="button",t.dataset.uiInputOtpChar="",t.textContent="\xA0",e.append(t),e},en=(a,e,t)=>{!a.hasAttribute(t)||e.hasAttribute(t)||e.setAttribute(t,a.getAttribute(t)??"")},tn=(a,e)=>{let t=a.querySelector(ma);const n=!t;t||(t=document.createElement("input"),a.prepend(t)),t.classList.add("ui-input-otp","ui-input-otp__native"),t.dataset.uiInputOtpNative="",t.hasAttribute("autocomplete")||t.setAttribute("autocomplete",a.getAttribute("autocomplete")??"one-time-code"),t.hasAttribute("inputmode")||t.setAttribute("inputmode",a.getAttribute("inputmode")??"numeric"),t.hasAttribute("maxlength")||t.setAttribute("maxlength",a.getAttribute("maxlength")??a.getAttribute("length")??String(e)),t.hasAttribute("pattern")||t.setAttribute("pattern",a.getAttribute("pattern")??ht),t.hasAttribute("type")||t.setAttribute("type","text");for(const s of["aria-describedby","aria-label","name","placeholder"])en(a,t,s);return t.disabled=a.hasAttribute("disabled")||t.disabled,t.required=a.hasAttribute("required")||t.required,a.hasAttribute("aria-invalid")&&!t.hasAttribute("aria-invalid")&&t.setAttribute("aria-invalid",a.getAttribute("aria-invalid")??"true"),n&&a.hasAttribute("value")&&(t.value=a.getAttribute("value")??""),t},an=a=>{let e=a.querySelector(ba);return e||(e=document.createElement("div"),a.append(e)),e.classList.add("ui-input-otp__segments"),e.dataset.uiInputOtpSegments="",e},nn=(a,e)=>{const t=[...a.querySelectorAll(ha)];for(let n=t.length;n<e;n+=1){const s=Qa(n);a.append(s),t.push(s)}for(const n of t.splice(e))n.remove();for(const[n,s]of t.entries())if(s.classList.add("ui-input-otp__segment"),s.dataset.index=String(n),s.dataset.uiInputOtpSegment="",s.setAttribute("aria-hidden","true"),s.tabIndex=-1,s.type="button",!s.querySelector("[data-ui-input-otp-char]")){const r=document.createElement("span");r.dataset.uiInputOtpChar="",s.append(r)}return t},sn=(a,e,t,n)=>{const s=bt(e,e.value,n);e.value!==s&&(e.value=s);const r=Math.min(n-1,Math.max(0,e.selectionStart??s.length));a.dataset.disabled=e.disabled?"true":"false",a.dataset.invalid=e.getAttribute("aria-invalid")==="true"?"true":"false";for(const[i,o]of t.entries()){const l=o.querySelector("[data-ui-input-otp-char]");o.disabled=e.disabled,o.dataset.active=String(document.activeElement===e&&i===r),l&&(l.textContent=s[i]??"\xA0")}},rn=a=>{const e=U(a,ze),t=F(a,ze);e instanceof HTMLElement&&!t.includes(e)&&t.unshift(e);for(const n of t){if(n.dataset.uiBound==="true")continue;const s=Ja(n),r=tn(n,s),i=an(n),o=nn(i,s);n.dataset.uiBound="true",n.dataset.uiInputOtpLength=String(s),r.dataset.uiEnhanced="true",i.hidden=!1;const l=()=>{sn(n,r,o,s)},u=d=>{const g=Math.min(r.value.length,Math.max(0,d));r.focus({preventScroll:!0}),r.setSelectionRange(g,g),l()},h=d=>{r.value=bt(r,d,s),r.setSelectionRange(r.value.length,r.value.length),r.dispatchEvent(new Event("input",{bubbles:!0})),r.dispatchEvent(new Event("change",{bubbles:!0})),l()};l(),r.addEventListener("input",l),r.addEventListener("change",l),r.addEventListener("focus",l),r.addEventListener("blur",l),r.addEventListener("click",l),r.addEventListener("keyup",l),r.addEventListener("keydown",d=>{if(d.key==="ArrowLeft"){d.preventDefault(),u((r.selectionStart??r.value.length)-1);return}if(d.key==="ArrowRight"){d.preventDefault(),u((r.selectionStart??r.value.length)+1);return}if(d.key==="Home"){d.preventDefault(),u(0);return}d.key==="End"&&(d.preventDefault(),u(r.value.length))}),r.addEventListener("paste",d=>{const g=d.clipboardData?.getData("text")??"";g&&(d.preventDefault(),h(g))}),r.form?.addEventListener("reset",()=>{globalThis.setTimeout(l)});for(const[d,g]of o.entries())g.addEventListener("click",()=>{u(d)})}},Ee=(a=document)=>{rn(a)},pt=()=>{if(!x()||document.documentElement.dataset.uiElementsInputOtpBound==="true"||(document.documentElement.dataset.uiElementsInputOtpBound="true",Ee(document),typeof MutationObserver>"u"))return;new MutationObserver(e=>{for(const t of e)for(const n of t.addedNodes)(n instanceof Element||n instanceof DocumentFragment)&&Ee(n)}).observe(document.documentElement,{childList:!0,subtree:!0})},on=/^\d{4}-\d{2}-\d{2}$/,ln=/^\d{4}-\d{2}$/,I=a=>{if(!a||!on.test(a))return null;const[e=Number.NaN,t=Number.NaN,n=Number.NaN]=a.split("-").map(Number),s=new Date(Date.UTC(e,t-1,n));return s.getUTCFullYear()===e&&s.getUTCMonth()===t-1&&s.getUTCDate()===n?s:null},te=a=>{if(!a||!ln.test(a))return null;const[e=Number.NaN,t=Number.NaN]=a.split("-").map(Number),n=new Date(Date.UTC(e,t-1,1));return n.getUTCFullYear()===e&&n.getUTCMonth()===t-1?n:null},q=a=>a.toISOString().slice(0,10),$=a=>a.toISOString().slice(0,7),J=(a,e)=>new Date(Date.UTC(a.getUTCFullYear(),a.getUTCMonth(),a.getUTCDate()+e)),gt=a=>new Date(Date.UTC(a.getUTCFullYear(),a.getUTCMonth()+1,0)).getUTCDate(),ae=(a,e)=>{const t=new Date(Date.UTC(a.getUTCFullYear(),a.getUTCMonth()+e,1)),n=Math.min(a.getUTCDate(),gt(t));return new Date(Date.UTC(t.getUTCFullYear(),t.getUTCMonth(),n))},K=(a,e)=>e?q(a).localeCompare(q(e)):0,Q=()=>{const a=new Date;return new Date(Date.UTC(a.getFullYear(),a.getMonth(),a.getDate()))},un=a=>J(a,-((a.getUTCDay()+6)%7)),cn=()=>document.documentElement.lang||navigator.language||"en",ne=(a,e,t,n)=>a.dataset.disabled==="true"||K(e,t)<0||K(e,n)>0,ft=(a,e,t)=>e&&K(a,e)<0?e:t&&K(a,t)>0?t:a,dn=(a,e,t,n,s)=>{const r=I(a.dataset.uiCalendarValue),i=Q(),o=[s,r,i,e];for(const l of o)if(l&&$(l)===$(e)&&!ne(a,l,t,n))return l;for(let l=0;l<gt(e);l+=1){const u=J(e,l);if(!ne(a,u,t,n))return u}return e},mn=a=>{a.id||=R("ui-calendar");const e=`${a.id}-label`,t=I(a.getAttribute("value")??a.dataset.uiCalendarValue),n=I(a.getAttribute("min")??a.dataset.uiCalendarMin),s=I(a.getAttribute("max")??a.dataset.uiCalendarMax),r=te(a.getAttribute("month")??a.dataset.uiCalendarMonth)??(t?new Date(Date.UTC(t.getUTCFullYear(),t.getUTCMonth(),1)):null)??new Date(Date.UTC(Q().getUTCFullYear(),Q().getUTCMonth(),1));let i=a.querySelector(be);if(a.dataset.uiCalendarInitialMonth??=$(r),a.dataset.uiCalendarMonth||=$(r),n&&(a.dataset.uiCalendarMin=q(n)),s&&(a.dataset.uiCalendarMax=q(s)),t&&(a.dataset.uiCalendarValue=q(t)),a.hasAttribute("disabled")&&(a.dataset.disabled="true"),i||(i=document.createElement("input"),i.type="hidden",i.dataset.uiCalendarInput="",a.prepend(i)),i.disabled=a.dataset.disabled==="true",i.value=a.dataset.uiCalendarValue??"",a.hasAttribute("name")&&!i.name&&(i.name=a.getAttribute("name")??""),!a.querySelector("[data-ui-calendar-prev]")){const l=document.createElement("div"),u=document.createElement("button"),h=document.createElement("strong"),d=document.createElement("button");l.className="ui-calendar__header",u.type="button",u.className="ui-calendar__nav",u.dataset.uiCalendarPrev="",u.setAttribute("aria-label","Previous month"),u.innerHTML='<span aria-hidden="true">&lsaquo;</span>',h.className="ui-calendar__label",h.dataset.uiCalendarLabel="",h.id=e,d.type="button",d.className="ui-calendar__nav",d.dataset.uiCalendarNext="",d.setAttribute("aria-label","Next month"),d.innerHTML='<span aria-hidden="true">&rsaquo;</span>',l.append(u,h,d),i.after(l)}const o=a.querySelector(Ue);if(o&&(o.id||=e),!a.querySelector(je)){const l=document.createElement("table");l.className="ui-calendar__grid",l.dataset.uiCalendarGrid="",l.role="grid",l.setAttribute("aria-labelledby",o?.id??e),a.append(l)}},hn=(a,e,t,n)=>{const s=a.querySelector("[data-ui-calendar-prev]"),r=a.querySelector("[data-ui-calendar-next]"),i=a.dataset.disabled==="true",o=J(e,-1),l=ae(e,1);s&&(s.disabled=i||K(o,t)<0),r&&(r.disabled=i||K(l,n)>0)},W=(a,e,t=!1)=>{const n=a.querySelector(Ue),s=a.querySelector(je);if(!n||!s)return;const r=cn(),i=I(a.dataset.uiCalendarMin),o=I(a.dataset.uiCalendarMax),l=I(a.dataset.uiCalendarValue),u=q(Q()),h=te(a.dataset.uiCalendarMonth)??(l?new Date(Date.UTC(l.getUTCFullYear(),l.getUTCMonth(),1)):null)??Q(),d=new Date(Date.UTC(h.getUTCFullYear(),h.getUTCMonth(),1)),g=dn(a,d,i,o,e),m=q(g),b=l?q(l):"",p=new Intl.DateTimeFormat(r,{month:"long",timeZone:"UTC",year:"numeric"}).format(d),S=new Intl.DateTimeFormat(r,{day:"numeric",month:"long",timeZone:"UTC",weekday:"long",year:"numeric"}),y=new Intl.DateTimeFormat(r,{timeZone:"UTC",weekday:"short"}),D=document.createElement("thead"),w=document.createElement("tr"),M=document.createElement("tbody"),v=un(d);a.dataset.uiCalendarMonth=$(d),n.textContent=p,hn(a,d,i,o),w.role="row";for(let E=0;E<7;E+=1){const f=document.createElement("th");f.scope="col",f.role="columnheader",f.textContent=y.format(new Date(Date.UTC(2026,0,5+E))),w.append(f)}D.append(w);for(let E=0;E<6;E+=1){const f=document.createElement("tr");f.role="row";for(let B=0;B<7;B+=1){const L=J(v,E*7+B),N=q(L),T=document.createElement("td"),Y=ne(a,L,i,o);T.role="gridcell",T.tabIndex=!Y&&N===m?0:-1,T.textContent=String(L.getUTCDate()),T.dataset.date=N,T.dataset.uiCalendarDay="",T.setAttribute("aria-label",S.format(L)),T.setAttribute("aria-selected",String(b===N)),Y&&T.setAttribute("aria-disabled","true"),$(L)!==$(d)&&(T.dataset.outside="true"),N===u&&(T.dataset.today="true"),b===N&&(T.dataset.selected="true"),f.append(T)}M.append(f)}s.replaceChildren(D,M),t&&a.querySelector(`${Ge}[data-date="${m}"]`)?.focus({preventScroll:!0})},Ct=(a,e)=>{const t=a.querySelector(be);if(!t||a.dataset.disabled==="true")return;const n=I(a.dataset.uiCalendarMin),s=I(a.dataset.uiCalendarMax),r=ft(e,n,s);ne(a,r,n,s)||(t.value=q(r),a.dataset.uiCalendarValue=t.value,a.dataset.uiCalendarMonth=$(r),t.dispatchEvent(new Event("input",{bubbles:!0})),t.dispatchEvent(new Event("change",{bubbles:!0})),W(a,r,!0))},vt=(a,e)=>{const t=I(a.dataset.uiCalendarMin),n=I(a.dataset.uiCalendarMax),s=ft(e,t,n);a.dataset.uiCalendarMonth=$(s),W(a,s,!0)},bn=(a,e,t)=>{const n=(e.getUTCDay()+6)%7,s={ArrowDown:7,ArrowLeft:-1,ArrowRight:1,ArrowUp:-7,End:6-n,Home:-n};if(t==="PageDown"||t==="PageUp"){vt(a,ae(e,t==="PageDown"?1:-1));return}const r=s[t];r!==void 0&&vt(a,J(e,r))},pn=a=>{const e=U(a,he),t=F(a,he);e instanceof HTMLElement&&!t.includes(e)&&t.unshift(e);for(const n of t){if(n.dataset.uiBound==="true")continue;mn(n);const s=n.querySelector(be);s&&(n.dataset.uiBound="true",W(n),n.querySelector("[data-ui-calendar-prev]")?.addEventListener("click",()=>{const r=te(n.dataset.uiCalendarMonth);if(!r)return;const i=ae(r,-1);n.dataset.uiCalendarMonth=$(i),W(n,i,!0)}),n.querySelector("[data-ui-calendar-next]")?.addEventListener("click",()=>{const r=te(n.dataset.uiCalendarMonth);if(!r)return;const i=ae(r,1);n.dataset.uiCalendarMonth=$(i),W(n,i,!0)}),n.addEventListener("click",r=>{const i=r.target;if(!(i instanceof Element))return;const o=i.closest(Ge);if(!o||!n.contains(o)||o.getAttribute("aria-disabled")==="true")return;const l=I(o.dataset.date);l&&Ct(n,l)}),n.addEventListener("keydown",r=>{const i=r.target;if(!(i instanceof HTMLElement)||!i.hasAttribute("data-ui-calendar-day"))return;const o=I(i.dataset.date);if(o){if(r.key==="Enter"||r.key===" "){r.preventDefault(),Ct(n,o);return}r.key!=="ArrowDown"&&r.key!=="ArrowLeft"&&r.key!=="ArrowRight"&&r.key!=="ArrowUp"&&r.key!=="End"&&r.key!=="Home"&&r.key!=="PageDown"&&r.key!=="PageUp"||(r.preventDefault(),bn(n,o,r.key))}}),s.form?.addEventListener("reset",()=>{globalThis.setTimeout(()=>{n.dataset.uiCalendarValue=s.value,n.dataset.uiCalendarMonth=n.dataset.uiCalendarInitialMonth??n.dataset.uiCalendarMonth,W(n)})}))}},xt=(a=document)=>{pn(a)},gn=()=>{if(!x()||document.documentElement.dataset.uiElementsCalendarsBound==="true"||(document.documentElement.dataset.uiElementsCalendarsBound="true",xt(document),typeof MutationObserver>"u"))return;new MutationObserver(e=>{for(const t of e)for(const n of t.addedNodes)(n instanceof Element||n instanceof DocumentFragment)&&xt(n)}).observe(document.documentElement,{childList:!0,subtree:!0})},se=a=>{a.dataset.state==="open"&&(a.dataset.state="closed",a.hidden=!0)},Et=a=>{if(x())for(const e of document.querySelectorAll(`${He}[data-state="open"]`))e!==a&&se(e)},yt=(a,e,t)=>{Et(a),a.hidden=!1,a.style.position="fixed",a.style.zIndex="60",a.dataset.state="open";const n=a.getBoundingClientRect(),s=Math.max(8,Math.min(e,window.innerWidth-n.width-8)),r=Math.max(8,Math.min(t,window.innerHeight-n.height-8));a.style.left=`${s}px`,a.style.top=`${r}px`,H(a)[0]?.focus()},fn=a=>{for(const e of F(a,da)){if(e.dataset.uiContextMenuBound==="true")continue;const t=e.getAttribute("data-ui-context-menu-trigger"),n=t&&x()?document.getElementById(t):null;n instanceof HTMLElement&&(e.dataset.uiContextMenuBound="true",n.hidden=!0,n.dataset.state="closed",e.addEventListener("contextmenu",s=>{s.preventDefault(),yt(n,s.clientX,s.clientY)}),e.addEventListener("keydown",s=>{if(s.key!=="ContextMenu"&&!(s.shiftKey&&s.key==="F10"))return;s.preventDefault();const r=e.getBoundingClientRect();yt(n,r.left+16,r.top+16)}),n.dataset.uiContextMenuMenuBound!=="true"&&(n.dataset.uiContextMenuMenuBound="true",n.addEventListener("keydown",s=>{if(s.key==="Escape"){s.preventDefault(),se(n),e.focus({preventScroll:!0});return}if(!["ArrowDown","ArrowUp","End","Home"].includes(s.key))return;const r=H(n);if(r.length===0)return;s.preventDefault();const i=r.indexOf(document.activeElement);r[j(s.key,i,r.length,["ArrowDown"])]?.focus()}),n.addEventListener("click",s=>{s.target instanceof HTMLElement&&s.target.closest('[role="menuitem"]')&&se(n)})))}},At=(a=document)=>{fn(a)},Cn=()=>{if(!x()||document.documentElement.dataset.uiElementsContextMenusBound==="true"||(document.documentElement.dataset.uiElementsContextMenusBound="true",At(document),document.addEventListener("pointerdown",e=>{const t=z(e);if(t)for(const n of document.querySelectorAll(`${He}[data-state="open"]`))n.contains(t)||se(n)}),document.addEventListener("keydown",e=>{e.key==="Escape"&&Et()}),typeof MutationObserver>"u"))return;new MutationObserver(e=>{for(const t of e)for(const n of t.addedNodes)(n instanceof Element||n instanceof DocumentFragment)&&At(n)}).observe(document.documentElement,{childList:!0,subtree:!0})},St=a=>a?a.dataset.sortValue??a.textContent.trim():"",vn=(a,e,t)=>{const n=Number(a.replaceAll(",","")),s=Number(e.replaceAll(",",""));return t==="number"||t!=="string"&&a.trim()!==""&&e.trim()!==""&&Number.isFinite(n)&&Number.isFinite(s)?n-s:a.localeCompare(e,void 0,{numeric:!0,sensitivity:"base"})},Lt=a=>[...a.tBodies[0]?.rows??[]],kt=(a,e)=>a.dataset.value||a.id||String(e),xn=(a,e,t)=>a!==String(e)||t==="none"?"ascending":t==="ascending"?"descending":"none",En=a=>{const e=a.getAttribute("aria-controls");return e&&x()?document.getElementById(e):a.nextElementSibling instanceof HTMLElement?a.nextElementSibling:null},O=(a,e,t)=>{a.setAttribute("aria-expanded",String(t)),e.hidden=!t,e.dataset.state=t?"open":"closed"},yn=a=>a.key.length===1&&!a.altKey&&!a.ctrlKey&&!a.metaKey,An=a=>typeof CSS<"u"&&typeof CSS.escape=="function"?CSS.escape(a):a.replaceAll(/["#.:?[\\\]]/g,"\\$&"),Sn=a=>a==="top-left"||a==="top-center"||a==="top-right"||a==="bottom-left"||a==="bottom-center"||a==="bottom-right",Nt=a=>Sn(a)?a:"bottom-right",Ln=a=>a==="success"?"ui-toast--success":a==="warning"?"ui-toast--warning":a==="destructive"?"ui-toast--destructive":!1,re=(a,e)=>{a.classList.add("ui-sonner"),a.dataset.uiSonner="",a.dataset.placement=Nt(e??a.dataset.placement),a.setAttribute("aria-live",a.getAttribute("aria-live")??"polite"),a.setAttribute("aria-atomic",a.getAttribute("aria-atomic")??"false"),a.setAttribute("aria-label",a.getAttribute("aria-label")??"Notifications")},kn=a=>{if(!x())return null;const e=Nt(a),t=a===void 0,n=document.querySelector(`[data-ui-sonner][data-placement="${e}"]`)??(t?document.querySelector("[data-ui-sonner]"):null);if(n)return re(n,n.dataset.placement??e),n;const s=typeof customElements<"u"&&customElements.get("lumen-sonner")?"lumen-sonner":"div",r=document.createElement(s);return re(r,e),document.body.append(r),r},ye=a=>{const e=ge.get(a);e&&(e.timer&&globalThis.clearTimeout(e.timer),e.cleanup?.(),ge.delete(a))},G=a=>{ye(a),a.dataset.state="closed",globalThis.setTimeout(()=>{a.remove()},Sa)},Ae=(a,e)=>{if(ye(a),!Number.isFinite(e)||e<=0)return;const t={cleanup:void 0,remaining:e,startedAt:Date.now(),timer:void 0},n=()=>{t.startedAt=Date.now(),t.timer=globalThis.setTimeout(()=>{G(a)},t.remaining)},s=()=>{t.timer&&globalThis.clearTimeout(t.timer),t.remaining=Math.max(0,t.remaining-(Date.now()-t.startedAt))},r=()=>{t.remaining>0&&n()};t.cleanup=()=>{a.removeEventListener("mouseenter",s),a.removeEventListener("mouseleave",r),a.removeEventListener("focusin",s),a.removeEventListener("focusout",r)},a.addEventListener("mouseenter",s),a.addEventListener("mouseleave",r),a.addEventListener("focusin",s),a.addEventListener("focusout",r),ge.set(a,t),n()},Se=(a,e)=>{const t=e.title??a.dataset.title??"Notification",n=e.description??a.dataset.description??"",s=e.variant??a.dataset.variant??"default",r=Ln(s);a.className=r?`ui-toast ${r}`:"ui-toast",a.dataset.uiToast="",a.dataset.variant=s,a.dataset.title=t,a.dataset.description=n,a.setAttribute("variant",s),a.setAttribute("role",s==="destructive"?"alert":"status"),a.setAttribute("aria-live",s==="destructive"?"assertive":"polite"),a.replaceChildren();const i=document.createElement("div"),o=document.createElement("strong");if(i.className="ui-toast__body",o.textContent=t,i.append(o),n){const u=document.createElement("p");u.textContent=n,i.append(u)}if(a.append(i),e.action?.label){const u=document.createElement("button");u.className="ui-button ui-button--secondary ui-button--sm ui-toast__action",u.type="button",u.textContent=e.action.label,u.addEventListener("click",h=>{e.action?.onClick?.(h,a),a.dispatchEvent(new CustomEvent(e.action?.event??"ui:toast-action",{bubbles:!0,detail:{id:a.id,value:e.action?.value}})),G(a)}),a.append(u)}const l=document.createElement("button");l.className="ui-toast__dismiss",l.type="button",l.setAttribute("aria-label","Dismiss notification"),l.textContent="Dismiss",l.addEventListener("click",()=>{G(a)}),a.append(l)},ie={create(a){const e=kn(a.placement);if(!e)return a.id??R("ui-toast");const t=a.id??R("ui-toast"),n=a.duration??ya,s=a.max??Number(e.dataset.uiToastMax??Aa),r=document.getElementById(t);if(r instanceof HTMLElement&&r.hasAttribute("data-ui-toast"))return r.dataset.state="open",Se(r,a),e.append(r),Ae(r,n),t;const i=typeof customElements<"u"&&customElements.get("lumen-toast")?"lumen-toast":"aside",o=document.createElement(i);o.id=t,o.dataset.state="open",o.addEventListener("keydown",u=>{u.key==="Escape"&&(u.preventDefault(),G(o))}),Se(o,a),e.append(o),Ae(o,n);const l=[...e.querySelectorAll("[data-ui-toast]")];for(const u of l.slice(0,Math.max(0,l.length-s)))G(u);return t},dismiss(a){if(!x())return;const e=a?`#${An(a)}`:"[data-ui-toast]";for(const t of document.querySelectorAll(e))t.hasAttribute("data-ui-toast")&&G(t)},update(a,e){if(!x())return;const t=document.getElementById(a);!(t instanceof HTMLElement)||!t.hasAttribute("data-ui-toast")||(Se(t,{...e,id:a}),e.duration!==void 0&&Ae(t,e.duration))}},wt=()=>{if(!(!x()||document.documentElement.dataset.uiElementsToastsBound==="true")){document.documentElement.dataset.uiElementsToastsBound="true",globalThis.LumenToast=ie;for(const a of document.querySelectorAll("[data-ui-sonner]"))re(a);document.addEventListener("ui:toast",a=>{ie.create(a instanceof CustomEvent?a.detail:{})}),document.addEventListener("ui:toast-update",a=>{const e=a instanceof CustomEvent?a.detail:{};e.id&&ie.update(e.id,e)}),document.addEventListener("ui:toast-dismiss",a=>{const e=a instanceof CustomEvent?a.detail:{};ie.dismiss(e.id)})}};class C extends HTMLElement{static config;static get observedAttributes(){return ka}connectedCallback(){this.applyDefaults(),this.applyClassNames()}disconnectedCallback(){}attributeChangedCallback(e,t,n){this.applyClassNames()}get config(){return this.constructor.config}applyDefaults(){for(const[e,t]of Object.entries(this.config.defaults??{}))this.hasAttribute(e)||this.setAttribute(e,t);this.config.role&&!this.hasAttribute("role")&&this.setAttribute("role",this.config.role)}applyClassNames(){const e=Fe.get(this)??[];for(const n of e)this.classList.remove(n);const t=Ye(this.config.baseClassName);for(const[n,s]of Object.entries(this.config.attributeClasses??{})){const r=this.hasAttribute(n)?this.getAttribute(n)||"true":this.config.defaults?.[n],i=r?s[r]:void 0;i&&t.push(...Ye(i))}this.classList.add(...t),Fe.set(this,t)}}const Nn=["accept","aria-describedby","aria-label","aria-labelledby","autocomplete","disabled","form","inputmode","max","maxlength","min","minlength","multiple","pattern","placeholder","readonly","required","rows","step"],wn=a=>({badInput:a.badInput,customError:a.customError,patternMismatch:a.patternMismatch,rangeOverflow:a.rangeOverflow,rangeUnderflow:a.rangeUnderflow,stepMismatch:a.stepMismatch,tooLong:a.tooLong,tooShort:a.tooShort,typeMismatch:a.typeMismatch,valueMissing:a.valueMissing});class _ extends C{static formAssociated=!0;static nativeTagName="input";control;defaultCheckedState=!1;defaultValueState="";eventController;internals;constructor(){if(super(),typeof this.attachInternals=="function"){const e=this.attachInternals();typeof e.setFormValue=="function"&&typeof e.setValidity=="function"&&(this.internals=e)}}get checked(){return this.control instanceof HTMLInputElement&&this.control.checked}set checked(e){this.control instanceof HTMLInputElement&&(this.control.checked=e,this.syncFormState()),this.toggleAttribute("checked",e)}get defaultChecked(){return this.defaultCheckedState}set defaultChecked(e){this.defaultCheckedState=e,this.toggleAttribute("checked",e)}get defaultValue(){return this.defaultValueState}set defaultValue(e){this.defaultValueState=e,this.setAttribute("value",e)}get disabled(){return this.hasAttribute("disabled")}set disabled(e){this.toggleAttribute("disabled",e)}get form(){return this.internals?.form??this.control?.form??null}get labels(){return this.internals?.labels??null}get name(){return this.getAttribute("name")??""}set name(e){this.setAttribute("name",e)}get type(){return this.control instanceof HTMLInputElement?this.control.type:"textarea"}get validationMessage(){return this.internals?.validationMessage??this.control?.validationMessage??""}get validity(){return this.internals?.validity??this.control?.validity??{}}get value(){return this.control?.value??this.getAttribute("value")??""}set value(e){if(this.control){this.control.value=e,this.syncFormState();return}this.setAttribute("value",e)}get willValidate(){return this.internals?.willValidate??this.control?.willValidate??!1}connectedCallback(){super.connectedCallback(),x()&&(this.defaultValueState=this.getAttribute("value")??this.textContent,this.defaultCheckedState=this.hasAttribute("checked"),this.ensureControl(),this.syncControlAttributes(),this.syncFormState())}disconnectedCallback(){this.eventController?.abort(),this.eventController=void 0}attributeChangedCallback(e,t,n){super.attributeChangedCallback(),!(t===n||!this.control)&&(this.syncControlAttributes(),e==="value"&&(this.defaultValueState=n??"",this.control.value=this.defaultValueState),e==="checked"&&this.control instanceof HTMLInputElement&&(this.defaultCheckedState=n!==null,this.control.checked=this.defaultCheckedState),this.syncFormState())}checkValidity(){const e=this.control?.checkValidity()??!0;return this.syncFormState(),e}focus(e){this.control?.focus(e)}formDisabledCallback(e){this.control&&(this.control.disabled=e||this.disabled)}formResetCallback(){this.control&&(this.control.value=this.defaultValueState,this.control instanceof HTMLInputElement&&(this.control.checked=this.defaultCheckedState),this.syncFormState())}formStateRestoreCallback(e){typeof e=="string"&&(this.value=e)}reportValidity(){const e=this.control?.reportValidity()??!0;return this.syncFormState(),e}setCustomValidity(e){this.control?.setCustomValidity(e),this.syncFormState()}ensureControl(){const e=this.querySelector("[data-ui-element-control]");if(e){this.control=e;return}const t=this.constructor,n=document.createElement(t.nativeTagName);n.dataset.uiElementControl="",n.className=this.className,n.defaultValue=this.defaultValueState,n.value=this.defaultValueState,n instanceof HTMLInputElement&&(n.defaultChecked=this.defaultCheckedState,n.checked=this.defaultCheckedState),this.style.display="contents",this.replaceChildren(n),this.control=n,this.eventController?.abort(),this.eventController=new AbortController;for(const s of["change","input"])n.addEventListener(s,r=>{r.stopPropagation(),this.syncFormState(),this.dispatchEvent(new Event(s,{bubbles:!0,composed:!0}))},{signal:this.eventController.signal})}syncControlAttributes(){const e=this.control;if(e){e.className=this.className;for(const t of Nn){const n=this.getAttribute(t);n===null||t==="form"&&this.internals?e.removeAttribute(t):e.setAttribute(t,n)}e instanceof HTMLInputElement&&(e.type=this.getAttribute("type")??this.config.defaults?.type??"text"),this.id&&(e.id=`${this.id}-control`),this.internals?e.removeAttribute("name"):this.name?e.name=this.name:e.removeAttribute("name")}}syncFormState(){const e=this.control;if(!e)return;const n=e instanceof HTMLInputElement&&["checkbox","radio"].includes(e.type)&&!e.checked?null:e.value;this.internals&&(this.internals.setFormValue(n,e.value),e.validity.valid?this.internals.setValidity({}):this.internals.setValidity(wn(e.validity),e.validationMessage,e)),e.validity.valid?this.removeAttribute("aria-invalid"):this.setAttribute("aria-invalid","true")}}class Tn extends _{static nativeTagName="textarea"}class Dn extends C{connectedCallback(){super.connectedCallback(),x()&&Qe(this)}}class Mn extends C{connectedCallback(){super.connectedCallback(),x()&&tt(this)}}const k=a=>String(a).replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&#39;"),P=(a,e,t)=>a.hasAttribute(e)?a.getAttribute(e)!=="false":t,In=a=>{if(!a)return[];try{const e=JSON.parse(a);return Array.isArray(e)?e.flatMap((t,n)=>{if(typeof t!="object"||t===null)return[];const s=t;if(!Array.isArray(s.data))return[];const i=s.data.flatMap(l=>{if(typeof l!="object"||l===null||!("x"in l)||!("y"in l))return[];const u=l;return typeof u.x!="string"&&typeof u.x!="number"||u.y!==null&&(typeof u.y!="number"||!Number.isFinite(u.y))?[]:[{...typeof u.label=="string"?{label:u.label}:{},...typeof u.tone=="string"&&ce.includes(u.tone)?{tone:u.tone}:{},x:u.x,y:u.y}]}),o=typeof s.tone=="string"&&ce.includes(s.tone)?s.tone:void 0;return[{data:i,id:typeof s.id=="string"?s.id:`series-${n+1}`,label:typeof s.label=="string"?s.label:`Series ${n+1}`,...o?{tone:o}:{}}]}):[]}catch{return[]}},oe=a=>{const e=a.getAttribute("heading"),t=a.getAttribute("description"),n=a.getAttribute("value");return!e&&!t&&!n?"":`<header><div class="ui-chart__heading">${e?`<h3>${k(e)}</h3>`:""}${t?`<p>${k(t)}</p>`:""}</div>${n?`<strong data-ui-chart-value>${k(n)}</strong>`:""}</header>`},le=a=>{const e=a.getAttribute("caption");return e?`<figcaption>${k(e)}</figcaption>`:""},Tt=a=>`<ul class="ui-chart__legend" aria-label="Chart legend">${a.map((e,t)=>`<li class="ui-chart-tone--${de(e.tone,t)}"><span aria-hidden="true"></span>${k(e.label)}</li>`).join("")}</ul>`,Dt=(a,e,t=String,n=String)=>{const s=e.map(i=>`<th scope="col">${k(i.label)}</th>`).join(""),r=a.map(i=>{const o=e.map(u=>{const h=u.data.find(g=>g.x===i),d=h?.label??(h?.y===null||h===void 0?"Not available":n(h.y));return`<td>${k(d)}</td>`}).join(""),l=e.flatMap(u=>u.data).find(u=>u.x===i)?.xLabel??t(i);return`<tr><th scope="row">${k(l)}</th>${o}</tr>`}).join("");return['<details class="ui-chart__data"><summary>View chart data</summary>','<div><table><thead><tr><th scope="col">Category</th>',`${s}</tr></thead><tbody>${r}</tbody></table></div></details>`].join("")},Mt=a=>new Intl.NumberFormat(void 0,{maximumFractionDigits:a<.01?1:0,style:"percent"}).format(a),Le=(a,e)=>[oe(a),`<p class="ui-chart__empty" role="status">${k(e)}</p>`,le(a)].join("");class ke extends C{#e;#t;#a;get categoryFormatter(){return this.#e??String}set categoryFormatter(e){this.#e=e,this.renderChart()}get series(){return this.#t??In(this.getAttribute("series"))}set series(e){this.#t=e,this.renderChart()}get valueFormatter(){return this.#a??String}set valueFormatter(e){this.#a=e,this.renderChart()}connectedCallback(){super.connectedCallback(),this.renderChart()}attributeChangedCallback(){super.attributeChangedCallback(),this.isConnected&&this.renderChart()}}class Bn extends C{#e;#t;get values(){if(this.#t)return this.#t;const e=this.getAttribute("values");if(!e)return[];try{const t=JSON.parse(e);if(Array.isArray(t))return t.filter(n=>typeof n=="number"&&Number.isFinite(n))}catch{return e.split(",").map(t=>Number(t.trim())).filter(Number.isFinite)}return[]}set values(e){this.#t=e,this.renderSparkline()}connectedCallback(){super.connectedCallback(),this.renderSparkline()}attributeChangedCallback(){super.attributeChangedCallback(),this.isConnected&&this.renderSparkline()}renderSparkline(){const e=this.values;if(e.length===0){const u=this.getAttribute("label")??"No trend data available.";this.setAttribute("aria-label",u),this.setAttribute("role","img"),this.innerHTML=`<span class="ui-sr-only">${k(u)}</span>`;return}const t=this.getAttribute("label")??"Trend",n=this.getAttribute("tone"),s=de(n&&ce.includes(n)?n:void 0),r=Te(e.map((u,h)=>({x:h,y:u})),{height:40,padding:3,width:120}),i=P(this,"area",!1),o=P(this,"show-endpoint",!0),l=r.points.at(-1);this.#e&&this.classList.remove(this.#e),this.#e=`ui-chart-tone--${s}`,this.classList.add(this.#e),this.setAttribute("aria-label",t),this.setAttribute("role","img"),this.innerHTML=`<svg aria-hidden="true" preserveAspectRatio="none" viewBox="0 0 120 40">${i?r.areaPaths.map(u=>`<path class="ui-sparkline__area" d="${u}"></path>`).join(""):""}<path class="ui-sparkline__line" d="${r.path}"></path>${o&&l?`<circle class="ui-sparkline__endpoint" cx="${l.xCoordinate}" cy="${l.yCoordinate}" r="2.5"></circle>`:""}</svg><span class="ui-sr-only">${k(t)}</span>`}}class Fn extends ke{renderChart(){const e=this.series;if(!Me(e)){const p=this.getAttribute("empty-label")??"No chart data available.";this.innerHTML=Le(this,p);return}const t=this.getAttribute("orientation")==="horizontal"?"horizontal":"vertical",n=this.getAttribute("layout")==="stacked"?"stacked":"grouped",s=Number(this.getAttribute("category-width")),r=Number.isFinite(s)&&s>0?s:void 0,i=zt(e,{...r===void 0?{}:{categoryWidth:r},layout:n,orientation:t}),o=De(i.domain),l=t==="horizontal"?{bottom:24,left:Math.max(64,Math.min(240,r??112)),right:20,top:16}:{bottom:52,left:52,right:16,top:16},u=o.map(p=>{const S=t==="horizontal"?ee(p,i.domain,l.left,i.width-l.right):ee(p,i.domain,i.height-l.bottom,l.top);return t==="horizontal"?[`<line x1="${S}" x2="${S}" y1="${l.top}"`,` y2="${i.height-l.bottom}"></line>`].join(""):[`<line x1="${l.left}" x2="${i.width-l.right}"`,` y1="${S}" y2="${S}"></line>`].join("")}).join(""),h=i.categories.map(p=>[`<text dominant-baseline="${t==="horizontal"?"middle":"auto"}" text-anchor="${t==="horizontal"?"end":"middle"}"`,` x="${p.x}" y="${p.y}">`,`${k(p.label)}</text>`].join("")).join(""),d=i.marks.map(p=>{const D=`${e.flatMap(w=>w.data).find(w=>w.x===p.category)?.xLabel??this.categoryFormatter(p.category)} \xB7 ${p.seriesLabel}: ${this.valueFormatter(p.value)}`;return[`<rect class="ui-chart-tone--${p.tone}" height="${p.height}"`,` rx="4" width="${p.width}" x="${p.x}" y="${p.y}">`,`<title>${k(D)}</title></rect>`].join("")}).join(""),g=P(this,"show-legend",e.length>1),m=P(this,"show-table",!0),b=i.categories.map(p=>p.category);this.innerHTML=`${oe(this)}${g?Tt(e):""}<div class="ui-chart__plot"><svg aria-hidden="true" preserveAspectRatio="xMidYMid meet" viewBox="0 0 ${i.width} ${i.height}"><g class="ui-chart__grid">${u}</g><g class="ui-chart__axis-labels">${h}</g><g class="ui-bar-chart__marks">${d}</g></svg></div>${m?Dt(b,e,this.categoryFormatter,this.valueFormatter):""}${le(this)}`}}class $n extends ke{renderChart(){const e=this.series;if(!Me(e)){const L=this.getAttribute("empty-label")??"No chart data available.";this.innerHTML=Le(this,L);return}const t=640,n=320,s=44,r=Yt(e),i=e.map(L=>Ht(L,r)),o=this.getAttribute("reference-value"),l=o===null?void 0:Number(o),u=l!==void 0&&Number.isFinite(l)?l:void 0,h=Kt([...i.flatMap(L=>L.data.map(N=>N.y)),u??null],!1),d=i.map(L=>Te(L.data,{domain:h,height:n,includeZero:!1,padding:s,width:t})),g=De(h),m=Math.max(1,Math.ceil(r.length/8)),b=g.map(L=>{const N=ee(L,h,n-s,s);return[`<line x1="${s}" x2="${t-s}" y1="${N}" y2="${N}"></line>`,`<text x="${s-8}" y="${N}">`,`${k(this.valueFormatter(L))}</text>`].join("")}).join(""),p=r.map((L,N)=>{if(N%m!==0&&N!==r.length-1)return"";const T=Math.max(1,r.length-1),Y=s+N/T*(t-s*2),ue=e.flatMap(Z=>Z.data).find(Z=>Z.x===L)?.xLabel??this.categoryFormatter(L);return`<text text-anchor="middle" x="${Y}" y="${n-14}">${k(ue)}</text>`}).join(""),S=P(this,"area",!1),y=this.getAttribute("markers")??"auto",D=Number(y);let w=1;y==="false"||y==="none"?w=Number.POSITIVE_INFINITY:Number.isFinite(D)&&D>0?w=Math.max(1,Math.round(D)):y==="auto"&&(w=Math.max(1,Math.ceil(r.length/24)));const M=d.map((L,N)=>{const T=e[N];if(!T)return"";const Y=de(T.tone,N),ue=S?L.areaPaths.map(V=>`<path class="ui-line-chart__area" d="${V}"></path>`).join(""):"",Z=Number.isFinite(w)?L.points.map((V,Pt)=>{if(Pt%w!==0)return"";const Rt=`${V.xLabel??this.categoryFormatter(V.x)} \xB7 ${T.label}: ${this.valueFormatter(V.y??0)}`;return[`<circle class="ui-line-chart__point" cx="${V.xCoordinate}"`,` cy="${V.yCoordinate}" r="3">`,`<title>${k(Rt)}</title></circle>`].join("")}).join(""):"";return[`<g class="ui-line-chart__series ui-chart-tone--${Y}">${ue}`,`<path class="ui-line-chart__line" d="${L.path}"></path>`,`${Z}</g>`].join("")}).join(""),v=u===void 0?void 0:ee(u,h,n-s,s),E=v===void 0?"":[`<line class="ui-chart__reference" x1="${s}" x2="${t-s}"`,` y1="${v}" y2="${v}"></line>`].join(""),f=P(this,"show-legend",e.length>1),B=P(this,"show-table",!0);this.innerHTML=[oe(this),f?Tt(e):"",'<div class="ui-chart__plot"><svg aria-hidden="true"',` preserveAspectRatio="xMidYMid meet" viewBox="0 0 ${t} ${n}">`,`<g class="ui-chart__grid">${b}</g>`,`<g class="ui-chart__axis-labels">${p}</g>`,`${E}${M}</svg></div>`,B?Dt(r,e,this.categoryFormatter,this.valueFormatter):"",le(this)].join("")}}class qn extends ke{renderChart(){const e=this.series[0];if(!e||!Xt(e.data)){this.innerHTML=Le(this,"No chart data available.");return}const t=this.getAttribute("variant")==="pie"?"pie":"donut",n=Ut(e.data,{variant:t}),s=P(this,"show-legend",!0),r=P(this,"show-table",!0),i=n.slices.map(m=>[`<li class="ui-chart-tone--${m.tone}"><span aria-hidden="true"></span>`,`${k(m.label)}</li>`].join("")).join(""),o=s?`<ul class="ui-chart__legend" aria-label="Chart legend">${i}</ul>`:"",l=n.slices.map(m=>{const b=[`${m.label}: ${this.valueFormatter(m.value)}`,`(${Mt(m.percentage)})`].join(" ");return[`<path class="ui-chart-tone--${m.tone}" d="${m.path}"`,` fill-rule="evenodd"><title>${k(b)}</title></path>`].join("")}).join(""),u=this.getAttribute("center-label"),h=this.getAttribute("center-value"),d=t==="donut"&&(u||h)?`<div class="ui-pie-chart__center" aria-hidden="true">${h?`<strong>${k(h)}</strong>`:""}${u?`<span>${k(u)}</span>`:""}</div>`:"",g=r?this.pieDataTable(n.slices):"";this.innerHTML=[oe(this),o,'<div class="ui-chart__plot ui-pie-chart__plot">','<svg aria-hidden="true" preserveAspectRatio="xMidYMid meet"',` viewBox="0 0 ${n.size} ${n.size}">`,`<g class="ui-pie-chart__slices">${l}</g></svg>${d}</div>`,g,le(this)].join("")}pieDataTable(e){return['<details class="ui-chart__data"><summary>View chart data</summary>','<div><table><thead><tr><th scope="col">Category</th>','<th scope="col">Value</th><th scope="col">Share</th></tr></thead>',`<tbody>${e.map(n=>[`<tr><th scope="row">${k(n.label)}</th>`,`<td>${k(this.valueFormatter(n.value))}</td>`,`<td>${k(Mt(n.percentage))}</td></tr>`].join("")).join("")}</tbody></table></div></details>`].join("")}}class _n extends C{connectedCallback(){super.connectedCallback(),this.renderIcon()}attributeChangedCallback(){super.attributeChangedCallback(),this.renderIcon()}renderIcon(){const e=this.getAttribute("name"),t=this.getAttribute("label")??this.getAttribute("aria-label"),n=this.hasAttribute("decorative")||!t;if(e){const s=ta(e);s!==this.innerHTML&&(this.innerHTML=s)}n?(this.setAttribute("aria-hidden","true"),this.removeAttribute("aria-label"),this.removeAttribute("role")):(this.removeAttribute("aria-hidden"),this.setAttribute("aria-label",t),this.setAttribute("role","img"))}}class It extends C{abortController;lastTrigger;connectedCallback(){super.connectedCallback(),x()&&(this.abortController?.abort(),this.abortController=new AbortController,this.setupDialog(this.abortController.signal))}disconnectedCallback(){this.abortController?.abort(),this.abortController=void 0}show(e){this.openDialog(e)}close(){this.closeDialog()}get isAlertDialog(){return this.hasAttribute("data-ui-alert-dialog")||this.tagName.toLowerCase()==="lumen-alert-dialog"}get nativeDialog(){const e=this.querySelector("dialog");return e instanceof HTMLDialogElement?e:null}get dialogRoot(){return this.nativeDialog??this}setupDialog(e){const t=this.dialogRoot,n=this.hasAttribute("open")||this.nativeDialog?.open===!0;t.setAttribute("aria-modal","true"),t.setAttribute("role",this.isAlertDialog?"alertdialog":"dialog"),this.nativeDialog||(this.hidden=!n,this.dataset.state=n?"open":"closed"),this.nativeDialog?.addEventListener("click",s=>{s.target===this.nativeDialog&&!this.isAlertDialog&&this.closeDialog()},{signal:e}),this.nativeDialog?.addEventListener("close",()=>{this.returnFocus()},{signal:e}),this.addEventListener("click",s=>{const r=z(s);r instanceof Element&&r.closest("[data-ui-dialog-close], [data-ui-alert-dialog-close]")&&this.closeDialog()},{signal:e}),this.addEventListener("keydown",s=>{if(s.key==="Escape"){s.preventDefault(),this.closeDialog();return}s.key==="Tab"&&this.trapFocus(s)},{signal:e}),document.addEventListener("click",s=>{const r=z(s),i=r instanceof Element?r.closest("[data-ui-dialog-trigger], [data-ui-alert-dialog-trigger]"):null,o=i?.dataset.uiDialogTrigger??i?.dataset.uiAlertDialogTrigger;!i||o!==this.id||this.openDialog(i)},{signal:e}),document.addEventListener("pointerdown",s=>{if(!this.isOpen()||this.isAlertDialog)return;const r=z(s);!r||this.contains(r)||this.closeDialog()},{signal:e})}isOpen(){return this.nativeDialog?.open===!0||this.hasAttribute("open")||this.dataset.state==="open"}openDialog(e){e&&(e.id||(e.id=R("ui-trigger")),this.lastTrigger=e);const t=this.nativeDialog;t?typeof t.showModal=="function"&&!t.open?t.showModal():t.setAttribute("open",""):(this.hidden=!1,this.setAttribute("open",""),this.dataset.state="open"),H(this.dialogRoot)[0]?.focus({preventScroll:!0})}closeDialog(){const e=this.nativeDialog;if(e?.open){e.close();return}e||(this.hidden=!0,this.removeAttribute("open"),this.dataset.state="closed",this.returnFocus())}returnFocus(){this.lastTrigger?.focus({preventScroll:!0})}trapFocus(e){const t=H(this.dialogRoot);if(!t.length)return;const n=t[0],s=t.at(-1);if(!(!n||!s)){if(e.shiftKey&&document.activeElement===n){e.preventDefault(),s.focus();return}!e.shiftKey&&document.activeElement===s&&(e.preventDefault(),n.focus())}}}class Bt extends C{abortController;connectedCallback(){super.connectedCallback(),x()&&(this.abortController?.abort(),this.abortController=new AbortController,this.setupDisclosure(this.abortController.signal))}disconnectedCallback(){this.abortController?.abort(),this.abortController=void 0}setupDisclosure(e){const t=this.querySelector("[data-ui-trigger]");if(!t)return;const n=En(t);if(!n)return;t.setAttribute("aria-haspopup",t.getAttribute("aria-haspopup")??"menu"),O(t,n,t.getAttribute("aria-expanded")==="true");const s=()=>{O(t,n,!1)},r=()=>{O(t,n,!0)};t.addEventListener("click",()=>{O(t,n,t.getAttribute("aria-expanded")!=="true")},{signal:e}),t.addEventListener("keydown",i=>{i.key!=="ArrowDown"&&i.key!=="Enter"&&i.key!==" "||(i.preventDefault(),r(),H(n)[0]?.focus())},{signal:e}),n.addEventListener("keydown",i=>{if(i.key==="Escape"){i.preventDefault(),s(),t.focus({preventScroll:!0});return}if(!["ArrowDown","ArrowUp","Home","End"].includes(i.key))return;const l=H(n);if(!l.length)return;i.preventDefault();const u=l.indexOf(document.activeElement);l[j(i.key,Math.max(0,u),l.length,["ArrowDown"])]?.focus()},{signal:e}),document.addEventListener("pointerdown",i=>{if(t.getAttribute("aria-expanded")!=="true")return;const o=z(i);!o||this.contains(o)||n.contains(o)||s()},{signal:e})}}class Ft extends C{abortController;connectedCallback(){super.connectedCallback(),x()&&(this.abortController?.abort(),this.abortController=new AbortController,this.setupTabs(this.abortController.signal))}disconnectedCallback(){this.abortController?.abort(),this.abortController=void 0}setupTabs(e){const t=[...this.querySelectorAll('[role="tab"]')],n=[...this.querySelectorAll('[role="tabpanel"]')];if(!t.length||!n.length)return;const s=r=>{for(const i of t){const o=i===r,l=i.getAttribute("aria-controls"),u=l?document.getElementById(l):null;i.setAttribute("aria-selected",String(o)),i.tabIndex=o?0:-1,u&&(u.hidden=!o)}};s(t.find(r=>r.getAttribute("aria-selected")==="true")??t[0]);for(const r of t)r.addEventListener("click",()=>{s(r)},{signal:e}),r.addEventListener("keydown",i=>{if(!["ArrowLeft","ArrowRight","Home","End"].includes(i.key))return;i.preventDefault();const l=t.indexOf(r),u=t[j(i.key,Math.max(0,l),t.length,["ArrowRight"])];u&&(s(u),u.focus())},{signal:e})}}class Pn extends C{abortController;typeahead="";typeaheadTimer;connectedCallback(){super.connectedCallback(),x()&&(this.dataset.uiSelect="",this.abortController?.abort(),this.abortController=new AbortController,this.setupSelect(this.abortController.signal))}disconnectedCallback(){this.abortController?.abort(),this.abortController=void 0,this.typeaheadTimer&&(globalThis.clearTimeout(this.typeaheadTimer),this.typeaheadTimer=void 0)}setupSelect(e){const t=this.ensureNativeSelect(),n=this.ensureControl(t),s=n.querySelector("[data-ui-select-trigger]"),r=n.querySelector("[data-ui-select-list]");if(!(!s||!r)){this.renderOptions(t,r),n.hidden=!1,t.dataset.uiEnhanced="true",t.dataset.uiSelectNative="",t.tabIndex=-1,t.setAttribute("aria-hidden","true"),s.disabled=t.disabled,s.setAttribute("aria-haspopup","listbox"),s.setAttribute("role","combobox");for(const i of["aria-label","aria-labelledby","aria-describedby","aria-invalid"]){const o=t.getAttribute(i);o&&s.setAttribute(i,o)}if(t.required&&s.setAttribute("aria-required","true"),!s.hasAttribute("aria-label")&&!s.hasAttribute("aria-labelledby")){const i=[...t.labels].find(o=>o.textContent.trim());i?.textContent&&s.setAttribute("aria-label",i.textContent.trim())}for(const i of t.labels)i.addEventListener("click",o=>{o.preventDefault(),s.focus({preventScroll:!0})},{signal:e});this.syncValue(t,s),this.closeSelect(s,r),s.addEventListener("click",()=>{s.getAttribute("aria-expanded")==="true"?this.closeSelect(s,r):this.openSelect(s,r)},{signal:e}),s.addEventListener("keydown",i=>{if(this.handleTypeahead(i))return;if(i.key==="Escape"){this.closeSelect(s,r);return}if(["ArrowDown","ArrowUp","Home","End","Enter"," "].includes(i.key)){if(i.preventDefault(),this.openSelect(s,r),i.key==="Enter"||i.key===" "){(this.getSelectedItem()??this.getEnabledItems()[0])?.focus();return}this.focusOption(i.key)}},{signal:e}),t.addEventListener("change",()=>{this.syncValue(t,s)},{signal:e}),t.form?.addEventListener("reset",()=>{globalThis.setTimeout(()=>{this.syncValue(t,s)})},{signal:e});for(const i of this.getItems())i.tabIndex=-1,i.addEventListener("click",()=>{this.selectOption(t,s,r,i)},{signal:e}),i.addEventListener("keydown",o=>{if(this.handleTypeahead(o,i))return;if(o.key==="Escape"){this.closeSelect(s,r),s.focus({preventScroll:!0});return}if(o.key==="Enter"||o.key===" "){o.preventDefault(),this.selectOption(t,s,r,i);return}["ArrowDown","ArrowUp","Home","End"].includes(o.key)&&(o.preventDefault(),this.focusOption(o.key,i))},{signal:e});document.addEventListener("pointerdown",i=>{if(s.getAttribute("aria-expanded")!=="true")return;const o=z(i);!o||this.contains(o)||this.closeSelect(s,r)},{signal:e})}}ensureNativeSelect(){const e=this.querySelector("[data-ui-select-native], select");if(e)return e;const t=document.createElement("select"),n=[...this.children].filter(s=>s instanceof HTMLOptionElement);t.className="ui-select ui-select__native",t.dataset.uiSelectNative="";for(const s of["id","name","required","disabled","value"]){const r=this.getAttribute(s);r!==null&&t.setAttribute(s,r)}for(const s of n)t.append(s);return this.prepend(t),t}ensureControl(e){const t=this.querySelector("[data-ui-select-control]");if(t)return t;const n=document.createElement("div"),s=document.createElement("button"),r=document.createElement("span"),i=document.createElement("div"),o=e.id||R("ui-select");return e.id=o,n.className="ui-select__control",n.dataset.uiSelectControl="",n.hidden=!0,s.className="ui-select ui-select__trigger",s.dataset.uiSelectTrigger="",s.id=`${o}-trigger`,s.type="button",s.setAttribute("aria-controls",`${o}-listbox`),s.setAttribute("aria-expanded","false"),s.setAttribute("aria-haspopup","listbox"),r.dataset.uiSelectValue="",i.className="ui-select__list",i.dataset.uiSelectList="",i.dataset.state="closed",i.hidden=!0,i.id=`${o}-listbox`,i.setAttribute("role","listbox"),s.append(r),n.append(s,i),e.after(n),n}renderOptions(e,t){const n=[...e.options].filter(s=>!s.hasAttribute("data-ui-select-placeholder")).map(s=>{const r=document.createElement("button");return r.type="button",r.setAttribute("role","option"),r.dataset.uiSelectOption="",r.dataset.value=s.value,r.textContent=s.label,s.disabled&&(r.disabled=!0,r.setAttribute("aria-disabled","true")),r});t.replaceChildren(...n)}syncValue(e,t){const n=this.querySelector("[data-ui-select-value]");if(!n)return;const s=e.selectedOptions[0],r=e.querySelector("[data-ui-select-placeholder]"),i=!!(s&&!s.hasAttribute("data-ui-select-placeholder")),o=i&&s?s.label:"";n.textContent=i?o:r?.textContent.trim()||"Select an option",this.dataset.placeholder=i?"false":"true",t.setAttribute("aria-expanded",t.getAttribute("aria-expanded")??"false");for(const l of this.getItems())l.setAttribute("aria-selected",String(i&&l.dataset.value===e.value))}openSelect(e,t){e.setAttribute("aria-expanded","true"),t.hidden=!1,t.dataset.state="open"}closeSelect(e,t){e.setAttribute("aria-expanded","false"),t.hidden=!0,t.dataset.state="closed"}getItems(){return[...this.querySelectorAll(Ea)]}getEnabledItems(){return this.getItems().filter(e=>!e.hasAttribute("disabled")&&e.getAttribute("aria-disabled")!=="true")}getSelectedItem(){return this.getEnabledItems().find(e=>e.getAttribute("aria-selected")==="true")}selectOption(e,t,n,s){s.hasAttribute("disabled")||s.getAttribute("aria-disabled")==="true"||(e.value=s.dataset.value??"",e.dispatchEvent(new Event("input",{bubbles:!0})),e.dispatchEvent(new Event("change",{bubbles:!0})),this.syncValue(e,t),this.closeSelect(t,n),t.focus({preventScroll:!0}))}focusOption(e,t){const n=this.getEnabledItems();if(!n.length)return;const s=t??this.getSelectedItem()??n[0];if(!s)return;const r=n.indexOf(s);n[j(e,Math.max(0,r),n.length,["ArrowDown"])]?.focus()}handleTypeahead(e,t){if(!yn(e))return!1;e.preventDefault(),this.typeahead+=e.key.toLowerCase(),this.typeaheadTimer&&globalThis.clearTimeout(this.typeaheadTimer),this.typeaheadTimer=globalThis.setTimeout(()=>{this.typeahead=""},700);const n=this.querySelector("[data-ui-select-trigger]"),s=this.querySelector("[data-ui-select-list]");return n&&s&&this.openSelect(n,s),this.focusTypeaheadOption(t),!0}focusTypeaheadOption(e){const t=this.getEnabledItems();if(!t.length||!this.typeahead)return;const n=e??this.getSelectedItem()??t[0];if(!n)return;const s=t.indexOf(n),r=Math.max(0,s+1);[...t.slice(r),...t.slice(0,r)].find(l=>l.textContent.trim().toLowerCase().startsWith(this.typeahead))?.focus()}}class Rn extends C{abortController;connectedCallback(){super.connectedCallback(),x()&&(this.hasAttribute("selectable")&&this.dataset.uiDatatableSelectable!=="true"&&(this.dataset.uiDatatableSelectable="true"),this.hasAttribute("name")&&!this.dataset.uiDatatableName&&(this.dataset.uiDatatableName=this.getAttribute("name")??""),this.abortController?.abort(),this.abortController=new AbortController,this.setupDataTable(this.abortController.signal))}disconnectedCallback(){this.abortController?.abort(),this.abortController=void 0}setupDataTable(e){const t=this.querySelector("table");t&&(this.setupSelection(t,e),this.setupSorting(t,e))}setupSorting(e,t){const n=e.tBodies[0];if(!n)return;for(const[r,i]of[...n.rows].entries())i.dataset.uiDatatableIndex=i.dataset.uiDatatableIndex??String(r);const s=[...e.querySelectorAll("thead th")].filter(r=>r.dataset.uiDatatableSortable==="true"||r.dataset.sortable==="true"||r.hasAttribute("data-sortable"));for(const r of s){const i=r.parentElement,o=i?[...i.children].indexOf(r):-1;if(o<0)continue;r.dataset.uiDatatableColumn=String(o),r.setAttribute("aria-sort",r.getAttribute("aria-sort")??"none"),this.ensureSortButton(r).addEventListener("click",()=>{const u=xn(this.dataset.uiDatatableSortColumn,o,r.getAttribute("aria-sort"));this.updateSort(e,r,u),this.sortRows(e,r,o,u)},{signal:t})}}ensureSortButton(e){const t=e.querySelector("[data-ui-datatable-sort]");if(t)return t;const n=document.createElement("button");for(n.type="button",n.className="ui-data-table__sort",n.dataset.uiDatatableSort="";e.firstChild;)n.append(e.firstChild);return e.append(n),n}updateSort(e,t,n){for(const s of e.querySelectorAll("thead th[aria-sort]"))s.setAttribute("aria-sort",s===t?n:"none"),s.dataset.sort=s===t?n:"none";this.dataset.uiDatatableSortDirection=n,n==="none"?delete this.dataset.uiDatatableSortColumn:this.dataset.uiDatatableSortColumn=t.dataset.uiDatatableColumn??""}sortRows(e,t,n,s){const r=e.tBodies[0];if(!r)return;const i=[...r.rows],o=t.dataset.uiDatatableSortType;i.sort((l,u)=>{if(s==="none")return Number(l.dataset.uiDatatableIndex??"0")-Number(u.dataset.uiDatatableIndex??"0");const h=vn(St(l.cells[n]),St(u.cells[n]),o);return(s==="ascending"?h:-h)||Number(l.dataset.uiDatatableIndex??"0")-Number(u.dataset.uiDatatableIndex??"0")});for(const l of i)r.append(l)}setupSelection(e,t){if(!(this.dataset.uiDatatableSelectable==="true"||this.hasAttribute("selectable")))return;const s=e.tHead?.rows[0],r=e.tBodies[0];if(!s||!r)return;const i=this.ensureSelectAll(s);for(const[o,l]of Lt(e).entries())this.ensureRowSelect(l,o).addEventListener("change",()=>{this.syncSelection(e,i,!0)},{signal:t});i.addEventListener("change",()=>{for(const o of e.querySelectorAll("[data-ui-datatable-row-select]"))o.checked=i.checked;this.syncSelection(e,i,!0)},{signal:t}),this.closest("form")?.addEventListener("reset",()=>{globalThis.setTimeout(()=>{this.syncSelection(e,i,!0)})},{signal:t}),this.syncSelection(e,i)}ensureSelectAll(e){const t=e.querySelector("[data-ui-datatable-select-all]");if(t)return t;const n=document.createElement("th"),s=document.createElement("input");return n.className="ui-data-table__selection",n.scope="col",s.type="checkbox",s.className="ui-data-table__checkbox",s.dataset.uiDatatableSelectAll="",s.setAttribute("aria-label","Select all rows"),n.append(s),e.prepend(n),s}ensureRowSelect(e,t){const n=e.querySelector("[data-ui-datatable-row-select]");if(e.dataset.uiDatatableRow="",e.dataset.value=kt(e,t),n)return n;const s=document.createElement("td"),r=document.createElement("input"),i=e.dataset.state==="selected"||e.getAttribute("aria-selected")==="true";return s.className="ui-data-table__selection",r.type="checkbox",r.className="ui-data-table__checkbox",r.dataset.uiDatatableRowSelect="",r.checked=i,r.defaultChecked=i,r.setAttribute("aria-label",`Select row ${t+1}`),s.append(r),e.prepend(s),r}syncSelection(e,t,n=!1){const s=Lt(e),r=[];for(const[i,o]of s.entries()){const u=o.querySelector("[data-ui-datatable-row-select]")?.checked===!0;o.setAttribute("aria-selected",String(u)),u?(o.dataset.state="selected",r.push(kt(o,i))):delete o.dataset.state}if(t.checked=s.length>0&&r.length===s.length,t.indeterminate=r.length>0&&r.length<s.length,this.syncSelectionInputs(r),n){const i={values:r};this.dispatchEvent(new CustomEvent("ui:data-table-selection-change",{bubbles:!0,detail:i}))}}syncSelectionInputs(e){const t=this.dataset.uiDatatableName;let n=this.querySelector("[data-ui-datatable-inputs]");t?(n||(n=document.createElement("div"),n.hidden=!0,n.dataset.uiDatatableInputs="",this.append(n)),n.replaceChildren(...e.map(s=>{const r=document.createElement("input");return r.type="hidden",r.name=t,r.value=s,r}))):n?.replaceChildren()}}class Hn extends C{abortController;connectedCallback(){super.connectedCallback(),x()&&(this.abortController?.abort(),this.abortController=new AbortController,this.setupVirtualList(this.abortController.signal))}disconnectedCallback(){this.abortController?.abort(),this.abortController=void 0}setupVirtualList(e){const t=[...this.children].filter(s=>s instanceof HTMLElement);if(!t.length)return;const n=()=>{const s=this.getNumberAttribute("data-ui-overscan","overscan",4,0),r=this.getNumberAttribute("data-ui-item-size","item-size",44),i=Zt(this.scrollTop,this.clientHeight,r,t.length,s);for(const[o,l]of t.entries())l.hidden=o<i.startIndex||o>i.endIndex;this.dispatchEvent(new CustomEvent("ui:virtual-list-range",{bubbles:!0,detail:i}))};this.addEventListener("scroll",n,{passive:!0,signal:e}),n()}getNumberAttribute(e,t,n,s=1){const r=Number(this.getAttribute(e)??this.getAttribute(t)??n);return Number.isFinite(r)&&r>=s?r:n}}class On extends C{abortController;currentExportFormat="css";currentExportValue="";currentScheme="light";currentTokens=null;connectedCallback(){super.connectedCallback(),x()&&(this.abortController?.abort(),this.abortController=new AbortController,this.setupThemeBuilder(this.abortController.signal))}disconnectedCallback(){this.abortController?.abort(),this.abortController=void 0}setupThemeBuilder(e){const t=this.querySelector("[data-ui-theme-brand-hue], [data-ui-theme-hue]"),n=this.querySelector("[data-ui-theme-brand-hue-number]"),s=this.querySelector("[data-ui-theme-accent-hue]"),r=this.querySelector("[data-ui-theme-accent-hue-number]"),i=this.querySelector("[data-ui-theme-primary-color]"),o=this.querySelector("[data-ui-theme-primary-hex]"),l=this.querySelector("[data-ui-theme-secondary-color]"),u=this.querySelector("[data-ui-theme-secondary-hex]"),h=this.querySelector("[data-ui-theme-export]"),d=this.querySelector("[data-ui-theme-output]"),g=[...this.querySelectorAll("[data-ui-theme-export-format]")],m=[...this.querySelectorAll("[data-ui-theme-mode]")],b=[...this.querySelectorAll("[data-ui-theme-scheme]")],p=this.querySelector("[data-ui-theme-import]"),S=this.querySelector("[data-ui-theme-check-contrast]"),y=this.querySelector("[data-ui-theme-contrast-score]"),D=this.querySelector("[data-ui-theme-contrast-status]");this.currentExportFormat=Ne(this.getButtonValue(g,"data-ui-theme-export-format","css")),this.currentScheme=we(this.getButtonValue(b,"data-ui-theme-scheme",this.getDefaultScheme()));const w=v=>{if(!y&&!D)return;const E=aa(v,"ink","canvas");y&&(y.textContent=String(E.ratio)),D&&(D.textContent=E.wcagAA?"Passes WCAG AA":"Fails WCAG AA",D.dataset.status=E.wcagAA?"pass":"fail")},M=(v=!0)=>{const E=jt({accentHue:s?.value??r?.value??this.getAttribute("data-ui-theme-accent-hue")??null,hue:t?.value??n?.value??this.getAttribute("data-ui-theme-brand-hue")??this.getAttribute("data-ui-theme-hue")??null,mode:this.getButtonValue(m,"data-ui-theme-mode","generated"),primaryColor:o?.value??i?.value??null,scheme:this.currentScheme,secondaryColor:u?.value??l?.value??null});this.currentScheme=E.scheme,this.currentTokens=E.tokens;const f=this.getTarget();f&&this.applyTokens(f,E.tokens,E.scheme),this.writeExport(d),w(E.tokens),v&&this.dispatchEvent(new CustomEvent("ui:theme-change",{bubbles:!0,detail:E}))};this.bindHueInputs(t,n,M,e),this.bindHueInputs(s,r,M,e),this.bindHexInputs(i,o,M,e),this.bindHexInputs(l,u,M,e);for(const v of g)v.addEventListener("click",()=>{this.currentExportFormat=Ne(v.getAttribute("data-ui-theme-export-format")),this.setPressedState(g,"data-ui-theme-export-format",this.currentExportFormat),this.writeExport(d)},{signal:e});for(const v of m)v.addEventListener("click",()=>{this.setPressedState(m,"data-ui-theme-mode",Ot(v.getAttribute("data-ui-theme-mode"))),M()},{signal:e});for(const v of b)v.addEventListener("click",()=>{this.currentScheme=we(v.getAttribute("data-ui-theme-scheme")),this.setPressedState(b,"data-ui-theme-scheme",this.currentScheme),M()},{signal:e});h?.addEventListener("click",()=>{this.currentTokens?this.writeExport(d):M(!1);const v=d?.value||this.currentExportValue;navigator.clipboard.writeText(v).catch(()=>null),this.dispatchEvent(new CustomEvent("ui:theme-export",{bubbles:!0,detail:{css:this.currentExportFormat==="css"?v:void 0,format:this.currentExportFormat,tokens:this.currentTokens,value:v}}))},{signal:e}),p?.addEventListener("click",()=>{const v=d?.value||"";if(!v)return;const E=ea(v);if(Object.keys(E).length===0)return;this.currentTokens=E;const f=this.getTarget();f&&this.applyTokens(f,this.currentTokens,this.currentScheme),this.writeExport(d),w(this.currentTokens),this.dispatchEvent(new CustomEvent("ui:theme-change",{bubbles:!0,detail:{accentHue:0,hue:0,mode:"manual",scheme:this.currentScheme,tokens:this.currentTokens}}))},{signal:e}),S?.addEventListener("click",()=>{if(!this.currentTokens)return;this.currentTokens=na(this.currentTokens,"ink","canvas");const v=this.getTarget();v&&this.applyTokens(v,this.currentTokens,this.currentScheme),this.writeExport(d),w(this.currentTokens),this.dispatchEvent(new CustomEvent("ui:theme-change",{bubbles:!0,detail:{accentHue:0,hue:0,mode:"manual",scheme:this.currentScheme,tokens:this.currentTokens}}))},{signal:e}),M(!1)}getDefaultScheme(){return document.documentElement.dataset.theme?.includes("dark")?"dark":"light"}getTarget(){const e=this.dataset.uiThemeTarget;if(!e)return document.documentElement;try{return document.querySelector(e)}catch{return null}}getButtonValue(e,t,n){return e.find(r=>r.getAttribute("aria-selected")==="true"||r.getAttribute("aria-pressed")==="true")?.getAttribute(t)??this.getAttribute(t)??n}setPressedState(e,t,n){for(const s of e){const r=s.getAttribute(t)===n;s.hasAttribute("aria-pressed")&&s.setAttribute("aria-pressed",String(r)),s.classList.toggle("ui-button--secondary",r),s.classList.toggle("ui-button--outline",!r)}}bindHueInputs(e,t,n,s){const r=(i,o)=>{o&&(o.value=i.value),n()};e?.addEventListener("input",()=>{r(e,t)},{signal:s}),t?.addEventListener("input",()=>{r(t,e)},{signal:s})}bindHexInputs(e,t,n,s){e?.addEventListener("input",()=>{t&&(t.value=e.value,t.removeAttribute("aria-invalid")),n()},{signal:s}),t?.addEventListener("input",()=>{const r=Qt(t.value);r?(e&&(e.value=r),t.removeAttribute("aria-invalid"),n()):t.setAttribute("aria-invalid","true")},{signal:s})}applyTokens(e,t,n){e.style.colorScheme=n;for(const[s,r]of Object.entries(t))e.style.setProperty(`--${s}`,r)}writeExport(e){this.currentTokens&&(this.currentExportValue=Gt(this.currentTokens,this.currentScheme,this.currentExportFormat),e&&(e.value=this.currentExportValue))}}class Vn extends C{abortController;showTimer;connectedCallback(){super.connectedCallback(),x()&&(this.abortController?.abort(),this.abortController=new AbortController,this.setupTooltip(this.abortController.signal))}disconnectedCallback(){this.abortController?.abort(),this.abortController=void 0,this.clearTimer()}setupTooltip(e){const t=this.querySelector('[role="tooltip"]'),n=this.querySelector('[data-ui-tooltip-trigger], [data-ui-trigger], button, a[href], input:not([type="hidden"]), select, textarea, [tabindex]:not([tabindex="-1"])');if(!t)return;if(n&&!n.closest('[role="tooltip"]')){t.id||(t.id=R("ui-tooltip"));const i=new Set((n.getAttribute("aria-describedby")??"").split(/\s+/).filter(Boolean));i.add(t.id),n.setAttribute("aria-describedby",[...i].join(" "))}const s=i=>{this.clearTimer(),this.showTimer=globalThis.setTimeout(()=>{t.style.removeProperty("visibility")},i)},r=()=>{this.clearTimer(),t.style.visibility="hidden"};this.addEventListener("mouseenter",()=>{s(250)},{signal:e}),this.addEventListener("mouseleave",r,{signal:e}),this.addEventListener("focusin",()=>{s(0)},{signal:e}),this.addEventListener("focusout",r,{signal:e}),this.addEventListener("keydown",i=>{i.key==="Escape"&&r()},{signal:e})}clearTimer(){this.showTimer&&(globalThis.clearTimeout(this.showTimer),this.showTimer=void 0)}}class zn extends C{connectedCallback(){super.connectedCallback(),re(this),wt()}}class Un extends C{abortController;connectedCallback(){super.connectedCallback(),this.dataset.uiToast="",this.setAttribute("role",this.getAttribute("role")??(this.getAttribute("variant")==="destructive"?"alert":"status")),this.setAttribute("aria-live",this.getAttribute("aria-live")??(this.getAttribute("variant")==="destructive"?"assertive":"polite")),this.abortController?.abort(),this.abortController=new AbortController,this.addEventListener("keydown",e=>{e.key==="Escape"&&(e.preventDefault(),G(this))},{signal:this.abortController.signal})}disconnectedCallback(){this.abortController?.abort(),this.abortController=void 0,ye(this)}}class jn extends C{abortController;connectedCallback(){super.connectedCallback(),this.abortController?.abort(),this.abortController=new AbortController;const e=this.querySelector("[data-ui-file-upload-input]");if(!e)return;const t=this.querySelector("[data-ui-file-upload-files]"),n=()=>{const s=e.files?[...e.files]:[];this.dataset.state=s.length>0?"selected":"idle",t&&(s.length===1?t.textContent=s[0]?.name??"":t.textContent=s.length>1?`${s.length} files selected`:"")};e.addEventListener("change",n,{signal:this.abortController.signal}),this.addEventListener("dragover",s=>{e.disabled||(s.preventDefault(),this.dataset.state="drag-over")},{signal:this.abortController.signal}),this.addEventListener("dragleave",s=>{s.relatedTarget instanceof Node&&this.contains(s.relatedTarget)||(this.dataset.state=e.files?.length?"selected":"idle")},{signal:this.abortController.signal}),this.addEventListener("drop",s=>{e.disabled||(s.preventDefault(),s.dataTransfer&&(e.files=s.dataTransfer.files,e.dispatchEvent(new Event("change",{bubbles:!0}))))},{signal:this.abortController.signal}),n()}disconnectedCallback(){this.abortController?.abort(),this.abortController=void 0}}class Gn extends C{connectedCallback(){super.connectedCallback(),this.update()}attributeChangedCallback(){super.attributeChangedCallback(),this.isConnected&&this.update()}update(){const e=Number(this.getAttribute("max")),t=Number.isFinite(e)&&e>0?e:100,n=Number(this.getAttribute("value")),s=Math.min(t,Math.max(0,Number.isFinite(n)?n:0));let r=this.querySelector('[data-slot="progress-indicator"]');r||(r=document.createElement("span"),r.className="ui-progress__bar",r.dataset.slot="progress-indicator",this.append(r)),this.setAttribute("aria-valuemax",String(t)),this.setAttribute("aria-valuenow",String(s)),r.style.width=`${s/t*100}%`}}class Yn extends C{abortController;resetTimer;connectedCallback(){super.connectedCallback(),this.abortController?.abort(),this.abortController=new AbortController,this.addEventListener("click",()=>{this.copy().catch(()=>{})},{signal:this.abortController.signal}),this.addEventListener("keydown",e=>{e.key!==" "&&e.key!=="Enter"||(e.preventDefault(),this.click())},{signal:this.abortController.signal})}disconnectedCallback(){this.abortController?.abort(),this.abortController=void 0,globalThis.clearTimeout(this.resetTimer)}copy=async()=>{const e=this.getAttribute("label")??"Copy to clipboard",t=this.getAttribute("copied-label")??"Copied to clipboard",n=this.getAttribute("error-label")??"Could not copy to clipboard";try{const i=this.getAttribute("target"),o=i?document.querySelector(i):null,l=o instanceof HTMLInputElement||o instanceof HTMLTextAreaElement?o.value:o?.innerText??o?.textContent,u=this.hasAttribute("value")?this.getAttribute("value")??"":l;if(u===void 0)throw new Error(n);await navigator.clipboard.writeText(u),this.dataset.state="copied",this.setAttribute("aria-label",t),this.dispatchEvent(new CustomEvent("ui:copy-success",{bubbles:!0,detail:{value:u}})),this.hasAttribute("toast")&&document.dispatchEvent(new CustomEvent("ui:toast",{detail:{title:t,variant:"success"}}))}catch(i){this.dataset.state="error",this.setAttribute("aria-label",n),this.dispatchEvent(new CustomEvent("ui:copy-error",{bubbles:!0,detail:{error:i}})),this.hasAttribute("toast")&&document.dispatchEvent(new CustomEvent("ui:toast",{detail:{title:n,variant:"destructive"}}))}globalThis.clearTimeout(this.resetTimer);const s=Number(this.getAttribute("reset-after")??"2000"),r=Number.isFinite(s)?Math.max(0,s):2e3;this.resetTimer=globalThis.setTimeout(()=>{this.dataset.state="idle",this.setAttribute("aria-label",e)},r)}}class Kn extends C{abortController;frame=0;connectedCallback(){super.connectedCallback(),this.abortController?.abort(),this.abortController=new AbortController;const e=[...this.querySelectorAll('a[href^="#"]')],t=[];for(const i of e){const o=decodeURIComponent(i.getAttribute("href")?.slice(1)??""),l=o?document.getElementById(o):null;l&&t.push({link:i,target:l})}if(!t.length)return;const n=i=>{for(const o of e){const l=o===i;o.dataset.active=String(l),l?o.setAttribute("aria-current","location"):o.removeAttribute("aria-current")}},s=()=>{this.frame=0;const i=document.scrollingElement??document.documentElement,o=i.scrollTop+i.clientHeight>=i.scrollHeight-1,l=Number(this.getAttribute("activation-offset")??this.dataset.uiAnchorOffset)||0;let u=t[0]?.link;if(o)u=t.at(-1)?.link;else for(const h of t){if(h.target.getBoundingClientRect().top>l)break;u=h.link}u&&n(u)},r=()=>{this.frame||(this.frame=requestAnimationFrame(s))};for(const{link:i}of t)i.addEventListener("click",()=>{n(i)},{signal:this.abortController.signal});window.addEventListener("resize",r,{passive:!0,signal:this.abortController.signal}),window.addEventListener("scroll",r,{passive:!0,signal:this.abortController.signal}),s()}disconnectedCallback(){this.abortController?.abort(),this.abortController=void 0,this.frame&&cancelAnimationFrame(this.frame),this.frame=0}}class Wn extends C{abortController;frame=0;update=()=>{this.frame=0;const e=document.scrollingElement??document.documentElement,t=e.scrollHeight-e.clientHeight,n=t>0?Math.min(100,Math.max(0,e.scrollTop/t*100)):0;let s=this.querySelector(".ui-scroll-progress__bar");s||(s=document.createElement("span"),s.className="ui-scroll-progress__bar",this.append(s)),this.setAttribute("aria-valuenow",`${Math.round(n)}`),s.style.transform=`scaleX(${n/100})`};scheduleUpdate=()=>{if(!this.frame){if(typeof requestAnimationFrame>"u"){this.update();return}this.frame=requestAnimationFrame(this.update)}};connectedCallback(){super.connectedCallback(),this.abortController?.abort(),this.abortController=new AbortController,window.addEventListener("resize",this.scheduleUpdate,{passive:!0,signal:this.abortController.signal}),window.addEventListener("scroll",this.scheduleUpdate,{passive:!0,signal:this.abortController.signal}),this.update()}disconnectedCallback(){this.abortController?.abort(),this.abortController=void 0,this.frame&&typeof cancelAnimationFrame<"u"&&cancelAnimationFrame(this.frame),this.frame=0}}class Zn extends C{abortController;opener=null;connectedCallback(){super.connectedCallback(),this.abortController?.abort(),this.abortController=new AbortController;const e=this.querySelector("[data-ui-tour-popover]"),t=[...this.querySelectorAll("[data-ui-tour-step]")];if(!e||!t.length)return;let n=0;const s=()=>{const l=t[n];if(!l)return;for(const[h,d]of t.entries())d.hidden=h!==n;const u=l.dataset.target?document.querySelector(l.dataset.target):null;if(u){const h=u.getBoundingClientRect();e.style.top=`${h.bottom+8}px`,e.style.left=`${h.left}px`}},r=()=>{this.hidden=!1,n=0,s()},i=()=>{this.hidden=!0};this.addEventListener("click",l=>{const u=l.target;u instanceof HTMLElement&&(u.closest("[data-ui-tour-next]")?n<t.length-1?(n+=1,s()):i():u.closest("[data-ui-tour-prev]")?n>0&&(n-=1,s()):(u.closest("[data-ui-tour-close]")||u.hasAttribute("data-ui-tour-backdrop"))&&i())},{signal:this.abortController.signal}),this.opener=this.id?document.querySelector(`[data-ui-tour-open="#${this.id}"]`):null,this.opener?.addEventListener("click",r,{signal:this.abortController.signal});const o=window;o.LumenTours??={},this.id&&(o.LumenTours[this.id]=r)}disconnectedCallback(){this.abortController?.abort(),this.abortController=void 0,this.opener=null;const e=window;this.id&&e.LumenTours&&Reflect.deleteProperty(e.LumenTours,this.id)}}class Xn extends C{abortController;connectedCallback(){super.connectedCallback(),this.abortController?.abort(),this.abortController=new AbortController;const e=new Map;for(const n of this.querySelectorAll("[data-ui-transfer-list]"))n.dataset.side&&e.set(n.dataset.side,n);const t=(n,s)=>{const r=e.get(n),i=e.get(s);if(!r||!i)return;const o=[];for(const l of r.querySelectorAll("[data-ui-transfer-item]")){if(!l.checked)continue;const u=l.closest(".ui-transfer__item");u&&(l.checked=!1,i.append(u),o.push(l.value))}o.length&&this.dispatchEvent(new CustomEvent("ui:transfer-change",{bubbles:!0,detail:{from:n,to:s,values:o}}))};for(const n of this.querySelectorAll("[data-ui-transfer-move]"))n.addEventListener("click",()=>{n.dataset.uiTransferMove==="target"?t("source","target"):n.dataset.uiTransferMove==="source"&&t("target","source")},{signal:this.abortController.signal})}disconnectedCallback(){this.abortController?.abort(),this.abortController=void 0}}class Jn extends C{abortController;closeTimer;connectedCallback(){super.connectedCallback(),this.abortController?.abort(),this.abortController=new AbortController;const e=this.querySelector("[data-ui-mentions-input]"),t=this.querySelector("[data-ui-mentions-list]");if(!e||!t)return;t.id||(t.id=`ui-mentions-${R("list")}`),e.setAttribute("aria-autocomplete","list"),e.setAttribute("aria-controls",t.id),e.setAttribute("aria-expanded","false"),e.setAttribute("aria-label",e.getAttribute("aria-label")??this.getAttribute("label")??"Mentions"),e.setAttribute("role","combobox");const n=this.dataset.uiMentionsTrigger??"@",s=n.replaceAll(/[.*+?^${}()|[\]\\]/g,"\\$&"),r=[...t.querySelectorAll("[data-ui-mentions-option]")];let i=-1;for(const[d,g]of r.entries())g.id||=`${t.id}-option-${d}`,g.setAttribute("aria-selected","false");const o=d=>{const g=r.filter(b=>!b.hidden);i=g.length&&d>=0?Math.min(d,g.length-1):-1;for(const b of r)b.setAttribute("aria-selected",b===g[i]?"true":"false");const m=g[i];m?.id?e.setAttribute("aria-activedescendant",m.id):e.removeAttribute("aria-activedescendant")},l=()=>{t.hidden=!0,e.setAttribute("aria-expanded","false"),o(-1)},u=()=>{const d=e.selectionStart,g=new RegExp(`${s}(\\w*)$`).exec(e.value.slice(0,d));if(!g){l();return}const m=(g[1]??"").toLowerCase();let b=0;for(const p of r){const S=(p.dataset.value??"").toLowerCase().startsWith(m);p.hidden=!S,S&&(b+=1)}t.hidden=b===0,e.setAttribute("aria-expanded",b>0?"true":"false"),o(0)},h=d=>{const g=e.selectionStart,m=e.value.slice(0,g).replace(new RegExp(`${s}\\w*$`),`${n}${d} `);e.value=m+e.value.slice(g),e.focus(),e.setSelectionRange(m.length,m.length),l(),e.dispatchEvent(new Event("input",{bubbles:!0}))};e.addEventListener("input",u,{signal:this.abortController.signal}),e.addEventListener("keydown",d=>{const g=r.filter(m=>!m.hidden);if(d.key==="Escape"&&!t.hidden)d.preventDefault(),l();else if(["ArrowDown","ArrowUp","End","Home"].includes(d.key)&&g.length){d.preventDefault();const m=j(d.key,i,g.length,["ArrowDown"]);o(m)}else d.key==="Enter"&&i>=0&&!t.hidden&&(d.preventDefault(),h(g[i]?.dataset.value??""))},{signal:this.abortController.signal}),e.addEventListener("blur",()=>{this.closeTimer=globalThis.setTimeout(l,120)},{signal:this.abortController.signal});for(const d of r)d.addEventListener("mousedown",g=>{g.preventDefault()},{signal:this.abortController.signal}),d.addEventListener("click",()=>{h(d.dataset.value??"")},{signal:this.abortController.signal})}disconnectedCallback(){this.abortController?.abort(),this.abortController=void 0,this.closeTimer&&globalThis.clearTimeout(this.closeTimer),this.closeTimer=void 0}}const $t=(a,e,t=!0)=>{const n=a.querySelector("[data-ui-trigger]"),s=a.querySelector("[data-ui-panel]");if(!n||!s)return;const r=()=>{O(n,s,!1)};return O(n,s,n.getAttribute("aria-expanded")==="true"),n.addEventListener("click",()=>{O(n,s,n.getAttribute("aria-expanded")!=="true")},{signal:e}),n.addEventListener("keydown",i=>{["ArrowDown","Enter"," "].includes(i.key)&&(i.preventDefault(),O(n,s,!0),H(s)[0]?.focus())},{signal:e}),s.addEventListener("keydown",i=>{if(i.key==="Escape"){i.preventDefault(),r(),n.focus({preventScroll:!0});return}if(!t||!["ArrowDown","ArrowUp","Home","End"].includes(i.key))return;const o=H(s);if(!o.length)return;i.preventDefault();const l=Math.max(0,o.indexOf(document.activeElement));o[j(i.key,l,o.length,["ArrowDown"])]?.focus()},{signal:e}),document.addEventListener("pointerdown",i=>{const o=z(i);!o||a.contains(o)||r()},{signal:e}),{close:r,panel:s,trigger:n}};class Qn extends C{abortController;connectedCallback(){super.connectedCallback(),this.abortController?.abort(),this.abortController=new AbortController;const e=$t(this,this.abortController.signal,!1);if(!e)return;const t=this.querySelector("[data-ui-cascader-value]"),n=this.querySelector("[data-ui-cascader-input]"),s=[...this.querySelectorAll(".ui-cascader__column")];for(const r of this.querySelectorAll("[data-ui-cascader-option]"))r.addEventListener("click",()=>{const i=r.closest(".ui-cascader__column");if(i){const u=s.indexOf(i);for(const h of s.slice(u+1)){h.hidden=!0;for(const d of h.querySelectorAll("[data-ui-cascader-option]"))d.dataset.active="false",d.setAttribute("aria-selected","false")}for(const h of i.querySelectorAll("[data-ui-cascader-option]"))h.dataset.active="false",h.setAttribute("aria-selected","false")}r.dataset.active="true",r.setAttribute("aria-selected","true");const o=r.dataset.uiCascaderNext?this.querySelector(r.dataset.uiCascaderNext):null;if(o){o.hidden=!1;return}const l=r.dataset.value??r.textContent.trim();t&&(t.textContent=r.dataset.label??r.textContent.trim()),n&&(n.value=l),e.close(),this.dispatchEvent(new CustomEvent("ui:cascader-change",{bubbles:!0,detail:{value:l}}))},{signal:this.abortController.signal});e.panel.addEventListener("keydown",r=>{const i=r.target;if(!(i instanceof HTMLElement))return;const o=i.closest("[data-ui-cascader-option]"),l=o?.closest(".ui-cascader__column");if(!o||!l)return;const u=s.indexOf(l),h=[...l.querySelectorAll("[data-ui-cascader-option]")];if(["ArrowDown","ArrowUp","Home","End"].includes(r.key))r.preventDefault(),h[j(r.key,h.indexOf(o),h.length,["ArrowDown"])]?.focus();else if(r.key==="ArrowRight"){const d=o.dataset.uiCascaderNext?this.querySelector(o.dataset.uiCascaderNext):null;d&&(r.preventDefault(),o.click(),d.querySelector("[data-ui-cascader-option]")?.focus())}else if(r.key==="ArrowLeft"&&u>0){r.preventDefault();for(const d of s.slice(u))d.hidden=!0;s.slice(0,u).reverse().find(d=>!d.hidden)?.querySelector('[data-ui-cascader-option][data-active="true"]')?.focus()}},{signal:this.abortController.signal})}disconnectedCallback(){this.abortController?.abort(),this.abortController=void 0}}class es extends C{abortController;connectedCallback(){super.connectedCallback(),this.abortController?.abort(),this.abortController=new AbortController;const e=$t(this,this.abortController.signal);if(!e)return;const t=this.querySelector("[data-ui-tree-select-value]"),n=this.querySelector("[data-ui-tree-select-input]");for(const s of this.querySelectorAll("[data-ui-panel] [data-value]"))s.addEventListener("click",()=>{const r=s.dataset.value??"";t&&(t.textContent=s.textContent.trim()),n&&(n.value=r),e.close(),this.dispatchEvent(new CustomEvent("ui:tree-select-change",{bubbles:!0,detail:{value:r}}))},{signal:this.abortController.signal})}disconnectedCallback(){this.abortController?.abort(),this.abortController=void 0}}class ts extends C{connectedCallback(){super.connectedCallback(),this.addEventListener("click",()=>{window.scrollTo({top:0,behavior:"smooth"})})}}class as extends C{connectedCallback(){super.connectedCallback(),this.addEventListener("click",()=>{window.dispatchEvent(new CustomEvent("language-change"))})}}class ns extends C{connectedCallback(){if(super.connectedCallback(),!x()||window.matchMedia("(prefers-reduced-motion: reduce)").matches||this.hasAttribute("data-ui-particles-initialized"))return;this.setAttribute("data-ui-particles-initialized","");const e={low:15,medium:25,high:40},t=["var(--brand)","var(--accent)","var(--glow, var(--brand))"],n=this.getAttribute("data-ui-particles")||"medium",s=e[n];for(let r=0;r<s;r++){const i=document.createElement("span"),o=Math.random()*12+8;i.className="ui-particles__particle";const l={"--ui-particle-delay":`${Math.random()*8}s`,"--ui-particle-duration":`${20+Math.random()*15}s`,"--ui-particle-left":`${Math.random()*100}%`,"--ui-particle-size":`${o}px`,"--ui-particle-tone":t[Math.floor(Math.random()*t.length)]??"var(--brand)","--ui-particle-top":`${Math.random()*100}%`};for(const[u,h]of Object.entries(l))i.style.setProperty(u,h);this.appendChild(i)}}}class ss extends C{connectedCallback(){super.connectedCallback(),this.addEventListener("click",e=>{if(this.getAttribute("data-readonly")==="true")return;const t=e.target.closest(".ui-rating__star");if(!t)return;const n=[...this.querySelectorAll(".ui-rating__star")],s=n.indexOf(t);if(s===-1)return;const r=s+1;this.setAttribute("data-value",r.toString());for(const[i,o]of n.entries())o.setAttribute("data-active",i<r?"true":"false");this.dispatchEvent(new CustomEvent("change",{detail:{value:r}}))})}}class qt extends C{observer;connectedCallback(){if(super.connectedCallback(),!x())return;this.dataset.uiScrollRevealBound="true";const e=Math.max(0,Number(this.getAttribute("delay"))||0);if(this.style.setProperty("--ui-reveal-delay",`${e}ms`),window.matchMedia("(prefers-reduced-motion: reduce)").matches||typeof IntersectionObserver>"u"){this.classList.add("is-revealed");return}const t=this.getAttribute("once")!=="false",n=Math.min(1,Math.max(0,Number(this.getAttribute("threshold"))||0));this.observer=new IntersectionObserver(s=>{for(const r of s)r.target.classList.toggle("is-revealed",r.isIntersecting),r.isIntersecting&&t&&this.observer?.unobserve(r.target)},{threshold:n}),this.observer.observe(this)}disconnectedCallback(){this.observer?.disconnect(),this.observer=void 0}}class rs extends qt{connectedCallback(){super.connectedCallback();const e=Math.max(0,Number(this.getAttribute("stagger"))||80);this.style.setProperty("--ui-reveal-stagger",`${e}ms`);for(const[t,n]of[...this.children].entries())n instanceof HTMLElement&&n.style.setProperty("--ui-reveal-index",String(t))}}class is extends C{animationFrame;observer;connectedCallback(){super.connectedCallback(),this.animateValue()}attributeChangedCallback(){super.attributeChangedCallback(),this.isConnected&&this.animateValue()}disconnectedCallback(){this.observer?.disconnect(),this.animationFrame!==void 0&&cancelAnimationFrame(this.animationFrame)}animateValue(){if(!x())return;this.observer?.disconnect(),this.animationFrame!==void 0&&cancelAnimationFrame(this.animationFrame);const e=Number(this.getAttribute("from")),t=Number(this.getAttribute("value"));if(!Number.isFinite(e)||!Number.isFinite(t))return;const n=Math.max(0,Math.min(20,Number(this.getAttribute("decimals"))||0)),s=this.getAttribute("prefix")??"",r=this.getAttribute("suffix")??"",i=new Intl.NumberFormat(this.getAttribute("locale")||void 0,{maximumFractionDigits:n,minimumFractionDigits:n}),o=u=>`${s}${i.format(u)}${r}`,l=o(t);if(this.setAttribute("aria-label",l),window.matchMedia("(prefers-reduced-motion: reduce)").matches||typeof IntersectionObserver>"u"){this.textContent=l;return}this.textContent=o(e),this.observer=new IntersectionObserver(u=>{if(!u.some(b=>b.isIntersecting))return;this.observer?.disconnect();const h=getComputedStyle(this).getPropertyValue("--ui-motion-duration").trim(),d=Na(h),g=performance.now(),m=b=>{const p=Math.min(1,(b-g)/Math.max(1,d)),S=1-Math.pow(1-p,3);this.textContent=o(e+(t-e)*S),p<1?this.animationFrame=requestAnimationFrame(m):this.textContent=l};this.animationFrame=requestAnimationFrame(m)},{threshold:.15}),this.observer.observe(this)}}class os extends C{#e=!1;connectedCallback(){super.connectedCallback(),this.setAttribute("role","switch"),this.setAttribute("aria-checked",String(this.#t())),this.addEventListener("click",()=>{if(this.#e)return;const e=this.#t(),t=e?"light":"dark";if(window.matchMedia("(prefers-reduced-motion: reduce)").matches){this.#a(t);return}this.#n(e,t)})}#t(){const e=document.documentElement;return e.getAttribute("data-theme")==="dark"||e.classList.contains("dark")}#a(e){const t=document.documentElement;t.setAttribute("data-theme",e),e==="dark"?t.classList.add("dark"):t.classList.remove("dark"),localStorage.setItem("theme",e),window.dispatchEvent(new CustomEvent("theme-change",{detail:e})),this.setAttribute("aria-checked",String(this.#t()))}#n(e,t){if(window.matchMedia("(hover: none) and (pointer: coarse)").matches){this.#a(t);return}this.#e=!0;const s=this.getBoundingClientRect(),r=Math.round(s.left+s.width/2),i=Math.round(s.top+s.height/2),o=Math.hypot(Math.max(r,window.innerWidth-r),Math.max(i,window.innerHeight-i)),l=e?"hsl(277 20% 10%)":"hsl(268 20% 98%)",u=document.createElement("div");u.setAttribute("aria-hidden","true"),Object.assign(u.style,{position:"fixed",inset:"0",zIndex:"99999",pointerEvents:"none",backgroundColor:l,clipPath:`circle(${o}px at ${r}px ${i}px)`,willChange:"clip-path"}),document.body.appendChild(u),this.#a(t),requestAnimationFrame(()=>{requestAnimationFrame(()=>{u.style.transition="clip-path 580ms cubic-bezier(0.4, 0, 0.2, 1)",u.style.clipPath=`circle(0px at ${r}px ${i}px)`;const h=()=>{u.remove(),this.#e=!1};u.addEventListener("transitionend",h,{once:!0}),setTimeout(h,750)})})}}const ls=a=>class extends C{static config=a},us=(a,e)=>class extends a{static config=e},cs={AlertDialog:It,Anchor:Kn,AnimatedNumber:is,BackToTop:ts,BarChart:Fn,Cascader:Qn,Checkbox:_,CodeTabs:Ft,ColorPicker:_,CopyButton:Yn,DataTable:Rn,Dialog:It,DropdownMenu:Bt,FileUpload:jn,Icon:_n,Input:_,LanguageToggle:as,LineChart:$n,ListBox:Mn,Mentions:Jn,NumberField:_,Particles:ns,PieChart:qn,Popover:Bt,Progress:Gn,PasswordField:Dn,Rating:ss,RevealGroup:rs,ScrollProgress:Wn,ScrollReveal:qt,SearchField:_,Select:Pn,Slider:_,Sonner:zn,Sparkline:Bn,Switch:_,Tabs:Ft,Textarea:Tn,ThemeBuilder:On,ThemeToggle:os,Toast:Un,TimeField:_,Tour:Zn,Transfer:Xn,TreeSelect:es,Tooltip:Vn,VirtualList:Hn},c=Object.fromEntries(Ie.map(a=>{const e=cs[a];return e?[a,us(e,fe[a])]:[a,ls(fe[a])]})),_t=Ie.map(a=>[fe[a].tagName,c[a]]),hs=(a=document)=>{ve(a),xe(a),Ee(a),Xe(a),Je(a),Qe(a),tt(a)},bs=(a=typeof customElements>"u"?void 0:customElements)=>{if(a){for(const[e,t]of _t)!Be.has(e)&&!a.get(e)&&(a.define(e,t),Be.add(e));wt(),qa(),Pa(),Oa(),Ya(),Cn(),dt(),mt(),pt(),gn()}},ps=()=>{dt(),mt(),pt()},gs=_t,fs=c.Accordion,Cs=c.Alert,vs=c.AlertDialog,xs=c.Agenda,Es=c.AspectRatio,ys=c.Attachment,As=c.Autocomplete,Ss=c.Avatar,Ls=c.Badge,ks=c.BarChart,Ns=c.Breadcrumb,ws=c.Bubble,Ts=c.Button,Ds=c.ButtonGroup,Ms=c.Calendar,Is=c.Card,Bs=c.CardContent,Fs=c.CardDescription,$s=c.CardFooter,qs=c.CardHeader,_s=c.CardTitle,Ps=c.Carousel,Rs=c.Chart,Hs=c.Checkbox,Os=c.Collapsible,Vs=c.Code,zs=c.CodeTabs,Us=c.Combobox,js=c.Command,Gs=c.ColorPicker,Ys=c.ContextMenu,Ks=c.DataTable,Ws=c.DatePicker,Zs=c.DateRangePicker,Xs=c.Dialog,Js=c.Direction,Qs=c.Drawer,er=c.DropdownMenu,tr=c.Empty,ar=c.Field,nr=c.HoverCard,sr=c.Icon,rr=c.Input,ir=c.InputGroup,or=c.InputOTP,lr=c.NumberField,ur=c.Item,cr=c.Kbd,dr=c.Label,mr=c.LineChart,hr=c.Marker,br=c.Menubar,pr=c.Message,gr=c.MessageScroller,fr=c.NativeSelect,Cr=c.NavigationMenu,vr=c.Pagination,xr=c.PhoneInput,Er=c.PieChart,yr=c.Popover,Ar=c.Progress,Sr=c.RadioGroup,Lr=c.Resizable,kr=c.RichTextEditor,Nr=c.ScrollArea,wr=c.ScrollProgress,Tr=c.Schedule,Dr=c.SearchField,Mr=c.Select,Ir=c.Separator,Br=c.Sheet,Fr=c.Sidebar,$r=c.Skeleton,qr=c.Slider,_r=c.Sonner,Pr=c.Sparkline,Rr=c.Spinner,Hr=c.Switch,Or=c.Table,Vr=c.Tabs,zr=c.TagGroup,Ur=c.Textarea,jr=c.ThemeBuilder,Gr=c.TimeField,Yr=c.Toast,Kr=c.Toggle,Wr=c.ToggleGroup,Zr=c.Tooltip,Xr=c.Tree,Jr=c.TreeGrid,Qr=c.Typography,ei=c.VirtualList,ti=c.LanguageToggle,ai=c.Particles,ni=c.AnimatedNumber,si=c.RevealGroup,ri=c.ScrollReveal,ii=c.Stat,oi=c.StatDescription,li=c.StatIcon,ui=c.StatLabel,ci=c.StatTrend,di=c.StatValue,mi=c.Meter,hi=c.Note,bi=c.Rating,pi=c.Timeline,gi=c.AnimatedLogo,fi=c.AnimatedPortrait,Ci=c.ButtonLink,vi=c.CoverImage,xi=c.GradientDivider,Ei=c.CheckboxGroup,yi=c.Container,Ai=c.CopyButton,Si=c.ErrorSummary,Li=c.FieldError,ki=c.Form,Ni=c.Grid,wi=c.ListBox,Ti=c.PasswordField,Di=c.Stack,Mi=c.VisuallyHidden;export{fs as LumenAccordionElement,xs as LumenAgendaElement,vs as LumenAlertDialogElement,Cs as LumenAlertElement,gi as LumenAnimatedLogoElement,ni as LumenAnimatedNumberElement,fi as LumenAnimatedPortraitElement,Es as LumenAspectRatioElement,ys as LumenAttachmentElement,As as LumenAutocompleteElement,Ss as LumenAvatarElement,Ls as LumenBadgeElement,ks as LumenBarChartElement,Ns as LumenBreadcrumbElement,ws as LumenBubbleElement,Ts as LumenButtonElement,Ds as LumenButtonGroupElement,Ci as LumenButtonLinkElement,Ms as LumenCalendarElement,Bs as LumenCardContentElement,Fs as LumenCardDescriptionElement,Is as LumenCardElement,$s as LumenCardFooterElement,qs as LumenCardHeaderElement,_s as LumenCardTitleElement,Ps as LumenCarouselElement,Rs as LumenChartElement,Hs as LumenCheckboxElement,Ei as LumenCheckboxGroupElement,Vs as LumenCodeElement,zs as LumenCodeTabsElement,Os as LumenCollapsibleElement,Gs as LumenColorPickerElement,Us as LumenComboboxElement,js as LumenCommandElement,yi as LumenContainerElement,Ys as LumenContextMenuElement,Ai as LumenCopyButtonElement,vi as LumenCoverImageElement,Ks as LumenDataTableElement,Ws as LumenDatePickerElement,Zs as LumenDateRangePickerElement,Xs as LumenDialogElement,Js as LumenDirectionElement,Qs as LumenDrawerElement,er as LumenDropdownMenuElement,C as LumenElement,tr as LumenEmptyElement,Si as LumenErrorSummaryElement,ar as LumenFieldElement,Li as LumenFieldErrorElement,ki as LumenFormElement,xi as LumenGradientDividerElement,Ni as LumenGridElement,nr as LumenHoverCardElement,sr as LumenIconElement,rr as LumenInputElement,ir as LumenInputGroupElement,or as LumenInputOTPElement,ur as LumenItemElement,cr as LumenKbdElement,dr as LumenLabelElement,ti as LumenLanguageToggleElement,mr as LumenLineChartElement,wi as LumenListBoxElement,hr as LumenMarkerElement,br as LumenMenubarElement,pr as LumenMessageElement,gr as LumenMessageScrollerElement,mi as LumenMeterElement,fr as LumenNativeSelectElement,Cr as LumenNavigationMenuElement,hi as LumenNoteElement,lr as LumenNumberFieldElement,vr as LumenPaginationElement,ai as LumenParticlesElement,Ti as LumenPasswordFieldElement,xr as LumenPhoneInputElement,Er as LumenPieChartElement,yr as LumenPopoverElement,Ar as LumenProgressElement,Sr as LumenRadioGroupElement,bi as LumenRatingElement,Lr as LumenResizableElement,si as LumenRevealGroupElement,kr as LumenRichTextEditorElement,Tr as LumenScheduleElement,Nr as LumenScrollAreaElement,wr as LumenScrollProgressElement,ri as LumenScrollRevealElement,Dr as LumenSearchFieldElement,Mr as LumenSelectElement,Ir as LumenSeparatorElement,Br as LumenSheetElement,Fr as LumenSidebarElement,$r as LumenSkeletonElement,qr as LumenSliderElement,_r as LumenSonnerElement,Pr as LumenSparklineElement,Rr as LumenSpinnerElement,Di as LumenStackElement,oi as LumenStatDescriptionElement,ii as LumenStatElement,li as LumenStatIconElement,ui as LumenStatLabelElement,ci as LumenStatTrendElement,di as LumenStatValueElement,Hr as LumenSwitchElement,Or as LumenTableElement,Vr as LumenTabsElement,zr as LumenTagGroupElement,Ur as LumenTextareaElement,jr as LumenThemeBuilderElement,Gr as LumenTimeFieldElement,pi as LumenTimelineElement,ie as LumenToast,Yr as LumenToastElement,Kr as LumenToggleElement,Wr as LumenToggleGroupElement,Zr as LumenTooltipElement,Xr as LumenTreeElement,Jr as LumenTreeGridElement,Qr as LumenTypographyElement,ei as LumenVirtualListElement,Mi as LumenVisuallyHiddenElement,bs as defineLumenElements,xt as enhanceLumenCalendars,At as enhanceLumenContextMenus,xe as enhanceLumenDatePickers,ve as enhanceLumenDateRangePickers,hs as enhanceLumenElements,at as enhanceLumenForms,Ee as enhanceLumenInputOTPs,tt as enhanceLumenListBoxes,Qe as enhanceLumenPasswordFields,ut as enhanceLumenResizable,it as enhanceLumenRichTextEditors,ot as enhanceLumenSchedules,ps as installLumenControllers,gs as lumenElementDefinitions};