@haiyue/ui 0.1.2 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/LICENSE +27 -0
  3. package/README.md +643 -2
  4. package/dist/adapters/web/controls.d.ts +19 -0
  5. package/dist/adapters/web/controls.js +307 -0
  6. package/dist/adapters/web/dom.d.ts +10 -0
  7. package/dist/adapters/web/dom.js +98 -0
  8. package/dist/adapters/web/index.d.ts +3 -0
  9. package/dist/adapters/web/index.js +3 -0
  10. package/dist/adapters/web/renderer.d.ts +18 -0
  11. package/dist/adapters/web/renderer.js +553 -0
  12. package/dist/adapters/web/styles.d.ts +3 -0
  13. package/dist/adapters/web/styles.js +83 -0
  14. package/dist/adapters/web/types.d.ts +46 -0
  15. package/dist/adapters/web/types.js +2 -0
  16. package/dist/affix.d.ts +35 -0
  17. package/dist/affix.js +137 -0
  18. package/dist/badge.d.ts +45 -0
  19. package/dist/badge.js +168 -0
  20. package/dist/breadcrumb.d.ts +37 -0
  21. package/dist/breadcrumb.js +210 -0
  22. package/dist/button-group.d.ts +12 -0
  23. package/dist/button-group.js +72 -0
  24. package/dist/button.d.ts +15 -1
  25. package/dist/button.js +101 -12
  26. package/dist/carousel.d.ts +92 -0
  27. package/dist/carousel.js +509 -0
  28. package/dist/cascader.d.ts +65 -0
  29. package/dist/cascader.js +479 -0
  30. package/dist/collapse.d.ts +68 -0
  31. package/dist/collapse.js +348 -0
  32. package/dist/core/actions.d.ts +32 -0
  33. package/dist/core/actions.js +145 -0
  34. package/dist/core/data.d.ts +4 -0
  35. package/dist/core/data.js +27 -0
  36. package/dist/core/index.d.ts +7 -0
  37. package/dist/core/index.js +6 -0
  38. package/dist/core/platform-view.d.ts +17 -0
  39. package/dist/core/platform-view.js +84 -0
  40. package/dist/core/selection.d.ts +14 -0
  41. package/dist/core/selection.js +93 -0
  42. package/dist/core/text.d.ts +31 -0
  43. package/dist/core/text.js +154 -0
  44. package/dist/core/types.d.ts +269 -0
  45. package/dist/core/types.js +2 -0
  46. package/dist/core/validation.d.ts +24 -0
  47. package/dist/core/validation.js +243 -0
  48. package/dist/date-picker.d.ts +60 -0
  49. package/dist/date-picker.js +355 -0
  50. package/dist/dialog.d.ts +4 -0
  51. package/dist/dialog.js +23 -5
  52. package/dist/divider.d.ts +33 -0
  53. package/dist/divider.js +113 -0
  54. package/dist/draggable.d.ts +78 -0
  55. package/dist/draggable.js +255 -0
  56. package/dist/index.d.ts +53 -1
  57. package/dist/index.js +78 -0
  58. package/dist/input.d.ts +30 -1
  59. package/dist/input.js +166 -54
  60. package/dist/internal/qrcodegen.d.ts +94 -0
  61. package/dist/internal/qrcodegen.js +856 -0
  62. package/dist/masonry.d.ts +36 -0
  63. package/dist/masonry.js +171 -0
  64. package/dist/modal.d.ts +73 -0
  65. package/dist/modal.js +361 -0
  66. package/dist/portable/icons.d.ts +5 -0
  67. package/dist/portable/icons.js +24 -0
  68. package/dist/portable/index.d.ts +7 -0
  69. package/dist/portable/index.js +5 -0
  70. package/dist/portable/page.d.ts +38 -0
  71. package/dist/portable/page.js +361 -0
  72. package/dist/portable/responsive.d.ts +20 -0
  73. package/dist/portable/responsive.js +15 -0
  74. package/dist/portable/theme.d.ts +24 -0
  75. package/dist/portable/theme.js +60 -0
  76. package/dist/portable/tree.d.ts +10 -0
  77. package/dist/portable/tree.js +96 -0
  78. package/dist/qr-code.d.ts +62 -0
  79. package/dist/qr-code.js +224 -0
  80. package/dist/range.d.ts +3 -0
  81. package/dist/range.js +16 -5
  82. package/dist/rate.d.ts +46 -0
  83. package/dist/rate.js +193 -0
  84. package/dist/resizable.d.ts +97 -0
  85. package/dist/resizable.js +426 -0
  86. package/dist/skeleton.d.ts +41 -0
  87. package/dist/skeleton.js +141 -0
  88. package/dist/steps.d.ts +45 -0
  89. package/dist/steps.js +203 -0
  90. package/dist/table.d.ts +106 -0
  91. package/dist/table.js +689 -0
  92. package/dist/tabs.d.ts +3 -0
  93. package/dist/tabs.js +11 -1
  94. package/dist/tag.d.ts +55 -0
  95. package/dist/tag.js +225 -0
  96. package/dist/time-picker.d.ts +62 -0
  97. package/dist/time-picker.js +298 -0
  98. package/dist/timeline.d.ts +48 -0
  99. package/dist/timeline.js +201 -0
  100. package/dist/toast.d.ts +55 -0
  101. package/dist/toast.js +224 -0
  102. package/dist/tour.d.ts +89 -0
  103. package/dist/tour.js +306 -0
  104. package/dist/virtual-keyboard.d.ts +95 -0
  105. package/dist/virtual-keyboard.js +432 -0
  106. package/dist/virtual-mouse.d.ts +82 -0
  107. package/dist/virtual-mouse.js +358 -0
  108. package/dist/watermark.d.ts +44 -0
  109. package/dist/watermark.js +148 -0
  110. package/package.json +132 -4
