@lytjs/ui 6.0.0 → 6.5.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/index.cjs +742 -174
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -38
- package/dist/index.d.ts +14 -38
- package/dist/index.mjs +742 -174
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -9
package/dist/index.cjs
CHANGED
|
@@ -256,6 +256,14 @@ var Input = component.defineComponent({
|
|
|
256
256
|
};
|
|
257
257
|
}
|
|
258
258
|
});
|
|
259
|
+
var FOCUSABLE_SELECTORS = [
|
|
260
|
+
"a[href]",
|
|
261
|
+
"button:not([disabled])",
|
|
262
|
+
"input:not([disabled])",
|
|
263
|
+
"select:not([disabled])",
|
|
264
|
+
"textarea:not([disabled])",
|
|
265
|
+
'[tabindex]:not([tabindex="-1"])'
|
|
266
|
+
].join(", ");
|
|
259
267
|
var Dialog = component.defineComponent({
|
|
260
268
|
name: "LytDialog",
|
|
261
269
|
props: {
|
|
@@ -271,6 +279,8 @@ var Dialog = component.defineComponent({
|
|
|
271
279
|
ariaLabel: { type: String, default: "" },
|
|
272
280
|
ariaDescribedBy: { type: String, default: "" },
|
|
273
281
|
ariaModal: { type: Boolean, default: true },
|
|
282
|
+
initialFocus: { type: [String, Object], default: void 0 },
|
|
283
|
+
returnFocusOnClose: { type: Boolean, default: true },
|
|
274
284
|
onBeforeOpen: { type: Function, default: void 0 },
|
|
275
285
|
onBeforeClose: { type: Function, default: void 0 },
|
|
276
286
|
onOpen: { type: Function, default: void 0 },
|
|
@@ -282,6 +292,8 @@ var Dialog = component.defineComponent({
|
|
|
282
292
|
setup(props, { slots }) {
|
|
283
293
|
const p = props;
|
|
284
294
|
const visible = reactivity.signal(p.modelValue);
|
|
295
|
+
const dialogRef = reactivity.signal(null);
|
|
296
|
+
const previousActiveElement = reactivity.signal(null);
|
|
285
297
|
reactivity.watch(() => p.modelValue, (newVal) => {
|
|
286
298
|
visible.set(newVal);
|
|
287
299
|
if (newVal) {
|
|
@@ -295,6 +307,12 @@ var Dialog = component.defineComponent({
|
|
|
295
307
|
}
|
|
296
308
|
visible.set(false);
|
|
297
309
|
p.onClose?.();
|
|
310
|
+
if (p.returnFocusOnClose) {
|
|
311
|
+
const prevEl = previousActiveElement();
|
|
312
|
+
if (prevEl && prevEl.focus) {
|
|
313
|
+
prevEl.focus();
|
|
314
|
+
}
|
|
315
|
+
}
|
|
298
316
|
};
|
|
299
317
|
const handleKeydown = (e) => {
|
|
300
318
|
if (p.closeOnPressEscape && e.key === "Escape") {
|
|
@@ -303,6 +321,58 @@ var Dialog = component.defineComponent({
|
|
|
303
321
|
}
|
|
304
322
|
p.onKeydown?.(e);
|
|
305
323
|
};
|
|
324
|
+
const getFocusableElements = (container) => {
|
|
325
|
+
return Array.from(
|
|
326
|
+
container.querySelectorAll(FOCUSABLE_SELECTORS)
|
|
327
|
+
).filter((el) => {
|
|
328
|
+
return el.offsetParent !== null && !el.hasAttribute("aria-hidden");
|
|
329
|
+
});
|
|
330
|
+
};
|
|
331
|
+
const handleTabKey = (e) => {
|
|
332
|
+
const dialog = dialogRef();
|
|
333
|
+
if (!dialog) return;
|
|
334
|
+
const focusableElements = getFocusableElements(dialog);
|
|
335
|
+
if (focusableElements.length === 0) return;
|
|
336
|
+
const firstElement = focusableElements[0];
|
|
337
|
+
const lastElement = focusableElements[focusableElements.length - 1];
|
|
338
|
+
if (e.shiftKey) {
|
|
339
|
+
if (document.activeElement === firstElement) {
|
|
340
|
+
e.preventDefault();
|
|
341
|
+
lastElement.focus();
|
|
342
|
+
}
|
|
343
|
+
} else {
|
|
344
|
+
if (document.activeElement === lastElement) {
|
|
345
|
+
e.preventDefault();
|
|
346
|
+
firstElement.focus();
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
reactivity.effect(() => {
|
|
351
|
+
if (visible()) {
|
|
352
|
+
previousActiveElement.set(document.activeElement);
|
|
353
|
+
setTimeout(() => {
|
|
354
|
+
const dialog = dialogRef();
|
|
355
|
+
if (dialog) {
|
|
356
|
+
if (p.initialFocus) {
|
|
357
|
+
const initialEl = typeof p.initialFocus === "string" ? dialog.querySelector(p.initialFocus) : p.initialFocus;
|
|
358
|
+
if (initialEl && initialEl.focus) {
|
|
359
|
+
initialEl.focus();
|
|
360
|
+
} else {
|
|
361
|
+
const focusableElements = getFocusableElements(dialog);
|
|
362
|
+
if (focusableElements.length > 0) {
|
|
363
|
+
focusableElements[0].focus();
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
} else {
|
|
367
|
+
const focusableElements = getFocusableElements(dialog);
|
|
368
|
+
if (focusableElements.length > 0) {
|
|
369
|
+
focusableElements[0].focus();
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}, 0);
|
|
374
|
+
}
|
|
375
|
+
});
|
|
306
376
|
return () => {
|
|
307
377
|
if (!visible()) {
|
|
308
378
|
return vdom.createVNode("div", { style: "display: none;" }, []);
|
|
@@ -359,7 +429,15 @@ var Dialog = component.defineComponent({
|
|
|
359
429
|
});
|
|
360
430
|
return vdom.createVNode("div", {
|
|
361
431
|
class: "lyt-dialog__wrapper",
|
|
362
|
-
onKeydown:
|
|
432
|
+
onKeydown: (e) => {
|
|
433
|
+
if (e.key === "Tab") {
|
|
434
|
+
handleTabKey(e);
|
|
435
|
+
}
|
|
436
|
+
handleKeydown(e);
|
|
437
|
+
},
|
|
438
|
+
ref: (el) => {
|
|
439
|
+
dialogRef.set(el);
|
|
440
|
+
}
|
|
363
441
|
}, [
|
|
364
442
|
vdom.createVNode("div", {
|
|
365
443
|
class: "lyt-dialog__overlay",
|
|
@@ -368,12 +446,22 @@ var Dialog = component.defineComponent({
|
|
|
368
446
|
}),
|
|
369
447
|
vdom.createVNode("div", commonA11y.mergeA11yProps(dialogA11yProps, {
|
|
370
448
|
class: dialogClass,
|
|
371
|
-
style: dialogStyle
|
|
449
|
+
style: dialogStyle,
|
|
450
|
+
role: "dialog",
|
|
451
|
+
"aria-modal": p.ariaModal
|
|
372
452
|
}), children)
|
|
373
453
|
]);
|
|
374
454
|
};
|
|
375
455
|
}
|
|
376
456
|
});
|
|
457
|
+
var FOCUSABLE_SELECTORS2 = [
|
|
458
|
+
"a[href]",
|
|
459
|
+
"button:not([disabled])",
|
|
460
|
+
"input:not([disabled])",
|
|
461
|
+
"select:not([disabled])",
|
|
462
|
+
"textarea:not([disabled])",
|
|
463
|
+
'[tabindex]:not([tabindex="-1"])'
|
|
464
|
+
].join(", ");
|
|
377
465
|
var Select = component.defineComponent({
|
|
378
466
|
name: "LytSelect",
|
|
379
467
|
props: {
|
|
@@ -391,6 +479,8 @@ var Select = component.defineComponent({
|
|
|
391
479
|
ariaInvalid: { type: Boolean, default: false },
|
|
392
480
|
ariaRequired: { type: Boolean, default: false },
|
|
393
481
|
tabIndex: { type: Number, default: void 0 },
|
|
482
|
+
closeOnSelect: { type: Boolean, default: true },
|
|
483
|
+
filterable: { type: Boolean, default: false },
|
|
394
484
|
onChange: { type: Function, default: void 0 },
|
|
395
485
|
onClear: { type: Function, default: void 0 },
|
|
396
486
|
onKeydown: { type: Function, default: void 0 },
|
|
@@ -402,6 +492,11 @@ var Select = component.defineComponent({
|
|
|
402
492
|
const selectedValue = reactivity.signal(/* @__PURE__ */ new Set());
|
|
403
493
|
const searchValue = reactivity.signal("");
|
|
404
494
|
const highlightedIndex = reactivity.signal(-1);
|
|
495
|
+
const triggerRef = reactivity.signal(null);
|
|
496
|
+
const dropdownRef = reactivity.signal(null);
|
|
497
|
+
const previousActiveElement = reactivity.signal(null);
|
|
498
|
+
const listboxId = reactivity.signal(`lyt-select-listbox-${Math.random().toString(36).substr(2, 9)}`);
|
|
499
|
+
const activeDescendant = reactivity.signal("");
|
|
405
500
|
reactivity.effect(() => {
|
|
406
501
|
if (Array.isArray(p.modelValue)) {
|
|
407
502
|
selectedValue.set(new Set(p.modelValue));
|
|
@@ -412,11 +507,22 @@ var Select = component.defineComponent({
|
|
|
412
507
|
const getFilteredOptions = () => {
|
|
413
508
|
const opts = p.options || [];
|
|
414
509
|
const query = searchValue();
|
|
415
|
-
|
|
510
|
+
if (!p.filterable || !query) return opts;
|
|
511
|
+
const lowerQuery = query.toLowerCase();
|
|
512
|
+
return opts.filter(
|
|
513
|
+
(opt) => opt.label.toLowerCase().includes(lowerQuery)
|
|
514
|
+
);
|
|
416
515
|
};
|
|
417
516
|
const getEnabledOptions = () => {
|
|
418
517
|
return getFilteredOptions().filter((opt) => !opt.disabled);
|
|
419
518
|
};
|
|
519
|
+
const getFocusableElements = (container) => {
|
|
520
|
+
return Array.from(
|
|
521
|
+
container.querySelectorAll(FOCUSABLE_SELECTORS2)
|
|
522
|
+
).filter((el) => {
|
|
523
|
+
return el.offsetParent !== null && !el.hasAttribute("aria-hidden");
|
|
524
|
+
});
|
|
525
|
+
};
|
|
420
526
|
const toggleDropdown = () => {
|
|
421
527
|
if (p.disabled) return;
|
|
422
528
|
const newOpen = !isOpen();
|
|
@@ -431,6 +537,25 @@ var Select = component.defineComponent({
|
|
|
431
537
|
currentValue = foundIndex >= 0 ? foundIndex : 0;
|
|
432
538
|
}
|
|
433
539
|
highlightedIndex.set(currentValue);
|
|
540
|
+
const option = enabledOptions[currentValue];
|
|
541
|
+
if (option) {
|
|
542
|
+
activeDescendant.set(`lyt-select-option-${option.value}`);
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
previousActiveElement.set(document.activeElement);
|
|
546
|
+
setTimeout(() => {
|
|
547
|
+
const dropdown = dropdownRef();
|
|
548
|
+
if (dropdown) {
|
|
549
|
+
const focusable = getFocusableElements(dropdown);
|
|
550
|
+
if (focusable.length > 0) {
|
|
551
|
+
focusable[0]?.focus();
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
}, 10);
|
|
555
|
+
} else {
|
|
556
|
+
const prevEl = previousActiveElement();
|
|
557
|
+
if (prevEl && prevEl.focus) {
|
|
558
|
+
setTimeout(() => prevEl.focus(), 10);
|
|
434
559
|
}
|
|
435
560
|
}
|
|
436
561
|
p.onVisibleChange?.(newOpen);
|
|
@@ -448,9 +573,15 @@ var Select = component.defineComponent({
|
|
|
448
573
|
p.onChange?.(Array.from(newSelected));
|
|
449
574
|
} else {
|
|
450
575
|
selectedValue.set(/* @__PURE__ */ new Set([option.value]));
|
|
451
|
-
|
|
452
|
-
|
|
576
|
+
if (p.closeOnSelect) {
|
|
577
|
+
isOpen.set(false);
|
|
578
|
+
p.onVisibleChange?.(false);
|
|
579
|
+
}
|
|
453
580
|
p.onChange?.(option.value);
|
|
581
|
+
const prevEl = previousActiveElement();
|
|
582
|
+
if (prevEl && prevEl.focus) {
|
|
583
|
+
setTimeout(() => prevEl.focus(), 10);
|
|
584
|
+
}
|
|
454
585
|
}
|
|
455
586
|
};
|
|
456
587
|
const handleClear = (event) => {
|
|
@@ -466,7 +597,9 @@ var Select = component.defineComponent({
|
|
|
466
597
|
switch (event.key) {
|
|
467
598
|
case "Enter":
|
|
468
599
|
case " ":
|
|
469
|
-
|
|
600
|
+
if (!p.filterable || !open) {
|
|
601
|
+
event.preventDefault();
|
|
602
|
+
}
|
|
470
603
|
if (open) {
|
|
471
604
|
if (hIndex >= 0 && hIndex < enabledOptions.length) {
|
|
472
605
|
const option = enabledOptions[hIndex];
|
|
@@ -484,7 +617,12 @@ var Select = component.defineComponent({
|
|
|
484
617
|
toggleDropdown();
|
|
485
618
|
} else {
|
|
486
619
|
if (enabledOptions.length > 0) {
|
|
487
|
-
|
|
620
|
+
const nextIndex = Math.min(hIndex + 1, enabledOptions.length - 1);
|
|
621
|
+
highlightedIndex.set(nextIndex);
|
|
622
|
+
const option = enabledOptions[nextIndex];
|
|
623
|
+
if (option) {
|
|
624
|
+
activeDescendant.set(`lyt-select-option-${option.value}`);
|
|
625
|
+
}
|
|
488
626
|
}
|
|
489
627
|
}
|
|
490
628
|
break;
|
|
@@ -492,7 +630,12 @@ var Select = component.defineComponent({
|
|
|
492
630
|
event.preventDefault();
|
|
493
631
|
if (open) {
|
|
494
632
|
if (enabledOptions.length > 0) {
|
|
495
|
-
|
|
633
|
+
const prevIndex = Math.max(hIndex - 1, 0);
|
|
634
|
+
highlightedIndex.set(prevIndex);
|
|
635
|
+
const option = enabledOptions[prevIndex];
|
|
636
|
+
if (option) {
|
|
637
|
+
activeDescendant.set(`lyt-select-option-${option.value}`);
|
|
638
|
+
}
|
|
496
639
|
}
|
|
497
640
|
}
|
|
498
641
|
break;
|
|
@@ -501,23 +644,64 @@ var Select = component.defineComponent({
|
|
|
501
644
|
event.preventDefault();
|
|
502
645
|
isOpen.set(false);
|
|
503
646
|
p.onVisibleChange?.(false);
|
|
647
|
+
const prevEl = previousActiveElement();
|
|
648
|
+
if (prevEl && prevEl.focus) {
|
|
649
|
+
prevEl.focus();
|
|
650
|
+
}
|
|
504
651
|
}
|
|
505
652
|
break;
|
|
506
653
|
case "Home":
|
|
507
654
|
event.preventDefault();
|
|
508
655
|
if (open && enabledOptions.length > 0) {
|
|
509
656
|
highlightedIndex.set(0);
|
|
657
|
+
const option = enabledOptions[0];
|
|
658
|
+
if (option) {
|
|
659
|
+
activeDescendant.set(`lyt-select-option-${option.value}`);
|
|
660
|
+
}
|
|
510
661
|
}
|
|
511
662
|
break;
|
|
512
663
|
case "End":
|
|
513
664
|
event.preventDefault();
|
|
514
665
|
if (open && enabledOptions.length > 0) {
|
|
515
|
-
|
|
666
|
+
const lastIndex = enabledOptions.length - 1;
|
|
667
|
+
highlightedIndex.set(lastIndex);
|
|
668
|
+
const option = enabledOptions[lastIndex];
|
|
669
|
+
if (option) {
|
|
670
|
+
activeDescendant.set(`lyt-select-option-${option.value}`);
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
break;
|
|
674
|
+
case "Tab":
|
|
675
|
+
if (open) {
|
|
676
|
+
isOpen.set(false);
|
|
677
|
+
p.onVisibleChange?.(false);
|
|
516
678
|
}
|
|
517
679
|
break;
|
|
518
680
|
}
|
|
519
681
|
p.onKeydown?.(event);
|
|
520
682
|
};
|
|
683
|
+
const handleTriggerKeydown = (event) => {
|
|
684
|
+
if (event.key === "ArrowDown" && !isOpen()) {
|
|
685
|
+
event.preventDefault();
|
|
686
|
+
toggleDropdown();
|
|
687
|
+
} else if (event.key === "ArrowUp" && !isOpen()) {
|
|
688
|
+
event.preventDefault();
|
|
689
|
+
toggleDropdown();
|
|
690
|
+
}
|
|
691
|
+
};
|
|
692
|
+
const handleOptionKeydown = (event, option) => {
|
|
693
|
+
if (event.key === "Tab") {
|
|
694
|
+
isOpen.set(false);
|
|
695
|
+
p.onVisibleChange?.(false);
|
|
696
|
+
return;
|
|
697
|
+
}
|
|
698
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
699
|
+
event.preventDefault();
|
|
700
|
+
handleSelect(option);
|
|
701
|
+
return;
|
|
702
|
+
}
|
|
703
|
+
handleKeydown(event);
|
|
704
|
+
};
|
|
521
705
|
const getSelectedLabel = () => {
|
|
522
706
|
const selected = Array.from(selectedValue());
|
|
523
707
|
if (selected.length === 0) return "";
|
|
@@ -539,13 +723,19 @@ var Select = component.defineComponent({
|
|
|
539
723
|
const filteredOptions = getFilteredOptions();
|
|
540
724
|
const selected = selectedValue();
|
|
541
725
|
const hIndex = highlightedIndex();
|
|
726
|
+
const listId = listboxId();
|
|
727
|
+
const activeId = activeDescendant();
|
|
542
728
|
const dropdownContent = [];
|
|
543
729
|
if (filteredOptions.length === 0) {
|
|
544
|
-
dropdownContent.push(vdom.createVNode("div", {
|
|
730
|
+
dropdownContent.push(vdom.createVNode("div", {
|
|
731
|
+
class: "lyt-select__empty",
|
|
732
|
+
role: "status"
|
|
733
|
+
}, [vdom.createVNode("span", {}, "\u65E0\u5339\u914D\u9009\u9879")]));
|
|
545
734
|
} else {
|
|
546
735
|
filteredOptions.forEach((option, index) => {
|
|
547
736
|
const isSelected = selected.has(option.value);
|
|
548
737
|
const isHighlighted = !option.disabled && index === hIndex;
|
|
738
|
+
const optionId = `lyt-select-option-${option.value}`;
|
|
549
739
|
const optionChildren = [];
|
|
550
740
|
if (isSelected) {
|
|
551
741
|
optionChildren.push(vdom.createVNode("span", { class: "lyt-select__check" }, [vdom.createVNode("span", {}, "\u2713")]));
|
|
@@ -553,8 +743,10 @@ var Select = component.defineComponent({
|
|
|
553
743
|
optionChildren.push(vdom.createVNode("span", {}, option.label));
|
|
554
744
|
dropdownContent.push(vdom.createVNode("div", {
|
|
555
745
|
key: String(option.value),
|
|
746
|
+
id: optionId,
|
|
556
747
|
role: "option",
|
|
557
748
|
"aria-selected": isSelected,
|
|
749
|
+
"aria-disabled": option.disabled,
|
|
558
750
|
class: [
|
|
559
751
|
"lyt-select__option",
|
|
560
752
|
isSelected ? "lyt-select__option--selected" : "",
|
|
@@ -563,8 +755,12 @@ var Select = component.defineComponent({
|
|
|
563
755
|
].filter(Boolean).join(" "),
|
|
564
756
|
onClick: () => handleSelect(option),
|
|
565
757
|
onMouseenter: () => {
|
|
566
|
-
if (!option.disabled)
|
|
567
|
-
|
|
758
|
+
if (!option.disabled) {
|
|
759
|
+
highlightedIndex.set(index);
|
|
760
|
+
activeDescendant.set(optionId);
|
|
761
|
+
}
|
|
762
|
+
},
|
|
763
|
+
onKeydown: (e) => handleOptionKeydown(e, option)
|
|
568
764
|
}, optionChildren));
|
|
569
765
|
});
|
|
570
766
|
}
|
|
@@ -578,33 +774,65 @@ var Select = component.defineComponent({
|
|
|
578
774
|
if (p.clearable && selected.size > 0) {
|
|
579
775
|
triggerChildren.push(vdom.createVNode("span", {
|
|
580
776
|
class: "lyt-select__clear",
|
|
581
|
-
onClick: handleClear
|
|
777
|
+
onClick: handleClear,
|
|
778
|
+
role: "button",
|
|
779
|
+
"aria-label": "\u6E05\u9664\u9009\u62E9",
|
|
780
|
+
tabIndex: 0
|
|
582
781
|
}, [vdom.createVNode("span", {}, "\xD7")]));
|
|
583
782
|
}
|
|
584
783
|
triggerChildren.push(vdom.createVNode("span", { class: "lyt-select__arrow" }, [vdom.createVNode("span", {}, "\u25BC")]));
|
|
585
|
-
const resultChildren = [
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
784
|
+
const resultChildren = [];
|
|
785
|
+
if (p.filterable) {
|
|
786
|
+
resultChildren.push(vdom.createVNode("input", {
|
|
787
|
+
class: "lyt-select__search",
|
|
788
|
+
type: "text",
|
|
789
|
+
placeholder: "\u641C\u7D22...",
|
|
790
|
+
value: searchValue(),
|
|
791
|
+
onInput: (e) => {
|
|
792
|
+
searchValue.set(e.target.value);
|
|
793
|
+
},
|
|
794
|
+
onKeydown: handleTriggerKeydown,
|
|
795
|
+
"aria-label": "\u641C\u7D22\u9009\u9879",
|
|
796
|
+
"aria-controls": listId
|
|
797
|
+
}));
|
|
798
|
+
}
|
|
799
|
+
resultChildren.push(vdom.createVNode("div", {
|
|
800
|
+
ref: (el) => triggerRef.set(el),
|
|
801
|
+
class: "lyt-select__trigger",
|
|
802
|
+
onClick: toggleDropdown,
|
|
803
|
+
onKeydown: handleTriggerKeydown,
|
|
804
|
+
tabIndex: p.disabled ? -1 : p.tabIndex ?? 0,
|
|
805
|
+
role: "combobox",
|
|
806
|
+
"aria-haspopup": "listbox",
|
|
807
|
+
"aria-expanded": open,
|
|
808
|
+
"aria-controls": listId,
|
|
809
|
+
"aria-activedescendant": open ? activeId : void 0
|
|
810
|
+
}, triggerChildren));
|
|
591
811
|
if (open) {
|
|
592
812
|
resultChildren.push(vdom.createVNode("div", {
|
|
813
|
+
ref: (el) => dropdownRef.set(el),
|
|
814
|
+
id: listId,
|
|
593
815
|
class: "lyt-select__dropdown",
|
|
594
816
|
role: "listbox",
|
|
595
|
-
"aria-multiselectable": p.multiple
|
|
817
|
+
"aria-multiselectable": p.multiple,
|
|
818
|
+
"aria-label": p.ariaLabel || "\u9009\u62E9\u9009\u9879"
|
|
596
819
|
}, dropdownContent));
|
|
820
|
+
resultChildren.push(vdom.createVNode("div", {
|
|
821
|
+
class: "lyt-select__sro",
|
|
822
|
+
role: "status",
|
|
823
|
+
"aria-live": "polite"
|
|
824
|
+
}, `\u5DF2\u9009\u62E9 ${selected.size} \u4E2A\u9009\u9879`));
|
|
597
825
|
}
|
|
598
826
|
const a11yProps = commonA11y.getComboboxA11yProps({
|
|
599
827
|
id: p.id,
|
|
600
|
-
ariaLabel: p.ariaLabel,
|
|
828
|
+
ariaLabel: p.ariaLabel || "\u9009\u62E9\u5668",
|
|
601
829
|
ariaDescribedBy: p.ariaDescribedBy,
|
|
602
830
|
ariaRequired: p.ariaRequired,
|
|
603
831
|
ariaInvalid: p.ariaInvalid,
|
|
604
832
|
disabled: p.disabled,
|
|
605
833
|
tabIndex: p.tabIndex,
|
|
606
834
|
expanded: open,
|
|
607
|
-
controls:
|
|
835
|
+
controls: listId
|
|
608
836
|
});
|
|
609
837
|
return vdom.createVNode("div", commonA11y.mergeA11yProps(a11yProps, {
|
|
610
838
|
class: selectClass,
|
|
@@ -658,6 +886,10 @@ var Tabs = component.defineComponent({
|
|
|
658
886
|
dropIndex: -1
|
|
659
887
|
});
|
|
660
888
|
const activeIndex = reactivity.signal(0);
|
|
889
|
+
const tabListRef = reactivity.signal(null);
|
|
890
|
+
const previousActiveElement = reactivity.signal(null);
|
|
891
|
+
const announcement = reactivity.signal("");
|
|
892
|
+
const tablistId = reactivity.signal(`lyt-tabs-${Math.random().toString(36).substr(2, 9)}`);
|
|
661
893
|
const getPanes = () => {
|
|
662
894
|
const defaultSlot = slots.default;
|
|
663
895
|
const defaultSlotContent = defaultSlot ? defaultSlot() : [];
|
|
@@ -670,11 +902,28 @@ var Tabs = component.defineComponent({
|
|
|
670
902
|
const getEnabledPanes = (panes) => {
|
|
671
903
|
return panes.filter((pane) => !pane.props.disabled);
|
|
672
904
|
};
|
|
905
|
+
const announce = (message) => {
|
|
906
|
+
announcement.set(message);
|
|
907
|
+
setTimeout(() => announcement.set(""), 1e3);
|
|
908
|
+
};
|
|
673
909
|
const handleTabClick = (pane, index) => {
|
|
674
910
|
if (pane.props.disabled) return;
|
|
911
|
+
const oldIndex = activeIndex();
|
|
912
|
+
activeIndex.set(index);
|
|
913
|
+
if (oldIndex !== index) {
|
|
914
|
+
const panes = getPanes();
|
|
915
|
+
announce(`\u5DF2\u5207\u6362\u5230\u6807\u7B7E\u9875 ${index + 1}\uFF1A${pane.props.label}\uFF0C\u5171 ${panes.length} \u4E2A\u6807\u7B7E\u9875`);
|
|
916
|
+
}
|
|
675
917
|
p.onChange?.(pane.props.name);
|
|
676
918
|
p.onTabClick?.(pane, index);
|
|
677
|
-
|
|
919
|
+
previousActiveElement.set(document.activeElement);
|
|
920
|
+
setTimeout(() => {
|
|
921
|
+
const tabList = tabListRef();
|
|
922
|
+
if (tabList) {
|
|
923
|
+
const activeTab = tabList.querySelector('[role="tab"][aria-selected="true"]');
|
|
924
|
+
activeTab?.focus();
|
|
925
|
+
}
|
|
926
|
+
}, 10);
|
|
678
927
|
};
|
|
679
928
|
const handleKeydown = (e) => {
|
|
680
929
|
const panes = getPanes();
|
|
@@ -719,18 +968,30 @@ var Tabs = component.defineComponent({
|
|
|
719
968
|
}
|
|
720
969
|
break;
|
|
721
970
|
case "Enter":
|
|
722
|
-
case " ":
|
|
971
|
+
case " ": {
|
|
723
972
|
e.preventDefault();
|
|
724
973
|
const currentPane = panes[activeIndex()];
|
|
725
974
|
if (currentPane && !currentPane.props.disabled) {
|
|
726
975
|
handleTabClick(currentPane, activeIndex());
|
|
727
976
|
}
|
|
728
977
|
break;
|
|
978
|
+
}
|
|
979
|
+
case "Delete":
|
|
980
|
+
case "Backspace":
|
|
981
|
+
if (p.closable) {
|
|
982
|
+
const currentPane = panes[activeIndex()];
|
|
983
|
+
if (currentPane && currentPane.props.closable) {
|
|
984
|
+
e.preventDefault();
|
|
985
|
+
handleTabRemove(currentPane, new Event("keydown"));
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
break;
|
|
729
989
|
}
|
|
730
990
|
if (newIndex !== activeIndex()) {
|
|
731
|
-
activeIndex.set(newIndex);
|
|
732
991
|
const pane = panes[newIndex];
|
|
733
992
|
if (pane && !pane.props.disabled) {
|
|
993
|
+
activeIndex.set(newIndex);
|
|
994
|
+
announce(`\u5DF2\u5207\u6362\u5230\u6807\u7B7E\u9875 ${newIndex + 1}\uFF1A${pane.props.label}`);
|
|
734
995
|
handleTabClick(pane, newIndex);
|
|
735
996
|
}
|
|
736
997
|
}
|
|
@@ -738,9 +999,27 @@ var Tabs = component.defineComponent({
|
|
|
738
999
|
};
|
|
739
1000
|
const handleTabRemove = (pane, e) => {
|
|
740
1001
|
e.stopPropagation();
|
|
1002
|
+
const panes = getPanes();
|
|
1003
|
+
const index = panes.findIndex((p2) => p2.props.name === pane.props.name);
|
|
1004
|
+
if (index > 0) {
|
|
1005
|
+
const prevPane = panes[index - 1];
|
|
1006
|
+
activeIndex.set(index - 1);
|
|
1007
|
+
if (prevPane) {
|
|
1008
|
+
announce(`\u5DF2\u5173\u95ED\u6807\u7B7E\u9875 ${pane.props.label}\uFF0C\u73B0\u5728\u663E\u793A\u6807\u7B7E\u9875 ${prevPane.props.label}`);
|
|
1009
|
+
}
|
|
1010
|
+
} else if (panes.length > 1) {
|
|
1011
|
+
const nextPane = panes[index + 1];
|
|
1012
|
+
activeIndex.set(0);
|
|
1013
|
+
if (nextPane) {
|
|
1014
|
+
announce(`\u5DF2\u5173\u95ED\u6807\u7B7E\u9875 ${pane.props.label}\uFF0C\u73B0\u5728\u663E\u793A\u6807\u7B7E\u9875 ${nextPane.props.label}`);
|
|
1015
|
+
}
|
|
1016
|
+
} else {
|
|
1017
|
+
announce(`\u5DF2\u5173\u95ED\u6807\u7B7E\u9875 ${pane.props.label}\uFF0C\u73B0\u5728\u6CA1\u6709\u6807\u7B7E\u9875`);
|
|
1018
|
+
}
|
|
741
1019
|
p.onTabRemove?.(pane.props.name);
|
|
742
1020
|
};
|
|
743
1021
|
const handleTabAdd = () => {
|
|
1022
|
+
announce("\u6B63\u5728\u6DFB\u52A0\u65B0\u6807\u7B7E\u9875");
|
|
744
1023
|
p.onTabAdd?.();
|
|
745
1024
|
};
|
|
746
1025
|
const handleDragStart = (index) => {
|
|
@@ -762,6 +1041,7 @@ var Tabs = component.defineComponent({
|
|
|
762
1041
|
const handleDragEnd = () => {
|
|
763
1042
|
const { dragIndex, dropIndex } = dragState();
|
|
764
1043
|
if (dragIndex !== -1 && dropIndex !== -1 && dragIndex !== dropIndex) {
|
|
1044
|
+
announce(`\u6807\u7B7E\u9875\u5DF2\u4ECE\u4F4D\u7F6E ${dragIndex + 1} \u79FB\u52A8\u5230\u4F4D\u7F6E ${dropIndex + 1}`);
|
|
765
1045
|
p.onTabDragEnd?.(dragIndex, dropIndex);
|
|
766
1046
|
}
|
|
767
1047
|
dragState.set({
|
|
@@ -782,6 +1062,7 @@ var Tabs = component.defineComponent({
|
|
|
782
1062
|
`lyt-tabs--${p.type || "normal"}`,
|
|
783
1063
|
p.class
|
|
784
1064
|
].filter(Boolean).join(" ");
|
|
1065
|
+
const tabListId = tablistId();
|
|
785
1066
|
const tabItems = panes.map((pane, index) => {
|
|
786
1067
|
const isActive = pane.props.name === currentName;
|
|
787
1068
|
const isDraggable = p.draggable;
|
|
@@ -790,7 +1071,7 @@ var Tabs = component.defineComponent({
|
|
|
790
1071
|
];
|
|
791
1072
|
if (pane.props.closable || p.closable) {
|
|
792
1073
|
const closeBtnProps = commonA11y.getButtonA11yProps({
|
|
793
|
-
ariaLabel:
|
|
1074
|
+
ariaLabel: `\u5173\u95ED\u6807\u7B7E\u9875 ${pane.props.label}`,
|
|
794
1075
|
disabled: pane.props.disabled
|
|
795
1076
|
});
|
|
796
1077
|
tabChildren.push(vdom.createVNode("span", commonA11y.mergeA11yProps(closeBtnProps, {
|
|
@@ -798,11 +1079,13 @@ var Tabs = component.defineComponent({
|
|
|
798
1079
|
onClick: (e) => handleTabRemove(pane, e)
|
|
799
1080
|
}), [vdom.createTextVNode("\xD7")]));
|
|
800
1081
|
}
|
|
1082
|
+
const tabId = `${p.id || tabListId}-tab-${pane.props.name}`;
|
|
1083
|
+
const panelId2 = `${p.id || tabListId}-panel-${pane.props.name}`;
|
|
801
1084
|
const tabA11yProps = commonA11y.getTabA11yProps({
|
|
802
|
-
id:
|
|
1085
|
+
id: tabId,
|
|
803
1086
|
selected: isActive,
|
|
804
1087
|
disabled: pane.props.disabled,
|
|
805
|
-
controls:
|
|
1088
|
+
controls: panelId2
|
|
806
1089
|
});
|
|
807
1090
|
return vdom.createVNode("div", commonA11y.mergeA11yProps(tabA11yProps, {
|
|
808
1091
|
key: String(pane.props.name),
|
|
@@ -825,7 +1108,7 @@ var Tabs = component.defineComponent({
|
|
|
825
1108
|
});
|
|
826
1109
|
if (p.addable || p.editable) {
|
|
827
1110
|
const addBtnProps = commonA11y.getButtonA11yProps({
|
|
828
|
-
ariaLabel: "
|
|
1111
|
+
ariaLabel: "\u6DFB\u52A0\u65B0\u6807\u7B7E\u9875"
|
|
829
1112
|
});
|
|
830
1113
|
tabItems.push(vdom.createVNode("div", commonA11y.mergeA11yProps(addBtnProps, {
|
|
831
1114
|
class: "lyt-tabs__add-btn",
|
|
@@ -833,26 +1116,40 @@ var Tabs = component.defineComponent({
|
|
|
833
1116
|
}), [vdom.createTextVNode("+")]));
|
|
834
1117
|
}
|
|
835
1118
|
const content = panes.find((pane) => pane.props.name === currentName);
|
|
1119
|
+
const panelId = `${p.id || tabListId}-panel-${content?.props.name || "default"}`;
|
|
836
1120
|
const tabpanelProps = content ? commonA11y.getTabpanelA11yProps({
|
|
837
|
-
id:
|
|
838
|
-
labelledBy: `${p.id ||
|
|
1121
|
+
id: panelId,
|
|
1122
|
+
labelledBy: `${p.id || tabListId}-tab-${content.props.name}`
|
|
839
1123
|
}) : {};
|
|
840
1124
|
const contentPane = content ? vdom.createVNode("div", commonA11y.mergeA11yProps(tabpanelProps, {
|
|
841
|
-
class: "lyt-tabs__pane"
|
|
842
|
-
|
|
1125
|
+
class: "lyt-tabs__pane",
|
|
1126
|
+
id: panelId,
|
|
1127
|
+
role: "tabpanel"
|
|
1128
|
+
}), content.children) : vdom.createVNode("div", { style: "display: none;", id: panelId }, []);
|
|
843
1129
|
const tablistA11yProps = commonA11y.getTablistA11yProps({
|
|
844
|
-
id: p.id,
|
|
845
|
-
ariaLabel: p.ariaLabel || "
|
|
1130
|
+
id: p.id || tabListId,
|
|
1131
|
+
ariaLabel: p.ariaLabel || "\u6807\u7B7E\u9875\u5BFC\u822A",
|
|
846
1132
|
ariaDescribedBy: p.ariaDescribedBy
|
|
847
1133
|
});
|
|
848
1134
|
return vdom.createVNode("div", commonA11y.mergeA11yProps(tablistA11yProps, {
|
|
849
1135
|
class: tabsClass,
|
|
850
1136
|
onKeydown: handleKeydown
|
|
851
1137
|
}), [
|
|
852
|
-
vdom.createVNode("div", {
|
|
1138
|
+
vdom.createVNode("div", {
|
|
1139
|
+
ref: (el) => tabListRef.set(el),
|
|
1140
|
+
class: "lyt-tabs__header",
|
|
1141
|
+
role: "tablist",
|
|
1142
|
+
"aria-label": p.ariaLabel || "\u6807\u7B7E\u9875"
|
|
1143
|
+
}, [
|
|
853
1144
|
vdom.createVNode("div", { class: "lyt-tabs__nav" }, tabItems)
|
|
854
1145
|
]),
|
|
855
|
-
vdom.createVNode("div", { class: "lyt-tabs__content" }, [contentPane])
|
|
1146
|
+
vdom.createVNode("div", { class: "lyt-tabs__content" }, [contentPane]),
|
|
1147
|
+
vdom.createVNode("div", {
|
|
1148
|
+
class: "lyt-tabs__sro",
|
|
1149
|
+
role: "status",
|
|
1150
|
+
"aria-live": "polite",
|
|
1151
|
+
"aria-atomic": "true"
|
|
1152
|
+
}, announcement())
|
|
856
1153
|
]);
|
|
857
1154
|
};
|
|
858
1155
|
}
|
|
@@ -1025,6 +1322,22 @@ var Table = component.defineComponent({
|
|
|
1025
1322
|
};
|
|
1026
1323
|
}
|
|
1027
1324
|
});
|
|
1325
|
+
var DEFAULT_LOCALE = {
|
|
1326
|
+
required: "\u6B64\u5B57\u6BB5\u5FC5\u586B",
|
|
1327
|
+
pattern: "\u683C\u5F0F\u4E0D\u6B63\u786E",
|
|
1328
|
+
min: "\u957F\u5EA6\u4E0D\u80FD\u5C11\u4E8E {min} \u4E2A\u5B57\u7B26",
|
|
1329
|
+
max: "\u957F\u5EA6\u4E0D\u80FD\u8D85\u8FC7 {max} \u4E2A\u5B57\u7B26",
|
|
1330
|
+
type: "\u7C7B\u578B\u4E0D\u6B63\u786E",
|
|
1331
|
+
validator: "\u9A8C\u8BC1\u5931\u8D25",
|
|
1332
|
+
default: "\u9A8C\u8BC1\u5931\u8D25"
|
|
1333
|
+
};
|
|
1334
|
+
function formatMessage(template, params) {
|
|
1335
|
+
let message = template;
|
|
1336
|
+
for (const [key, value] of Object.entries(params)) {
|
|
1337
|
+
message = message.replace(new RegExp(`\\{${key}\\}`, "g"), String(value));
|
|
1338
|
+
}
|
|
1339
|
+
return message;
|
|
1340
|
+
}
|
|
1028
1341
|
var Form = component.defineComponent({
|
|
1029
1342
|
name: "LytForm",
|
|
1030
1343
|
props: {
|
|
@@ -1032,6 +1345,7 @@ var Form = component.defineComponent({
|
|
|
1032
1345
|
rules: { type: Object, default: () => ({}) },
|
|
1033
1346
|
labelWidth: { type: String, default: "100px" },
|
|
1034
1347
|
labelPosition: { type: String, default: "right" },
|
|
1348
|
+
locale: { type: Object, default: () => DEFAULT_LOCALE },
|
|
1035
1349
|
class: { type: String, default: "" },
|
|
1036
1350
|
id: { type: String, default: "" },
|
|
1037
1351
|
ariaLabel: { type: String, default: "" },
|
|
@@ -1041,44 +1355,81 @@ var Form = component.defineComponent({
|
|
|
1041
1355
|
setup(props, { slots }) {
|
|
1042
1356
|
const p = props;
|
|
1043
1357
|
const errors = reactivity.signal({});
|
|
1044
|
-
const
|
|
1358
|
+
const validating = reactivity.signal({});
|
|
1359
|
+
const locale = p.locale || DEFAULT_LOCALE;
|
|
1360
|
+
const validateField = async (field) => {
|
|
1045
1361
|
const rules = p.rules[field];
|
|
1046
1362
|
if (!rules || rules.length === 0) return true;
|
|
1047
1363
|
const value = p.model[field];
|
|
1364
|
+
const fieldErrors = [];
|
|
1048
1365
|
for (const rule of rules) {
|
|
1049
1366
|
if (rule.required && (!value || value === "")) {
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1367
|
+
const message = rule.message || formatMessage(locale.required, { field });
|
|
1368
|
+
fieldErrors.push(message);
|
|
1369
|
+
continue;
|
|
1370
|
+
}
|
|
1371
|
+
if (value !== void 0 && value !== null && value !== "") {
|
|
1372
|
+
if (rule.type) {
|
|
1373
|
+
const typeValid = validateType(value, rule.type);
|
|
1374
|
+
if (!typeValid) {
|
|
1375
|
+
fieldErrors.push(rule.message || formatMessage(locale.type, { type: rule.type, field }));
|
|
1376
|
+
continue;
|
|
1377
|
+
}
|
|
1378
|
+
}
|
|
1379
|
+
if (rule.pattern && !rule.pattern.test(String(value))) {
|
|
1380
|
+
fieldErrors.push(rule.message || formatMessage(locale.pattern, { field }));
|
|
1381
|
+
continue;
|
|
1382
|
+
}
|
|
1383
|
+
if (typeof value === "string") {
|
|
1384
|
+
if (rule.min !== void 0 && value.length < rule.min) {
|
|
1385
|
+
fieldErrors.push(rule.message || formatMessage(locale.min, { min: rule.min, field }));
|
|
1386
|
+
continue;
|
|
1387
|
+
}
|
|
1388
|
+
if (rule.max !== void 0 && value.length > rule.max) {
|
|
1389
|
+
fieldErrors.push(rule.message || formatMessage(locale.max, { max: rule.max, field }));
|
|
1390
|
+
continue;
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1056
1393
|
}
|
|
1057
1394
|
if (rule.validator) {
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1395
|
+
validating.set({ ...validating(), [field]: true });
|
|
1396
|
+
try {
|
|
1397
|
+
const result = await Promise.resolve(rule.validator(value, p.model));
|
|
1398
|
+
if (result !== true) {
|
|
1399
|
+
const errorMessage = typeof result === "string" ? result : formatMessage(locale.validator, { field });
|
|
1400
|
+
fieldErrors.push(errorMessage);
|
|
1401
|
+
}
|
|
1402
|
+
} catch (_error) {
|
|
1403
|
+
fieldErrors.push(rule.message || formatMessage(locale.validator, { field }));
|
|
1404
|
+
} finally {
|
|
1405
|
+
validating.set({ ...validating(), [field]: false });
|
|
1062
1406
|
}
|
|
1063
1407
|
}
|
|
1064
1408
|
}
|
|
1409
|
+
if (fieldErrors.length > 0) {
|
|
1410
|
+
errors.set({ ...errors(), [field]: fieldErrors[0] });
|
|
1411
|
+
return false;
|
|
1412
|
+
}
|
|
1065
1413
|
const newErrors = { ...errors() };
|
|
1066
1414
|
delete newErrors[field];
|
|
1067
1415
|
errors.set(newErrors);
|
|
1068
1416
|
return true;
|
|
1069
1417
|
};
|
|
1070
|
-
const validate = () => {
|
|
1418
|
+
const validate = async () => {
|
|
1071
1419
|
let isValid = true;
|
|
1072
|
-
|
|
1073
|
-
|
|
1420
|
+
const fieldNames = Object.keys(p.rules);
|
|
1421
|
+
for (const field of fieldNames) {
|
|
1422
|
+
const fieldValid = await validateField(field);
|
|
1423
|
+
if (!fieldValid) {
|
|
1074
1424
|
isValid = false;
|
|
1075
1425
|
}
|
|
1076
1426
|
}
|
|
1077
1427
|
return isValid;
|
|
1078
1428
|
};
|
|
1079
|
-
const handleSubmit = (event) => {
|
|
1429
|
+
const handleSubmit = async (event) => {
|
|
1080
1430
|
event.preventDefault();
|
|
1081
|
-
|
|
1431
|
+
const isValid = await validate();
|
|
1432
|
+
if (isValid) {
|
|
1082
1433
|
p.onSubmit?.(p.model);
|
|
1083
1434
|
}
|
|
1084
1435
|
};
|
|
@@ -1099,6 +1450,33 @@ var Form = component.defineComponent({
|
|
|
1099
1450
|
};
|
|
1100
1451
|
}
|
|
1101
1452
|
});
|
|
1453
|
+
function validateType(value, type) {
|
|
1454
|
+
switch (type) {
|
|
1455
|
+
case "string":
|
|
1456
|
+
return typeof value === "string";
|
|
1457
|
+
case "number":
|
|
1458
|
+
return typeof value === "number" && !isNaN(value);
|
|
1459
|
+
case "boolean":
|
|
1460
|
+
return typeof value === "boolean";
|
|
1461
|
+
case "array":
|
|
1462
|
+
return Array.isArray(value);
|
|
1463
|
+
case "date":
|
|
1464
|
+
return value instanceof Date || !isNaN(Date.parse(String(value)));
|
|
1465
|
+
case "email": {
|
|
1466
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
1467
|
+
return typeof value === "string" && emailRegex.test(value);
|
|
1468
|
+
}
|
|
1469
|
+
case "url":
|
|
1470
|
+
try {
|
|
1471
|
+
new URL(String(value));
|
|
1472
|
+
return true;
|
|
1473
|
+
} catch {
|
|
1474
|
+
return false;
|
|
1475
|
+
}
|
|
1476
|
+
default:
|
|
1477
|
+
return true;
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1102
1480
|
var FormItem = component.defineComponent({
|
|
1103
1481
|
name: "LytFormItem",
|
|
1104
1482
|
props: {
|
|
@@ -1157,15 +1535,16 @@ var Transition = component.defineComponent({
|
|
|
1157
1535
|
class: { type: String, default: "" }
|
|
1158
1536
|
},
|
|
1159
1537
|
setup(props, { slots }) {
|
|
1538
|
+
const p = props;
|
|
1160
1539
|
const getTransitionClass = () => {
|
|
1161
|
-
const classes = [`${
|
|
1162
|
-
if (
|
|
1163
|
-
classes.push(
|
|
1540
|
+
const classes = [`${p.name}-transition`];
|
|
1541
|
+
if (p.class) {
|
|
1542
|
+
classes.push(p.class);
|
|
1164
1543
|
}
|
|
1165
1544
|
return classes.join(" ");
|
|
1166
1545
|
};
|
|
1167
1546
|
const getTransitionStyle = () => {
|
|
1168
|
-
return `transition-duration: ${
|
|
1547
|
+
return `transition-duration: ${p.duration}ms;`;
|
|
1169
1548
|
};
|
|
1170
1549
|
return () => {
|
|
1171
1550
|
return vdom.createVNode("div", {
|
|
@@ -1184,17 +1563,18 @@ var TransitionGroup = component.defineComponent({
|
|
|
1184
1563
|
class: { type: String, default: "" }
|
|
1185
1564
|
},
|
|
1186
1565
|
setup(props, { slots }) {
|
|
1566
|
+
const p = props;
|
|
1187
1567
|
return () => {
|
|
1188
1568
|
const children = slots.default?.() || [];
|
|
1189
1569
|
const wrappedChildren = children.map(
|
|
1190
1570
|
(child, index) => vdom.createVNode("div", {
|
|
1191
1571
|
key: child.key || index,
|
|
1192
|
-
class: `${
|
|
1193
|
-
style: `transition: all ${
|
|
1572
|
+
class: `${p.name}-item`,
|
|
1573
|
+
style: `transition: all ${p.duration}ms ease;`
|
|
1194
1574
|
}, [child])
|
|
1195
1575
|
);
|
|
1196
|
-
return vdom.createVNode(
|
|
1197
|
-
class: `lyt-transition-group ${
|
|
1576
|
+
return vdom.createVNode(p.tag, {
|
|
1577
|
+
class: `lyt-transition-group ${p.class}`
|
|
1198
1578
|
}, wrappedChildren);
|
|
1199
1579
|
};
|
|
1200
1580
|
}
|
|
@@ -1661,24 +2041,167 @@ var Menu = component.defineComponent({
|
|
|
1661
2041
|
const p = props;
|
|
1662
2042
|
const activeIndex = reactivity.signal(p.defaultActive);
|
|
1663
2043
|
const openedIndexes = reactivity.signal(new Set(p.defaultOpeneds));
|
|
2044
|
+
const menuRef = reactivity.signal(null);
|
|
2045
|
+
const currentSubmenu = reactivity.signal(null);
|
|
2046
|
+
const focusedIndex = reactivity.signal(-1);
|
|
2047
|
+
const announcement = reactivity.signal("");
|
|
2048
|
+
const previousActiveElement = reactivity.signal(null);
|
|
2049
|
+
const menuId = reactivity.signal(`lyt-menu-${Math.random().toString(36).substr(2, 9)}`);
|
|
2050
|
+
const announce = (message) => {
|
|
2051
|
+
announcement.set(message);
|
|
2052
|
+
setTimeout(() => announcement.set(""), 1e3);
|
|
2053
|
+
};
|
|
2054
|
+
const getMenuItems = () => {
|
|
2055
|
+
const items = slots.default?.() || [];
|
|
2056
|
+
const menuItems = [];
|
|
2057
|
+
items.forEach((item) => {
|
|
2058
|
+
const itemProps = item.props;
|
|
2059
|
+
if (!itemProps || !itemProps.index) return;
|
|
2060
|
+
const hasChildren = !!(itemProps.children && itemProps.children.length > 0);
|
|
2061
|
+
menuItems.push({
|
|
2062
|
+
index: itemProps.index,
|
|
2063
|
+
label: itemProps.label || "",
|
|
2064
|
+
disabled: !!itemProps.disabled,
|
|
2065
|
+
hasChildren,
|
|
2066
|
+
element: null
|
|
2067
|
+
});
|
|
2068
|
+
});
|
|
2069
|
+
return menuItems;
|
|
2070
|
+
};
|
|
1664
2071
|
const handleSelect = (index) => {
|
|
1665
2072
|
activeIndex.set(index);
|
|
2073
|
+
announce(`\u5DF2\u9009\u62E9\u83DC\u5355\u9879\uFF1A${index}`);
|
|
1666
2074
|
p.onSelect?.(index);
|
|
1667
2075
|
};
|
|
1668
|
-
const toggleSubmenu = (index) => {
|
|
2076
|
+
const toggleSubmenu = (index, itemLabel) => {
|
|
1669
2077
|
const newOpened = new Set(openedIndexes());
|
|
1670
2078
|
if (newOpened.has(index)) {
|
|
1671
2079
|
newOpened.delete(index);
|
|
2080
|
+
announce(`\u5DF2\u5173\u95ED\u5B50\u83DC\u5355\uFF1A${itemLabel}`);
|
|
1672
2081
|
p.onClose?.(index);
|
|
2082
|
+
currentSubmenu.set(null);
|
|
2083
|
+
const prevEl = previousActiveElement();
|
|
2084
|
+
if (prevEl && prevEl.focus) {
|
|
2085
|
+
prevEl.focus();
|
|
2086
|
+
}
|
|
1673
2087
|
} else {
|
|
1674
2088
|
if (p.uniqueOpened) {
|
|
1675
2089
|
newOpened.clear();
|
|
2090
|
+
if (currentSubmenu()) {
|
|
2091
|
+
announce("\u5DF2\u5173\u95ED\u5176\u4ED6\u5B50\u83DC\u5355");
|
|
2092
|
+
}
|
|
1676
2093
|
}
|
|
1677
2094
|
newOpened.add(index);
|
|
2095
|
+
announce(`\u5DF2\u6253\u5F00\u5B50\u83DC\u5355\uFF1A${itemLabel}`);
|
|
1678
2096
|
p.onOpen?.(index);
|
|
2097
|
+
currentSubmenu.set(index);
|
|
2098
|
+
previousActiveElement.set(document.activeElement);
|
|
2099
|
+
setTimeout(() => {
|
|
2100
|
+
const menu = menuRef();
|
|
2101
|
+
if (menu) {
|
|
2102
|
+
const submenu = menu.querySelector(`[data-submenu-id="${index}"] ul`);
|
|
2103
|
+
if (submenu) {
|
|
2104
|
+
const firstItem = submenu.querySelector('[role="menuitem"]');
|
|
2105
|
+
firstItem?.focus();
|
|
2106
|
+
}
|
|
2107
|
+
}
|
|
2108
|
+
}, 10);
|
|
1679
2109
|
}
|
|
1680
2110
|
openedIndexes.set(newOpened);
|
|
1681
2111
|
};
|
|
2112
|
+
const handleKeydown = (e, itemIndex, hasChildren, itemLabel) => {
|
|
2113
|
+
const menuItems = getMenuItems();
|
|
2114
|
+
const currentIndex = menuItems.findIndex((item) => item.index === itemIndex);
|
|
2115
|
+
switch (e.key) {
|
|
2116
|
+
case "ArrowDown":
|
|
2117
|
+
e.preventDefault();
|
|
2118
|
+
if (hasChildren && !openedIndexes().has(itemIndex)) {
|
|
2119
|
+
toggleSubmenu(itemIndex, itemLabel);
|
|
2120
|
+
} else {
|
|
2121
|
+
for (let i = 1; i <= menuItems.length; i++) {
|
|
2122
|
+
const nextIndex = (currentIndex + i) % menuItems.length;
|
|
2123
|
+
const nextItem = menuItems[nextIndex];
|
|
2124
|
+
if (nextItem && !nextItem.disabled) {
|
|
2125
|
+
announce(`\u5BFC\u822A\u5230\u83DC\u5355\u9879\uFF1A${nextItem.label}`);
|
|
2126
|
+
focusedIndex.set(nextIndex);
|
|
2127
|
+
break;
|
|
2128
|
+
}
|
|
2129
|
+
}
|
|
2130
|
+
}
|
|
2131
|
+
break;
|
|
2132
|
+
case "ArrowUp":
|
|
2133
|
+
e.preventDefault();
|
|
2134
|
+
for (let i = 1; i <= menuItems.length; i++) {
|
|
2135
|
+
const prevIndex = (currentIndex - i + menuItems.length) % menuItems.length;
|
|
2136
|
+
const prevItem = menuItems[prevIndex];
|
|
2137
|
+
if (prevItem && !prevItem.disabled) {
|
|
2138
|
+
announce(`\u5BFC\u822A\u5230\u83DC\u5355\u9879\uFF1A${prevItem.label}`);
|
|
2139
|
+
focusedIndex.set(prevIndex);
|
|
2140
|
+
break;
|
|
2141
|
+
}
|
|
2142
|
+
}
|
|
2143
|
+
break;
|
|
2144
|
+
case "ArrowRight":
|
|
2145
|
+
e.preventDefault();
|
|
2146
|
+
for (let i = 1; i <= menuItems.length; i++) {
|
|
2147
|
+
const nextIndex = (currentIndex + i) % menuItems.length;
|
|
2148
|
+
const nextItem = menuItems[nextIndex];
|
|
2149
|
+
if (nextItem && !nextItem.disabled) {
|
|
2150
|
+
announce(`\u5BFC\u822A\u5230\u83DC\u5355\u9879\uFF1A${nextItem.label}`);
|
|
2151
|
+
focusedIndex.set(nextIndex);
|
|
2152
|
+
break;
|
|
2153
|
+
}
|
|
2154
|
+
}
|
|
2155
|
+
break;
|
|
2156
|
+
case "ArrowLeft":
|
|
2157
|
+
e.preventDefault();
|
|
2158
|
+
for (let i = 1; i <= menuItems.length; i++) {
|
|
2159
|
+
const prevIndex = (currentIndex - i + menuItems.length) % menuItems.length;
|
|
2160
|
+
const prevItem = menuItems[prevIndex];
|
|
2161
|
+
if (prevItem && !prevItem.disabled) {
|
|
2162
|
+
announce(`\u5BFC\u822A\u5230\u83DC\u5355\u9879\uFF1A${prevItem.label}`);
|
|
2163
|
+
focusedIndex.set(prevIndex);
|
|
2164
|
+
break;
|
|
2165
|
+
}
|
|
2166
|
+
}
|
|
2167
|
+
break;
|
|
2168
|
+
case "Enter":
|
|
2169
|
+
case " ":
|
|
2170
|
+
e.preventDefault();
|
|
2171
|
+
if (hasChildren) {
|
|
2172
|
+
toggleSubmenu(itemIndex, itemLabel);
|
|
2173
|
+
} else {
|
|
2174
|
+
handleSelect(itemIndex);
|
|
2175
|
+
}
|
|
2176
|
+
break;
|
|
2177
|
+
case "Escape":
|
|
2178
|
+
if (openedIndexes().has(itemIndex)) {
|
|
2179
|
+
e.preventDefault();
|
|
2180
|
+
toggleSubmenu(itemIndex, itemLabel);
|
|
2181
|
+
}
|
|
2182
|
+
break;
|
|
2183
|
+
case "Home": {
|
|
2184
|
+
e.preventDefault();
|
|
2185
|
+
const firstEnabled = menuItems.find((item) => !item.disabled);
|
|
2186
|
+
if (firstEnabled) {
|
|
2187
|
+
announce(`\u5BFC\u822A\u5230\u7B2C\u4E00\u4E2A\u83DC\u5355\u9879\uFF1A${firstEnabled.label}`);
|
|
2188
|
+
focusedIndex.set(menuItems.indexOf(firstEnabled));
|
|
2189
|
+
}
|
|
2190
|
+
break;
|
|
2191
|
+
}
|
|
2192
|
+
case "End":
|
|
2193
|
+
e.preventDefault();
|
|
2194
|
+
for (let i = menuItems.length - 1; i >= 0; i--) {
|
|
2195
|
+
const item = menuItems[i];
|
|
2196
|
+
if (item && !item.disabled) {
|
|
2197
|
+
announce(`\u5BFC\u822A\u5230\u6700\u540E\u4E00\u4E2A\u83DC\u5355\u9879\uFF1A${item.label}`);
|
|
2198
|
+
focusedIndex.set(i);
|
|
2199
|
+
break;
|
|
2200
|
+
}
|
|
2201
|
+
}
|
|
2202
|
+
break;
|
|
2203
|
+
}
|
|
2204
|
+
};
|
|
1682
2205
|
return () => {
|
|
1683
2206
|
const menuClass = [
|
|
1684
2207
|
"lyt-menu",
|
|
@@ -1686,66 +2209,105 @@ var Menu = component.defineComponent({
|
|
|
1686
2209
|
p.class
|
|
1687
2210
|
].filter(Boolean).join(" ");
|
|
1688
2211
|
const items = slots.default?.() || [];
|
|
1689
|
-
const
|
|
2212
|
+
const menuListId = menuId();
|
|
2213
|
+
const menuItems = items.map((item, index) => {
|
|
1690
2214
|
const itemProps = item.props;
|
|
1691
2215
|
if (!itemProps) return item;
|
|
1692
2216
|
const isActive = itemProps.index === activeIndex();
|
|
1693
2217
|
const isOpened = openedIndexes().has(itemProps.index);
|
|
2218
|
+
const isFocused = focusedIndex() === index;
|
|
1694
2219
|
const itemChildren = [];
|
|
1695
2220
|
if (itemProps.icon) {
|
|
1696
2221
|
itemChildren.push(vdom.createVNode("span", { class: "lyt-menu__icon" }, [itemProps.icon]));
|
|
1697
2222
|
}
|
|
1698
2223
|
itemChildren.push(vdom.createVNode("span", { class: "lyt-menu__title" }, [vdom.createVNode("span", {}, String(itemProps.label || ""))]));
|
|
1699
|
-
|
|
2224
|
+
const hasChildren = !!(itemProps.children && itemProps.children.length > 0);
|
|
2225
|
+
const itemId = `${menuListId}-item-${itemProps.index}`;
|
|
2226
|
+
if (hasChildren) {
|
|
1700
2227
|
itemChildren.push(vdom.createVNode("span", {
|
|
1701
|
-
class: ["lyt-menu__arrow", isOpened ? "lyt-menu__arrow--opened" : ""].filter(Boolean).join(" ")
|
|
2228
|
+
class: ["lyt-menu__arrow", isOpened ? "lyt-menu__arrow--opened" : ""].filter(Boolean).join(" "),
|
|
2229
|
+
"aria-hidden": "true"
|
|
1702
2230
|
}, [vdom.createVNode("span", {}, isOpened ? "\u25B2" : "\u25BC")]));
|
|
1703
2231
|
const submenuChildren = itemProps.children.map((child) => {
|
|
1704
2232
|
const childItem = child;
|
|
1705
|
-
const
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
});
|
|
1709
|
-
return vdom.createVNode("li", commonA11y.mergeA11yProps(childBtnProps, {
|
|
2233
|
+
const childItemId = `${itemId}-child-${childItem.index}`;
|
|
2234
|
+
const isChildActive = childItem.index === activeIndex();
|
|
2235
|
+
return vdom.createVNode("li", {
|
|
1710
2236
|
key: childItem.index,
|
|
2237
|
+
id: childItemId,
|
|
1711
2238
|
class: [
|
|
1712
2239
|
"lyt-menu__item",
|
|
1713
|
-
|
|
2240
|
+
"lyt-menu__submenu-item",
|
|
2241
|
+
isChildActive ? "lyt-menu__item--active" : "",
|
|
1714
2242
|
childItem.disabled ? "lyt-menu__item--disabled" : ""
|
|
1715
2243
|
].filter(Boolean).join(" "),
|
|
2244
|
+
role: "menuitem",
|
|
2245
|
+
"aria-disabled": childItem.disabled,
|
|
1716
2246
|
onClick: () => {
|
|
1717
2247
|
if (childItem.disabled) return;
|
|
1718
2248
|
handleSelect(childItem.index);
|
|
1719
2249
|
}
|
|
1720
|
-
}
|
|
2250
|
+
}, [
|
|
1721
2251
|
childItem.icon ? vdom.createVNode("span", { class: "lyt-menu__icon" }, [childItem.icon]) : vdom.createVNode("span", {}, ""),
|
|
1722
2252
|
vdom.createVNode("span", { class: "lyt-menu__title" }, [vdom.createVNode("span", {}, String(childItem.label || ""))])
|
|
1723
2253
|
]);
|
|
1724
2254
|
});
|
|
1725
|
-
itemChildren.push(vdom.createVNode("
|
|
2255
|
+
itemChildren.push(vdom.createVNode("div", {
|
|
2256
|
+
"data-submenu-id": itemProps.index,
|
|
2257
|
+
class: ["lyt-menu__submenu", isOpened ? "lyt-menu__submenu--opened" : ""].filter(Boolean).join(" "),
|
|
2258
|
+
"aria-label": itemProps.label
|
|
2259
|
+
}, [
|
|
2260
|
+
vdom.createVNode("ul", {
|
|
2261
|
+
class: "lyt-menu__submenu-list",
|
|
2262
|
+
role: "menu"
|
|
2263
|
+
}, submenuChildren)
|
|
2264
|
+
]));
|
|
1726
2265
|
}
|
|
1727
|
-
const
|
|
1728
|
-
|
|
1729
|
-
disabled: itemProps.disabled
|
|
1730
|
-
|
|
1731
|
-
|
|
2266
|
+
const itemMenuitemProps = {
|
|
2267
|
+
id: itemId,
|
|
2268
|
+
"aria-disabled": itemProps.disabled ? true : void 0,
|
|
2269
|
+
"aria-expanded": hasChildren ? isOpened : void 0,
|
|
2270
|
+
"aria-haspopup": hasChildren ? true : void 0
|
|
2271
|
+
};
|
|
2272
|
+
return vdom.createVNode("li", commonA11y.mergeA11yProps(itemMenuitemProps, {
|
|
1732
2273
|
key: itemProps.index,
|
|
1733
2274
|
class: [
|
|
1734
2275
|
"lyt-menu__item",
|
|
1735
2276
|
isActive ? "lyt-menu__item--active" : "",
|
|
2277
|
+
isFocused ? "lyt-menu__item--focused" : "",
|
|
1736
2278
|
itemProps.disabled ? "lyt-menu__item--disabled" : ""
|
|
1737
2279
|
].filter(Boolean).join(" "),
|
|
2280
|
+
role: "menuitem",
|
|
2281
|
+
tabIndex: isFocused ? 0 : -1,
|
|
2282
|
+
"aria-haspopup": hasChildren,
|
|
2283
|
+
"aria-expanded": hasChildren ? isOpened : void 0,
|
|
1738
2284
|
onClick: () => {
|
|
1739
2285
|
if (itemProps.disabled) return;
|
|
1740
|
-
if (
|
|
1741
|
-
toggleSubmenu(itemProps.index);
|
|
2286
|
+
if (hasChildren) {
|
|
2287
|
+
toggleSubmenu(itemProps.index, itemProps.label || "");
|
|
1742
2288
|
} else {
|
|
1743
2289
|
handleSelect(itemProps.index);
|
|
1744
2290
|
}
|
|
1745
|
-
}
|
|
2291
|
+
},
|
|
2292
|
+
onKeydown: (e) => handleKeydown(e, itemProps.index, hasChildren, itemProps.label || "")
|
|
1746
2293
|
}), itemChildren);
|
|
1747
2294
|
});
|
|
1748
|
-
return vdom.createVNode("
|
|
2295
|
+
return vdom.createVNode("div", {
|
|
2296
|
+
ref: (el) => menuRef.set(el)
|
|
2297
|
+
}, [
|
|
2298
|
+
vdom.createVNode("ul", {
|
|
2299
|
+
class: menuClass,
|
|
2300
|
+
role: "menubar",
|
|
2301
|
+
id: p.id || menuListId,
|
|
2302
|
+
"aria-label": p.ariaLabel || "\u4E3B\u83DC\u5355"
|
|
2303
|
+
}, menuItems),
|
|
2304
|
+
vdom.createVNode("div", {
|
|
2305
|
+
class: "lyt-menu__sro",
|
|
2306
|
+
role: "status",
|
|
2307
|
+
"aria-live": "polite",
|
|
2308
|
+
"aria-atomic": "true"
|
|
2309
|
+
}, announcement())
|
|
2310
|
+
]);
|
|
1749
2311
|
};
|
|
1750
2312
|
}
|
|
1751
2313
|
});
|
|
@@ -1815,7 +2377,7 @@ var Cascader = component.defineComponent({
|
|
|
1815
2377
|
const newPath = [...activePath().slice(0, level), option.value];
|
|
1816
2378
|
activePath.set(newPath);
|
|
1817
2379
|
const nextOptions = option.children || [];
|
|
1818
|
-
if (option.isLeaf
|
|
2380
|
+
if (option.isLeaf) {
|
|
1819
2381
|
if (p.multiple) {
|
|
1820
2382
|
const exists = selectedValues().some((item) => item.join("-") === newPath.join("-"));
|
|
1821
2383
|
const newSelected = exists ? selectedValues().filter((item) => item.join("-") !== newPath.join("-")) : [...selectedValues(), newPath];
|
|
@@ -1826,7 +2388,7 @@ var Cascader = component.defineComponent({
|
|
|
1826
2388
|
isDropdownOpen.set(false);
|
|
1827
2389
|
p.onChange?.(newPath);
|
|
1828
2390
|
}
|
|
1829
|
-
} else if (
|
|
2391
|
+
} else if (nextOptions.length === 0 && p.load) {
|
|
1830
2392
|
option.loading = true;
|
|
1831
2393
|
p.load(option, (children) => {
|
|
1832
2394
|
option.loading = false;
|
|
@@ -3903,23 +4465,24 @@ var Icon = component.defineComponent({
|
|
|
3903
4465
|
ariaDescribedBy: { type: String, default: "" }
|
|
3904
4466
|
},
|
|
3905
4467
|
setup(props, { slots }) {
|
|
4468
|
+
const p = props;
|
|
3906
4469
|
const getIconClass = () => {
|
|
3907
4470
|
const classes = ["lyt-icon"];
|
|
3908
|
-
if (
|
|
3909
|
-
if (
|
|
3910
|
-
if (
|
|
4471
|
+
if (p.name) classes.push(`lyt-icon--${p.name}`);
|
|
4472
|
+
if (p.spin) classes.push("lyt-icon--spin");
|
|
4473
|
+
if (p.class) classes.push(p.class);
|
|
3911
4474
|
return classes.join(" ");
|
|
3912
4475
|
};
|
|
3913
4476
|
const getIconStyle = () => {
|
|
3914
4477
|
const style = {};
|
|
3915
|
-
if (
|
|
3916
|
-
if (
|
|
3917
|
-
if (
|
|
3918
|
-
if (commonIs.isString(
|
|
3919
|
-
return
|
|
4478
|
+
if (p.size) style.fontSize = p.size;
|
|
4479
|
+
if (p.color) style.color = p.color;
|
|
4480
|
+
if (p.style) {
|
|
4481
|
+
if (commonIs.isString(p.style)) {
|
|
4482
|
+
return p.style;
|
|
3920
4483
|
}
|
|
3921
|
-
if (commonIs.isObject(
|
|
3922
|
-
Object.assign(style,
|
|
4484
|
+
if (commonIs.isObject(p.style)) {
|
|
4485
|
+
Object.assign(style, p.style);
|
|
3923
4486
|
}
|
|
3924
4487
|
}
|
|
3925
4488
|
return style;
|
|
@@ -3930,9 +4493,9 @@ var Icon = component.defineComponent({
|
|
|
3930
4493
|
children.push(...slots.default());
|
|
3931
4494
|
}
|
|
3932
4495
|
return vdom.createVNode("i", commonA11y.mergeA11yProps({
|
|
3933
|
-
id:
|
|
3934
|
-
"aria-label":
|
|
3935
|
-
"aria-describedby":
|
|
4496
|
+
id: p.id,
|
|
4497
|
+
"aria-label": p.ariaLabel,
|
|
4498
|
+
"aria-describedby": p.ariaDescribedBy
|
|
3936
4499
|
}, {
|
|
3937
4500
|
class: getIconClass(),
|
|
3938
4501
|
style: getIconStyle()
|
|
@@ -4094,6 +4657,7 @@ var Spin = component.defineComponent({
|
|
|
4094
4657
|
ariaDescribedBy: { type: String, default: "" }
|
|
4095
4658
|
},
|
|
4096
4659
|
setup(props, { slots }) {
|
|
4660
|
+
const p = props;
|
|
4097
4661
|
const state = reactivity.reactive({
|
|
4098
4662
|
visible: props.spinning
|
|
4099
4663
|
});
|
|
@@ -4101,10 +4665,10 @@ var Spin = component.defineComponent({
|
|
|
4101
4665
|
reactivity.watch(() => props.spinning, (val) => {
|
|
4102
4666
|
if (delayTimer) clearTimeout(delayTimer);
|
|
4103
4667
|
if (val) {
|
|
4104
|
-
if (
|
|
4668
|
+
if (p.delay && p.delay > 0) {
|
|
4105
4669
|
delayTimer = setTimeout(() => {
|
|
4106
4670
|
state.visible = true;
|
|
4107
|
-
},
|
|
4671
|
+
}, p.delay);
|
|
4108
4672
|
} else {
|
|
4109
4673
|
state.visible = true;
|
|
4110
4674
|
}
|
|
@@ -4118,14 +4682,14 @@ var Spin = component.defineComponent({
|
|
|
4118
4682
|
const getSpinClass = () => {
|
|
4119
4683
|
const classes = ["lyt-spin"];
|
|
4120
4684
|
if (state.visible) classes.push("lyt-spin--spinning");
|
|
4121
|
-
if (
|
|
4685
|
+
if (p.class) classes.push(p.class);
|
|
4122
4686
|
return classes.join(" ");
|
|
4123
4687
|
};
|
|
4124
4688
|
const getSpinStyle = () => {
|
|
4125
|
-
if (!
|
|
4126
|
-
if (commonIs.isString(
|
|
4127
|
-
if (commonIs.isObject(
|
|
4128
|
-
return Object.entries(
|
|
4689
|
+
if (!p.style) return void 0;
|
|
4690
|
+
if (commonIs.isString(p.style)) return p.style;
|
|
4691
|
+
if (commonIs.isObject(p.style)) {
|
|
4692
|
+
return Object.entries(p.style).map(([key, value]) => `${key}: ${value}`).join("; ");
|
|
4129
4693
|
}
|
|
4130
4694
|
return void 0;
|
|
4131
4695
|
};
|
|
@@ -4133,15 +4697,15 @@ var Spin = component.defineComponent({
|
|
|
4133
4697
|
const children = [];
|
|
4134
4698
|
if (state.visible) {
|
|
4135
4699
|
const loadingChildren = [];
|
|
4136
|
-
loadingChildren.push(vdom.createVNode("div", { class: `lyt-spin__icon lyt-spin__icon--${
|
|
4700
|
+
loadingChildren.push(vdom.createVNode("div", { class: `lyt-spin__icon lyt-spin__icon--${p.size}` }, [
|
|
4137
4701
|
vdom.createVNode("svg", { viewBox: "0 0 1024 1024", class: "lyt-spin__svg" }, [
|
|
4138
4702
|
vdom.createVNode("path", {
|
|
4139
4703
|
d: "M512 64a32 32 0 0 1 32 32v192a32 32 0 0 1-64 0V96a32 32 0 0 1 32-32zm0 640a32 32 0 0 1 32 32v192a32 32 0 0 1-64 0V736a32 32 0 0 1 32-32zm-448-192a32 32 0 0 1 32-32h192a32 32 0 0 1 0 64H96a32 32 0 0 1-32-32zm640 0a32 32 0 0 1 32-32h192a32 32 0 0 1 0 64H736a32 32 0 0 1-32-32z"
|
|
4140
4704
|
})
|
|
4141
4705
|
])
|
|
4142
4706
|
]));
|
|
4143
|
-
if (
|
|
4144
|
-
loadingChildren.push(vdom.createVNode("div", { class: "lyt-spin__tip" }, slots.tip ? slots.tip() : [
|
|
4707
|
+
if (p.tip || slots.tip) {
|
|
4708
|
+
loadingChildren.push(vdom.createVNode("div", { class: "lyt-spin__tip" }, slots.tip ? slots.tip() : [vdom.createTextVNode(p.tip)]));
|
|
4145
4709
|
}
|
|
4146
4710
|
children.push(vdom.createVNode("div", { class: "lyt-spin__loading" }, loadingChildren));
|
|
4147
4711
|
}
|
|
@@ -4151,9 +4715,9 @@ var Spin = component.defineComponent({
|
|
|
4151
4715
|
}, slots.default()));
|
|
4152
4716
|
}
|
|
4153
4717
|
return vdom.createVNode("div", commonA11y.mergeA11yProps({
|
|
4154
|
-
id:
|
|
4155
|
-
"aria-label":
|
|
4156
|
-
"aria-describedby":
|
|
4718
|
+
id: p.id,
|
|
4719
|
+
"aria-label": p.ariaLabel,
|
|
4720
|
+
"aria-describedby": p.ariaDescribedBy,
|
|
4157
4721
|
role: "alert",
|
|
4158
4722
|
"aria-live": "polite"
|
|
4159
4723
|
}, {
|
|
@@ -4176,16 +4740,17 @@ var Empty = component.defineComponent({
|
|
|
4176
4740
|
ariaDescribedBy: { type: String, default: "" }
|
|
4177
4741
|
},
|
|
4178
4742
|
setup(props, { slots }) {
|
|
4743
|
+
const p = props;
|
|
4179
4744
|
const getEmptyClass = () => {
|
|
4180
4745
|
const classes = ["lyt-empty"];
|
|
4181
|
-
if (
|
|
4746
|
+
if (p.class) classes.push(p.class);
|
|
4182
4747
|
return classes.join(" ");
|
|
4183
4748
|
};
|
|
4184
4749
|
const getEmptyStyle = () => {
|
|
4185
|
-
if (!
|
|
4186
|
-
if (commonIs.isString(
|
|
4187
|
-
if (commonIs.isObject(
|
|
4188
|
-
return Object.entries(
|
|
4750
|
+
if (!p.style) return void 0;
|
|
4751
|
+
if (commonIs.isString(p.style)) return p.style;
|
|
4752
|
+
if (commonIs.isObject(p.style)) {
|
|
4753
|
+
return Object.entries(p.style).map(([key, value]) => `${key}: ${value}`).join("; ");
|
|
4189
4754
|
}
|
|
4190
4755
|
return void 0;
|
|
4191
4756
|
};
|
|
@@ -4193,12 +4758,12 @@ var Empty = component.defineComponent({
|
|
|
4193
4758
|
const children = [];
|
|
4194
4759
|
if (slots.image) {
|
|
4195
4760
|
children.push(vdom.createVNode("div", { class: "lyt-empty__image" }, slots.image()));
|
|
4196
|
-
} else if (
|
|
4761
|
+
} else if (p.image) {
|
|
4197
4762
|
children.push(vdom.createVNode("div", { class: "lyt-empty__image" }, [
|
|
4198
4763
|
vdom.createVNode("img", {
|
|
4199
|
-
src:
|
|
4764
|
+
src: p.image,
|
|
4200
4765
|
alt: "empty",
|
|
4201
|
-
style: { width: `${
|
|
4766
|
+
style: { width: `${p.imageSize}px`, height: `${p.imageSize}px` }
|
|
4202
4767
|
})
|
|
4203
4768
|
]));
|
|
4204
4769
|
} else {
|
|
@@ -4206,7 +4771,7 @@ var Empty = component.defineComponent({
|
|
|
4206
4771
|
vdom.createVNode("svg", {
|
|
4207
4772
|
viewBox: "0 0 400 320",
|
|
4208
4773
|
class: "lyt-empty__svg",
|
|
4209
|
-
style: { width: `${
|
|
4774
|
+
style: { width: `${p.imageSize || 160}px`, height: `${(p.imageSize || 160) * 0.8}px` }
|
|
4210
4775
|
}, [
|
|
4211
4776
|
vdom.createVNode("g", { fill: "none", "fill-rule": "evenodd" }, [
|
|
4212
4777
|
vdom.createVNode("g", { transform: "translate(40 40)" }, [
|
|
@@ -4224,16 +4789,16 @@ var Empty = component.defineComponent({
|
|
|
4224
4789
|
}
|
|
4225
4790
|
if (slots.description) {
|
|
4226
4791
|
children.push(vdom.createVNode("div", { class: "lyt-empty__description" }, slots.description()));
|
|
4227
|
-
} else if (
|
|
4228
|
-
children.push(vdom.createVNode("div", { class: "lyt-empty__description" }, [
|
|
4792
|
+
} else if (p.description) {
|
|
4793
|
+
children.push(vdom.createVNode("div", { class: "lyt-empty__description" }, [vdom.createTextVNode(p.description)]));
|
|
4229
4794
|
}
|
|
4230
4795
|
if (slots.default) {
|
|
4231
4796
|
children.push(vdom.createVNode("div", { class: "lyt-empty__bottom" }, slots.default()));
|
|
4232
4797
|
}
|
|
4233
4798
|
return vdom.createVNode("div", commonA11y.mergeA11yProps({
|
|
4234
|
-
id:
|
|
4235
|
-
"aria-label":
|
|
4236
|
-
"aria-describedby":
|
|
4799
|
+
id: p.id,
|
|
4800
|
+
"aria-label": p.ariaLabel,
|
|
4801
|
+
"aria-describedby": p.ariaDescribedBy,
|
|
4237
4802
|
role: "status",
|
|
4238
4803
|
"aria-live": "polite"
|
|
4239
4804
|
}, {
|
|
@@ -4334,21 +4899,22 @@ var Container = component.defineComponent({
|
|
|
4334
4899
|
style: { type: String, default: "" }
|
|
4335
4900
|
},
|
|
4336
4901
|
setup(props, { slots }) {
|
|
4902
|
+
const p = props;
|
|
4337
4903
|
const getContainerClass = () => {
|
|
4338
4904
|
const classes = ["lyt-container"];
|
|
4339
|
-
if (
|
|
4905
|
+
if (p.fluid) {
|
|
4340
4906
|
classes.push("lyt-container--fluid");
|
|
4341
4907
|
}
|
|
4342
|
-
if (
|
|
4343
|
-
classes.push(
|
|
4908
|
+
if (p.class) {
|
|
4909
|
+
classes.push(p.class);
|
|
4344
4910
|
}
|
|
4345
4911
|
return classes.join(" ");
|
|
4346
4912
|
};
|
|
4347
4913
|
const getContainerStyle = () => {
|
|
4348
|
-
if (!
|
|
4349
|
-
if (commonIs.isString(
|
|
4350
|
-
if (commonIs.isObject(
|
|
4351
|
-
return Object.entries(
|
|
4914
|
+
if (!p.style) return void 0;
|
|
4915
|
+
if (commonIs.isString(p.style)) return p.style;
|
|
4916
|
+
if (commonIs.isObject(p.style)) {
|
|
4917
|
+
return Object.entries(p.style).map(([key, value]) => `${key}: ${value}`).join("; ");
|
|
4352
4918
|
}
|
|
4353
4919
|
return void 0;
|
|
4354
4920
|
};
|
|
@@ -4376,24 +4942,25 @@ var Divider = component.defineComponent({
|
|
|
4376
4942
|
ariaDescribedBy: { type: String, default: "" }
|
|
4377
4943
|
},
|
|
4378
4944
|
setup(props, { slots }) {
|
|
4945
|
+
const p = props;
|
|
4379
4946
|
const getDividerClass = () => {
|
|
4380
4947
|
const classes = ["lyt-divider"];
|
|
4381
|
-
if (
|
|
4382
|
-
classes.push(`lyt-divider--${
|
|
4948
|
+
if (p.type !== "horizontal") {
|
|
4949
|
+
classes.push(`lyt-divider--${p.type}`);
|
|
4383
4950
|
}
|
|
4384
4951
|
if (slots.default) {
|
|
4385
|
-
classes.push(`lyt-divider--${
|
|
4952
|
+
classes.push(`lyt-divider--${p.contentPosition}`);
|
|
4386
4953
|
}
|
|
4387
|
-
if (
|
|
4388
|
-
classes.push(
|
|
4954
|
+
if (p.class) {
|
|
4955
|
+
classes.push(p.class);
|
|
4389
4956
|
}
|
|
4390
4957
|
return classes.join(" ");
|
|
4391
4958
|
};
|
|
4392
4959
|
const getDividerStyle = () => {
|
|
4393
|
-
if (!
|
|
4394
|
-
if (commonIs.isString(
|
|
4395
|
-
if (commonIs.isObject(
|
|
4396
|
-
return Object.entries(
|
|
4960
|
+
if (!p.style) return void 0;
|
|
4961
|
+
if (commonIs.isString(p.style)) return p.style;
|
|
4962
|
+
if (commonIs.isObject(p.style)) {
|
|
4963
|
+
return Object.entries(p.style).map(([key, value]) => `${key}: ${value}`).join("; ");
|
|
4397
4964
|
}
|
|
4398
4965
|
return void 0;
|
|
4399
4966
|
};
|
|
@@ -4403,9 +4970,9 @@ var Divider = component.defineComponent({
|
|
|
4403
4970
|
children.push(vdom.createVNode("span", { class: "lyt-divider__text" }, slots.default()));
|
|
4404
4971
|
}
|
|
4405
4972
|
return vdom.createVNode("div", commonA11y.mergeA11yProps({
|
|
4406
|
-
id:
|
|
4407
|
-
"aria-label":
|
|
4408
|
-
"aria-describedby":
|
|
4973
|
+
id: p.id,
|
|
4974
|
+
"aria-label": p.ariaLabel,
|
|
4975
|
+
"aria-describedby": p.ariaDescribedBy,
|
|
4409
4976
|
role: "separator"
|
|
4410
4977
|
}, {
|
|
4411
4978
|
class: getDividerClass(),
|
|
@@ -4617,59 +5184,60 @@ var Tooltip = component.defineComponent({
|
|
|
4617
5184
|
ariaDescribedBy: { type: String, default: "" }
|
|
4618
5185
|
},
|
|
4619
5186
|
setup(props, { slots }) {
|
|
5187
|
+
const p = props;
|
|
4620
5188
|
const state = reactivity.reactive({
|
|
4621
|
-
visible: false
|
|
4622
|
-
openTimer: null,
|
|
4623
|
-
closeTimer: null
|
|
5189
|
+
visible: false
|
|
4624
5190
|
});
|
|
5191
|
+
let openTimer = null;
|
|
5192
|
+
let closeTimer = null;
|
|
4625
5193
|
const handleMouseEnter = () => {
|
|
4626
|
-
if (
|
|
4627
|
-
clearTimeout(
|
|
4628
|
-
if (
|
|
4629
|
-
|
|
5194
|
+
if (p.disabled || p.trigger !== "hover") return;
|
|
5195
|
+
if (closeTimer) clearTimeout(closeTimer);
|
|
5196
|
+
if (p.openDelay && p.openDelay > 0) {
|
|
5197
|
+
openTimer = setTimeout(() => {
|
|
4630
5198
|
state.visible = true;
|
|
4631
|
-
},
|
|
5199
|
+
}, p.openDelay);
|
|
4632
5200
|
} else {
|
|
4633
5201
|
state.visible = true;
|
|
4634
5202
|
}
|
|
4635
5203
|
};
|
|
4636
5204
|
const handleMouseLeave = () => {
|
|
4637
|
-
if (
|
|
4638
|
-
clearTimeout(
|
|
4639
|
-
if (
|
|
4640
|
-
|
|
5205
|
+
if (p.disabled || p.trigger !== "hover") return;
|
|
5206
|
+
if (openTimer) clearTimeout(openTimer);
|
|
5207
|
+
if (p.closeDelay && p.closeDelay > 0) {
|
|
5208
|
+
closeTimer = setTimeout(() => {
|
|
4641
5209
|
state.visible = false;
|
|
4642
|
-
},
|
|
5210
|
+
}, p.closeDelay);
|
|
4643
5211
|
} else {
|
|
4644
5212
|
state.visible = false;
|
|
4645
5213
|
}
|
|
4646
5214
|
};
|
|
4647
5215
|
const handleClick = () => {
|
|
4648
|
-
if (
|
|
5216
|
+
if (p.disabled || p.trigger !== "click") return;
|
|
4649
5217
|
state.visible = !state.visible;
|
|
4650
5218
|
};
|
|
4651
5219
|
const handleFocus = () => {
|
|
4652
|
-
if (
|
|
5220
|
+
if (p.disabled || p.trigger !== "focus") return;
|
|
4653
5221
|
state.visible = true;
|
|
4654
5222
|
};
|
|
4655
5223
|
const handleBlur = () => {
|
|
4656
|
-
if (
|
|
5224
|
+
if (p.disabled || p.trigger !== "focus") return;
|
|
4657
5225
|
state.visible = false;
|
|
4658
5226
|
};
|
|
4659
5227
|
const getTooltipClass = () => {
|
|
4660
5228
|
const classes = ["lyt-tooltip"];
|
|
4661
|
-
classes.push(`lyt-tooltip--${
|
|
4662
|
-
if (
|
|
5229
|
+
classes.push(`lyt-tooltip--${p.placement}`);
|
|
5230
|
+
if (p.class) classes.push(p.class);
|
|
4663
5231
|
return classes.join(" ");
|
|
4664
5232
|
};
|
|
4665
5233
|
const getTooltipStyle = () => {
|
|
4666
5234
|
const style = {};
|
|
4667
|
-
if (
|
|
4668
|
-
if (commonIs.isString(
|
|
4669
|
-
return
|
|
5235
|
+
if (p.style) {
|
|
5236
|
+
if (commonIs.isString(p.style)) {
|
|
5237
|
+
return p.style;
|
|
4670
5238
|
}
|
|
4671
|
-
if (commonIs.isObject(
|
|
4672
|
-
Object.assign(style,
|
|
5239
|
+
if (commonIs.isObject(p.style)) {
|
|
5240
|
+
Object.assign(style, p.style);
|
|
4673
5241
|
}
|
|
4674
5242
|
}
|
|
4675
5243
|
return style;
|
|
@@ -4686,17 +5254,17 @@ var Tooltip = component.defineComponent({
|
|
|
4686
5254
|
onBlur: handleBlur
|
|
4687
5255
|
}, slots.default()));
|
|
4688
5256
|
}
|
|
4689
|
-
if (state.visible && !
|
|
5257
|
+
if (state.visible && !p.disabled) {
|
|
4690
5258
|
const contentChildren = [];
|
|
4691
|
-
if (
|
|
5259
|
+
if (p.showArrow) {
|
|
4692
5260
|
contentChildren.push(vdom.createVNode("div", {
|
|
4693
5261
|
class: "lyt-tooltip__arrow"
|
|
4694
5262
|
}, []));
|
|
4695
5263
|
}
|
|
4696
|
-
if (
|
|
5264
|
+
if (p.content) {
|
|
4697
5265
|
contentChildren.push(vdom.createVNode("div", {
|
|
4698
5266
|
class: "lyt-tooltip__content"
|
|
4699
|
-
}, [
|
|
5267
|
+
}, [vdom.createTextVNode(p.content)]));
|
|
4700
5268
|
} else if (slots.content) {
|
|
4701
5269
|
contentChildren.push(vdom.createVNode("div", {
|
|
4702
5270
|
class: "lyt-tooltip__content"
|
|
@@ -4708,9 +5276,9 @@ var Tooltip = component.defineComponent({
|
|
|
4708
5276
|
}, contentChildren));
|
|
4709
5277
|
}
|
|
4710
5278
|
return vdom.createVNode("div", commonA11y.mergeA11yProps({
|
|
4711
|
-
id:
|
|
4712
|
-
"aria-label":
|
|
4713
|
-
"aria-describedby":
|
|
5279
|
+
id: p.id,
|
|
5280
|
+
"aria-label": p.ariaLabel,
|
|
5281
|
+
"aria-describedby": p.ariaDescribedBy
|
|
4714
5282
|
}, {
|
|
4715
5283
|
class: "lyt-tooltip-wrapper"
|
|
4716
5284
|
}), children);
|
|
@@ -5764,7 +6332,7 @@ var Slider = component.defineComponent({
|
|
|
5764
6332
|
} else {
|
|
5765
6333
|
state.secondValue = Math.max(newValue, state.firstValue);
|
|
5766
6334
|
}
|
|
5767
|
-
const newModelValue = [state.firstValue, state.secondValue];
|
|
6335
|
+
const newModelValue = _props.range ? [state.firstValue, state.secondValue] : state.firstValue;
|
|
5768
6336
|
emit("update:modelValue", newModelValue);
|
|
5769
6337
|
emit("input", newModelValue);
|
|
5770
6338
|
_props.onInput?.(newModelValue);
|