@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 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: handleKeydown
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
- return query ? opts.filter((opt) => opt.label.includes(query)) : opts;
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
- isOpen.set(false);
452
- p.onVisibleChange?.(false);
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
- event.preventDefault();
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
- highlightedIndex.set(Math.min(hIndex + 1, enabledOptions.length - 1));
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
- highlightedIndex.set(Math.max(hIndex - 1, 0));
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
- highlightedIndex.set(enabledOptions.length - 1);
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", { class: "lyt-select__empty" }, [vdom.createVNode("span", {}, "\u65E0\u5339\u914D\u9009\u9879")]));
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) highlightedIndex.set(index);
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
- vdom.createVNode("div", {
587
- class: "lyt-select__trigger",
588
- onClick: toggleDropdown
589
- }, triggerChildren)
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: void 0
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
- activeIndex.set(index);
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: "Close tab",
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: `${p.id || "tabs"}-tab-${pane.props.name}`,
1085
+ id: tabId,
803
1086
  selected: isActive,
804
1087
  disabled: pane.props.disabled,
805
- controls: `${p.id || "tabs"}-panel-${pane.props.name}`
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: "Add tab"
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: `${p.id || "tabs"}-panel-${content.props.name}`,
838
- labelledBy: `${p.id || "tabs"}-tab-${content.props.name}`
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
- }), content.children) : vdom.createVNode("div", { style: "display: none;" }, []);
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 || "Tabs",
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", { class: "lyt-tabs__header" }, [
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 validateField = (field) => {
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
- errors.set({ ...errors(), [field]: rule.message || "\u6B64\u5B57\u6BB5\u5FC5\u586B" });
1051
- return false;
1052
- }
1053
- if (rule.pattern && !rule.pattern.test(String(value || ""))) {
1054
- errors.set({ ...errors(), [field]: rule.message || "\u683C\u5F0F\u4E0D\u6B63\u786E" });
1055
- return false;
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
- const result = rule.validator(value, p.model);
1059
- if (result !== true) {
1060
- errors.set({ ...errors(), [field]: typeof result === "string" ? result : "\u9A8C\u8BC1\u5931\u8D25" });
1061
- return false;
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
- for (const field in p.rules) {
1073
- if (!validateField(field)) {
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
- if (validate()) {
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 = [`${props.name}-transition`];
1162
- if (props.class) {
1163
- classes.push(props.class);
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: ${props.duration}ms;`;
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: `${props.name}-item`,
1193
- style: `transition: all ${props.duration}ms ease;`
1572
+ class: `${p.name}-item`,
1573
+ style: `transition: all ${p.duration}ms ease;`
1194
1574
  }, [child])
1195
1575
  );
1196
- return vdom.createVNode(props.tag, {
1197
- class: `lyt-transition-group ${props.class}`
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 menuItems = items.map((item) => {
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
- if (itemProps.children && itemProps.children.length > 0) {
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 childBtnProps = commonA11y.getButtonA11yProps({
1706
- ariaLabel: childItem.label,
1707
- disabled: childItem.disabled
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
- childItem.index === activeIndex() ? "lyt-menu__item--active" : "",
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("ul", { class: "lyt-menu__submenu" }, submenuChildren));
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 itemBtnProps = commonA11y.getButtonA11yProps({
1728
- ariaLabel: itemProps.label,
1729
- disabled: itemProps.disabled
1730
- });
1731
- return vdom.createVNode("li", commonA11y.mergeA11yProps(itemBtnProps, {
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 (itemProps.children && itemProps.children.length > 0) {
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("ul", { class: menuClass, role: "menubar", id: p.id, "aria-label": p.ariaLabel }, menuItems);
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 || nextOptions.length === 0) {
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 (p.load && nextOptions.length === 0) {
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 (props.name) classes.push(`lyt-icon--${props.name}`);
3909
- if (props.spin) classes.push("lyt-icon--spin");
3910
- if (props.class) classes.push(props.class);
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 (props.size) style.fontSize = props.size;
3916
- if (props.color) style.color = props.color;
3917
- if (props.style) {
3918
- if (commonIs.isString(props.style)) {
3919
- return props.style;
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(props.style)) {
3922
- Object.assign(style, props.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: props.id,
3934
- "aria-label": props.ariaLabel,
3935
- "aria-describedby": props.ariaDescribedBy
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 (props.delay > 0) {
4668
+ if (p.delay && p.delay > 0) {
4105
4669
  delayTimer = setTimeout(() => {
4106
4670
  state.visible = true;
4107
- }, props.delay);
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 (props.class) classes.push(props.class);
4685
+ if (p.class) classes.push(p.class);
4122
4686
  return classes.join(" ");
4123
4687
  };
4124
4688
  const getSpinStyle = () => {
4125
- if (!props.style) return void 0;
4126
- if (commonIs.isString(props.style)) return props.style;
4127
- if (commonIs.isObject(props.style)) {
4128
- return Object.entries(props.style).map(([key, value]) => `${key}: ${value}`).join("; ");
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--${props.size}` }, [
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 (props.tip || slots.tip) {
4144
- loadingChildren.push(vdom.createVNode("div", { class: "lyt-spin__tip" }, slots.tip ? slots.tip() : [props.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: props.id,
4155
- "aria-label": props.ariaLabel,
4156
- "aria-describedby": props.ariaDescribedBy,
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 (props.class) classes.push(props.class);
4746
+ if (p.class) classes.push(p.class);
4182
4747
  return classes.join(" ");
4183
4748
  };
4184
4749
  const getEmptyStyle = () => {
4185
- if (!props.style) return void 0;
4186
- if (commonIs.isString(props.style)) return props.style;
4187
- if (commonIs.isObject(props.style)) {
4188
- return Object.entries(props.style).map(([key, value]) => `${key}: ${value}`).join("; ");
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 (props.image) {
4761
+ } else if (p.image) {
4197
4762
  children.push(vdom.createVNode("div", { class: "lyt-empty__image" }, [
4198
4763
  vdom.createVNode("img", {
4199
- src: props.image,
4764
+ src: p.image,
4200
4765
  alt: "empty",
4201
- style: { width: `${props.imageSize}px`, height: `${props.imageSize}px` }
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: `${props.imageSize}px`, height: `${props.imageSize * 0.8}px` }
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 (props.description) {
4228
- children.push(vdom.createVNode("div", { class: "lyt-empty__description" }, [props.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: props.id,
4235
- "aria-label": props.ariaLabel,
4236
- "aria-describedby": props.ariaDescribedBy,
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 (props.fluid) {
4905
+ if (p.fluid) {
4340
4906
  classes.push("lyt-container--fluid");
4341
4907
  }
4342
- if (props.class) {
4343
- classes.push(props.class);
4908
+ if (p.class) {
4909
+ classes.push(p.class);
4344
4910
  }
4345
4911
  return classes.join(" ");
4346
4912
  };
4347
4913
  const getContainerStyle = () => {
4348
- if (!props.style) return void 0;
4349
- if (commonIs.isString(props.style)) return props.style;
4350
- if (commonIs.isObject(props.style)) {
4351
- return Object.entries(props.style).map(([key, value]) => `${key}: ${value}`).join("; ");
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 (props.type !== "horizontal") {
4382
- classes.push(`lyt-divider--${props.type}`);
4948
+ if (p.type !== "horizontal") {
4949
+ classes.push(`lyt-divider--${p.type}`);
4383
4950
  }
4384
4951
  if (slots.default) {
4385
- classes.push(`lyt-divider--${props.contentPosition}`);
4952
+ classes.push(`lyt-divider--${p.contentPosition}`);
4386
4953
  }
4387
- if (props.class) {
4388
- classes.push(props.class);
4954
+ if (p.class) {
4955
+ classes.push(p.class);
4389
4956
  }
4390
4957
  return classes.join(" ");
4391
4958
  };
4392
4959
  const getDividerStyle = () => {
4393
- if (!props.style) return void 0;
4394
- if (commonIs.isString(props.style)) return props.style;
4395
- if (commonIs.isObject(props.style)) {
4396
- return Object.entries(props.style).map(([key, value]) => `${key}: ${value}`).join("; ");
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: props.id,
4407
- "aria-label": props.ariaLabel,
4408
- "aria-describedby": props.ariaDescribedBy,
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 (props.disabled || props.trigger !== "hover") return;
4627
- clearTimeout(state.closeTimer);
4628
- if (props.openDelay > 0) {
4629
- state.openTimer = setTimeout(() => {
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
- }, props.openDelay);
5199
+ }, p.openDelay);
4632
5200
  } else {
4633
5201
  state.visible = true;
4634
5202
  }
4635
5203
  };
4636
5204
  const handleMouseLeave = () => {
4637
- if (props.disabled || props.trigger !== "hover") return;
4638
- clearTimeout(state.openTimer);
4639
- if (props.closeDelay > 0) {
4640
- state.closeTimer = setTimeout(() => {
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
- }, props.closeDelay);
5210
+ }, p.closeDelay);
4643
5211
  } else {
4644
5212
  state.visible = false;
4645
5213
  }
4646
5214
  };
4647
5215
  const handleClick = () => {
4648
- if (props.disabled || props.trigger !== "click") return;
5216
+ if (p.disabled || p.trigger !== "click") return;
4649
5217
  state.visible = !state.visible;
4650
5218
  };
4651
5219
  const handleFocus = () => {
4652
- if (props.disabled || props.trigger !== "focus") return;
5220
+ if (p.disabled || p.trigger !== "focus") return;
4653
5221
  state.visible = true;
4654
5222
  };
4655
5223
  const handleBlur = () => {
4656
- if (props.disabled || props.trigger !== "focus") return;
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--${props.placement}`);
4662
- if (props.class) classes.push(props.class);
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 (props.style) {
4668
- if (commonIs.isString(props.style)) {
4669
- return props.style;
5235
+ if (p.style) {
5236
+ if (commonIs.isString(p.style)) {
5237
+ return p.style;
4670
5238
  }
4671
- if (commonIs.isObject(props.style)) {
4672
- Object.assign(style, props.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 && !props.disabled) {
5257
+ if (state.visible && !p.disabled) {
4690
5258
  const contentChildren = [];
4691
- if (props.showArrow) {
5259
+ if (p.showArrow) {
4692
5260
  contentChildren.push(vdom.createVNode("div", {
4693
5261
  class: "lyt-tooltip__arrow"
4694
5262
  }, []));
4695
5263
  }
4696
- if (props.content) {
5264
+ if (p.content) {
4697
5265
  contentChildren.push(vdom.createVNode("div", {
4698
5266
  class: "lyt-tooltip__content"
4699
- }, [props.content]));
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: props.id,
4712
- "aria-label": props.ariaLabel,
4713
- "aria-describedby": props.ariaDescribedBy
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);