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