origam 2.17.0 → 2.18.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.
Files changed (213) hide show
  1. package/CHANGELOG.md +744 -1
  2. package/dist/src/assets/css/main.css +1 -1
  3. package/dist/src/assets/css/tokens/dark.css +125 -24
  4. package/dist/src/assets/css/tokens/light.css +49 -12
  5. package/dist/src/assets/locales/en.json +21 -6
  6. package/dist/src/assets/locales/fr.json +21 -6
  7. package/dist/src/assets/scss/main.scss +10 -2
  8. package/dist/src/assets/scss/tokens/_dark.scss +2846 -12
  9. package/dist/src/assets/scss/tokens/_light.scss +49 -12
  10. package/dist/src/components/Alert/OrigamAlert.vue +6 -6
  11. package/dist/src/components/Avatar/OrigamAvatar.vue +15 -2
  12. package/dist/src/components/Badge/OrigamBadge.vue +7 -7
  13. package/dist/src/components/Breadcrumb/OrigamBreadcrumbItem.vue +23 -4
  14. package/dist/src/components/Btn/OrigamBtn.vue +21 -3
  15. package/dist/src/components/Btn/OrigamBtnGroup.vue +1 -1
  16. package/dist/src/components/Calendar/OrigamCalendar.vue +1 -1
  17. package/dist/src/components/Card/OrigamCard.vue +2 -0
  18. package/dist/src/components/Card/OrigamCardHeader.vue +7 -7
  19. package/dist/src/components/Carousel/OrigamCarousel.vue +14 -1
  20. package/dist/src/components/Chart/OrigamChartBoxPlot.vue +1 -1
  21. package/dist/src/components/Chart/OrigamChartBullet.vue +3 -2
  22. package/dist/src/components/Chart/OrigamChartCandlestick.vue +2 -2
  23. package/dist/src/components/Chart/OrigamChartCartesian.vue +49 -4
  24. package/dist/src/components/Chart/OrigamChartLegend.vue +39 -18
  25. package/dist/src/components/Chart/OrigamChartPareto.vue +7 -1
  26. package/dist/src/components/Chart/OrigamChartPictorial.vue +2 -2
  27. package/dist/src/components/Chart/OrigamChartRadar.vue +3 -1
  28. package/dist/src/components/Chart/OrigamChartSparkline.vue +3 -1
  29. package/dist/src/components/Chart/OrigamChartStreamgraph.vue +2 -1
  30. package/dist/src/components/Checkbox/OrigamCheckbox.vue +2 -0
  31. package/dist/src/components/Checkbox/OrigamCheckboxGroup.vue +36 -11
  32. package/dist/src/components/Chip/OrigamChip.vue +19 -4
  33. package/dist/src/components/Code/OrigamCode.vue +20 -3
  34. package/dist/src/components/ColorPickerField/OrigamColorPickerField.vue +43 -18
  35. package/dist/src/components/CommandPalette/OrigamCommandPalette.vue +3 -3
  36. package/dist/src/components/ConfirmWrapper/OrigamConfirmWrapper.vue +6 -6
  37. package/dist/src/components/ContextualMenu/OrigamContextualMenu.vue +0 -4
  38. package/dist/src/components/DataList/OrigamDataList.vue +2 -0
  39. package/dist/src/components/DataList/OrigamDataText.vue +6 -6
  40. package/dist/src/components/DataList/OrigamDataTitle.vue +6 -6
  41. package/dist/src/components/DataTable/OrigamDataTableHeaderCell.vue +1 -1
  42. package/dist/src/components/DataTable/OrigamDataTableHeadersCell.vue +4 -1
  43. package/dist/src/components/DatePicker/OrigamDatePicker.vue +2 -0
  44. package/dist/src/components/DatePicker/OrigamDatePickerHeader.vue +6 -6
  45. package/dist/src/components/DatePickerField/OrigamDatePickerField.vue +34 -14
  46. package/dist/src/components/Dialog/OrigamDialog.vue +25 -0
  47. package/dist/src/components/Dialog/OrigamDialogConfirmation.vue +6 -0
  48. package/dist/src/components/ExpansionPanel/OrigamExpansionPanel.vue +2 -0
  49. package/dist/src/components/ExpansionPanel/OrigamExpansionPanelHeader.vue +6 -6
  50. package/dist/src/components/Field/OrigamField.vue +83 -28
  51. package/dist/src/components/FileField/OrigamFileField.vue +20 -15
  52. package/dist/src/components/Icon/OrigamSvgIcon.vue +3 -1
  53. package/dist/src/components/Img/OrigamImg.vue +9 -2
  54. package/dist/src/components/InfiniteScroll/OrigamInfiniteScroll.vue +34 -18
  55. package/dist/src/components/InlineEdit/OrigamInlineEdit.vue +46 -5
  56. package/dist/src/components/Input/OrigamInput.vue +6 -6
  57. package/dist/src/components/List/OrigamListGroup.vue +4 -0
  58. package/dist/src/components/List/OrigamListItem.vue +68 -4
  59. package/dist/src/components/Masonry/OrigamMasonry.vue +19 -3
  60. package/dist/src/components/Menu/OrigamMenu.vue +79 -9
  61. package/dist/src/components/NumberField/OrigamNumberField.vue +26 -16
  62. package/dist/src/components/OtpInputField/OrigamOtpInputField.vue +48 -24
  63. package/dist/src/components/PasswordField/OrigamPasswordField.vue +20 -15
  64. package/dist/src/components/Radio/OrigamRadio.vue +2 -0
  65. package/dist/src/components/Radio/OrigamRadioGroup.vue +36 -11
  66. package/dist/src/components/RatingField/OrigamRatingField.vue +58 -7
  67. package/dist/src/components/RatingField/OrigamRatingFieldItem.vue +78 -30
  68. package/dist/src/components/Select/OrigamSelect.vue +57 -34
  69. package/dist/src/components/SliderField/OrigamSliderField.vue +20 -10
  70. package/dist/src/components/Snackbar/OrigamSnackbarGroup.vue +1 -1
  71. package/dist/src/components/Switch/OrigamSwitch.vue +2 -0
  72. package/dist/src/components/Switch/OrigamSwitchTrack.vue +20 -0
  73. package/dist/src/components/Tabs/OrigamTab.vue +7 -4
  74. package/dist/src/components/Tabs/OrigamTabPanel.vue +4 -2
  75. package/dist/src/components/Tabs/OrigamTabs.vue +7 -5
  76. package/dist/src/components/TextField/OrigamTextField.vue +20 -15
  77. package/dist/src/components/TextareaField/OrigamTextareaField.vue +20 -15
  78. package/dist/src/components/Transition/OrigamExpandX.vue +19 -3
  79. package/dist/src/components/Transition/OrigamExpandY.vue +19 -3
  80. package/dist/src/components/Transition/OrigamTranslateScale.vue +26 -4
  81. package/dist/src/components/Video/OrigamVideo.vue +3 -2
  82. package/dist/src/components/VirtualScroll/OrigamVirtualScroll.vue +1 -1
  83. package/dist/src/components/Window/OrigamWindow.vue +20 -3
  84. package/dist/src/composables/Commons/accessibleCommand.composable.cjs +26 -0
  85. package/dist/src/composables/Commons/accessibleCommand.composable.d.ts +78 -0
  86. package/dist/src/composables/Commons/accessibleCommand.composable.js +20 -0
  87. package/dist/src/composables/Commons/activator.composable.cjs +10 -1
  88. package/dist/src/composables/Commons/activator.composable.js +11 -2
  89. package/dist/src/composables/Commons/adjacent.composable.cjs +17 -0
  90. package/dist/src/composables/Commons/adjacent.composable.d.ts +12 -0
  91. package/dist/src/composables/Commons/adjacent.composable.js +17 -0
  92. package/dist/src/composables/Commons/adjacentInner.composable.cjs +20 -0
  93. package/dist/src/composables/Commons/adjacentInner.composable.d.ts +24 -5
  94. package/dist/src/composables/Commons/adjacentInner.composable.js +20 -0
  95. package/dist/src/composables/Commons/audio.composable.cjs +14 -1
  96. package/dist/src/composables/Commons/audio.composable.js +14 -1
  97. package/dist/src/composables/Commons/backButton.composable.cjs +3 -1
  98. package/dist/src/composables/Commons/backButton.composable.js +3 -1
  99. package/dist/src/composables/Commons/border.composable.d.ts +13 -0
  100. package/dist/src/composables/Commons/colorEffect.composable.cjs +58 -46
  101. package/dist/src/composables/Commons/colorEffect.composable.d.ts +10 -5
  102. package/dist/src/composables/Commons/colorEffect.composable.js +70 -46
  103. package/dist/src/composables/Commons/createLayout.composable.cjs +21 -12
  104. package/dist/src/composables/Commons/createLayout.composable.js +21 -12
  105. package/dist/src/composables/Commons/delay.composable.d.ts +16 -0
  106. package/dist/src/composables/Commons/dimension.composable.d.ts +11 -0
  107. package/dist/src/composables/Commons/elevation.composable.cjs +6 -2
  108. package/dist/src/composables/Commons/elevation.composable.d.ts +37 -1
  109. package/dist/src/composables/Commons/elevation.composable.js +7 -2
  110. package/dist/src/composables/Commons/goTo.composable.cjs +4 -2
  111. package/dist/src/composables/Commons/goTo.composable.js +5 -3
  112. package/dist/src/composables/Commons/group.composable.cjs +14 -14
  113. package/dist/src/composables/Commons/group.composable.js +14 -14
  114. package/dist/src/composables/Commons/hotkey.composable.d.ts +18 -7
  115. package/dist/src/composables/Commons/hydration.composable.d.ts +8 -0
  116. package/dist/src/composables/Commons/link.composable.d.ts +20 -0
  117. package/dist/src/composables/Commons/locationStrategies.composable.d.ts +17 -0
  118. package/dist/src/composables/Commons/message.composable.d.ts +19 -5
  119. package/dist/src/composables/Commons/position.composable.d.ts +17 -6
  120. package/dist/src/composables/Commons/refs.composable.d.ts +11 -5
  121. package/dist/src/composables/Commons/rounded.composable.d.ts +11 -1
  122. package/dist/src/composables/Commons/scrolling.composable.cjs +15 -12
  123. package/dist/src/composables/Commons/scrolling.composable.js +15 -12
  124. package/dist/src/composables/Commons/size.composable.d.ts +15 -0
  125. package/dist/src/composables/Commons/ssrBoot.composable.cjs +9 -1
  126. package/dist/src/composables/Commons/ssrBoot.composable.js +10 -2
  127. package/dist/src/composables/Commons/stack.composable.cjs +13 -1
  128. package/dist/src/composables/Commons/stack.composable.js +13 -1
  129. package/dist/src/composables/Commons/theme-props-resolver.composable.cjs +41 -32
  130. package/dist/src/composables/Commons/theme-props-resolver.composable.js +41 -32
  131. package/dist/src/composables/Commons/validation.composable.cjs +3 -3
  132. package/dist/src/composables/Commons/validation.composable.js +3 -3
  133. package/dist/src/composables/Commons/virtual.composable.cjs +24 -8
  134. package/dist/src/composables/Commons/virtual.composable.js +24 -8
  135. package/dist/src/composables/Masonry/masonry.composable.cjs +18 -11
  136. package/dist/src/composables/Masonry/masonry.composable.js +18 -11
  137. package/dist/src/composables/Parallax/parallax.composable.cjs +1 -1
  138. package/dist/src/composables/Parallax/parallax.composable.js +1 -1
  139. package/dist/src/composables/index.cjs +36 -0
  140. package/dist/src/composables/index.d.ts +3 -0
  141. package/dist/src/composables/index.js +3 -0
  142. package/dist/src/consts/Chart/chart-cartesian.const.cjs +5 -2
  143. package/dist/src/consts/Chart/chart-cartesian.const.d.ts +42 -0
  144. package/dist/src/consts/Chart/chart-cartesian.const.js +3 -0
  145. package/dist/src/consts/Commons/border.const.cjs +2 -1
  146. package/dist/src/consts/Commons/border.const.d.ts +19 -0
  147. package/dist/src/consts/Commons/border.const.js +15 -0
  148. package/dist/src/consts/Commons/elevation.const.cjs +5 -1
  149. package/dist/src/consts/Commons/elevation.const.d.ts +52 -2
  150. package/dist/src/consts/Commons/elevation.const.js +4 -0
  151. package/dist/src/consts/Commons/ripple.const.cjs +13 -3
  152. package/dist/src/consts/Commons/ripple.const.js +13 -3
  153. package/dist/src/consts/RatingField/rating-field.const.cjs +10 -0
  154. package/dist/src/consts/RatingField/rating-field.const.d.ts +36 -0
  155. package/dist/src/consts/RatingField/rating-field.const.js +12 -0
  156. package/dist/src/consts/index.cjs +11 -0
  157. package/dist/src/consts/index.d.ts +1 -0
  158. package/dist/src/consts/index.js +1 -0
  159. package/dist/src/directives/ClickOutside/clickOutside.directive.cjs +2 -0
  160. package/dist/src/directives/ClickOutside/clickOutside.directive.js +2 -0
  161. package/dist/src/directives/Ripple/ripple.directive.cjs +2 -0
  162. package/dist/src/directives/Ripple/ripple.directive.js +2 -0
  163. package/dist/src/enums/Commons/color.enum.cjs +0 -1
  164. package/dist/src/enums/Commons/color.enum.d.ts +14 -5
  165. package/dist/src/enums/Commons/color.enum.js +0 -1
  166. package/dist/src/enums/Sheet/sheet.enum.d.ts +1 -1
  167. package/dist/src/interfaces/Chart/chart-cartesian.interface.d.ts +6 -2
  168. package/dist/src/interfaces/Commons/activator.interface.d.ts +3 -2
  169. package/dist/src/interfaces/Commons/adjacent.interface.d.ts +29 -0
  170. package/dist/src/interfaces/Commons/group.interface.d.ts +13 -2
  171. package/dist/src/interfaces/Commons/ripple.interface.d.ts +16 -0
  172. package/dist/src/interfaces/Commons/scroll.interface.d.ts +3 -2
  173. package/dist/src/interfaces/DataTable/data-table-header.interface.d.ts +2 -2
  174. package/dist/src/interfaces/DatePicker/date-picker-month.interface.d.ts +2 -1
  175. package/dist/src/interfaces/Field/field.interface.d.ts +21 -1
  176. package/dist/src/interfaces/Menu/menu.interface.d.ts +28 -1
  177. package/dist/src/interfaces/OtpInputField/otp-input-field.interface.d.ts +21 -1
  178. package/dist/src/interfaces/RatingField/rating-field-item.interface.d.ts +16 -1
  179. package/dist/src/interfaces/index.cjs +11 -0
  180. package/dist/src/interfaces/index.d.ts +1 -0
  181. package/dist/src/interfaces/index.js +1 -0
  182. package/dist/src/themes/origam.theme.cjs +8 -14
  183. package/dist/src/themes/origam.theme.js +6 -8
  184. package/dist/src/types/Commons/color.type.d.ts +4 -3
  185. package/dist/src/types/Commons/commons.type.d.ts +33 -0
  186. package/dist/src/types/Commons/theme.type.d.ts +2 -1
  187. package/dist/src/types/Sheet/sheet.type.d.ts +2 -1
  188. package/dist/src/types/index.cjs +22 -0
  189. package/dist/src/types/index.d.ts +2 -0
  190. package/dist/src/types/index.js +2 -0
  191. package/dist/src/types/tokens.type.d.ts +1 -1
  192. package/dist/src/utils/Commons/a11y.util.cjs +35 -0
  193. package/dist/src/utils/Commons/a11y.util.d.ts +63 -0
  194. package/dist/src/utils/Commons/a11y.util.js +33 -0
  195. package/dist/src/utils/Commons/clickOutside.util.cjs +5 -1
  196. package/dist/src/utils/Commons/clickOutside.util.js +5 -1
  197. package/dist/src/utils/Commons/color.util.cjs +10 -5
  198. package/dist/src/utils/Commons/color.util.d.ts +34 -5
  199. package/dist/src/utils/Commons/color.util.js +9 -5
  200. package/dist/src/utils/Commons/goTo.util.cjs +31 -14
  201. package/dist/src/utils/Commons/goTo.util.d.ts +1 -1
  202. package/dist/src/utils/Commons/goTo.util.js +31 -16
  203. package/dist/src/utils/Commons/location.util.cjs +18 -3
  204. package/dist/src/utils/Commons/location.util.js +18 -3
  205. package/dist/src/utils/Commons/ripple.util.cjs +5 -1
  206. package/dist/src/utils/Commons/ripple.util.js +5 -1
  207. package/dist/src/utils/index.cjs +11 -0
  208. package/dist/src/utils/index.d.ts +1 -0
  209. package/dist/src/utils/index.js +1 -0
  210. package/package.json +13 -2
  211. package/dist/src/types/Commons/locale.type.cjs +0 -1
  212. package/dist/src/types/Commons/locale.type.d.ts +0 -0
  213. package/dist/src/types/Commons/locale.type.js +0 -0
