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
@@ -11,6 +11,25 @@
11
11
  * This file is now HAND-MAINTAINED SOURCE: edit it directly. There is no
12
12
  * regeneration step, and no "do not edit" rule any more. A design-token
13
13
  * pipeline may be reintroduced later, once the DS is stable.
14
+ *
15
+ * ── #789 — CONTRASTE : POURQUOI CES PALIERS-LÀ ─────────────────────────────
16
+ * `feedback--{success,warning,info}---bg` portent tous un `---fg` BLANC. Le
17
+ * couple doit donc tenir 4.5:1 (WCAG AA, texte). Mesuré en Chromium, alpha
18
+ * composité, avec témoins calculables à la main :
19
+ *
20
+ * success green-500 #4caf50 2.78 → green-700 #15803d 5.02
21
+ * warning amber-600 #fb8c00 2.37 → amber-700 #b45309 5.02
22
+ * info blue-500 #2196f3 3.12 → #2563eb 5.17
23
+ *
24
+ * ⛔ Ne pas « re-éclaircir » ces trois paliers sans remesurer : sur cette
25
+ * palette, aucun palier plus clair ne tient AA avec du texte blanc. La
26
+ * mesure et ses témoins vivent dans
27
+ * `packages/tests/e2e/token-intent-contrast.spec.ts` — elle rougit ici.
28
+ *
29
+ * `info---bg` est le seul littéral du lot : `#2563eb` n'existe pas dans la
30
+ * palette primitive (son `blue---600` vaut `#1d4ed8`, soit le 700 de
31
+ * Tailwind). La valeur est celle de `origam.theme.ts`, ce qui ferme du même
32
+ * coup la divergence feuille ↔ thème que #793 suit.
14
33
  */
15
34
  :root,