@@ -0,0 +1,479 @@
1
+ const PANEL_ID_PREFIX = 'hy-cascader-panel';
2
+ function sameValue(left, right) {
3
+ return left === right;
4
+ }
5
+ function normalizeOptions(value) {
6
+ if (!Array.isArray(value))
7
+ return [];
8
+ return value.flatMap(item => {
9
+ if (!item || typeof item !== 'object')
10
+ return [];
11
+ const record = item;
12
+ if (record.value == null || (typeof record.value !== 'string' && typeof record.value !== 'number'))
13
+ return [];
14
+ const children = normalizeOptions(record.children);
15
+ return [{
16
+ label: String(record.label ?? record.value),
17
+ value: record.value,
18
+ disabled: Boolean(record.disabled),
19
+ ...(children.length ? { children } : {}),
20
+ }];
21
+ });
22
+ }
23
+ /** Tree-backed cascading dropdown that commits a complete value path. */
24
+ export class HYCascader extends HTMLElement {
25
+ _control = document.createElement('div');
26
+ _trigger = document.createElement('button');
27
+ _label = document.createElement('span');
28
+ _arrow = document.createElement('span');
29
+ _clear = document.createElement('button');
30
+ _panel = document.createElement('div');
31
+ _panelId = `${PANEL_ID_PREFIX}-${globalThis.crypto?.randomUUID?.() ?? Math.random().toString(36).slice(2)}`;
32
+ _options = [];
33
+ _value = [];
34
+ _activePath = [];
35
+ _reflecting = false;
36
+ _outsideAbort = null;
37
+ static get observedAttributes() {
38
+ return ['options', 'value', 'placeholder', 'display-separator', 'disabled', 'clearable', 'change-on-select', 'open', 'aria-label'];
39
+ }
40
+ constructor() {
41
+ super();
42
+ const root = this.attachShadow({ mode: 'open' });
43
+ const style = document.createElement('style');
44
+ style.textContent = `
45
+ :host {
46
+ position: relative;
47
+ display: inline-block;
48
+ min-width: 180px;
49
+ color: var(--hy-text-color, #eef3ff);
50
+ font: 12px/1.4 system-ui, sans-serif;
51
+ }
52
+ .control {
53
+ display: grid;
54
+ grid-template-columns: minmax(0, 1fr) auto;
55
+ min-width: 0;
56
+ height: var(--hy-cascader-height, 34px);
57
+ box-sizing: border-box;
58
+ border: 1px solid var(--hy-border-color, #3d4654);
59
+ border-radius: var(--hy-cascader-radius, 6px);
60
+ background: var(--hy-input-bg-color, #111722);
61
+ }
62
+ :host(:not([disabled])) .control:hover { border-color: var(--hy-hover-border-color, #596779); }
63
+ :host(:focus-within) .control, :host([open]) .control {
64
+ border-color: var(--hy-focus-border-color, #79a8ff);
65
+ box-shadow: 0 0 0 2px var(--hy-focus-ring-color, rgba(121, 168, 255, 0.22));
66
+ }
67
+ .trigger {
68
+ display: flex;
69
+ align-items: center;
70
+ min-width: 0;
71
+ gap: 8px;
72
+ padding: 0 8px 0 10px;
73
+ overflow: hidden;
74
+ border: 0;
75
+ color: inherit;
76
+ background: transparent;
77
+ cursor: pointer;
78
+ font: inherit;
79
+ text-align: left;
80
+ }
81
+ .label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
82
+ .label.placeholder { color: var(--hy-muted-color, #788697); }
83
+ .arrow { flex: 0 0 auto; color: var(--hy-muted-color, #788697); transition: transform 140ms ease; }
84
+ :host([open]) .arrow { transform: rotate(180deg); }
85
+ .clear {
86
+ width: 28px;
87
+ padding: 0;
88
+ border: 0;
89
+ color: var(--hy-muted-color, #788697);
90
+ background: transparent;
91
+ cursor: pointer;
92
+ font: 15px/1 system-ui, sans-serif;
93
+ }
94
+ .clear:hover { color: var(--hy-text-color, #eef3ff); }
95
+ .clear[hidden] { display: none; }
96
+ .trigger:focus-visible, .clear:focus-visible { outline: none; }
97
+ :host([disabled]) { opacity: 0.52; }
98
+ :host([disabled]) .trigger, :host([disabled]) .clear { cursor: not-allowed; }
99
+ .panel {
100
+ position: absolute;
101
+ z-index: var(--hy-cascader-z-index, 50);
102
+ top: calc(100% + 6px);
103
+ left: 0;
104
+ display: flex;
105
+ max-width: min(720px, 90vw);
106
+ overflow: auto;
107
+ border: 1px solid var(--hy-border-color, #3d4654);
108
+ border-radius: var(--hy-cascader-panel-radius, 7px);
109
+ background: var(--hy-menu-bg-color, var(--hy-surface-elevated-color, #171d27));
110
+ box-shadow: 0 12px 32px var(--hy-menu-shadow-color, rgba(0, 0, 0, 0.36));
111
+ }
112
+ .panel[hidden] { display: none; }
113
+ .column {
114
+ flex: 0 0 var(--hy-cascader-column-width, 184px);
115
+ min-width: 130px;
116
+ max-height: var(--hy-cascader-panel-height, 260px);
117
+ box-sizing: border-box;
118
+ margin: 0;
119
+ padding: 5px;
120
+ overflow-y: auto;
121
+ list-style: none;
122
+ scrollbar-color: var(--hy-border-strong-color, #596779) transparent;
123
+ scrollbar-width: thin;
124
+ }
125
+ .column + .column { border-left: 1px solid var(--hy-border-color, #3d4654); }
126
+ .option {
127
+ display: flex;
128
+ width: 100%;
129
+ min-height: 32px;
130
+ align-items: center;
131
+ gap: 8px;
132
+ padding: 6px 8px;
133
+ overflow: hidden;
134
+ border: 0;
135
+ border-radius: 4px;
136
+ color: var(--hy-secondary-text-color, #aebbd0);
137
+ background: transparent;
138
+ cursor: pointer;
139
+ font: inherit;
140
+ text-align: left;
141
+ }
142
+ .option-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
143
+ .option-arrow { flex: 0 0 auto; color: var(--hy-muted-color, #788697); }
144
+ .option:hover:not(:disabled), .option:focus-visible, .option[aria-selected="true"] {
145
+ outline: none;
146
+ color: var(--hy-text-color, #eef3ff);
147
+ background: var(--hy-hover-bg-color, #273241);
148
+ }
149
+ .option[aria-selected="true"] { color: var(--hy-accent-color, #79a8ff); }
150
+ .option:disabled { cursor: not-allowed; opacity: 0.46; }
151
+ .empty { min-width: 184px; padding: 28px 18px; color: var(--hy-muted-color, #788697); text-align: center; }
152
+ `;
153
+ this._control.className = 'control';
154
+ this._control.part.add('control');
155
+ this._trigger.type = 'button';
156
+ this._trigger.className = 'trigger';
157
+ this._trigger.part.add('trigger');
158
+ this._trigger.setAttribute('aria-haspopup', 'listbox');
159
+ this._trigger.setAttribute('aria-controls', this._panelId);
160
+ this._label.className = 'label';
161
+ this._label.part.add('label');
162
+ this._arrow.className = 'arrow';
163
+ this._arrow.part.add('arrow');
164
+ this._arrow.setAttribute('aria-hidden', 'true');
165
+ this._arrow.textContent = '⌄';
166
+ this._trigger.append(this._label, this._arrow);
167
+ this._clear.type = 'button';
168
+ this._clear.className = 'clear';
169
+ this._clear.part.add('clear');
170
+ this._clear.setAttribute('aria-label', 'Clear selection');
171
+ this._clear.textContent = '×';
172
+ this._panel.id = this._panelId;
173
+ this._panel.className = 'panel';
174
+ this._panel.part.add('panel');
175
+ this._control.append(this._trigger, this._clear);
176
+ root.append(style, this._control, this._panel);
177
+ this._trigger.addEventListener('click', () => { if (!this.disabled)
178
+ this.open = !this.open; });
179
+ this._trigger.addEventListener('keydown', event => {
180
+ if (event.key === 'ArrowDown' && !this.disabled) {
181
+ event.preventDefault();
182
+ this.open = true;
183
+ queueMicrotask(() => this._panel.querySelector('.option:not(:disabled)')?.focus());
184
+ }
185
+ else if (event.key === 'Escape' && this.open) {
186
+ event.preventDefault();
187
+ this.open = false;
188
+ }
189
+ });
190
+ this._clear.addEventListener('click', event => {
191
+ event.stopPropagation();
192
+ if (!this.disabled)
193
+ this._commit([], true);
194
+ });
195
+ }
196
+ connectedCallback() {
197
+ this._syncAttributes();
198
+ this._render();
199
+ this._syncOutsideListener();
200
+ }
201
+ disconnectedCallback() {
202
+ this._outsideAbort?.abort();
203
+ this._outsideAbort = null;
204
+ }
205
+ attributeChangedCallback(name, oldValue, newValue) {
206
+ if (oldValue === newValue || this._reflecting)
207
+ return;
208
+ if (name === 'options')
209
+ this._readOptionsAttribute();
210
+ if (name === 'value')
211
+ this._readValueAttribute();
212
+ if (name === 'open' && this.open)
213
+ this._activePath = [...this._value];
214
+ this._render();
215
+ if (name === 'open') {
216
+ this._syncOutsideListener();
217
+ this._dispatchOpenChange();
218
+ }
219
+ }
220
+ get options() { return this._options; }
221
+ set options(value) {
222
+ this._options = normalizeOptions(value);
223
+ this._value = this._normalizePath(this._value);
224
+ this._activePath = this.open ? [...this._value] : [];
225
+ this._reflectValue();
226
+ this._render();
227
+ }
228
+ get value() { return [...this._value]; }
229
+ set value(value) {
230
+ this._value = this._normalizePath(Array.isArray(value) ? value : []);
231
+ this._activePath = this.open ? [...this._value] : [];
232
+ this._reflectValue();
233
+ this._render();
234
+ }
235
+ get open() { return this.hasAttribute('open'); }
236
+ set open(value) { this.toggleAttribute('open', Boolean(value)); }
237
+ get disabled() { return this.hasAttribute('disabled'); }
238
+ set disabled(value) { this.toggleAttribute('disabled', Boolean(value)); }
239
+ get clearable() { return this.getAttribute('clearable') !== 'false'; }
240
+ set clearable(value) { this.setAttribute('clearable', String(Boolean(value))); }
241
+ get changeOnSelect() { return this.hasAttribute('change-on-select') && this.getAttribute('change-on-select') !== 'false'; }
242
+ set changeOnSelect(value) { this.toggleAttribute('change-on-select', Boolean(value)); }
243
+ get placeholder() { return this.getAttribute('placeholder') ?? 'Please select'; }
244
+ set placeholder(value) { this.setAttribute('placeholder', String(value)); }
245
+ get displaySeparator() { return this.getAttribute('display-separator') ?? ' / '; }
246
+ set displaySeparator(value) { this.setAttribute('display-separator', String(value)); }
247
+ _syncAttributes() {
248
+ if (this.hasAttribute('options'))
249
+ this._readOptionsAttribute();
250
+ if (this.hasAttribute('value'))
251
+ this._readValueAttribute();
252
+ if (this.open)
253
+ this._activePath = [...this._value];
254
+ }
255
+ _readOptionsAttribute() {
256
+ const raw = this.getAttribute('options');
257
+ if (!raw) {
258
+ this._options = [];
259
+ return;
260
+ }
261
+ try {
262
+ this._options = normalizeOptions(JSON.parse(raw));
263
+ }
264
+ catch (error) {
265
+ console.warn('Invalid hy-cascader options attribute.', error);
266
+ }
267
+ }
268
+ _readValueAttribute() {
269
+ const raw = this.getAttribute('value');
270
+ if (!raw) {
271
+ this._value = [];
272
+ return;
273
+ }
274
+ try {
275
+ this._value = this._normalizePath(JSON.parse(raw));
276
+ }
277
+ catch (error) {
278
+ console.warn('Invalid hy-cascader value attribute.', error);
279
+ }
280
+ }
281
+ _reflectValue() {
282
+ const serialized = JSON.stringify(this._value);
283
+ if (this.getAttribute('value') === serialized)
284
+ return;
285
+ this._reflecting = true;
286
+ if (this._value.length)
287
+ this.setAttribute('value', serialized);
288
+ else
289
+ this.removeAttribute('value');
290
+ this._reflecting = false;
291
+ }
292
+ _normalizePath(value) {
293
+ const normalized = [];
294
+ let options = this._options;
295
+ for (const segment of value) {
296
+ const option = options.find(item => sameValue(item.value, segment));
297
+ if (!option || option.disabled)
298
+ break;
299
+ normalized.push(option.value);
300
+ options = option.children ? [...option.children] : [];
301
+ }
302
+ return normalized;
303
+ }
304
+ _resolveOptions(value) {
305
+ const resolved = [];
306
+ let options = this._options;
307
+ for (const segment of value) {
308
+ const option = options.find(item => sameValue(item.value, segment));
309
+ if (!option)
310
+ break;
311
+ resolved.push(option);
312
+ options = option.children ? [...option.children] : [];
313
+ }
314
+ return resolved;
315
+ }
316
+ _render() {
317
+ const selected = this._resolveOptions(this._value);
318
+ const text = selected.map(option => option.label).join(this.displaySeparator);
319
+ this._label.textContent = text || this.placeholder;
320
+ this._label.classList.toggle('placeholder', !text);
321
+ this._trigger.disabled = this.disabled;
322
+ this._trigger.setAttribute('aria-expanded', String(this.open));
323
+ const accessibleName = this.getAttribute('aria-label');
324
+ if (accessibleName)
325
+ this._trigger.setAttribute('aria-label', accessibleName);
326
+ else
327
+ this._trigger.removeAttribute('aria-label');
328
+ this._clear.hidden = !this.clearable || !this._value.length;
329
+ this._clear.disabled = this.disabled;
330
+ this._panel.hidden = !this.open;
331
+ if (this.open)
332
+ this._renderPanel();
333
+ else
334
+ this._panel.replaceChildren();
335
+ }
336
+ _renderPanel() {
337
+ if (!this._options.length) {
338
+ const empty = document.createElement('div');
339
+ empty.className = 'empty';
340
+ empty.part.add('empty');
341
+ empty.textContent = 'No options';
342
+ this._panel.replaceChildren(empty);
343
+ return;
344
+ }
345
+ const columns = [];
346
+ let options = this._options;
347
+ let depth = 0;
348
+ while (options.length) {
349
+ const column = document.createElement('ul');
350
+ column.className = 'column';
351
+ column.part.add('column');
352
+ column.dataset.depth = String(depth);
353
+ column.setAttribute('role', 'listbox');
354
+ column.setAttribute('aria-label', `Level ${depth + 1}`);
355
+ const activeValue = this._activePath[depth];
356
+ for (const option of options)
357
+ column.append(this._createOption(option, depth, activeValue));
358
+ columns.push(column);
359
+ const active = options.find(option => activeValue !== undefined && sameValue(option.value, activeValue));
360
+ if (!active?.children?.length)
361
+ break;
362
+ options = active.children;
363
+ depth += 1;
364
+ }
365
+ this._panel.replaceChildren(...columns);
366
+ }
367
+ _createOption(option, depth, activeValue) {
368
+ const row = document.createElement('li');
369
+ row.part.add('option-item');
370
+ const button = document.createElement('button');
371
+ button.type = 'button';
372
+ button.className = 'option';
373
+ button.part.add('option');
374
+ button.setAttribute('role', 'option');
375
+ button.setAttribute('aria-selected', String(activeValue !== undefined && sameValue(option.value, activeValue)));
376
+ button.disabled = Boolean(option.disabled);
377
+ const label = document.createElement('span');
378
+ label.className = 'option-label';
379
+ label.textContent = option.label;
380
+ button.append(label);
381
+ if (option.children?.length) {
382
+ button.setAttribute('aria-haspopup', 'listbox');
383
+ const arrow = document.createElement('span');
384
+ arrow.className = 'option-arrow';
385
+ arrow.setAttribute('aria-hidden', 'true');
386
+ arrow.textContent = '›';
387
+ button.append(arrow);
388
+ }
389
+ button.addEventListener('click', () => this._activateOption(option, depth));
390
+ button.addEventListener('keydown', event => this._handleOptionKeydown(event, option, depth, button));
391
+ row.append(button);
392
+ return row;
393
+ }
394
+ _activateOption(option, depth, focusNext = false) {
395
+ if (option.disabled)
396
+ return;
397
+ const next = [...this._activePath.slice(0, depth), option.value];
398
+ this._activePath = next;
399
+ if (option.children?.length) {
400
+ if (this.changeOnSelect)
401
+ this._commit(next, false);
402
+ else
403
+ this._renderPanel();
404
+ if (focusNext)
405
+ queueMicrotask(() => this._panel.querySelector(`.column[data-depth="${depth + 1}"]`)?.querySelector('.option:not(:disabled)')?.focus());
406
+ return;
407
+ }
408
+ this._commit(next, true);
409
+ }
410
+ _commit(value, close) {
411
+ this._value = this._normalizePath(value);
412
+ this._activePath = [...this._value];
413
+ this._reflectValue();
414
+ if (close && this.open)
415
+ this.open = false;
416
+ else
417
+ this._render();
418
+ this.dispatchEvent(new CustomEvent('value-change', {
419
+ bubbles: true,
420
+ composed: true,
421
+ detail: { value: [...this._value], options: this._resolveOptions(this._value) },
422
+ }));
423
+ }
424
+ _handleOptionKeydown(event, option, depth, button) {
425
+ if (event.key === 'Escape') {
426
+ event.preventDefault();
427
+ this.open = false;
428
+ this._trigger.focus();
429
+ return;
430
+ }
431
+ if (event.key === 'ArrowRight' && option.children?.length) {
432
+ event.preventDefault();
433
+ this._activateOption(option, depth, true);
434
+ return;
435
+ }
436
+ if (event.key === 'ArrowLeft' && depth > 0) {
437
+ event.preventDefault();
438
+ const previous = this._panel.querySelector(`.column[data-depth="${depth - 1}"]`);
439
+ (previous?.querySelector('.option[aria-selected="true"]') ?? previous?.querySelector('.option:not(:disabled)'))?.focus();
440
+ return;
441
+ }
442
+ if (!['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key))
443
+ return;
444
+ event.preventDefault();
445
+ const buttons = [...button.closest('.column').querySelectorAll('.option:not(:disabled)')];
446
+ const current = buttons.indexOf(button);
447
+ const next = event.key === 'Home' ? 0 : event.key === 'End' ? buttons.length - 1
448
+ : (current + (event.key === 'ArrowDown' ? 1 : -1) + buttons.length) % buttons.length;
449
+ buttons[next]?.focus();
450
+ }
451
+ _syncOutsideListener() {
452
+ this._outsideAbort?.abort();
453
+ this._outsideAbort = null;
454
+ if (!this.open || !this.isConnected)
455
+ return;
456
+ const abort = new AbortController();
457
+ this._outsideAbort = abort;
458
+ queueMicrotask(() => {
459
+ if (abort.signal.aborted)
460
+ return;
461
+ document.addEventListener('pointerdown', event => {
462
+ if (!event.composedPath().includes(this))
463
+ this.open = false;
464
+ }, { capture: true, signal: abort.signal });
465
+ });
466
+ }
467
+ _dispatchOpenChange() {
468
+ this.dispatchEvent(new CustomEvent('open-change', {
469
+ bubbles: true,
470
+ composed: true,
471
+ detail: { open: this.open },
472
+ }));
473
+ }
474
+ }
475
+ export function defineCascaderComponents() {
476
+ if (!customElements.get('hy-cascader'))
477
+ customElements.define('hy-cascader', HYCascader);
478
+ }
479
+ //# sourceMappingURL=cascader.js.map
@@ -0,0 +1,68 @@
1
+ export type HYCollapseKey = string;
2
+ export type HYCollapseIconPosition = 'start' | 'end';
3
+ export type HYCollapseTrigger = 'header' | 'icon' | 'disabled';
4
+ export type HYCollapseContent = string | Node | (() => string | Node);
5
+ export interface HYCollapseItem {
6
+ readonly key: HYCollapseKey;
7
+ readonly title: string;
8
+ readonly content?: HYCollapseContent;
9
+ readonly extra?: string;
10
+ readonly disabled?: boolean;
11
+ readonly showArrow?: boolean;
12
+ }
13
+ export interface HYCollapseChangeDetail {
14
+ readonly activeKeys: readonly HYCollapseKey[];
15
+ readonly changedKey: HYCollapseKey;
16
+ readonly expanded: boolean;
17
+ }
18
+ /** Accessible accordion and multi-panel disclosure group. */
19
+ export declare class HYCollapse extends HTMLElement {
20
+ private readonly _container;
21
+ private readonly _uid;
22
+ private _items;
23
+ private _itemsAssigned;
24
+ private _activeKeys;
25
+ private _panels;
26
+ private readonly _motion;
27
+ private readonly _resizeObserver;
28
+ static get observedAttributes(): string[];
29
+ constructor();
30
+ connectedCallback(): void;
31
+ disconnectedCallback(): void;
32
+ attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
33
+ get items(): readonly HYCollapseItem[];
34
+ set items(value: readonly HYCollapseItem[]);
35
+ get activeKeys(): readonly HYCollapseKey[];
36
+ set activeKeys(value: readonly HYCollapseKey[]);
37
+ get accordion(): boolean;
38
+ set accordion(value: boolean);
39
+ get bordered(): boolean;
40
+ set bordered(value: boolean);
41
+ get ghost(): boolean;
42
+ set ghost(value: boolean);
43
+ get iconPosition(): HYCollapseIconPosition;
44
+ set iconPosition(value: HYCollapseIconPosition);
45
+ get collapsible(): HYCollapseTrigger;
46
+ set collapsible(value: HYCollapseTrigger);
47
+ get destroyOnHidden(): boolean;
48
+ set destroyOnHidden(value: boolean);
49
+ /** Opt-in height and arrow transitions. Initial rendering is always immediate. */
50
+ get animated(): boolean;
51
+ set animated(value: boolean);
52
+ /** Milliseconds; zero disables animation. Defaults to 200 (or the inherited duration token). */
53
+ get animationDuration(): number;
54
+ set animationDuration(value: number);
55
+ toggle(key: HYCollapseKey, expanded?: boolean): void;
56
+ private _readItemsAttribute;
57
+ private _syncItems;
58
+ private _syncExpanded;
59
+ private _duration;
60
+ private _transition;
61
+ private _finishTransition;
62
+ private _onMotionChange;
63
+ private _renderContent;
64
+ private _normalizeActiveKeys;
65
+ private _reflectActiveKeys;
66
+ private _syncLabel;
67
+ }
68
+ export declare function defineCollapseComponents(): void;