@@ -275,6 +275,7 @@ import {
275
275
  inject,
276
276
  mergeProps,
277
277
  nextTick,
278
+ onBeforeUnmount,
278
279
  onMounted,
279
280
  ref,
280
281
  shallowRef,
@@ -374,6 +375,21 @@ const props = defineProps({
374
375
  prependInnerIcon: { type: null, required: false },
375
376
  clearIcon: { type: null, required: false },
376
377
  clearable: { type: Boolean, required: false },
378
+ prependInnerAriaLabel: { type: String, required: false },
379
+ appendInnerAriaLabel: { type: String, required: false },
380
+ border: { type: [Boolean, Number, String, Array], required: false, skipCheck: true, default: true },
381
+ borderTop: { type: [Boolean, Number, String], required: false },
382
+ borderLeft: { type: [Boolean, Number, String], required: false },
383
+ borderBottom: { type: [Boolean, Number, String], required: false },
384
+ borderRight: { type: [Boolean, Number, String], required: false },
385
+ borderBlock: { type: [Boolean, Number, String], required: false },
386
+ borderInline: { type: [Boolean, Number, String], required: false },
387
+ borderColor: { type: String, required: false },
388
+ borderStyle: { type: String, required: false },
389
+ borderTopColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
390
+ borderRightColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
391
+ borderBottomColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
392
+ borderLeftColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
377
393
  focused: { type: Boolean, required: false },
378
394
  text: { type: String, required: false },
379
395
  floating: { type: Boolean, required: false },
@@ -392,19 +408,6 @@ const props = defineProps({
392
408
  paddingRight: { type: [Boolean, Number, String], required: false },
393
409
  paddingBlock: { type: [Boolean, Number, String], required: false },
394
410
  paddingInline: { type: [Boolean, Number, String], required: false },
395
- border: { type: [Boolean, Number, String, Array], required: false, skipCheck: true, default: true },
396
- borderTop: { type: [Boolean, Number, String], required: false },
397
- borderLeft: { type: [Boolean, Number, String], required: false },
398
- borderBottom: { type: [Boolean, Number, String], required: false },
399
- borderRight: { type: [Boolean, Number, String], required: false },
400
- borderBlock: { type: [Boolean, Number, String], required: false },
401
- borderInline: { type: [Boolean, Number, String], required: false },
402
- borderColor: { type: String, required: false },
403
- borderStyle: { type: String, required: false },
404
- borderTopColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
405
- borderRightColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
406
- borderBottomColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
407
- borderLeftColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
408
411
  rounded: { type: [Boolean, Number, String, null], required: false, skipCheck: true, default: true },
409
412
  roundedTopRight: { type: [Boolean, Number, String], required: false },
410
413
  roundedTopLeft: { type: [Boolean, Number, String], required: false },
@@ -442,6 +445,8 @@ const props = defineProps({
442
445
  appendIcon: { type: null, required: false },
443
446
  prependAvatar: { type: String, required: false },
444
447
  prependIcon: { type: null, required: false },
448
+ prependAriaLabel: { type: String, required: false },
449
+ appendAriaLabel: { type: String, required: false },
445
450
  items: { type: Array, required: false, default: () => [] },
446
451
  itemTitle: { type: null, required: false, default: "title" },
447
452
  itemValue: { type: null, required: false, default: "value" },
@@ -592,6 +597,32 @@ const {
592
597
  onListScroll: handleListScroll,
593
598
  onListKeydown: handleListKeydown
594
599
  } = useScrolling(origamListRef, origamTextFieldRef);
600
+ const scrollFrames = /* @__PURE__ */ new Set();
601
+ let disposed = false;
602
+ const scheduleScrollFrame = (cb) => {
603
+ if (disposed || !IN_BROWSER) return;
604
+ const id2 = window.requestAnimationFrame(() => {
605
+ scrollFrames.delete(id2);
606
+ cb();
607
+ });
608
+ scrollFrames.add(id2);
609
+ };
610
+ const macrotasks = /* @__PURE__ */ new Set();
611
+ const scheduleMacrotask = (cb) => {
612
+ if (disposed || !IN_BROWSER) return;
613
+ const id2 = window.setTimeout(() => {
614
+ macrotasks.delete(id2);
615
+ cb();
616
+ }, 0);
617
+ macrotasks.add(id2);
618
+ };
619
+ onBeforeUnmount(() => {
620
+ disposed = true;
621
+ for (const id2 of scrollFrames) window.cancelAnimationFrame(id2);
622
+ for (const id2 of macrotasks) window.clearTimeout(id2);
623
+ scrollFrames.clear();
624
+ macrotasks.clear();
625
+ });
595
626
  const handleSelect = (item, set = true) => {
596
627
  if (item.props?.disabled) return;
597
628
  if (props.multiple) {
@@ -648,11 +679,11 @@ const handleMousedownControl = (e) => {
648
679
  if (menuDisabled.value) return;
649
680
  menu.value = !menu.value;
650
681
  if (props.autocomplete && !props.multiple && search.value) {
651
- setTimeout(() => {
682
+ scheduleMacrotask(() => {
652
683
  const root = vm?.proxy?.$el;
653
684
  const input = root?.querySelector("input");
654
685
  input?.select();
655
- }, 0);
686
+ });
656
687
  }
657
688
  };
658
689
  const handleMousedownMenuIcon = (e) => {
@@ -759,13 +790,11 @@ const handleKeydown = (e) => {
759
790
  if (item !== void 0) {
760
791
  model.value = [item];
761
792
  const index = displayItems.value.indexOf(item);
762
- if (IN_BROWSER) {
763
- window.requestAnimationFrame(() => {
764
- if (index >= 0) {
765
- origamVirtualScrollRef.value?.scrollToIndex(index);
766
- }
767
- });
768
- }
793
+ scheduleScrollFrame(() => {
794
+ if (index >= 0) {
795
+ origamVirtualScrollRef.value?.scrollToIndex(index);
796
+ }
797
+ });
769
798
  }
770
799
  }
771
800
  };
@@ -791,7 +820,7 @@ const handleAfterLeave = () => {
791
820
  };
792
821
  const handleFocusin = () => {
793
822
  isFocused.value = true;
794
- setTimeout(() => {
823
+ scheduleMacrotask(() => {
795
824
  listHasFocus.value = true;
796
825
  });
797
826
  };
@@ -880,13 +909,11 @@ watch(menu, () => {
880
909
  const index = displayItems.value.findIndex(
881
910
  (item) => model.value.some((s) => props.valueComparator ? props.valueComparator(s.value, item.value) : deepEqual(s.value, item.value))
882
911
  );
883
- if (IN_BROWSER) {
884
- window.requestAnimationFrame(() => {
885
- if (index >= 0) {
886
- origamVirtualScrollRef.value?.scrollToIndex(index);
887
- }
888
- });
889
- }
912
+ scheduleScrollFrame(() => {
913
+ if (index >= 0) {
914
+ origamVirtualScrollRef.value?.scrollToIndex(index);
915
+ }
916
+ });
890
917
  }
891
918
  });
892
919
  watch(() => props.items, (newVal, oldVal) => {
@@ -1134,10 +1161,6 @@ defineExpose(forwardRefs({
1134
1161
  max-width: none;
1135
1162
  }
1136
1163
 
1137
- .origam-select__content .origam-menu__list {
1138
- max-width: none;
1139
- }
1140
-
1141
1164
  .origam-select__content .origam-list-item {
1142
1165
  --origam-list-item---padding-inline-start: 32px;
1143
1166
  }
@@ -113,7 +113,7 @@
113
113
  <input
114
114
  :id="`${id}__start`"
115
115
  :aria-describedby="messagesId"
116
- :aria-label="label ? `${label} (start)` : undefined"
116
+ :aria-label="rangeStartAriaLabel"
117
117
  :class="nativeInputClasses(false)"
118
118
  :disabled="isDisabled"
119
119
  :max="resolvedMax"
@@ -139,7 +139,7 @@
139
139
  <input
140
140
  :id="`${id}__stop`"
141
141
  :aria-describedby="messagesId"
142
- :aria-label="label ? `${label} (end)` : undefined"
142
+ :aria-label="rangeEndAriaLabel"
143
143
  :class="nativeInputClasses(true)"
144
144
  :disabled="isDisabled"
145
145
  :max="resolvedMax"
@@ -327,7 +327,7 @@
327
327
  </template>
328
328
  <template v-else>
329
329
  <input
330
- :aria-label="label ? `${label} (start)` : undefined"
330
+ :aria-label="rangeStartAriaLabel"
331
331
  :class="nativeInputClasses(false)"
332
332
  :disabled="disabled"
333
333
  :max="resolvedMax"
@@ -351,7 +351,7 @@
351
351
  />
352
352
 
353
353
  <input
354
- :aria-label="label ? `${label} (end)` : undefined"
354
+ :aria-label="rangeEndAriaLabel"
355
355
  :class="nativeInputClasses(true)"
356
356
  :disabled="disabled"
357
357
  :max="resolvedMax"
@@ -416,6 +416,7 @@ import OrigamSliderFieldTrack from "./OrigamSliderFieldTrack.vue";
416
416
  import { OrigamAudioWaveform } from "../Audio";
417
417
  import { useBackgroundColor } from "../../composables/Commons/backgroundColor.composable";
418
418
  import { useFocus } from "../../composables/Commons/focus.composable";
419
+ import { useLocale } from "../../composables/Commons/locale.composable";
419
420
  import { useProps } from "../../composables/Commons/props.composable";
420
421
  import { useRounded } from "../../composables/Commons/rounded.composable";
421
422
  import { useRtl } from "../../composables/Commons/rtl.composable";
@@ -513,6 +514,8 @@ const props = defineProps({
513
514
  appendIcon: { type: null, required: false },
514
515
  prependAvatar: { type: String, required: false },
515
516
  prependIcon: { type: null, required: false },
517
+ prependAriaLabel: { type: String, required: false },
518
+ appendAriaLabel: { type: String, required: false },
516
519
  size: { type: null, required: false },
517
520
  fontSize: { type: null, required: false },
518
521
  fontWeight: { type: null, required: false },
@@ -524,6 +527,7 @@ defineSlots();
524
527
  const { filterProps } = useProps(props);
525
528
  const origamInputRef = ref();
526
529
  const slots = useSlots();
530
+ const { t } = useLocale();
527
531
  const isFieldVariant = computed(() => props.variant === SLIDER_FIELD_VARIANT.FIELD);
528
532
  const isAudioVariant = computed(() => props.variant === SLIDER_FIELD_VARIANT.AUDIO);
529
533
  const isBareVariant = computed(() => !isFieldVariant.value);
@@ -531,6 +535,12 @@ const isRange = computed(() => !!props.range);
531
535
  const isVertical = computed(() => props.direction === DIRECTION.VERTICAL);
532
536
  const isReversed = computed(() => !!props.reverse);
533
537
  const indexFromEnd = computed(() => isVertical.value !== isReversed.value);
538
+ const rangeStartAriaLabel = computed(() => {
539
+ return props.label ? t("origam.slider_field.thumb_start_aria_label", props.label) : void 0;
540
+ });
541
+ const rangeEndAriaLabel = computed(() => {
542
+ return props.label ? t("origam.slider_field.thumb_end_aria_label", props.label) : void 0;
543
+ });
534
544
  const steps = useSteps(props);
535
545
  const { min: resolvedMin, max: resolvedMax, step: resolvedStep, roundValue } = steps;
536
546
  const model = useVModel(
@@ -642,8 +652,8 @@ const parsedTicks = computed(() => {
642
652
  if (!step || span <= 0) return [];
643
653
  const count = span / step;
644
654
  if (!isFinite(count)) return [];
645
- return createRange(count + 1).map((t) => {
646
- const value = resolvedMin.value + t * step;
655
+ return createRange(count + 1).map((t2) => {
656
+ const value = resolvedMin.value + t2 * step;
647
657
  return {
648
658
  value,
649
659
  position: toPercent(value)
@@ -651,10 +661,10 @@ const parsedTicks = computed(() => {
651
661
  });
652
662
  }
653
663
  if (Array.isArray(ticksProp)) {
654
- return ticksProp.map((t) => ({
655
- value: t,
656
- position: toPercent(t),
657
- label: String(t)
664
+ return ticksProp.map((t2) => ({
665
+ value: t2,
666
+ position: toPercent(t2),
667
+ label: String(t2)
658
668
  }));
659
669
  }
660
670
  if (typeof ticksProp === "object" && ticksProp !== null) {
@@ -123,7 +123,7 @@ const stackClasses = computed(() => {
123
123
  ];
124
124
  });
125
125
  const resolvedDomId = computed(() => `origam-snackbar-group-${props.id}`);
126
- const { id: styleId, css, load, isLoaded, unload } = useStyle(stackStyles);
126
+ const { id: styleId, css, load, isLoaded, unload } = useStyle(stackStyles, () => resolvedDomId.value);
127
127
  defineExpose({
128
128
  filterProps,
129
129
  visibleItems,
@@ -229,6 +229,8 @@ const props = defineProps({
229
229
  appendIcon: { type: null, required: false },
230
230
  prependAvatar: { type: String, required: false },
231
231
  prependIcon: { type: null, required: false },
232
+ prependAriaLabel: { type: String, required: false },
233
+ appendAriaLabel: { type: String, required: false },
232
234
  size: { type: null, required: false },
233
235
  fontSize: { type: null, required: false },
234
236
  fontWeight: { type: null, required: false },
@@ -149,8 +149,28 @@ defineExpose({
149
149
  // Without `:where()`, this scoped rule's [data-v-hash] pushes it
150
150
  // to (0,2,0), beating the utility's (0,1,0), and the `rounded`
151
151
  // prop's scale form goes silently inert.
152
+ //
153
+ // #727 — the border longhands ride in the SAME zero-specificity
154
+ // block, for the same reason AND for one more. Before this, the
155
+ // track declared NO border at all outside `forced-colors`: the two
156
+ // tokens `--origam-switch__track---border-{width,color}` existed in
157
+ // `light.css` / `dark.css` but were read by nobody (both sat in
158
+ // `baseline/token-var-channels-dormant.json`). Giving them a
159
+ // visible value alone changed nothing — the declaration reading
160
+ // them had to be added here.
161
+ //
162
+ // Zero specificity is what keeps the default OVERRIDABLE, which is
163
+ // the explicit half of the request: `useBorder` emits `border`
164
+ // through the INLINE style channel (`border-width` / `border-style`
165
+ // / `border-color`), which outranks any selector, and the
166
+ // `.origam--border-{none,thin,thick}` utility at (0,1,0) also wins
167
+ // over `:where()` at (0,0,0). A consumer passing `border="none"`
168
+ // therefore still gets no border.
152
169
  :where(&) {
153
170
  border-radius: var(--origam-switch__track---border-radius, 9999px);
171
+ border-width: var(--origam-switch__track---border-width, 1px);
172
+ border-style: var(--origam-switch__track---border-style, solid);
173
+ border-color: var(--origam-switch__track---border-color, currentColor);
154
174
  }
155
175
 
156
176
  height: var(--origam-switch__track---height, 14px);
@@ -13,7 +13,6 @@
13
13
  :aria-disabled="isDisabled || undefined"
14
14
  :tabindex="tabIndex"
15
15
  :disabled="isDisabled || undefined"
16
- :data-origam-tab-id="groupItem?.id"
17
16
  @click="handleClick"
18
17
  >
19
18
  <span
@@ -75,6 +74,7 @@ import { useProps } from "../../composables/Commons/props.composable";
75
74
  import { useStyle } from "../../composables/Commons/style.composable";
76
75
  import { useTypography } from "../../composables/Commons/typography.composable";
77
76
  import vContrast from "../../directives/Contrast/contrast.directive";
77
+ import { getUid } from "../../utils/Commons/getCurrentInstance.util";
78
78
  import { ORIGAM_TABS_KEY, ORIGAM_TAB_PANELS_LINK_KEY } from "../../consts/Tabs/tabs.const";
79
79
  const props = defineProps({
80
80
  tag: { type: String, required: false, default: "button" },
@@ -93,7 +93,9 @@ const props = defineProps({
93
93
  appendAvatar: { type: String, required: false },
94
94
  appendIcon: { type: null, required: false },
95
95
  prependAvatar: { type: String, required: false },
96
- prependIcon: { type: null, required: false }
96
+ prependIcon: { type: null, required: false },
97
+ prependAriaLabel: { type: String, required: false },
98
+ appendAriaLabel: { type: String, required: false }
97
99
  });
98
100
  defineEmits(["group:selected"]);
99
101
  defineSlots();
@@ -116,7 +118,8 @@ const slotProps = computed(() => ({
116
118
  value: groupItem.value.value,
117
119
  disabled: groupItem.disabled.value
118
120
  }));
119
- const tabDomId = computed(() => props.id || `origam-tab-${groupItem.id}`);
121
+ const uid = getUid();
122
+ const tabDomId = computed(() => props.id || `origam-tab-${uid}`);
120
123
  watchEffect(() => {
121
124
  const self = groupItem.group.items.value.find((item) => item.id === groupItem.id);
122
125
  if (self) self.domId = tabDomId.value;
@@ -126,7 +129,7 @@ const panelId = computed(() => {
126
129
  if (!panelsGroup) return void 0;
127
130
  const panel = panelsGroup.items.value.find((item) => item.value === groupItem.value.value);
128
131
  if (!panel) return void 0;
129
- return panel.domId || `origam-tab-panel-${panel.id}`;
132
+ return panel.domId;
130
133
  });
131
134
  const ariaSelected = computed(() => groupItem.isSelected.value ? "true" : "false");
132
135
  const tabIndex = computed(() => {
@@ -27,6 +27,7 @@
27
27
  import { computed, inject, ref, StyleValue, watchEffect } from "vue";
28
28
  import { useGroupItem } from "../../composables/Commons/groupItem.composable";
29
29
  import { useLazy } from "../../composables/Commons/lazy.composable";
30
+ import { getUid } from "../../utils/Commons/getCurrentInstance.util";
30
31
  import { useProps } from "../../composables/Commons/props.composable";
31
32
  import { useStyle } from "../../composables/Commons/style.composable";
32
33
  import {
@@ -54,7 +55,8 @@ const panelsCtx = inject(ORIGAM_TAB_PANELS_CTX_KEY, null);
54
55
  if (!groupItem) {
55
56
  throw new Error("[Origam] <OrigamTabPanel> must be used inside an <OrigamTabPanels>");
56
57
  }
57
- const panelDomId = computed(() => props.id || `origam-tab-panel-${groupItem.id}`);
58
+ const uid = getUid();
59
+ const panelDomId = computed(() => props.id || `origam-tab-panel-${uid}`);
58
60
  watchEffect(() => {
59
61
  const self = groupItem.group.items.value.find((item) => item.id === groupItem.id);
60
62
  if (self) self.domId = panelDomId.value;
@@ -64,7 +66,7 @@ const tabLabelledBy = computed(() => {
64
66
  if (!tabsGroup) return void 0;
65
67
  const tab = tabsGroup.items.value.find((item) => item.value === groupItem.value.value);
66
68
  if (!tab) return void 0;
67
- return tab.domId || `origam-tab-${tab.id}`;
69
+ return tab.domId;
68
70
  });
69
71
  const isShown = computed(() => groupItem.isSelected.value);
70
72
  const { hasContent } = useLazy({ eager: !!props.eager }, isShown);
@@ -85,7 +85,9 @@ const slotDefaults = computed(() => ({
85
85
  const ariaOrientation = computed(() => props.direction === DIRECTION.VERTICAL ? "vertical" : "horizontal");
86
86
  const focusTab = (id2) => {
87
87
  if (!rootRef.value) return;
88
- const target = rootRef.value.querySelector(`[data-origam-tab-id="${id2}"]`);
88
+ const domId = items.value.find((item) => item.id === id2)?.domId;
89
+ if (!domId) return;
90
+ const target = rootRef.value.querySelector(`[id=${JSON.stringify(domId)}]`);
89
91
  target?.focus();
90
92
  };
91
93
  const focusFirstNonDisabled = (offset) => {
@@ -109,12 +111,12 @@ const handleKeydown = (event) => {
109
111
  const currentId = selected.value[0];
110
112
  if (event.key === prevKey) {
111
113
  event.preventDefault();
112
- prev();
113
- if (selected.value[0] != null) focusTab(selected.value[0]);
114
+ const movedTo = prev();
115
+ if (movedTo != null) focusTab(movedTo);
114
116
  } else if (event.key === nextKey) {
115
117
  event.preventDefault();
116
- next();
117
- if (selected.value[0] != null) focusTab(selected.value[0]);
118
+ const movedTo = next();
119
+ if (movedTo != null) focusTab(movedTo);
118
120
  } else if (event.key === "Home") {
119
121
  event.preventDefault();
120
122
  focusFirstNonDisabled(1);
@@ -197,6 +197,7 @@ import { useMask } from "../../composables/Commons/mask.composable";
197
197
  import { useProps } from "../../composables/Commons/props.composable";
198
198
  import { useStyle } from "../../composables/Commons/style.composable";
199
199
  import { useVModel } from "../../composables/Commons/vModel.composable";
200
+ import { BORDER_PROP_KEYS } from "../../consts/Commons/border.const";
200
201
  import { ACTIVE_TEXT_FIELD_TYPE, INPUT_TEXT_FIELD_TYPE } from "../../consts/TextField/text-field.const";
201
202
  import vIntersect from "../../directives/Intersect/intersect.directive";
202
203
  import { DENSITY } from "../../enums/Commons/density.enum";
@@ -244,6 +245,21 @@ const props = defineProps({
244
245
  prependInnerIcon: { type: null, required: false },
245
246
  clearIcon: { type: null, required: false, default: MDI_ICONS.CLOSE_CIRCLE_OUTLINE },
246
247
  clearable: { type: Boolean, required: false },
248
+ prependInnerAriaLabel: { type: String, required: false },
249
+ appendInnerAriaLabel: { type: String, required: false },
250
+ border: { type: [Boolean, Number, String, Array], required: false, skipCheck: true },
251
+ borderTop: { type: [Boolean, Number, String], required: false },
252
+ borderLeft: { type: [Boolean, Number, String], required: false },
253
+ borderBottom: { type: [Boolean, Number, String], required: false },
254
+ borderRight: { type: [Boolean, Number, String], required: false },
255
+ borderBlock: { type: [Boolean, Number, String], required: false },
256
+ borderInline: { type: [Boolean, Number, String], required: false },
257
+ borderColor: { type: String, required: false },
258
+ borderStyle: { type: String, required: false },
259
+ borderTopColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
260
+ borderRightColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
261
+ borderBottomColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
262
+ borderLeftColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
247
263
  focused: { type: Boolean, required: false },
248
264
  text: { type: String, required: false },
249
265
  floating: { type: Boolean, required: false },
@@ -262,19 +278,6 @@ const props = defineProps({
262
278
  paddingRight: { type: [Boolean, Number, String], required: false },
263
279
  paddingBlock: { type: [Boolean, Number, String], required: false },
264
280
  paddingInline: { type: [Boolean, Number, String], required: false },
265
- border: { type: [Boolean, Number, String, Array], required: false, skipCheck: true },
266
- borderTop: { type: [Boolean, Number, String], required: false },
267
- borderLeft: { type: [Boolean, Number, String], required: false },
268
- borderBottom: { type: [Boolean, Number, String], required: false },
269
- borderRight: { type: [Boolean, Number, String], required: false },
270
- borderBlock: { type: [Boolean, Number, String], required: false },
271
- borderInline: { type: [Boolean, Number, String], required: false },
272
- borderColor: { type: String, required: false },
273
- borderStyle: { type: String, required: false },
274
- borderTopColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
275
- borderRightColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
276
- borderBottomColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
277
- borderLeftColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
278
281
  rounded: { type: [Boolean, Number, String, null], required: false, skipCheck: true, default: true },
279
282
  roundedTopRight: { type: [Boolean, Number, String], required: false },
280
283
  roundedTopLeft: { type: [Boolean, Number, String], required: false },
@@ -311,7 +314,9 @@ const props = defineProps({
311
314
  appendAvatar: { type: String, required: false },
312
315
  appendIcon: { type: null, required: false },
313
316
  prependAvatar: { type: String, required: false },
314
- prependIcon: { type: null, required: false }
317
+ prependIcon: { type: null, required: false },
318
+ prependAriaLabel: { type: String, required: false },
319
+ appendAriaLabel: { type: String, required: false }
315
320
  });
316
321
  const emits = defineEmits(["click:control", "mousedown:control", "valid", "complete", "update:focused", "click:appendInner", "click:prependInner", "click:clear", "update:modelValue", "click:append", "click:prepend"]);
317
322
  defineSlots();
@@ -482,7 +487,7 @@ const enrichedRules = computed(() => {
482
487
  });
483
488
  const [rootAttrs, inputAttrs] = filterInputAttrs(attrs);
484
489
  const inputProps = computed(() => {
485
- return origamInputRef.value?.filterProps(props, ["modelValue", "class", "style", "focused"]);
490
+ return origamInputRef.value?.filterProps(props, ["modelValue", "class", "style", "focused", ...BORDER_PROP_KEYS]);
486
491
  });
487
492
  const fieldProps = computed(() => {
488
493
  return origamFieldRef.value?.filterProps(props, ["class", "id", "active", "dirty", "disabled", "focused", "error", "style"]);
@@ -277,6 +277,7 @@ import { useTextareaRich } from "../../composables/TextareaField/textarea-field-
277
277
  import { useTheme } from "../../composables/Commons/theme.composable";
278
278
  import { useTypography } from "../../composables/Commons/typography.composable";
279
279
  import { useVModel } from "../../composables/Commons/vModel.composable";
280
+ import { BORDER_PROP_KEYS } from "../../consts/Commons/border.const";
280
281
  import { DEFAULT_TOOLBAR } from "../../consts/TextareaField/textarea-field.const";
281
282
  import vIntersect from "../../directives/Intersect/intersect.directive";
282
283
  import { AXIS } from "../../enums/Commons/drag.enum";
@@ -331,6 +332,21 @@ const props = defineProps({
331
332
  prependInnerIcon: { type: null, required: false },
332
333
  clearIcon: { type: null, required: false, default: MDI_ICONS.CLOSE_CIRCLE_OUTLINE },
333
334
  clearable: { type: Boolean, required: false },
335
+ prependInnerAriaLabel: { type: String, required: false },
336
+ appendInnerAriaLabel: { type: String, required: false },
337
+ border: { type: [Boolean, Number, String, Array], required: false, skipCheck: true },
338
+ borderTop: { type: [Boolean, Number, String], required: false },
339
+ borderLeft: { type: [Boolean, Number, String], required: false },
340
+ borderBottom: { type: [Boolean, Number, String], required: false },
341
+ borderRight: { type: [Boolean, Number, String], required: false },
342
+ borderBlock: { type: [Boolean, Number, String], required: false },
343
+ borderInline: { type: [Boolean, Number, String], required: false },
344
+ borderColor: { type: String, required: false },
345
+ borderStyle: { type: String, required: false },
346
+ borderTopColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
347
+ borderRightColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
348
+ borderBottomColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
349
+ borderLeftColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
334
350
  focused: { type: Boolean, required: false },
335
351
  text: { type: String, required: false },
336
352
  floating: { type: Boolean, required: false },
@@ -349,19 +365,6 @@ const props = defineProps({
349
365
  paddingRight: { type: [Boolean, Number, String], required: false },
350
366
  paddingBlock: { type: [Boolean, Number, String], required: false },
351
367
  paddingInline: { type: [Boolean, Number, String], required: false },
352
- border: { type: [Boolean, Number, String, Array], required: false, skipCheck: true },
353
- borderTop: { type: [Boolean, Number, String], required: false },
354
- borderLeft: { type: [Boolean, Number, String], required: false },
355
- borderBottom: { type: [Boolean, Number, String], required: false },
356
- borderRight: { type: [Boolean, Number, String], required: false },
357
- borderBlock: { type: [Boolean, Number, String], required: false },
358
- borderInline: { type: [Boolean, Number, String], required: false },
359
- borderColor: { type: String, required: false },
360
- borderStyle: { type: String, required: false },
361
- borderTopColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
362
- borderRightColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
363
- borderBottomColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
364
- borderLeftColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
365
368
  rounded: { type: [Boolean, Number, String, null], required: false, skipCheck: true, default: true },
366
369
  roundedTopRight: { type: [Boolean, Number, String], required: false },
367
370
  roundedTopLeft: { type: [Boolean, Number, String], required: false },
@@ -398,7 +401,9 @@ const props = defineProps({
398
401
  appendAvatar: { type: String, required: false },
399
402
  appendIcon: { type: null, required: false },
400
403
  prependAvatar: { type: String, required: false },
401
- prependIcon: { type: null, required: false }
404
+ prependIcon: { type: null, required: false },
405
+ prependAriaLabel: { type: String, required: false },
406
+ appendAriaLabel: { type: String, required: false }
402
407
  });
403
408
  const emits = defineEmits(["update:height", "click:control", "mousedown:control", "format", "update:focused", "click:appendInner", "click:prependInner", "click:clear", "update:modelValue", "click:append", "click:prepend"]);
404
409
  defineSlots();
@@ -636,7 +641,7 @@ const enrichedRules = computed(() => {
636
641
  });
637
642
  const [rootAttrs, inputAttrs] = filterInputAttrs(attrs);
638
643
  const inputProps = computed(() => {
639
- return origamInputRef.value?.filterProps(props, ["modelValue", "class", "style", "focused", "centerAffix"]);
644
+ return origamInputRef.value?.filterProps(props, ["modelValue", "class", "style", "focused", "centerAffix", ...BORDER_PROP_KEYS]);
640
645
  });
641
646
  const fieldProps = computed(() => {
642
647
  return origamFieldRef.value?.filterProps(props, ["class", "id", "style", "active", "dirty", "disabled", "focused", "error", "centerAffix"]);
@@ -15,7 +15,7 @@
15
15
  </template>
16
16
 
17
17
  <script lang="ts" setup>
18
- import { camelize, computed, Transition, TransitionGroup } from "vue";
18
+ import { camelize, computed, onBeforeUnmount, Transition, TransitionGroup } from "vue";
19
19
  import { useProps } from "../../composables/Commons/props.composable";
20
20
  import { TRANSITION_MODE } from "../../enums/Transition/transition.enum";
21
21
  const props = defineProps({
@@ -29,6 +29,22 @@ const props = defineProps({
29
29
  const { filterProps } = useProps(props);
30
30
  defineEmits([]);
31
31
  defineSlots();
32
+ let disposed = false;
33
+ const frames = /* @__PURE__ */ new Set();
34
+ const scheduleFrame = (cb) => {
35
+ if (disposed) return;
36
+ const id = requestAnimationFrame(() => {
37
+ frames.delete(id);
38
+ if (disposed) return;
39
+ cb();
40
+ });
41
+ frames.add(id);
42
+ };
43
+ onBeforeUnmount(() => {
44
+ disposed = true;
45
+ for (const id of frames) cancelAnimationFrame(id);
46
+ frames.clear();
47
+ });
32
48
  const tag = computed(() => props.group ? TransitionGroup : Transition);
33
49
  const rootProps = computed(() => {
34
50
  const bind = {
@@ -88,7 +104,7 @@ const handleEnter = (el) => {
88
104
  if (expandedParentClass && element._parent) {
89
105
  element._parent.classList.add(expandedParentClass);
90
106
  }
91
- requestAnimationFrame(() => {
107
+ scheduleFrame(() => {
92
108
  element.style[sizeProperty] = offset;
93
109
  });
94
110
  };
@@ -128,7 +144,7 @@ const handleLeave = (el) => {
128
144
  if (props.hideOnLeave) {
129
145
  element.style.setProperty("display", "none", "important");
130
146
  } else {
131
- requestAnimationFrame(() => element.style[sizeProperty] = "0");
147
+ scheduleFrame(() => element.style[sizeProperty] = "0");
132
148
  }
133
149
  };
134
150
  const handleAfterLeave = (el) => {
@@ -15,7 +15,7 @@
15
15
  </template>
16
16
 
17
17
  <script lang="ts" setup>
18
- import { camelize, computed, Transition, TransitionGroup } from "vue";
18
+ import { camelize, computed, onBeforeUnmount, Transition, TransitionGroup } from "vue";
19
19
  import { useProps } from "../../composables/Commons/props.composable";
20
20
  import { TRANSITION_MODE } from "../../enums/Transition/transition.enum";
21
21
  const props = defineProps({
@@ -29,6 +29,22 @@ const props = defineProps({
29
29
  const { filterProps } = useProps(props);
30
30
  defineEmits([]);
31
31
  defineSlots();
32
+ let disposed = false;
33
+ const frames = /* @__PURE__ */ new Set();
34
+ const scheduleFrame = (cb) => {
35
+ if (disposed) return;
36
+ const id = requestAnimationFrame(() => {
37
+ frames.delete(id);
38
+ if (disposed) return;
39
+ cb();
40
+ });
41
+ frames.add(id);
42
+ };
43
+ onBeforeUnmount(() => {
44
+ disposed = true;
45
+ for (const id of frames) cancelAnimationFrame(id);
46
+ frames.clear();
47
+ });
32
48
  const tag = computed(() => props.group ? TransitionGroup : Transition);
33
49
  const rootProps = computed(() => {
34
50
  const bind = {
@@ -88,7 +104,7 @@ const handleEnter = (el) => {
88
104
  if (expandedParentClass && element._parent) {
89
105
  element._parent.classList.add(expandedParentClass);
90
106
  }
91
- requestAnimationFrame(() => {
107
+ scheduleFrame(() => {
92
108
  element.style[sizeProperty] = offset;
93
109
  });
94
110
  };
@@ -128,7 +144,7 @@ const handleLeave = (el) => {
128
144
  if (props.hideOnLeave) {
129
145
  element.style.setProperty("display", "none", "important");
130
146
  } else {
131
- requestAnimationFrame(() => element.style[sizeProperty] = "0");
147
+ scheduleFrame(() => element.style[sizeProperty] = "0");
132
148
  }
133
149
  };
134
150
  const handleAfterLeave = (el) => {