16
35
  [data-theme="light"] {
@@ -20,7 +39,19 @@
20
39
  --origam-color__surface---sunken: var(--origam-color__neutral---50);
21
40
  --origam-color__surface---disabled: var(--origam-color__neutral---200);
22
41
  --origam-color__surface---inverse: var(--origam-color__neutral---900);
23
- --origam-color__text---primary: var(--origam-color__neutral---900);
42
+ /* #615 — `950`, PAS `900`. Cette feuille NE gagne PAS la cascade au niveau
43
+ document : `createOrigam()` appelle `applyThemes()`, qui serialise
44
+ `origamLightTheme` (src/themes/origam.theme.ts) en un bloc `:root { … }`
45
+ injecte dans <head> APRES cette feuille. A specificite egale (0,1,0) c'est
46
+ l'ordre source qui tranche, donc le bloc runtime gagne — et il pose
47
+ `#0a0a0a`, soit neutral-950. Tant que cette ligne disait `900`, le meme
48
+ theme « light » peignait DEUX couleurs : `#0a0a0a` a la racine et
49
+ `#171717` dans un sous-arbre `<OrigamThemeProvider theme="light">` (ou
50
+ `[data-theme="light"]` matche alors que `:root` ne matche plus). Les deux
51
+ valeurs mesurees en Chromium ; le contraste sur `surface.default` passe de
52
+ 17.93:1 a 19.80:1. Si cette ligne doit revenir a `900`, c'est
53
+ `origam.theme.ts` qu'il faut changer AVEC, sinon la divergence revient. */
54
+ --origam-color__text---primary: var(--origam-color__neutral---950);
24
55
  --origam-color__text---secondary: var(--origam-color__neutral---600);
25
56
  --origam-color__text---disabled: var(--origam-color__neutral---400);
26
57
  --origam-color__text---inverse: var(--origam-color__neutral---0);
@@ -48,26 +79,26 @@
48
79
  --origam-color__action--ghost---bgDisabled: rgba(0, 0, 0, 0);
49
80
  --origam-color__action--ghost---fg: var(--origam-color__primary---600);
50
81
  --origam-color__action--ghost---fgDisabled: var(--origam-color__neutral---400);
51
- --origam-color__feedback--success---bg: var(--origam-color__green---500);
82
+ --origam-color__feedback--success---bg: var(--origam-color__green---700);
52
83
  --origam-color__feedback--success---bgSubtle: var(--origam-color__green---50);
53
84
  --origam-color__feedback--success---fg: var(--origam-color__neutral---0);
54
85
  --origam-color__feedback--success---fgSubtle: var(--origam-color__green---700);
55
- --origam-color__feedback--success---border: var(--origam-color__green---500);
56
- --origam-color__feedback--warning---bg: var(--origam-color__amber---600);
86
+ --origam-color__feedback--success---border: var(--origam-color__green---700);
87
+ --origam-color__feedback--warning---bg: var(--origam-color__amber---700);
57
88
  --origam-color__feedback--warning---bgSubtle: var(--origam-color__amber---50);
58
89
  --origam-color__feedback--warning---fg: var(--origam-color__neutral---0);
59
90
  --origam-color__feedback--warning---fgSubtle: var(--origam-color__amber---700);
60
- --origam-color__feedback--warning---border: var(--origam-color__amber---600);
91
+ --origam-color__feedback--warning---border: var(--origam-color__amber---700);
61
92
  --origam-color__feedback--danger---bg: var(--origam-color__red---600);
62
93
  --origam-color__feedback--danger---bgSubtle: var(--origam-color__red---50);
63
94
  --origam-color__feedback--danger---fg: var(--origam-color__neutral---0);
64
95
  --origam-color__feedback--danger---fgSubtle: var(--origam-color__red---700);
65
96
  --origam-color__feedback--danger---border: var(--origam-color__red---400);
66
- --origam-color__feedback--info---bg: var(--origam-color__blue---500);
97
+ --origam-color__feedback--info---bg: #2563eb;
67
98
  --origam-color__feedback--info---bgSubtle: var(--origam-color__blue---50);
68
99
  --origam-color__feedback--info---fg: var(--origam-color__neutral---0);
69
100
  --origam-color__feedback--info---fgSubtle: var(--origam-color__blue---700);
70
- --origam-color__feedback--info---border: var(--origam-color__blue---500);
101
+ --origam-color__feedback--info---border: #2563eb;
71
102
  --origam-color__overlay---scrim: var(--origam-color---white);
72
103
  --origam-gradient---sunset: linear-gradient(135deg, #ff7e5f, #feb47b);
73
104
  --origam-gradient---ocean: linear-gradient(135deg, #2193b0, #6dd5ed);
@@ -89,7 +120,7 @@
89
120
  --origam-btn---border-style: solid;
90
121
  --origam-btn---border-color: currentColor;
91
122
  --origam-btn---position: relative;
92
- --origam-btn---density: 0;
123
+ --origam-btn---density: 0px;
93
124
  --origam-btn---width: auto;
94
125
  --origam-btn---min-width: 64px;
95
126
  --origam-btn---max-width: 100%;
@@ -920,8 +951,8 @@
920
951
  --origam-field__input---padding-block-filled: 20px;
921
952
  --origam-field__input---padding-top: var(--origam-field__input---padding-block-md);
922
953
  --origam-field__input---padding-bottom: var(--origam-field__input---padding-block-md);
923
- --origam-field__input---padding-start: 0;
924
- --origam-field__input---padding-end: 0;
954
+ --origam-field__input---padding-start: 0px;
955
+ --origam-field__input---padding-end: 0px;
925
956
  --origam-field__input---opacity: 0.7;
926
957
  --origam-field__label---font-size: 0.75em;
927
958
  --origam-field__label---transition-duration: var(--origam-motion__duration---normal);
@@ -1431,6 +1462,11 @@
1431
1462
  --origam-table__header-cell---padding-inline: var(--origam-space---4);
1432
1463
  --origam-table__header-cell---border-bottom-color: var(--origam-color__border---default);
1433
1464
  --origam-table__header-cell---border-bottom-width: var(--origam-border__width---2);
1465
+ /* #840 — derived from the SAME density-aware padding-block token, so it
1466
+ never drifts out of sync with it: 2 * padding-block + border-bottom
1467
+ + 18px (measured content-box line height of a single-line header
1468
+ cell in Chromium, constant across the 3 density rungs). */
1469
+ --origam-table__header-cell---height: calc((2 * var(--origam-table__header-cell---padding-block, 12px)) + var(--origam-table__header-cell---border-bottom-width, 2px) + 18px);
1434
1470
  --origam-table__cell---padding-block: var(--origam-space---3);
1435
1471
  --origam-table__cell---padding-inline: var(--origam-space---4);
1436
1472
  --origam-table__cell---border-color: var(--origam-color__border---subtle);
@@ -1997,8 +2033,9 @@
1997
2033
  --origam-switch__track---background-color-disabled: var(--origam-color__surface---disabled);
1998
2034
  --origam-switch__track---background-color-error: var(--origam-color__feedback--danger---bg);
1999
2035
  --origam-switch__track---color-error: var(--origam-color__feedback--danger---fg);
2000
- --origam-switch__track---border-color: rgba(0, 0, 0, 0);
2001
- --origam-switch__track---border-width: var(--origam-border__width---0);
2036
+ --origam-switch__track---border-color: var(--origam-color__border---default);
2037
+ --origam-switch__track---border-style: solid;
2038
+ --origam-switch__track---border-width: var(--origam-border__width---thin);
2002
2039
  --origam-switch__track---backdrop-filter: none;
2003
2040
  --origam-switch__thumb---size: 20px;
2004
2041
  --origam-switch__thumb---background-color: var(--origam-color__surface---default);
@@ -20,8 +20,7 @@
20
20
  <div
21
21
  key="prepend"
22
22
  class="origam-alert__prepend"
23
- :role="isPrependClickable ? 'button' : undefined"
24
- :tabindex="isPrependClickable ? 0 : undefined"
23
+ v-bind="prependCommandAttrs"
25
24
  @click="handleClickPrepend"
26
25
  @keydown="handleKeydownPrepend"
27
26
  >
@@ -71,8 +70,7 @@
71
70
  <div
72
71
  key="append"
73
72
  class="origam-alert__append"
74
- :role="isAppendClickable ? 'button' : undefined"
75
- :tabindex="isAppendClickable ? 0 : undefined"
73
+ v-bind="appendCommandAttrs"
76
74
  @click="handleClickAppend"
77
75
  @keydown="handleKeydownAppend"
78
76
  >
@@ -202,6 +200,8 @@ const props = defineProps({
202
200
  appendIcon: { type: null, required: false },
203
201
  prependAvatar: { type: String, required: false },
204
202
  prependIcon: { type: null, required: false },
203
+ prependAriaLabel: { type: String, required: false },
204
+ appendAriaLabel: { type: String, required: false },
205
205
  fontSize: { type: null, required: false },
206
206
  fontWeight: { type: null, required: false },
207
207
  lineHeight: { type: null, required: false },
@@ -241,8 +241,8 @@ const {
241
241
  onClickAppend: handleClickAppend,
242
242
  onKeydownPrepend: handleKeydownPrepend,
243
243
  onKeydownAppend: handleKeydownAppend,
244
- isPrependClickable,
245
- isAppendClickable,
244
+ prependCommandAttrs,
245
+ appendCommandAttrs,
246
246
  hasAppend,
247
247
  hasPrepend
248
248
  } = useAdjacent(props, prependIcon, appendIcon);
@@ -56,6 +56,7 @@ import { useStateFlag } from "../../composables/Commons/stateFlag.composable";
56
56
  import { useStyle } from "../../composables/Commons/style.composable";
57
57
  import { useTypography } from "../../composables/Commons/typography.composable";
58
58
  import { isEmpty } from "../../utils/Commons/commons.util";
59
+ import { isIntent, tokenStylesForIntent } from "../../utils/Commons/color.util";
59
60
  import { computed, useSlots } from "vue";
60
61
  const props = defineProps({
61
62
  icon: { type: null, required: false },
@@ -116,7 +117,19 @@ defineSlots();
116
117
  const { filterProps } = useProps(props);
117
118
  const { classes: hoverClasses, isOn: isHover, config: hoverState, unset: handleMouseleave, set: handleMouseenter } = useStateFlag(props, { state: "hover" });
118
119
  const { classes: activeClasses, isOn: isActive, config: activeState, toggle: handleClick } = useStateFlag(props, { state: "active" });
119
- const { colorClasses, colorStyles, borderClasses, borderStyles, roundedClasses, roundedStyles, elevationClasses, elevationStyles, paddingClasses, paddingStyles, marginClasses, marginStyles } = useStateEffect(props, isHover, isActive, hoverState, activeState);
120
+ const { color: effectiveColor, bgColor: effectiveBgColor, colorClasses, colorStyles, borderClasses, borderStyles, roundedClasses, roundedStyles, elevationClasses, elevationStyles, paddingClasses, paddingStyles, marginClasses, marginStyles } = useStateEffect(props, isHover, isActive, hoverState, activeState);
121
+ const avatarColorStyles = computed(() => {
122
+ const bg = effectiveBgColor.value;
123
+ const fg = effectiveColor.value;
124
+ if (!bg || bg === "ghost" || !isIntent(bg) || fg != null && isIntent(fg)) {
125
+ return colorStyles.value;
126
+ }
127
+ const intentFg = tokenStylesForIntent(bg, "default").color;
128
+ return [
129
+ ...colorStyles.value.filter((decl) => !decl.startsWith("color:")),
130
+ `color: ${intentFg}`
131
+ ];
132
+ });
120
133
  const { typographyStyles } = useTypography(props, "avatar");
121
134
  const slots = useSlots();
122
135
  const hasImage = computed(() => {
@@ -149,7 +162,7 @@ const avatarStyles = computed(() => {
149
162
  paddingStyles.value,
150
163
  marginStyles.value,
151
164
  sizeStyles.value,
152
- colorStyles.value,
165
+ avatarColorStyles.value,
153
166
  elevationStyles.value,
154
167
  typographyStyles.value,
155
168
  props.style
@@ -29,8 +29,7 @@
29
29
  <span
30
30
  key="prepend"
31
31
  class="origam-badge__prepend"
32
- :role="isPrependClickable ? 'button' : undefined"
33
- :tabindex="isPrependClickable ? 0 : undefined"
32
+ v-bind="prependCommandAttrs"
34
33
  @click="handleClickPrepend"
35
34
  @keydown="handleKeydownPrepend"
36
35
  >
@@ -63,8 +62,7 @@
63
62
  <span
64
63
  key="append"
65
64
  class="origam-badge__append"
66
- :role="isAppendClickable ? 'button' : undefined"
67
- :tabindex="isAppendClickable ? 0 : undefined"
65
+ v-bind="appendCommandAttrs"
68
66
  @click="handleClickAppend"
69
67
  @keydown="handleKeydownAppend"
70
68
  >
@@ -154,7 +152,9 @@ const props = defineProps({
154
152
  appendAvatar: { type: String, required: false },
155
153
  appendIcon: { type: null, required: false },
156
154
  prependAvatar: { type: String, required: false },
157
- prependIcon: { type: null, required: false }
155
+ prependIcon: { type: null, required: false },
156
+ prependAriaLabel: { type: String, required: false },
157
+ appendAriaLabel: { type: String, required: false }
158
158
  });
159
159
  defineEmits(["click:append", "click:prepend", "update:hover"]);
160
160
  defineSlots();
@@ -171,8 +171,8 @@ const {
171
171
  onClickAppend: handleClickAppend,
172
172
  onKeydownPrepend: handleKeydownPrepend,
173
173
  onKeydownAppend: handleKeydownAppend,
174
- isPrependClickable,
175
- isAppendClickable,
174
+ prependCommandAttrs,
175
+ appendCommandAttrs,
176
176
  hasAppend,
177
177
  hasPrepend
178
178
  } = useAdjacent(props, prependIcon, appendIcon);
@@ -15,8 +15,7 @@
15
15
  <span
16
16
  key="prepend"
17
17
  class="origam-breadcrumb-item__prepend"
18
- :role="isPrependZoneFocusable ? 'button' : undefined"
19
- :tabindex="isPrependZoneFocusable ? 0 : undefined"
18
+ v-bind="prependCommandAttrs"
20
19
  @click="handleClickPrepend"
21
20
  @keydown="handleKeydownPrepend"
22
21
  >
@@ -45,8 +44,7 @@
45
44
  <span
46
45
  key="append"
47
46
  class="origam-breadcrumb-item__append"
48
- :role="isAppendZoneFocusable ? 'button' : undefined"
49
- :tabindex="isAppendZoneFocusable ? 0 : undefined"
47
+ v-bind="appendCommandAttrs"
50
48
  @click="handleClickAppend"
51
49
  @keydown="handleKeydownAppend"
52
50
  >
@@ -73,6 +71,7 @@
73
71
  import OrigamAvatar from "../Avatar/OrigamAvatar.vue";
74
72
  import OrigamIcon from "../Icon/OrigamIcon.vue";
75
73
  import vContrast from "../../directives/Contrast/contrast.directive";
74
+ import { useAccessibleCommand } from "../../composables/Commons/accessibleCommand.composable";
76
75
  import { useAdjacent } from "../../composables/Commons/adjacent.composable";
77
76
  import { useDensity } from "../../composables/Commons/density.composable";
78
77
  import { useLink } from "../../composables/Commons/link.composable";
@@ -132,6 +131,8 @@ const props = defineProps({
132
131
  appendIcon: { type: null, required: false },
133
132
  prependAvatar: { type: String, required: false },
134
133
  prependIcon: { type: null, required: false },
134
+ prependAriaLabel: { type: String, required: false },
135
+ appendAriaLabel: { type: String, required: false },
135
136
  hover: { type: [Boolean, Object], required: false },
136
137
  hoverClass: { type: String, required: false },
137
138
  active: { type: [Boolean, Object], required: false },
@@ -160,6 +161,20 @@ const {
160
161
  } = useAdjacent(props, toRef(props, "prependIcon"), toRef(props, "appendIcon"));
161
162
  const isPrependZoneFocusable = computed(() => isPrependClickable.value && !link.isLink?.value);
162
163
  const isAppendZoneFocusable = computed(() => isAppendClickable.value && !link.isLink?.value);
164
+ const prependCommandAttrs = useAccessibleCommand({
165
+ component: "OrigamBreadcrumbItem",
166
+ zone: "prepend",
167
+ prop: "prependAriaLabel",
168
+ active: isPrependZoneFocusable,
169
+ label: () => props.prependAriaLabel
170
+ });
171
+ const appendCommandAttrs = useAccessibleCommand({
172
+ component: "OrigamBreadcrumbItem",
173
+ zone: "append",
174
+ prop: "appendAriaLabel",
175
+ active: isAppendZoneFocusable,
176
+ label: () => props.appendAriaLabel
177
+ });
163
178
  const { densityClasses } = useDensity(props);
164
179
  const breadcrumbItemStyles = computed(() => {
165
180
  return [
@@ -252,6 +267,10 @@ defineExpose({
252
267
  pointer-events: none;
253
268
  }
254
269
 
270
+ &[aria-current='page'] {
271
+ --origam-breadcrumb-item---opacity: var(--origam-opacity---100);
272
+ }
273
+
255
274
  &--density-comfortable {
256
275
  --origam-breadcrumb-item---density: -8px;
257
276
  }
@@ -125,7 +125,7 @@
125
125
  </template>
126
126
 
127
127
  <script lang="ts" setup>
128
- import { computed, onMounted, ref, StyleValue, toRef, useAttrs, useSlots } from "vue";
128
+ import { computed, onMounted, ref, StyleValue, toRef, useAttrs, useSlots, watchEffect } from "vue";
129
129
  import OrigamAvatar from "../Avatar/OrigamAvatar.vue";
130
130
  import OrigamIcon from "../Icon/OrigamIcon.vue";
131
131
  import OrigamLoader from "../Loader/OrigamLoader.vue";
@@ -148,6 +148,7 @@ import { useStatus } from "../../composables/Commons/status.composable";
148
148
  import { useStyle } from "../../composables/Commons/style.composable";
149
149
  import { useTypography } from "../../composables/Commons/typography.composable";
150
150
  import { useVariant } from "../../composables/Commons/variant.composable";
151
+ import { warnMissingNativeControlName } from "../../utils/Commons/a11y.util";
151
152
  import { warnDeprecatedEmit } from "../../utils/Commons/color.util";
152
153
  import { ADJACENT_EMIT_REPLACEMENT } from "../../consts/Btn/btn.const";
153
154
  import { ORIGAM_BTN_TOGGLE_KEY } from "../../consts/Btn/btn-toggle.const";
@@ -234,6 +235,8 @@ const props = defineProps({
234
235
  appendIcon: { type: null, required: false },
235
236
  prependAvatar: { type: String, required: false },
236
237
  prependIcon: { type: null, required: false },
238
+ prependAriaLabel: { type: String, required: false },
239
+ appendAriaLabel: { type: String, required: false },
237
240
  hover: { type: [Boolean, Object], required: false },
238
241
  hoverClass: { type: String, required: false },
239
242
  active: { type: [Boolean, Object], required: false, default: void 0 },
@@ -331,6 +334,21 @@ const hasIcon = computed(() => {
331
334
  const hasLoader = computed(() => {
332
335
  return slots.loader || loaderConfig.value.isActive;
333
336
  });
337
+ const isUnnamedIconOnly = computed(() => {
338
+ if (!hasIcon.value) return false;
339
+ if (slots.default || props.text) return false;
340
+ return !(attrs["aria-label"] || attrs["aria-labelledby"] || attrs.title);
341
+ });
342
+ if (import.meta.env?.DEV) {
343
+ watchEffect(() => {
344
+ if (isUnnamedIconOnly.value) {
345
+ warnMissingNativeControlName(
346
+ "OrigamBtn",
347
+ "icon-only mode renders a <button> whose only content is an aria-hidden glyph"
348
+ );
349
+ }
350
+ });
351
+ }
334
352
  const isSkeletonLoading = computed(() => {
335
353
  return loaderConfig.value.isActive && loaderConfig.value.kind === "skeleton";
336
354
  });
@@ -1136,7 +1154,7 @@ defineExpose({
1136
1154
  --origam-btn__prepend---margin-inline-start: calc(var(--origam-btn---height) / -9);
1137
1155
  --origam-btn__prepend---margin-inline-end: calc(var(--origam-btn---height) / 4.5);
1138
1156
 
1139
- --origam-btn---min-width: calc(var(--origam-btn---width, 36px) + var(--origam-btn---density, 0));
1140
- --origam-btn---min-height: calc(var(--origam-btn---height, 36px) + var(--origam-btn---density, 0));
1157
+ --origam-btn---min-width: calc(var(--origam-btn---width, 36px) + var(--origam-btn---density, 0px));
1158
+ --origam-btn---min-height: calc(var(--origam-btn---height, 36px) + var(--origam-btn---density, 0px));
1141
1159
  }
1142
1160
  </style>
@@ -442,7 +442,7 @@ defineExpose({
442
442
 
443
443
  <style>
444
444
  :root {
445
- --origam-btn-group---density: 0;
445
+ --origam-btn-group---density: 0px;
446
446
 
447
447
  --origam-btn-group---border-radius: var(--origam-btn---border-radius, 4px);
448
448
  --origam-btn-group---border-width: var(--origam-btn---border-width, 0);
@@ -896,7 +896,7 @@ function onKeydown(event) {
896
896
  internalDate.value = next;
897
897
  emit("update:currentDate", next);
898
898
  const focusTarget = next;
899
- void nextTick(() => focusDayCell(focusTarget));
899
+ nextTick(() => focusDayCell(focusTarget));
900
900
  }
901
901
  }
902
902
  const {
@@ -246,6 +246,8 @@ const props = defineProps({
246
246
  appendIcon: { type: null, required: false },
247
247
  prependAvatar: { type: String, required: false },
248
248
  prependIcon: { type: null, required: false },
249
+ prependAriaLabel: { type: String, required: false },
250
+ appendAriaLabel: { type: String, required: false },
249
251
  active: { type: [Boolean, Object], required: false },
250
252
  activeClass: { type: String, required: false }
251
253
  });
@@ -16,8 +16,7 @@
16
16
  v-if="hasPrepend"
17
17
  key="prepend"
18
18
  class="origam-card-header__prepend"
19
- :role="isPrependClickable ? 'button' : undefined"
20
- :tabindex="isPrependClickable ? 0 : undefined"
19
+ v-bind="prependCommandAttrs"
21
20
  @click="handleClickPrepend"
22
21
  @keydown="handleKeydownPrepend"
23
22
  >
@@ -75,8 +74,7 @@
75
74
  v-if="hasAppend"
76
75
  key="append"
77
76
  class="origam-card-header__append"
78
- :role="isAppendClickable ? 'button' : undefined"
79
- :tabindex="isAppendClickable ? 0 : undefined"
77
+ v-bind="appendCommandAttrs"
80
78
  @click="handleClickAppend"
81
79
  @keydown="handleKeydownAppend"
82
80
  >
@@ -157,6 +155,8 @@ const props = defineProps({
157
155
  appendIcon: { type: null, required: false },
158
156
  prependAvatar: { type: String, required: false },
159
157
  prependIcon: { type: null, required: false },
158
+ prependAriaLabel: { type: String, required: false },
159
+ appendAriaLabel: { type: String, required: false },
160
160
  fontSize: { type: null, required: false },
161
161
  fontWeight: { type: null, required: false },
162
162
  lineHeight: { type: null, required: false },
@@ -178,8 +178,8 @@ const {
178
178
  onClickAppend: handleClickAppend,
179
179
  onKeydownPrepend: handleKeydownPrepend,
180
180
  onKeydownAppend: handleKeydownAppend,
181
- isPrependClickable,
182
- isAppendClickable,
181
+ prependCommandAttrs,
182
+ appendCommandAttrs,
183
183
  hasPrepend,
184
184
  hasAppend
185
185
  } = useAdjacent(props, toRef(props, "prependIcon"), toRef(props, "appendIcon"));
@@ -479,7 +479,7 @@ defineExpose({
479
479
  --origam-card-header__title---line-height: 1.5rem;
480
480
  --origam-card-header__title---text-transform: none;
481
481
 
482
- --origam-card-header__subtitle---color: var(--origam-color__text---secondary);
482
+ --origam-card-header__subtitle---color: currentColor;
483
483
  --origam-card-header__subtitle---display: -webkit-box;
484
484
  --origam-card-header__subtitle---overflow: hidden;
485
485
 
@@ -194,6 +194,8 @@ const { t } = useLocale();
194
194
  const model = useVModel(props, "modelValue");
195
195
  const origamWindowRef = ref();
196
196
  let slideTimeout = -1;
197
+ let restartFrame = -1;
198
+ let disposed = false;
197
199
  const progressPercent = ref(0);
198
200
  let progressRaf = -1;
199
201
  let progressStart = 0;
@@ -253,7 +255,13 @@ const playPauseIcon = computed(() => {
253
255
  });
254
256
  const restartTimeout = () => {
255
257
  window.clearTimeout(slideTimeout);
256
- window.requestAnimationFrame(startTimeout);
258
+ if (disposed) return;
259
+ window.cancelAnimationFrame(restartFrame);
260
+ restartFrame = window.requestAnimationFrame(() => {
261
+ restartFrame = -1;
262
+ if (disposed) return;
263
+ startTimeout();
264
+ });
257
265
  };
258
266
  watch(model, restartTimeout);
259
267
  watch(() => props.interval, restartTimeout);
@@ -271,6 +279,11 @@ watch(() => props.progress, (val) => {
271
279
  });
272
280
  onMounted(startTimeout);
273
281
  onBeforeUnmount(() => {
282
+ disposed = true;
283
+ if (restartFrame !== -1) {
284
+ window.cancelAnimationFrame(restartFrame);
285
+ restartFrame = -1;
286
+ }
274
287
  window.clearTimeout(slideTimeout);
275
288
  stopProgress();
276
289
  });
@@ -589,7 +589,7 @@ const svgDesc = computed(() => {
589
589
  });
590
590
  const boxAriaLabel = (box) => {
591
591
  const { min, q1, median, q3, max } = box.rawStats;
592
- return `${box.category}: min=${min} Q1=${q1} median=${median} Q3=${q3} max=${max}`;
592
+ return t("origam.chart.box_plot.box_aria_label", box.category, min, q1, median, q3, max);
593
593
  };
594
594
  const onBoxEnter = (box) => {
595
595
  hoveredIndex.value = box.index;
@@ -536,7 +536,8 @@ const rootClasses = computed(() => [
536
536
  elevationClasses.value,
537
537
  marginClasses.value,
538
538
  paddingClasses.value,
539
- roundedClasses.value
539
+ roundedClasses.value,
540
+ props.class
540
541
  ]);
541
542
  const rootStyles = computed(() => {
542
543
  const out = {};
@@ -562,7 +563,7 @@ const svgDesc = computed(() => {
562
563
  });
563
564
  const bulletAriaLabel = (bullet) => {
564
565
  const pct = bullet.datum.target ? Math.round(bullet.datum.value / bullet.datum.target * 100) : 0;
565
- return `${bullet.category}: value ${bullet.datum.value}, target ${bullet.datum.target}, ${pct}% achievement`;
566
+ return t("origam.chart.bullet.bullet_aria_label", bullet.category, bullet.datum.value, bullet.datum.target, pct);
566
567
  };
567
568
  const onBulletEnter = (bullet) => {
568
569
  hoveredIndex.value = bullet.index;
@@ -475,8 +475,8 @@ const svgDesc = computed(() => {
475
475
  });
476
476
  const candleAriaLabel = (candle) => {
477
477
  const d = candle.datum;
478
- const direction = candle.isBullish ? "bullish" : "bearish";
479
- return `${d.date}: ${direction}, open ${d.open}, high ${d.high}, low ${d.low}, close ${d.close}`;
478
+ const direction = candle.isBullish ? t("origam.chart.candlestick.direction_bullish") : t("origam.chart.candlestick.direction_bearish");
479
+ return t("origam.chart.candlestick.candle_aria_label", d.date, direction, d.open, d.high, d.low, d.close);
480
480
  };
481
481
  const onCandleEnter = (candle) => {
482
482
  hoveredIndex.value = candle.index;
@@ -290,12 +290,12 @@
290
290
  v-if="zoomable && isZoomed"
291
291
  class="origam-chart__zoom-reset"
292
292
  data-cy="origam-chart-zoom-reset"
293
- :transform="`translate(${ plot.x1 - 68 }, ${ plot.y0 })`"
293
+ :transform="`translate(${ plot.x1 - zoomResetWidth - CHART_ZOOM_RESET_GAP }, ${ plot.y0 })`"
294
294
  >
295
295
  <rect
296
296
  x="0"
297
297
  y="0"
298
- width="64"
298
+ :width="zoomResetWidth"
299
299
  height="20"
300
300
  rx="4"
301
301
  :style="{ fill: 'var(--origam-chart__zoom-reset---bg, rgba(59,130,246,0.9))', cursor: 'pointer' }"
@@ -308,13 +308,14 @@
308
308
  @keydown.space.prevent="onZoomReset"
309
309
  />
310
310
  <text
311
- x="32"
311
+ ref="zoomResetTextRef"
312
+ :x="zoomResetWidth / 2"
312
313
  y="13"
313
314
  text-anchor="middle"
314
315
  dominant-baseline="auto"
315
316
  pointer-events="none"
316
317
  :style="{ fill: '#ffffff', fontSize: '0.6875rem', fontWeight: '600' }"
317
- >Reset zoom</text>
318
+ >{{ zoomResetAriaLabel }}</text>
318
319
  </g>
319
320
 
320
321
  <g
@@ -486,6 +487,7 @@
486
487
  <script lang="ts" setup>
487
488
  import {
488
489
  computed,
490
+ nextTick,
489
491
  ref,
490
492
  watch
491
493
  } from "vue";
@@ -506,6 +508,11 @@ import {
506
508
  computePlotLineGeometry
507
509
  } from "../../composables/Chart/chart.composable";
508
510
  import { CHART_RANGE_SELECTOR_DEFAULT_BUTTONS } from "../../consts/Chart/chart.const";
511
+ import {
512
+ CHART_ZOOM_RESET_GAP,
513
+ CHART_ZOOM_RESET_MIN_WIDTH,
514
+ CHART_ZOOM_RESET_PADDING_X
515
+ } from "../../consts/Chart/chart-cartesian.const";
509
516
  import { OrigamBtn } from "../Btn";
510
517
  import OrigamChartAxis from "./OrigamChartAxis.vue";
511
518
  import OrigamChartLegend from "./OrigamChartLegend.vue";
@@ -598,6 +605,28 @@ const breadcrumbItems = computed(() => {
598
605
  const drilldownBackLabel = computed(() => props.drilldown?.backLabel ?? t("origam.chart.drilldown.back_label"));
599
606
  const drilldownNavAriaLabel = computed(() => t(props.drilldown?.navAriaLabel ?? "origam.chart.drilldown.aria_label"));
600
607
  const zoomResetAriaLabel = computed(() => t(props.zoomResetLabel));
608
+ const zoomResetTextRef = ref(null);
609
+ const zoomResetTextWidth = ref(0);
610
+ const zoomResetWidth = computed(() => {
611
+ if (!zoomResetTextWidth.value) return CHART_ZOOM_RESET_MIN_WIDTH;
612
+ return Math.max(
613
+ CHART_ZOOM_RESET_MIN_WIDTH,
614
+ zoomResetTextWidth.value + CHART_ZOOM_RESET_PADDING_X * 2
615
+ );
616
+ });
617
+ const measureZoomResetText = async () => {
618
+ await nextTick();
619
+ const el = zoomResetTextRef.value;
620
+ if (!el || typeof el.getBBox !== "function") {
621
+ zoomResetTextWidth.value = 0;
622
+ return;
623
+ }
624
+ try {
625
+ zoomResetTextWidth.value = el.getBBox().width;
626
+ } catch {
627
+ zoomResetTextWidth.value = 0;
628
+ }
629
+ };
601
630
  const resolveDrilldownLink = (link) => {
602
631
  if (!props.drilldown) return null;
603
632
  const dataset = props.drilldown.datasets.find((d) => d.id === link.id);
@@ -665,6 +694,22 @@ const {
665
694
  pxToCategoryIndex,
666
695
  WHEEL_ZOOM_STEP
667
696
  } = zoom;
697
+ watch(
698
+ [zoomResetAriaLabel, isZoomed, () => props.zoomable],
699
+ /*********************************************************
700
+ * Promesse flottante, deliberement
701
+ *
702
+ * @description
703
+ * La mesure se fait en `flush: 'post'` et rien n'attend la
704
+ * promesse. Le `void` qui marquait cette intention est retire
705
+ * (Sonar #771) : la valeur de retour reste ignoree a l'identique,
706
+ * et le callback rend toujours `undefined`.
707
+ ********************************************************/
708
+ () => {
709
+ measureZoomResetText();
710
+ },
711
+ { flush: "post", immediate: true }
712
+ );
668
713
  const visibleCategories = computed(() => {
669
714
  if (!props.zoomable) return activeCategories.value;
670
715
  const len = activeCategories.value.length;