@dialpad/dialtone-vue 4.4.1 → 4.6.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 (256) hide show
  1. package/dist/{Datepicker-CGFa1nGm.js → Datepicker-D-Lgvthq.js} +17 -5
  2. package/dist/Datepicker-D-Lgvthq.js.map +1 -0
  3. package/dist/Datepicker-DmKOuf5y.cjs +2 -0
  4. package/dist/Datepicker-DmKOuf5y.cjs.map +1 -0
  5. package/dist/EmojiPicker-CXFd-iVj.cjs +2 -0
  6. package/dist/EmojiPicker-CXFd-iVj.cjs.map +1 -0
  7. package/dist/{EmojiPicker-BllVwJf4.js → EmojiPicker-D46lLRMp.js} +75 -41
  8. package/dist/EmojiPicker-D46lLRMp.js.map +1 -0
  9. package/dist/{ForceLinkify-bO3ug94b.js → ForceLinkify-DuAo3TMB.js} +1 -1
  10. package/dist/{ForceLinkify-bO3ug94b.js.map → ForceLinkify-DuAo3TMB.js.map} +1 -1
  11. package/dist/{ForceLinkify-CI1tkUBf.cjs → ForceLinkify-kQ_kWKVm.cjs} +1 -1
  12. package/dist/{ForceLinkify-CI1tkUBf.cjs.map → ForceLinkify-kQ_kWKVm.cjs.map} +1 -1
  13. package/dist/{MarkdownRenderer-B6oyniLV.cjs → MarkdownRenderer-C5wdjC5_.cjs} +1 -1
  14. package/dist/{MarkdownRenderer-B6oyniLV.cjs.map → MarkdownRenderer-C5wdjC5_.cjs.map} +1 -1
  15. package/dist/{MarkdownRenderer-D-EV50_M.js → MarkdownRenderer-eMwmPygx.js} +1 -1
  16. package/dist/{MarkdownRenderer-D-EV50_M.js.map → MarkdownRenderer-eMwmPygx.js.map} +1 -1
  17. package/dist/RichTextEditor-7eY8gy9u.cjs +11 -0
  18. package/dist/RichTextEditor-7eY8gy9u.cjs.map +1 -0
  19. package/dist/{RichTextEditor-Cz2VXb7-.js → RichTextEditor-DaOHmXD_.js} +362 -1254
  20. package/dist/RichTextEditor-DaOHmXD_.js.map +1 -0
  21. package/dist/{Scroller-JDoDYC5V.js → Scroller-B1xwv6TG.js} +1 -1
  22. package/dist/{Scroller-JDoDYC5V.js.map → Scroller-B1xwv6TG.js.map} +1 -1
  23. package/dist/{Scroller-Du2kJsTR.cjs → Scroller-pAU8UWIH.cjs} +1 -1
  24. package/dist/{Scroller-Du2kJsTR.cjs.map → Scroller-pAU8UWIH.cjs.map} +1 -1
  25. package/dist/Slider-D2cDYZcJ.cjs +2 -0
  26. package/dist/Slider-D2cDYZcJ.cjs.map +1 -0
  27. package/dist/Slider-Du45PVLU.js +1188 -0
  28. package/dist/Slider-Du45PVLU.js.map +1 -0
  29. package/dist/{TextList-D40u4g4T.js → TextList-7RwngSie.js} +1 -1
  30. package/dist/{TextList-D40u4g4T.js.map → TextList-7RwngSie.js.map} +1 -1
  31. package/dist/{TextList-rS1MQdPB.cjs → TextList-CLUdOdlp.cjs} +1 -1
  32. package/dist/{TextList-rS1MQdPB.cjs.map → TextList-CLUdOdlp.cjs.map} +1 -1
  33. package/dist/{TextListItem-CF6DzdvT.cjs → TextListItem-B-bhrqik.cjs} +1 -1
  34. package/dist/{TextListItem-CF6DzdvT.cjs.map → TextListItem-B-bhrqik.cjs.map} +1 -1
  35. package/dist/{TextListItem-PHgDIWV1.js → TextListItem-D0UmIR_q.js} +1 -1
  36. package/dist/{TextListItem-PHgDIWV1.js.map → TextListItem-D0UmIR_q.js.map} +1 -1
  37. package/dist/{Toast-CN9x3jKH.cjs → Toast-57Ts-hX9.cjs} +1 -1
  38. package/dist/{Toast-CN9x3jKH.cjs.map → Toast-57Ts-hX9.cjs.map} +1 -1
  39. package/dist/{Toast-DVUE2_fV.js → Toast-BNhGD6l8.js} +1 -1
  40. package/dist/{Toast-DVUE2_fV.js.map → Toast-BNhGD6l8.js.map} +1 -1
  41. package/dist/common/sr_only_close_button.vue.d.ts +15 -1
  42. package/dist/component-documentation.json +1 -1
  43. package/dist/components/Banner/Banner.vue.d.ts +30 -2
  44. package/dist/components/Banner/Banner.vue.d.ts.map +1 -1
  45. package/dist/components/Button/Button.vue.d.ts +15 -1
  46. package/dist/components/Button/Button.vue.d.ts.map +1 -1
  47. package/dist/components/ButtonGroup/ButtonGroup.vue.d.ts.map +1 -1
  48. package/dist/components/Chip/Chip.vue.d.ts +15 -1
  49. package/dist/components/Chip/Chip.vue.d.ts.map +1 -1
  50. package/dist/components/Codeblock/Codeblock.vue.d.ts.map +1 -1
  51. package/dist/components/Collapsible/Collapsible.vue.d.ts +15 -1
  52. package/dist/components/Collapsible/Collapsible.vue.d.ts.map +1 -1
  53. package/dist/components/ComboboxWithPopover/ComboboxWithPopover.vue.d.ts +30 -2
  54. package/dist/components/ComboboxWithPopover/ComboboxWithPopover.vue.d.ts.map +1 -1
  55. package/dist/components/Datepicker/Datepicker.vue.d.ts.map +1 -1
  56. package/dist/components/Datepicker/Modules/Calendar.vue.d.ts.map +1 -1
  57. package/dist/components/Datepicker/Modules/MonthYearPicker.vue.d.ts.map +1 -1
  58. package/dist/components/DescriptionList/DescriptionList.vue.d.ts.map +1 -1
  59. package/dist/components/Dropdown/Dropdown.vue.d.ts +30 -2
  60. package/dist/components/Dropdown/Dropdown.vue.d.ts.map +1 -1
  61. package/dist/components/Emoji/Emoji.vue.d.ts.map +1 -1
  62. package/dist/components/EmojiPicker/EmojiPicker.vue.d.ts.map +1 -1
  63. package/dist/components/EmojiPicker/Modules/EmojiDescription.vue.d.ts.map +1 -1
  64. package/dist/components/EmojiPicker/Modules/EmojiSearch.vue.d.ts.map +1 -1
  65. package/dist/components/EmojiPicker/Modules/EmojiSelector.vue.d.ts.map +1 -1
  66. package/dist/components/EmojiPicker/Modules/EmojiSkinSelector.vue.d.ts.map +1 -1
  67. package/dist/components/EmojiPicker/Modules/EmojiTabset.vue.d.ts.map +1 -1
  68. package/dist/components/EmptyState/EmptyState.vue.d.ts.map +1 -1
  69. package/dist/components/FilterPill/FilterPill.vue.d.ts +75 -5
  70. package/dist/components/FilterPill/FilterPill.vue.d.ts.map +1 -1
  71. package/dist/components/Hovercard/Hovercard.vue.d.ts +60 -4
  72. package/dist/components/Hovercard/Hovercard.vue.d.ts.map +1 -1
  73. package/dist/components/ImageViewer/ImageViewer.vue.d.ts +30 -2
  74. package/dist/components/ImageViewer/ImageViewer.vue.d.ts.map +1 -1
  75. package/dist/components/KeyboardShortcut/KeyboardShortcut.vue.d.ts.map +1 -1
  76. package/dist/components/LazyShow/LazyShow.vue.d.ts.map +1 -1
  77. package/dist/components/Loader/Loader.vue.d.ts +15 -1
  78. package/dist/components/Loader/Loader.vue.d.ts.map +1 -1
  79. package/dist/components/Loader/LoaderConstants.d.ts +5 -0
  80. package/dist/components/Loader/LoaderConstants.d.ts.map +1 -0
  81. package/dist/components/Loader/index.d.ts +1 -0
  82. package/dist/components/Modal/Modal.vue.d.ts +30 -2
  83. package/dist/components/Modal/Modal.vue.d.ts.map +1 -1
  84. package/dist/components/ModeIsland/ModeIsland.vue.d.ts.map +1 -1
  85. package/dist/components/MotionText/MotionText.vue.d.ts.map +1 -1
  86. package/dist/components/MotionText/MotionTextConstants.d.ts +72 -0
  87. package/dist/components/MotionText/MotionTextConstants.d.ts.map +1 -1
  88. package/dist/components/MotionText/index.d.ts +1 -1
  89. package/dist/components/MotionText/utils.d.ts +9 -0
  90. package/dist/components/MotionText/utils.d.ts.map +1 -0
  91. package/dist/components/Notice/Notice.vue.d.ts +30 -2
  92. package/dist/components/Notice/Notice.vue.d.ts.map +1 -1
  93. package/dist/components/Notice/NoticeAction.vue.d.ts +30 -2
  94. package/dist/components/Notice/NoticeAction.vue.d.ts.map +1 -1
  95. package/dist/components/Pagination/Pagination.vue.d.ts +15 -1
  96. package/dist/components/Pagination/Pagination.vue.d.ts.map +1 -1
  97. package/dist/components/Popover/Popover.vue.d.ts +30 -2
  98. package/dist/components/Popover/Popover.vue.d.ts.map +1 -1
  99. package/dist/components/Popover/PopoverHeaderFooter.vue.d.ts +15 -1
  100. package/dist/components/Popover/PopoverHeaderFooter.vue.d.ts.map +1 -1
  101. package/dist/components/RichTextEditor/Extensions/Variable/VariableComponent.vue.d.ts +45 -3
  102. package/dist/components/RichTextEditor/Extensions/Variable/VariableComponent.vue.d.ts.map +1 -1
  103. package/dist/components/Skeleton/Skeleton.vue.d.ts.map +1 -1
  104. package/dist/components/Slider/Composables/UseSliderCollisionAvoidance.d.ts +25 -0
  105. package/dist/components/Slider/Composables/UseSliderCollisionAvoidance.d.ts.map +1 -0
  106. package/dist/components/Slider/Composables/UseSliderDevWarnings.d.ts +5 -0
  107. package/dist/components/Slider/Composables/UseSliderDevWarnings.d.ts.map +1 -0
  108. package/dist/components/Slider/Composables/UseSliderDirection.d.ts +4 -0
  109. package/dist/components/Slider/Composables/UseSliderDirection.d.ts.map +1 -0
  110. package/dist/components/Slider/Composables/UseSliderGeometry.d.ts +88 -0
  111. package/dist/components/Slider/Composables/UseSliderGeometry.d.ts.map +1 -0
  112. package/dist/components/Slider/Composables/UseSliderInteraction.d.ts +33 -0
  113. package/dist/components/Slider/Composables/UseSliderInteraction.d.ts.map +1 -0
  114. package/dist/components/Slider/Composables/UseSliderMagneticSnap.d.ts +8 -0
  115. package/dist/components/Slider/Composables/UseSliderMagneticSnap.d.ts.map +1 -0
  116. package/dist/components/Slider/Composables/UseSliderMarksAndTicks.d.ts +13 -0
  117. package/dist/components/Slider/Composables/UseSliderMarksAndTicks.d.ts.map +1 -0
  118. package/dist/components/Slider/Composables/UseSliderTooltipReadout.d.ts +10 -0
  119. package/dist/components/Slider/Composables/UseSliderTooltipReadout.d.ts.map +1 -0
  120. package/dist/components/Slider/Composables/UseSliderValue.d.ts +16 -0
  121. package/dist/components/Slider/Composables/UseSliderValue.d.ts.map +1 -0
  122. package/dist/components/Slider/Slider.vue.d.ts +304 -0
  123. package/dist/components/Slider/Slider.vue.d.ts.map +1 -0
  124. package/dist/components/Slider/SliderConstants.d.ts +7 -0
  125. package/dist/components/Slider/SliderConstants.d.ts.map +1 -0
  126. package/dist/components/Slider/index.d.ts +3 -0
  127. package/dist/components/Slider/index.d.ts.map +1 -0
  128. package/dist/components/Slider/utils.d.ts +8 -0
  129. package/dist/components/Slider/utils.d.ts.map +1 -0
  130. package/dist/components/SplitButton/SplitButton.vue.d.ts +60 -4
  131. package/dist/components/SplitButton/SplitButton.vue.d.ts.map +1 -1
  132. package/dist/components/SplitButton/SplitButtonEnd.vue.d.ts +15 -1
  133. package/dist/components/SplitButton/SplitButtonEnd.vue.d.ts.map +1 -1
  134. package/dist/components/SplitButton/SplitButtonStart.vue.d.ts +15 -1
  135. package/dist/components/Tab/Tab.vue.d.ts +15 -1
  136. package/dist/components/Toast/Layouts/ToastLayoutAlternate.vue.d.ts +30 -2
  137. package/dist/components/Toast/Layouts/ToastLayoutAlternate.vue.d.ts.map +1 -1
  138. package/dist/components/Toast/Layouts/ToastLayoutDefault.vue.d.ts +30 -2
  139. package/dist/components/Toast/Layouts/ToastLayoutDefault.vue.d.ts.map +1 -1
  140. package/dist/components/Toast/Toast.vue.d.ts +120 -8
  141. package/dist/components/Toast/Toast.vue.d.ts.map +1 -1
  142. package/dist/dialtone-vue.cjs +1 -1
  143. package/dist/dialtone-vue.js +117 -114
  144. package/dist/floating-ui.dom-D2zQ_96p.cjs +2 -0
  145. package/dist/floating-ui.dom-D2zQ_96p.cjs.map +1 -0
  146. package/dist/floating-ui.dom-j5GI2lJG.js +963 -0
  147. package/dist/floating-ui.dom-j5GI2lJG.js.map +1 -0
  148. package/dist/index.d.ts +1 -0
  149. package/dist/lib/button-group/button-group.cjs +1 -1
  150. package/dist/lib/button-group/button-group.cjs.map +1 -1
  151. package/dist/lib/button-group/button-group.js +2 -1
  152. package/dist/lib/button-group/button-group.js.map +1 -1
  153. package/dist/lib/codeblock/codeblock.cjs +1 -1
  154. package/dist/lib/codeblock/codeblock.cjs.map +1 -1
  155. package/dist/lib/codeblock/codeblock.js +7 -1
  156. package/dist/lib/codeblock/codeblock.js.map +1 -1
  157. package/dist/lib/datepicker/datepicker.cjs +1 -1
  158. package/dist/lib/datepicker/datepicker.js +1 -1
  159. package/dist/lib/datepicker/index.cjs +1 -1
  160. package/dist/lib/datepicker/index.js +1 -1
  161. package/dist/lib/description-list/description-list.cjs +1 -1
  162. package/dist/lib/description-list/description-list.cjs.map +1 -1
  163. package/dist/lib/description-list/description-list.js +14 -5
  164. package/dist/lib/description-list/description-list.js.map +1 -1
  165. package/dist/lib/emoji/emoji.cjs +1 -1
  166. package/dist/lib/emoji/emoji.cjs.map +1 -1
  167. package/dist/lib/emoji/emoji.js +5 -1
  168. package/dist/lib/emoji/emoji.js.map +1 -1
  169. package/dist/lib/emoji-picker/emoji-picker.cjs +1 -1
  170. package/dist/lib/emoji-picker/emoji-picker.js +1 -1
  171. package/dist/lib/emoji-picker/index.cjs +1 -1
  172. package/dist/lib/emoji-picker/index.js +1 -1
  173. package/dist/lib/empty-state/empty-state.cjs +1 -1
  174. package/dist/lib/empty-state/empty-state.cjs.map +1 -1
  175. package/dist/lib/empty-state/empty-state.js +6 -3
  176. package/dist/lib/empty-state/empty-state.js.map +1 -1
  177. package/dist/lib/keyboard-shortcut/keyboard-shortcut.cjs +1 -1
  178. package/dist/lib/keyboard-shortcut/keyboard-shortcut.cjs.map +1 -1
  179. package/dist/lib/keyboard-shortcut/keyboard-shortcut.js +8 -2
  180. package/dist/lib/keyboard-shortcut/keyboard-shortcut.js.map +1 -1
  181. package/dist/lib/lazy-show/lazy-show.cjs +1 -1
  182. package/dist/lib/lazy-show/lazy-show.cjs.map +1 -1
  183. package/dist/lib/lazy-show/lazy-show.js +10 -10
  184. package/dist/lib/lazy-show/lazy-show.js.map +1 -1
  185. package/dist/lib/loader/index.cjs +1 -1
  186. package/dist/lib/loader/index.js +3 -2
  187. package/dist/lib/loader/loader-constants.cjs +2 -0
  188. package/dist/lib/loader/loader-constants.cjs.map +1 -0
  189. package/dist/lib/loader/loader-constants.js +9 -0
  190. package/dist/lib/loader/loader-constants.js.map +1 -0
  191. package/dist/lib/loader/loader.cjs +21 -21
  192. package/dist/lib/loader/loader.cjs.map +1 -1
  193. package/dist/lib/loader/loader.js +68 -13
  194. package/dist/lib/loader/loader.js.map +1 -1
  195. package/dist/lib/mode-island/mode-island.cjs +1 -1
  196. package/dist/lib/mode-island/mode-island.cjs.map +1 -1
  197. package/dist/lib/mode-island/mode-island.js +1 -0
  198. package/dist/lib/mode-island/mode-island.js.map +1 -1
  199. package/dist/lib/motion-text/index.cjs +1 -1
  200. package/dist/lib/motion-text/index.js +3 -3
  201. package/dist/lib/motion-text/motion-text-constants.cjs +1 -1
  202. package/dist/lib/motion-text/motion-text-constants.cjs.map +1 -1
  203. package/dist/lib/motion-text/motion-text-constants.js +64 -2
  204. package/dist/lib/motion-text/motion-text-constants.js.map +1 -1
  205. package/dist/lib/motion-text/motion-text.cjs +1 -1
  206. package/dist/lib/motion-text/motion-text.cjs.map +1 -1
  207. package/dist/lib/motion-text/motion-text.js +186 -146
  208. package/dist/lib/motion-text/motion-text.js.map +1 -1
  209. package/dist/lib/motion-text/utils.cjs +2 -0
  210. package/dist/lib/motion-text/utils.cjs.map +1 -0
  211. package/dist/lib/motion-text/utils.js +24 -0
  212. package/dist/lib/motion-text/utils.js.map +1 -0
  213. package/dist/lib/rich-text-editor/force-linkify.cjs +1 -1
  214. package/dist/lib/rich-text-editor/force-linkify.js +1 -1
  215. package/dist/lib/rich-text-editor/index.cjs +1 -1
  216. package/dist/lib/rich-text-editor/index.js +1 -1
  217. package/dist/lib/rich-text-editor/markdown-renderer.cjs +1 -1
  218. package/dist/lib/rich-text-editor/markdown-renderer.js +1 -1
  219. package/dist/lib/rich-text-editor/rich-text-editor.cjs +1 -1
  220. package/dist/lib/rich-text-editor/rich-text-editor.js +1 -1
  221. package/dist/lib/scroller/index.cjs +1 -1
  222. package/dist/lib/scroller/index.js +1 -1
  223. package/dist/lib/scroller/scroller.cjs +1 -1
  224. package/dist/lib/scroller/scroller.js +1 -1
  225. package/dist/lib/skeleton/skeleton.cjs +1 -1
  226. package/dist/lib/skeleton/skeleton.cjs.map +1 -1
  227. package/dist/lib/skeleton/skeleton.js +1 -0
  228. package/dist/lib/skeleton/skeleton.js.map +1 -1
  229. package/dist/lib/slider/index.cjs +1 -0
  230. package/dist/lib/slider/index.js +2 -0
  231. package/dist/lib/slider/slider.cjs +1 -0
  232. package/dist/lib/slider/slider.js +2 -0
  233. package/dist/lib/slider/utils.cjs +2 -0
  234. package/dist/lib/slider/utils.cjs.map +1 -0
  235. package/dist/lib/slider/utils.js +32 -0
  236. package/dist/lib/slider/utils.js.map +1 -0
  237. package/dist/lib/text-list/index.cjs +1 -1
  238. package/dist/lib/text-list/index.js +2 -2
  239. package/dist/lib/text-list/text-list-item.cjs +1 -1
  240. package/dist/lib/text-list/text-list-item.js +1 -1
  241. package/dist/lib/text-list/text-list.cjs +1 -1
  242. package/dist/lib/text-list/text-list.js +1 -1
  243. package/dist/lib/toast/index.cjs +1 -1
  244. package/dist/lib/toast/index.js +1 -1
  245. package/dist/lib/toast/toast.cjs +1 -1
  246. package/dist/lib/toast/toast.js +1 -1
  247. package/package.json +5 -5
  248. package/dist/Datepicker-CGFa1nGm.js.map +0 -1
  249. package/dist/Datepicker-DkGmnVc8.cjs +0 -2
  250. package/dist/Datepicker-DkGmnVc8.cjs.map +0 -1
  251. package/dist/EmojiPicker-BllVwJf4.js.map +0 -1
  252. package/dist/EmojiPicker-KO1yhODv.cjs +0 -2
  253. package/dist/EmojiPicker-KO1yhODv.cjs.map +0 -1
  254. package/dist/RichTextEditor-Cz2VXb7-.js.map +0 -1
  255. package/dist/RichTextEditor-EHgahp8r.cjs +0 -11
  256. package/dist/RichTextEditor-EHgahp8r.cjs.map +0 -1
@@ -1,8 +1,13 @@
1
1
  import { t as e } from "../../_plugin-vue_export-helper-BTgDAbhb.js";
2
- import { MOTION_TEXT_ANIMATION_MODES as t, MOTION_TEXT_SPEEDS as n, MOTION_TEXT_TIMING_PRESETS as r } from "./motion-text-constants.js";
3
- import { Fragment as i, Transition as a, createBlock as o, createCommentVNode as s, createElementBlock as c, createTextVNode as l, normalizeClass as u, normalizeStyle as d, openBlock as f, renderList as p, renderSlot as m, toDisplayString as h, withCtx as g } from "vue";
2
+ import { MOTION_TEXT_ANIMATION_MODES as t, MOTION_TEXT_MODE_SETTINGS as n, MOTION_TEXT_SPEEDS as r, MOTION_TEXT_TIMING_PRESETS as i, MOTION_TEXT_TRACKS as a } from "./motion-text-constants.js";
3
+ import { getGradientSlices as o, splitWords as s } from "./utils.js";
4
+ import { Fragment as c, createCommentVNode as l, createElementBlock as u, createElementVNode as d, createTextVNode as f, normalizeClass as p, normalizeStyle as m, openBlock as h, renderList as g, renderSlot as _, toDisplayString as v } from "vue";
4
5
  //#region components/MotionText/MotionText.vue
5
- var _ = {
6
+ var y = i[300], b = {
7
+ tracks: [],
8
+ gradient: !1,
9
+ loopHold: 0
10
+ }, x = {
6
11
  name: "DtMotionText",
7
12
  props: {
8
13
  text: {
@@ -17,7 +22,7 @@ var _ = {
17
22
  speed: {
18
23
  type: [String, Number],
19
24
  default: 300,
20
- validator: (e) => n.includes(String(e))
25
+ validator: (e) => r.includes(String(e))
21
26
  },
22
27
  autoStart: {
23
28
  type: Boolean,
@@ -45,30 +50,70 @@ var _ = {
45
50
  ],
46
51
  data() {
47
52
  return {
48
- words: [],
49
- visibleWordCount: 0,
50
- visibleCharsPerWord: [],
53
+ words: s(this.text),
54
+ wordWidths: [],
55
+ isRtl: !1,
51
56
  isAnimating: !1,
52
57
  isPaused: !1,
58
+ isComplete: !1,
59
+ isRestarting: !1,
53
60
  isLooped: !1,
61
+ isUnmounted: !1,
54
62
  animationTimeouts: [],
63
+ timelineStartedAt: 0,
64
+ timelineElapsed: 0,
55
65
  prefersReducedMotion: !1,
56
- animationKey: 0
66
+ animationKey: 0,
67
+ cssIterations: 1
57
68
  };
58
69
  },
59
70
  computed: {
60
- timing() {
61
- return r[String(this.speed)];
71
+ modeSettings() {
72
+ return n[this.animationMode] ?? b;
73
+ },
74
+ isWholeText() {
75
+ return !!this.modeSettings.wholeText;
76
+ },
77
+ speedScale() {
78
+ return (i[String(this.speed)] ?? y).duration / y.duration;
62
79
  },
63
80
  componentStyles() {
64
- return {
65
- "--d-motion-text-duration": `${this.timing.duration}ms`,
66
- "--d-motion-text-char-duration": `${this.timing.duration}ms`,
67
- "--d-motion-text-word-duration": `${this.timing.duration * 2}ms`
68
- };
81
+ let e = {};
82
+ return this.modeSettings.tracks.forEach((t) => {
83
+ Object.entries(a[t]).forEach(([n, r]) => {
84
+ e[`--d-motion-text-${t}-${n}`] = `${Math.round(r * this.speedScale)}ms`;
85
+ });
86
+ }), e;
87
+ },
88
+ wordStyles() {
89
+ let e = this.modeSettings.gradient ? o(this.wordWidths, this.isRtl) : [];
90
+ return this.words.map((t, n) => {
91
+ let r = e[n];
92
+ return {
93
+ "--d-motion-text-word-index": n,
94
+ ...r && {
95
+ "--d-motion-text-gradient-size": r.size,
96
+ "--d-motion-text-gradient-position": r.position
97
+ }
98
+ };
99
+ });
100
+ },
101
+ wordEndTimes() {
102
+ return this.words.map((e, t) => {
103
+ let n = this.modeSettings.tracks.map((e) => {
104
+ let { delay: n, stagger: r, duration: i } = a[e];
105
+ return n + r * t + i;
106
+ });
107
+ return Math.max(0, ...n) * this.speedScale;
108
+ });
69
109
  },
70
- isStaticAnimationMode() {
71
- return this.animationMode === "gradient-sweep" || this.animationMode === "shimmer";
110
+ cycleDuration() {
111
+ if (!this.isWholeText) return Math.max(0, ...this.wordEndTimes);
112
+ let e = this.modeSettings.tracks.map((e) => {
113
+ let { delay: t, duration: n } = a[e];
114
+ return t + n;
115
+ });
116
+ return Math.max(0, ...e) * this.speedScale * this.cssIterations;
72
117
  },
73
118
  motionTextClasses() {
74
119
  return [
@@ -77,192 +122,187 @@ var _ = {
77
122
  {
78
123
  "d-motion-text--animating": this.isAnimating,
79
124
  "d-motion-text--paused": this.isPaused,
80
- "d-motion-text--looped": this.isLooped
125
+ "d-motion-text--complete": this.isComplete,
126
+ "d-motion-text--restarting": this.isRestarting,
127
+ "d-motion-text--looped": this.isLooped,
128
+ "d-motion-text--respects-reduced-motion": this.respectsReducedMotion
81
129
  }
82
130
  ];
83
131
  }
84
132
  },
85
133
  watch: {
86
134
  text() {
87
- this.reset(), this.initializeContent();
135
+ if (this.isWholeText) {
136
+ this.words = s(this.text), this.isComplete && this.autoStart && !this.loop && (this.reset(), this.$nextTick(() => this.start()));
137
+ return;
138
+ }
139
+ if (this.reset(), this.text) {
140
+ this.initializeContent();
141
+ return;
142
+ }
143
+ this.words = [], this.$nextTick(() => this.initializeContent());
144
+ },
145
+ animationMode(e, t) {
146
+ let r = !!n[t]?.wholeText;
147
+ if (!this.text && r !== this.isWholeText) {
148
+ let e = this.isAnimating;
149
+ this.reset(), this.words = [], this.$nextTick(() => {
150
+ this.words = s(this.getSlotText()), this.wordWidths = [], e && this.$nextTick(() => this.start());
151
+ });
152
+ return;
153
+ }
154
+ this.restartIfAnimating();
155
+ },
156
+ autoStart(e) {
157
+ e && !this.isAnimating && (this.isWholeText || this.words.length) && this.$nextTick(() => this.start());
158
+ },
159
+ speed() {
160
+ this.restartIfAnimating();
88
161
  },
89
162
  loop: {
90
163
  handler(e) {
91
- this.isLooped = e;
164
+ this.isLooped = e, this.isAnimating && !this.isPaused && (this.timelineElapsed = Date.now() - this.timelineStartedAt, this.clearTimeouts(), this.runTimeline());
92
165
  },
93
166
  immediate: !0
94
167
  }
95
168
  },
96
169
  mounted() {
97
- this.checkReducedMotion(), this.initializeContent();
170
+ this.initWatchReducedMotion(), this.initializeContent(), document.fonts?.ready.then(() => {
171
+ !this.isUnmounted && this.isAnimating && this.measureWords();
172
+ });
98
173
  },
99
174
  beforeUnmount() {
100
- this.clearTimeouts();
175
+ this.isUnmounted = !0, this.clearTimeouts(), this.stopWatchingReducedMotion?.();
101
176
  },
102
177
  methods: {
103
- processTextToChars(e) {
104
- let t = [], n = (e, r = 0) => {
105
- if (e.nodeType === Node.TEXT_NODE) {
106
- let n = e.textContent?.match(/\S+\s*/g) || [];
107
- return t.push(...n.map((e, t) => ({
108
- text: e,
109
- chars: e.split(""),
110
- index: r + t
111
- }))), r + n.length;
112
- } else if (e.nodeType === Node.ELEMENT_NODE) {
113
- let t = r;
114
- return Array.from(e.childNodes).forEach((e) => {
115
- t = n(e, t);
116
- }), t;
117
- }
118
- return r;
119
- };
120
- return n(e), t;
178
+ getSlotText() {
179
+ return this.$refs.slotRef?.textContent || "";
121
180
  },
122
- processDirectText(e) {
123
- return e ? (e.match(/\S+\s*/g) || []).map((e, t) => ({
124
- text: e,
125
- chars: e.split(""),
126
- index: t
127
- })) : [];
181
+ initWatchReducedMotion() {
182
+ if (typeof window > "u" || !window.matchMedia) return;
183
+ let e = window.matchMedia("(prefers-reduced-motion: reduce)"), t = (e) => {
184
+ this.prefersReducedMotion = e.matches, e.matches && this.respectsReducedMotion && this.isAnimating && this.skipToEnd();
185
+ };
186
+ this.prefersReducedMotion = e.matches, e.addEventListener?.("change", t), this.stopWatchingReducedMotion = () => e.removeEventListener?.("change", t);
128
187
  },
129
- checkReducedMotion() {
130
- typeof window < "u" && window.matchMedia && (this.prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches);
188
+ measureWords() {
189
+ if (!this.modeSettings.gradient) return;
190
+ let e = this.$refs.contentRef?.querySelectorAll(".d-motion-text__word") || [], t = Array.from(e, (e) => e.getBoundingClientRect().width);
191
+ this.isRtl = window.getComputedStyle(this.$el).direction === "rtl", this.wordWidths = t.length === this.words.length && t.every((e) => e > 0) ? t : this.words.map((e) => e.text.length);
131
192
  },
132
193
  clearTimeouts() {
133
194
  this.animationTimeouts.forEach((e) => clearTimeout(e)), this.animationTimeouts = [];
134
195
  },
196
+ schedule(e, t) {
197
+ this.animationTimeouts.push(setTimeout(t, Math.max(0, e)));
198
+ },
199
+ runTimeline() {
200
+ let e = this.timelineElapsed, t = this.words.length, n = this.cycleDuration;
201
+ if (this.timelineStartedAt = Date.now() - e, (this.isWholeText ? [] : this.wordEndTimes).forEach((n, r) => {
202
+ n <= e || this.schedule(n - e, () => {
203
+ this.$emit("progress", {
204
+ wordsComplete: r + 1,
205
+ totalWords: t,
206
+ progress: (r + 1) / t
207
+ });
208
+ });
209
+ }), n > e && this.schedule(n - e, () => this.completeAnimation()), this.loop) {
210
+ let t = n + this.modeSettings.loopHold * this.speedScale;
211
+ this.schedule(t - e, () => this.restartCycle());
212
+ } else n <= e && this.finishAnimation();
213
+ },
135
214
  start() {
136
- if (!this.isAnimating) {
137
- if (this.isAnimating = !0, this.isPaused = !1, this.$emit("start"), this.respectsReducedMotion && this.prefersReducedMotion) {
215
+ if (!(this.isAnimating || this.isUnmounted)) {
216
+ if (this.clearTimeouts(), this.isAnimating = !0, this.isPaused = !1, this.isComplete = !1, this.$emit("start"), this.respectsReducedMotion && this.prefersReducedMotion) {
138
217
  this.showAllContent();
139
218
  return;
140
219
  }
141
- if (this.animationMode === "none") {
220
+ if (!this.modeSettings.tracks.length || !this.isWholeText && !this.words.length) {
142
221
  this.showAllContent();
143
222
  return;
144
223
  }
145
- this.isStaticAnimationMode || this.showNextWord();
224
+ this.measureWords(), this.cssIterations = this.readCssIterations(), this.timelineElapsed = 0, this.runTimeline();
146
225
  }
147
226
  },
227
+ readCssIterations() {
228
+ if (!this.isWholeText || this.loop) return 1;
229
+ let e = parseFloat(window.getComputedStyle(this.$el).animationIterationCount);
230
+ return Number.isFinite(e) && e > 1 ? e : 1;
231
+ },
148
232
  pause() {
149
- !this.isAnimating || this.isPaused || (this.isPaused = !0, this.clearTimeouts(), this.$emit("pause"));
233
+ !this.isAnimating || this.isPaused || (this.timelineElapsed = Date.now() - this.timelineStartedAt, this.clearTimeouts(), this.isPaused = !0, this.$emit("pause"));
150
234
  },
151
235
  resume() {
152
- this.isPaused && (this.isPaused = !1, this.$emit("resume"), this.showNextWord());
236
+ this.isPaused && (this.isPaused = !1, this.$emit("resume"), this.runTimeline());
153
237
  },
154
238
  reset() {
155
- this.clearTimeouts(), this.isAnimating = !1, this.isPaused = !1, this.visibleWordCount = 0, this.visibleCharsPerWord = Array(this.words.length).fill(0), this.animationKey++;
239
+ this.clearTimeouts(), this.isAnimating = !1, this.isPaused = !1, this.isComplete = !1, this.timelineElapsed = 0, this.animationKey++, this.replayAnimations();
156
240
  },
157
241
  skipToEnd() {
158
242
  this.showAllContent();
159
243
  },
160
244
  showAllContent() {
161
- this.visibleWordCount = this.words.length, this.visibleCharsPerWord = this.words.map((e) => e.chars.length), setTimeout(() => {
162
- this.isAnimating = !1, this.$emit("complete");
163
- }, 0);
245
+ this.finishAnimation(), this.isPaused = !1, this.schedule(0, () => this.$emit("complete"));
164
246
  },
165
- showNextWord() {
166
- if (this.isPaused || this.visibleWordCount >= this.words.length) {
167
- this.visibleWordCount >= this.words.length && this.completeAnimation();
168
- return;
169
- }
170
- let e = setTimeout(() => {
171
- this.visibleWordCount++, this.$emit("progress", {
172
- wordsComplete: this.visibleWordCount,
173
- totalWords: this.words.length,
174
- progress: this.visibleWordCount / this.words.length
175
- }), this.animateCharsForWord(this.visibleWordCount - 1);
176
- }, this.timing.wordDelay);
177
- this.animationTimeouts.push(e);
178
- },
179
- animateCharsForWord(e) {
180
- if (this.isPaused || e >= this.words.length) return;
181
- this.visibleCharsPerWord[e] = 0;
182
- let t = this.words[e].chars.length, n = () => {
183
- if (this.isPaused || this.visibleCharsPerWord[e] >= t) {
184
- this.visibleCharsPerWord[e] >= t && this.showNextWord();
185
- return;
186
- }
187
- this.visibleCharsPerWord[e]++;
188
- let r = setTimeout(n, this.timing.characterDelay);
189
- this.animationTimeouts.push(r);
190
- };
191
- n();
247
+ finishAnimation() {
248
+ this.clearTimeouts(), this.isAnimating = !1, this.isComplete = !0;
249
+ },
250
+ restartIfAnimating() {
251
+ this.isAnimating && (this.reset(), this.$nextTick(() => this.start()));
192
252
  },
193
253
  completeAnimation() {
194
- if (this.isAnimating = !1, this.clearTimeouts(), this.$emit("complete"), this.loop) {
195
- let e = setTimeout(() => {
196
- this.reset(), this.$nextTick(() => {
197
- this.start();
198
- });
199
- }, 500);
200
- this.animationTimeouts.push(e);
201
- }
254
+ this.$emit("complete"), this.loop || this.finishAnimation();
255
+ },
256
+ replayAnimations(e) {
257
+ this.isRestarting = !0, this.$nextTick(() => {
258
+ this.$el?.getBoundingClientRect?.(), this.isRestarting = !1, e?.();
259
+ });
260
+ },
261
+ restartCycle() {
262
+ this.isUnmounted || (this.clearTimeouts(), this.replayAnimations(() => {
263
+ this.measureWords(), this.timelineElapsed = 0, this.$emit("start"), this.runTimeline();
264
+ }));
202
265
  },
203
266
  initializeContent() {
204
- if (this.isStaticAnimationMode) {
205
- this.autoStart && this.$nextTick(() => this.start());
206
- return;
207
- }
208
- this.text ? this.words = this.processDirectText(this.text) : this.$refs.contentRef && (this.words = this.processTextToChars(this.$refs.contentRef)), this.visibleCharsPerWord = Array(this.words.length).fill(0), this.visibleWordCount = 0, this.autoStart && this.words.length > 0 && this.$nextTick(() => this.start());
267
+ this.words = s(this.text || this.getSlotText()), this.wordWidths = [], this.autoStart && (this.isWholeText || this.words.length > 0) && this.$nextTick(() => this.start());
209
268
  }
210
269
  }
211
- }, v = [
212
- "data-text-content",
213
- "aria-live",
214
- "aria-label"
215
- ], y = {
270
+ }, S = ["aria-live", "aria-label"], C = {
216
271
  key: 0,
272
+ "data-qa": "dt-motion-text-sr-only",
217
273
  class: "d-motion-text__sr-only"
218
- }, b = ["aria-hidden"], x = ["data-text-content"], S = {
274
+ }, w = ["aria-hidden"], T = ["aria-hidden"], E = {
219
275
  key: 3,
276
+ ref: "slotRef",
220
277
  class: "d-motion-text__fallback"
221
278
  };
222
- function C(e, t, n, r, _, C) {
223
- return f(), c("span", {
224
- ref: "contentRef",
225
- class: u(C.motionTextClasses),
226
- style: d(C.componentStyles),
227
- "data-text-content": C.isStaticAnimationMode ? n.text : void 0,
228
- "aria-live": _.isAnimating ? "polite" : "off",
279
+ function D(e, t, n, r, i, a) {
280
+ return h(), u("span", {
281
+ "data-qa": "dt-motion-text",
282
+ class: p(a.motionTextClasses),
283
+ style: m(a.componentStyles),
284
+ "aria-live": i.isAnimating ? "polite" : "off",
229
285
  "aria-label": n.screenReaderText || void 0
230
- }, [
231
- n.screenReaderText ? (f(), c("span", y, h(n.screenReaderText), 1)) : s("", !0),
232
- C.isStaticAnimationMode ? (f(), c(i, { key: 1 }, [l(h(n.text) + " ", 1), n.text ? s("", !0) : m(e.$slots, "default", { key: 0 })], 64)) : (f(), c("span", {
233
- key: _.animationKey,
234
- class: "d-motion-text__content",
235
- "aria-hidden": _.isAnimating
236
- }, [(f(!0), c(i, null, p(_.words, (e, t) => (f(), o(a, {
237
- key: `${_.animationKey}-${t}`,
238
- name: `d-motion-text-word-${n.animationMode}`
239
- }, {
240
- default: g(() => [t < _.visibleWordCount ? (f(), c("span", {
241
- key: 0,
242
- class: "d-motion-text__word",
243
- "data-text-content": e.text,
244
- style: d({ "--word-index": t })
245
- }, [(f(!0), c(i, null, p(e.chars, (e, r) => (f(), o(a, {
246
- key: `${_.animationKey}-${t}-${r}`,
247
- name: `d-motion-text-char-${n.animationMode}`
248
- }, {
249
- default: g(() => [r < _.visibleCharsPerWord[t] ? (f(), c("span", {
250
- key: 0,
251
- class: "d-motion-text__char",
252
- style: d({
253
- "--char-index": r,
254
- "--char-delay": `${r * C.timing.characterDelay}ms`
255
- })
256
- }, h(e), 5)) : s("", !0)]),
257
- _: 2
258
- }, 1032, ["name"]))), 128))], 12, x)) : s("", !0)]),
259
- _: 2
260
- }, 1032, ["name"]))), 128))], 8, b)),
261
- !_.words.length && !n.text && !C.isStaticAnimationMode ? (f(), c("span", S, [m(e.$slots, "default")])) : s("", !0)
262
- ], 14, v);
286
+ }, [n.screenReaderText ? (h(), u("span", C, v(n.screenReaderText), 1)) : l("", !0), a.isWholeText ? (h(), u("span", {
287
+ key: 1,
288
+ ref: "slotRef",
289
+ "data-qa": "dt-motion-text-content",
290
+ class: "d-motion-text__content",
291
+ "aria-hidden": n.screenReaderText ? "true" : void 0
292
+ }, [f(v(n.text), 1), n.text ? l("", !0) : _(e.$slots, "default", { key: 0 })], 8, w)) : i.words.length ? (h(), u("span", {
293
+ ref: "contentRef",
294
+ key: i.animationKey,
295
+ "data-qa": "dt-motion-text-content",
296
+ class: "d-motion-text__content",
297
+ "aria-hidden": n.screenReaderText ? "true" : void 0
298
+ }, [(h(!0), u(c, null, g(i.words, (e, t) => (h(), u(c, { key: `${i.animationKey}-${t}` }, [d("span", {
299
+ "data-qa": "dt-motion-text-word",
300
+ class: "d-motion-text__word",
301
+ style: m(a.wordStyles[t])
302
+ }, v(e.text), 5), f(v(e.space), 1)], 64))), 128))], 8, T)) : (h(), u("span", E, [_(e.$slots, "default")], 512))], 14, S);
263
303
  }
264
- var w = /* @__PURE__ */ e(_, [["render", C]]);
304
+ var O = /* @__PURE__ */ e(x, [["render", D]]);
265
305
  //#endregion
266
- export { w as default };
306
+ export { O as default };
267
307
 
268
308
  //# sourceMappingURL=motion-text.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"motion-text.js","names":[],"sources":["../../../components/MotionText/MotionText.vue"],"sourcesContent":["<template>\n <span\n ref=\"contentRef\"\n :class=\"motionTextClasses\"\n :style=\"componentStyles\"\n :data-text-content=\"isStaticAnimationMode ? text : undefined\"\n :aria-live=\"isAnimating ? 'polite' : 'off'\"\n :aria-label=\"screenReaderText || undefined\"\n >\n <!-- Screen reader content -->\n <span\n v-if=\"screenReaderText\"\n class=\"d-motion-text__sr-only\"\n >\n {{ screenReaderText }}\n </span>\n\n <!-- Gradient-sweep and shimmer modes: Simple static text with gradient animation -->\n <template v-if=\"isStaticAnimationMode\">\n {{ text }}\n <slot v-if=\"!text\" />\n </template>\n\n <!-- Character-by-character animated content for other modes -->\n <span\n v-else\n :key=\"animationKey\"\n class=\"d-motion-text__content\"\n :aria-hidden=\"isAnimating\"\n >\n <template\n v-for=\"(word, wordIdx) in words\"\n :key=\"`${animationKey}-${wordIdx}`\"\n >\n <Transition\n :name=\"`d-motion-text-word-${animationMode}`\"\n >\n <span\n v-if=\"wordIdx < visibleWordCount\"\n class=\"d-motion-text__word\"\n :data-text-content=\"word.text\"\n :style=\"{ '--word-index': wordIdx }\"\n >\n <template\n v-for=\"(char, charIdx) in word.chars\"\n :key=\"`${animationKey}-${wordIdx}-${charIdx}`\"\n >\n <Transition\n :name=\"`d-motion-text-char-${animationMode}`\"\n >\n <span\n v-if=\"charIdx < visibleCharsPerWord[wordIdx]\"\n class=\"d-motion-text__char\"\n :style=\"{\n '--char-index': charIdx,\n '--char-delay': `${charIdx * timing.characterDelay}ms`,\n }\"\n >{{ char }}</span>\n </Transition>\n </template>\n </span>\n </Transition>\n </template>\n </span>\n\n <!-- Fallback slot content -->\n <span\n v-if=\"!words.length && !text && !isStaticAnimationMode\"\n class=\"d-motion-text__fallback\"\n >\n <slot />\n </span>\n </span>\n</template>\n\n<script>\nimport { MOTION_TEXT_ANIMATION_MODES, MOTION_TEXT_SPEEDS, MOTION_TEXT_TIMING_PRESETS } from './MotionTextConstants';\n\nexport default {\n name: 'DtMotionText',\n\n props: {\n /**\n * The text content to animate.\n * @type {string}\n */\n text: {\n type: String,\n default: '',\n },\n\n /**\n * The animation mode to use for the text reveal.\n * @values gradient-in, fade-in, slide-in, gradient-sweep, shimmer, none\n */\n animationMode: {\n type: String,\n default: 'gradient-in',\n validator: (value) => MOTION_TEXT_ANIMATION_MODES.includes(value),\n },\n\n /**\n * Animation speed.\n * @values 100, 200, 300, 400, 500\n */\n speed: {\n type: [String, Number],\n default: 300,\n validator: (value) => MOTION_TEXT_SPEEDS.includes(String(value)),\n },\n\n /**\n * Whether to start animation automatically when component is mounted.\n * @values true, false\n */\n autoStart: {\n type: Boolean,\n default: true,\n },\n\n /**\n * Whether to loop the animation continuously.\n * @values true, false\n */\n loop: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Whether to respect the user's prefers-reduced-motion system setting.\n * @values true, false\n */\n respectsReducedMotion: {\n type: Boolean,\n default: true,\n },\n\n /**\n * Alternative text for screen readers. If provided, this will be announced\n * instead of the animated text.\n * @type {string}\n */\n screenReaderText: {\n type: String,\n default: '',\n },\n },\n\n emits: [\n /**\n * Emitted when the animation starts.\n * @event start\n */\n 'start',\n\n /**\n * Emitted when the animation completes.\n * @event complete\n */\n 'complete',\n\n /**\n * Emitted during animation progress.\n * @event progress\n * @type {{ wordsComplete: number, totalWords: number, progress: number }}\n */\n 'progress',\n\n /**\n * Emitted when the animation is paused.\n * @event pause\n */\n 'pause',\n\n /**\n * Emitted when the animation resumes.\n * @event resume\n */\n 'resume',\n ],\n\n data () {\n return {\n words: [],\n visibleWordCount: 0,\n visibleCharsPerWord: [],\n isAnimating: false,\n isPaused: false,\n isLooped: false,\n animationTimeouts: [],\n prefersReducedMotion: false,\n animationKey: 0,\n };\n },\n\n computed: {\n /**\n * Get timing preset based on speed prop\n */\n timing () {\n return MOTION_TEXT_TIMING_PRESETS[String(this.speed)];\n },\n\n /**\n * Computed styles with timing CSS variables\n */\n componentStyles () {\n return {\n '--d-motion-text-duration': `${this.timing.duration}ms`,\n '--d-motion-text-char-duration': `${this.timing.duration}ms`,\n '--d-motion-text-word-duration': `${this.timing.duration * 2}ms`,\n };\n },\n\n /**\n * Check if current animation mode is static (gradient-sweep or shimmer)\n */\n isStaticAnimationMode () {\n return this.animationMode === 'gradient-sweep' || this.animationMode === 'shimmer';\n },\n\n /**\n * Computed classes for the motion text element\n */\n motionTextClasses () {\n return [\n 'd-motion-text',\n `d-motion-text--${this.animationMode}`,\n {\n 'd-motion-text--animating': this.isAnimating,\n 'd-motion-text--paused': this.isPaused,\n 'd-motion-text--looped': this.isLooped,\n },\n ];\n },\n },\n\n watch: {\n text () {\n this.reset();\n this.initializeContent();\n },\n\n loop: {\n handler (newVal) {\n this.isLooped = newVal;\n },\n\n immediate: true,\n },\n },\n\n mounted () {\n this.checkReducedMotion();\n this.initializeContent();\n },\n\n beforeUnmount () {\n this.clearTimeouts();\n },\n\n methods: {\n /**\n * Self-contained text processing from DOM nodes\n */\n processTextToChars (node) {\n const words = [];\n\n const processNode = (node, index = 0) => {\n if (node.nodeType === Node.TEXT_NODE) {\n const matches = node.textContent?.match(/\\S+\\s*/g) || [];\n words.push(...matches.map((text, i) => ({\n text,\n chars: text.split(''),\n index: index + i,\n })));\n return index + matches.length;\n } else if (node.nodeType === Node.ELEMENT_NODE) {\n let currentIdx = index;\n Array.from(node.childNodes).forEach(child => {\n currentIdx = processNode(child, currentIdx);\n });\n return currentIdx;\n }\n return index;\n };\n\n processNode(node);\n return words;\n },\n\n /**\n * Process direct text prop into word/character data\n */\n processDirectText (text) {\n if (!text) return [];\n\n const matches = text.match(/\\S+\\s*/g) || [];\n return matches.map((wordText, i) => ({\n text: wordText,\n chars: wordText.split(''),\n index: i,\n }));\n },\n\n /**\n * Check for reduced motion preference\n */\n checkReducedMotion () {\n if (typeof window !== 'undefined' && window.matchMedia) {\n this.prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n }\n },\n\n /**\n * Clear all animation timeouts\n */\n clearTimeouts () {\n this.animationTimeouts.forEach(timeout => clearTimeout(timeout));\n this.animationTimeouts = [];\n },\n\n /**\n * Start the animation\n * @public\n */\n start () {\n if (this.isAnimating) return;\n\n this.isAnimating = true;\n this.isPaused = false;\n this.$emit('start');\n\n // Skip animation if reduced motion is preferred and enabled\n if (this.respectsReducedMotion && this.prefersReducedMotion) {\n this.showAllContent();\n return;\n }\n\n if (this.animationMode === 'none') {\n this.showAllContent();\n return;\n }\n\n // For gradient-sweep and shimmer modes, just mark as animating (CSS handles the animation)\n if (this.isStaticAnimationMode) {\n return;\n }\n\n // Start the word-by-word animation for \"-in\" modes\n this.showNextWord();\n },\n\n /**\n * Pause the animation\n * @public\n */\n pause () {\n if (!this.isAnimating || this.isPaused) return;\n\n this.isPaused = true;\n this.clearTimeouts();\n this.$emit('pause');\n },\n\n /**\n * Resume the animation\n * @public\n */\n resume () {\n if (!this.isPaused) return;\n\n this.isPaused = false;\n this.$emit('resume');\n this.showNextWord();\n },\n\n /**\n * Reset the animation to initial state\n * @public\n */\n reset () {\n this.clearTimeouts();\n this.isAnimating = false;\n this.isPaused = false;\n this.visibleWordCount = 0;\n this.visibleCharsPerWord = Array(this.words.length).fill(0);\n this.animationKey++;\n },\n\n /**\n * Skip to the end of the animation\n * @public\n */\n skipToEnd () {\n this.showAllContent();\n },\n\n /**\n * Show all content immediately\n */\n showAllContent () {\n this.visibleWordCount = this.words.length;\n this.visibleCharsPerWord = this.words.map(word => word.chars.length);\n setTimeout(() => {\n this.isAnimating = false;\n this.$emit('complete');\n }, 0);\n },\n\n /**\n * Show next word in sequence\n */\n showNextWord () {\n if (this.isPaused || this.visibleWordCount >= this.words.length) {\n if (this.visibleWordCount >= this.words.length) {\n this.completeAnimation();\n }\n return;\n }\n\n const timeout = setTimeout(() => {\n this.visibleWordCount++;\n this.$emit('progress', {\n wordsComplete: this.visibleWordCount,\n totalWords: this.words.length,\n progress: this.visibleWordCount / this.words.length,\n });\n\n this.animateCharsForWord(this.visibleWordCount - 1);\n }, this.timing.wordDelay);\n\n this.animationTimeouts.push(timeout);\n },\n\n /**\n * Animate characters for a specific word\n */\n animateCharsForWord (wordIdx) {\n if (this.isPaused || wordIdx >= this.words.length) return;\n\n this.visibleCharsPerWord[wordIdx] = 0;\n const chars = this.words[wordIdx].chars.length;\n\n const revealChar = () => {\n if (this.isPaused || this.visibleCharsPerWord[wordIdx] >= chars) {\n if (this.visibleCharsPerWord[wordIdx] >= chars) {\n this.showNextWord();\n }\n return;\n }\n\n this.visibleCharsPerWord[wordIdx]++;\n const timeout = setTimeout(revealChar, this.timing.characterDelay);\n this.animationTimeouts.push(timeout);\n };\n\n revealChar();\n },\n\n /**\n * Complete the animation\n */\n completeAnimation () {\n this.isAnimating = false;\n this.clearTimeouts();\n\n this.$emit('complete');\n\n if (this.loop) {\n const timeout = setTimeout(() => {\n this.reset();\n this.$nextTick(() => {\n this.start();\n });\n }, 500);\n\n this.animationTimeouts.push(timeout);\n }\n },\n\n /**\n * Initialize content based on text prop or slot content\n */\n initializeContent () {\n // For gradient-sweep and shimmer modes, skip word/character processing\n if (this.isStaticAnimationMode) {\n if (this.autoStart) {\n this.$nextTick(() => this.start());\n }\n return;\n }\n\n if (this.text) {\n this.words = this.processDirectText(this.text);\n } else if (this.$refs.contentRef) {\n this.words = this.processTextToChars(this.$refs.contentRef);\n }\n\n this.visibleCharsPerWord = Array(this.words.length).fill(0);\n this.visibleWordCount = 0;\n\n if (this.autoStart && this.words.length > 0) {\n this.$nextTick(() => this.start());\n }\n },\n },\n};\n</script>\n"],"mappings":"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"}
1
+ {"version":3,"file":"motion-text.js","names":[],"sources":["../../../components/MotionText/MotionText.vue"],"sourcesContent":["<template>\n <span\n data-qa=\"dt-motion-text\"\n :class=\"motionTextClasses\"\n :style=\"componentStyles\"\n :aria-live=\"isAnimating ? 'polite' : 'off'\"\n :aria-label=\"screenReaderText || undefined\"\n >\n <!-- Screen reader content -->\n <span\n v-if=\"screenReaderText\"\n data-qa=\"dt-motion-text-sr-only\"\n class=\"d-motion-text__sr-only\"\n >\n {{ screenReaderText }}\n </span>\n\n <!-- Whole-text modes animate the root, so the text and slot render as-is and stay live -->\n <span\n v-if=\"isWholeText\"\n ref=\"slotRef\"\n data-qa=\"dt-motion-text-content\"\n class=\"d-motion-text__content\"\n :aria-hidden=\"screenReaderText ? 'true' : undefined\"\n >{{ text }}<slot v-if=\"!text\" /></span>\n\n <!-- Word-by-word animated content -->\n <span\n v-else-if=\"words.length\"\n ref=\"contentRef\"\n :key=\"animationKey\"\n data-qa=\"dt-motion-text-content\"\n class=\"d-motion-text__content\"\n :aria-hidden=\"screenReaderText ? 'true' : undefined\"\n >\n <template\n v-for=\"(word, wordIdx) in words\"\n :key=\"`${animationKey}-${wordIdx}`\"\n >\n <span\n data-qa=\"dt-motion-text-word\"\n class=\"d-motion-text__word\"\n :style=\"wordStyles[wordIdx]\"\n >{{ word.text }}</span>{{ word.space }}\n </template>\n </span>\n\n <!-- Slot content, rendered until its text has been split into words -->\n <span\n v-else\n ref=\"slotRef\"\n class=\"d-motion-text__fallback\"\n >\n <slot />\n </span>\n </span>\n</template>\n\n\n<script>\nimport {\n MOTION_TEXT_ANIMATION_MODES,\n MOTION_TEXT_MODE_SETTINGS,\n MOTION_TEXT_SPEEDS,\n MOTION_TEXT_TIMING_PRESETS,\n MOTION_TEXT_TRACKS,\n} from './MotionTextConstants';\nimport { getGradientSlices, splitWords } from './utils';\n\nconst DEFAULT_PRESET = MOTION_TEXT_TIMING_PRESETS['300'];\n// Unsupported modes render the text at rest, like 'none'\nconst RESTING_SETTINGS = { tracks: [], gradient: false, loopHold: 0 };\n\nexport default {\n name: 'DtMotionText',\n\n props: {\n /**\n * The text content to animate.\n * @type {string}\n */\n text: {\n type: String,\n default: '',\n },\n\n /**\n * The animation mode to use for the text reveal. `none` renders the text without animation.\n * @values gradient-in, fade-in, slide-in, slide-in-gradient, gradient-sweep, shimmer, none\n */\n animationMode: {\n type: String,\n default: 'gradient-in',\n validator: (value) => MOTION_TEXT_ANIMATION_MODES.includes(value),\n },\n\n /**\n * Animation speed. 300 plays the motion spec as designed; lower values are faster.\n * @values 100, 200, 300, 400, 500\n */\n speed: {\n type: [String, Number],\n default: 300,\n validator: (value) => MOTION_TEXT_SPEEDS.includes(String(value)),\n },\n\n /**\n * Whether to start animation automatically when component is mounted.\n * @values true, false\n */\n autoStart: {\n type: Boolean,\n default: true,\n },\n\n /**\n * Whether to loop the animation continuously.\n * @values true, false\n */\n loop: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Whether to respect the user's prefers-reduced-motion system setting.\n * @values true, false\n */\n respectsReducedMotion: {\n type: Boolean,\n default: true,\n },\n\n /**\n * Alternative text for screen readers. If provided, this will be announced\n * instead of the animated text.\n * @type {string}\n */\n screenReaderText: {\n type: String,\n default: '',\n },\n },\n\n emits: [\n /**\n * Emitted when the animation starts, and at the start of each looped cycle.\n * @event start\n */\n 'start',\n\n /**\n * Emitted when the animation completes, and at the end of each looped cycle.\n * @event complete\n */\n 'complete',\n\n /**\n * Emitted as each word finishes animating.\n * @event progress\n * @type {{ wordsComplete: number, totalWords: number, progress: number }}\n */\n 'progress',\n\n /**\n * Emitted when the animation is paused.\n * @event pause\n */\n 'pause',\n\n /**\n * Emitted when the animation resumes.\n * @event resume\n */\n 'resume',\n ],\n\n data () {\n return {\n words: splitWords(this.text),\n wordWidths: [],\n isRtl: false,\n isAnimating: false,\n isPaused: false,\n isComplete: false,\n isRestarting: false,\n isLooped: false,\n isUnmounted: false,\n animationTimeouts: [],\n timelineStartedAt: 0,\n timelineElapsed: 0,\n prefersReducedMotion: false,\n animationKey: 0,\n cssIterations: 1,\n };\n },\n\n computed: {\n modeSettings () {\n return MOTION_TEXT_MODE_SETTINGS[this.animationMode] ?? RESTING_SETTINGS;\n },\n\n isWholeText () {\n return Boolean(this.modeSettings.wholeText);\n },\n\n /**\n * Multiplier applied to every motion timing for the current speed.\n */\n speedScale () {\n const preset = MOTION_TEXT_TIMING_PRESETS[String(this.speed)] ?? DEFAULT_PRESET;\n return preset.duration / DEFAULT_PRESET.duration;\n },\n\n /**\n * Track timings for the current mode as CSS variables, e.g. --d-motion-text-enter-stagger\n */\n componentStyles () {\n const styles = {};\n this.modeSettings.tracks.forEach(track => {\n Object.entries(MOTION_TEXT_TRACKS[track]).forEach(([key, value]) => {\n styles[`--d-motion-text-${track}-${key}`] = `${Math.round(value * this.speedScale)}ms`;\n });\n });\n return styles;\n },\n\n /**\n * Per-word index (drives the stagger) and, in gradient modes, the slice of the shared gradient\n * each word shows so it reads as one continuous gradient across the text.\n */\n wordStyles () {\n const slices = this.modeSettings.gradient ? getGradientSlices(this.wordWidths, this.isRtl) : [];\n\n return this.words.map((word, index) => {\n const slice = slices[index];\n return {\n '--d-motion-text-word-index': index,\n ...(slice && {\n '--d-motion-text-gradient-size': slice.size,\n '--d-motion-text-gradient-position': slice.position,\n }),\n };\n });\n },\n\n /**\n * Time (ms) at which each word finishes its last track\n */\n wordEndTimes () {\n return this.words.map((word, index) => {\n const ends = this.modeSettings.tracks.map(track => {\n const { delay, stagger, duration } = MOTION_TEXT_TRACKS[track];\n return delay + stagger * index + duration;\n });\n return Math.max(0, ...ends) * this.speedScale;\n });\n },\n\n /**\n * Time (ms) at which one cycle of the animation ends\n */\n cycleDuration () {\n if (!this.isWholeText) return Math.max(0, ...this.wordEndTimes);\n\n const ends = this.modeSettings.tracks.map(track => {\n const { delay, duration } = MOTION_TEXT_TRACKS[track];\n return delay + duration;\n });\n return Math.max(0, ...ends) * this.speedScale * this.cssIterations;\n },\n\n motionTextClasses () {\n return [\n 'd-motion-text',\n `d-motion-text--${this.animationMode}`,\n {\n 'd-motion-text--animating': this.isAnimating,\n 'd-motion-text--paused': this.isPaused,\n 'd-motion-text--complete': this.isComplete,\n 'd-motion-text--restarting': this.isRestarting,\n 'd-motion-text--looped': this.isLooped,\n 'd-motion-text--respects-reduced-motion': this.respectsReducedMotion,\n },\n ];\n },\n },\n\n watch: {\n text () {\n // Whole-text modes render the text live and keep animating, as they always have\n if (this.isWholeText) {\n this.words = splitWords(this.text);\n\n // A finished single play runs again for the new text; a loop stopped with skipToEnd() stays at rest\n if (this.isComplete && this.autoStart && !this.loop) {\n this.reset();\n this.$nextTick(() => this.start());\n }\n return;\n }\n\n this.reset();\n\n if (this.text) {\n this.initializeContent();\n return;\n }\n\n // Slot content only renders once the words are cleared, so read it on the next tick\n this.words = [];\n this.$nextTick(() => this.initializeContent());\n },\n\n animationMode (mode, oldMode) {\n const wasWholeText = Boolean(MOTION_TEXT_MODE_SETTINGS[oldMode]?.wholeText);\n\n // Whole-text modes render the slot live, so read it again when switching to or from word mode\n if (!this.text && wasWholeText !== this.isWholeText) {\n const wasAnimating = this.isAnimating;\n this.reset();\n this.words = [];\n this.$nextTick(() => {\n this.words = splitWords(this.getSlotText());\n this.wordWidths = [];\n if (wasAnimating) this.$nextTick(() => this.start());\n });\n return;\n }\n\n this.restartIfAnimating();\n },\n\n autoStart (value) {\n if (value && !this.isAnimating && (this.isWholeText || this.words.length)) {\n this.$nextTick(() => this.start());\n }\n },\n\n speed () {\n this.restartIfAnimating();\n },\n\n loop: {\n handler (newVal) {\n this.isLooped = newVal;\n\n // Reschedule so the current cycle ends (or restarts) according to the new value\n if (this.isAnimating && !this.isPaused) {\n this.timelineElapsed = Date.now() - this.timelineStartedAt;\n this.clearTimeouts();\n this.runTimeline();\n }\n },\n\n immediate: true,\n },\n },\n\n mounted () {\n this.initWatchReducedMotion();\n this.initializeContent();\n\n // Word widths change once web fonts load, which would misalign the gradient slices\n document.fonts?.ready.then(() => {\n if (!this.isUnmounted && this.isAnimating) this.measureWords();\n });\n },\n\n beforeUnmount () {\n this.isUnmounted = true;\n this.clearTimeouts();\n this.stopWatchingReducedMotion?.();\n },\n\n methods: {\n /**\n * Collect the text of slot content, ignoring markup\n */\n getSlotText () {\n return this.$refs.slotRef?.textContent || '';\n },\n\n /**\n * Track the reduced motion preference, finishing any running animation if it turns on\n */\n initWatchReducedMotion () {\n if (typeof window === 'undefined' || !window.matchMedia) return;\n\n const query = window.matchMedia('(prefers-reduced-motion: reduce)');\n const onChange = (event) => {\n this.prefersReducedMotion = event.matches;\n if (event.matches && this.respectsReducedMotion && this.isAnimating) this.skipToEnd();\n };\n\n this.prefersReducedMotion = query.matches;\n query.addEventListener?.('change', onChange);\n this.stopWatchingReducedMotion = () => query.removeEventListener?.('change', onChange);\n },\n\n /**\n * Measure rendered word widths so each word can show its slice of the gradient.\n * Falls back to character counts when layout is unavailable (e.g. not yet rendered).\n */\n measureWords () {\n if (!this.modeSettings.gradient) return;\n\n const wordEls = this.$refs.contentRef?.querySelectorAll('.d-motion-text__word') || [];\n const widths = Array.from(wordEls, el => el.getBoundingClientRect().width);\n\n this.isRtl = window.getComputedStyle(this.$el).direction === 'rtl';\n this.wordWidths = widths.length === this.words.length && widths.every(width => width > 0)\n ? widths\n : this.words.map(word => word.text.length);\n },\n\n /**\n * Clear all animation timeouts\n */\n clearTimeouts () {\n this.animationTimeouts.forEach(timeout => clearTimeout(timeout));\n this.animationTimeouts = [];\n },\n\n schedule (delay, callback) {\n this.animationTimeouts.push(setTimeout(callback, Math.max(0, delay)));\n },\n\n /**\n * Schedule progress, completion and (when looping) restart events for the remainder\n * of the current cycle. CSS runs the animation itself; this keeps events in step with it.\n */\n runTimeline () {\n const elapsed = this.timelineElapsed;\n const totalWords = this.words.length;\n const cycleEnd = this.cycleDuration;\n\n this.timelineStartedAt = Date.now() - elapsed;\n\n // Whole-text modes have no per-word progress\n const wordEnds = this.isWholeText ? [] : this.wordEndTimes;\n wordEnds.forEach((end, index) => {\n if (end <= elapsed) return;\n this.schedule(end - elapsed, () => {\n this.$emit('progress', {\n wordsComplete: index + 1,\n totalWords,\n progress: (index + 1) / totalWords,\n });\n });\n });\n\n if (cycleEnd > elapsed) {\n this.schedule(cycleEnd - elapsed, () => this.completeAnimation());\n }\n\n if (this.loop) {\n const restartAt = cycleEnd + this.modeSettings.loopHold * this.speedScale;\n this.schedule(restartAt - elapsed, () => this.restartCycle());\n } else if (cycleEnd <= elapsed) {\n // The cycle already ended while looping (e.g. loop turned off during the hold)\n this.finishAnimation();\n }\n },\n\n /**\n * Start the animation\n * @public\n */\n start () {\n if (this.isAnimating || this.isUnmounted) return;\n\n this.clearTimeouts();\n this.isAnimating = true;\n this.isPaused = false;\n this.isComplete = false;\n this.$emit('start');\n\n // Skip animation if reduced motion is preferred and enabled\n if (this.respectsReducedMotion && this.prefersReducedMotion) {\n this.showAllContent();\n return;\n }\n\n if (!this.modeSettings.tracks.length || (!this.isWholeText && !this.words.length)) {\n this.showAllContent();\n return;\n }\n\n this.measureWords();\n this.cssIterations = this.readCssIterations();\n this.timelineElapsed = 0;\n this.runTimeline();\n },\n\n /**\n * Whole-text animations honor a consumer's animation-iteration-count override (e.g. 2 sweeps)\n */\n readCssIterations () {\n if (!this.isWholeText || this.loop) return 1;\n\n const count = parseFloat(window.getComputedStyle(this.$el).animationIterationCount);\n return Number.isFinite(count) && count > 1 ? count : 1;\n },\n\n /**\n * Pause the animation\n * @public\n */\n pause () {\n if (!this.isAnimating || this.isPaused) return;\n\n this.timelineElapsed = Date.now() - this.timelineStartedAt;\n this.clearTimeouts();\n this.isPaused = true;\n this.$emit('pause');\n },\n\n /**\n * Resume the animation\n * @public\n */\n resume () {\n if (!this.isPaused) return;\n\n this.isPaused = false;\n this.$emit('resume');\n this.runTimeline();\n },\n\n /**\n * Reset the animation to initial state\n * @public\n */\n reset () {\n this.clearTimeouts();\n this.isAnimating = false;\n this.isPaused = false;\n this.isComplete = false;\n this.timelineElapsed = 0;\n this.animationKey++;\n // Whole-text modes animate the root, which re-keying the words doesn't reset\n this.replayAnimations();\n },\n\n /**\n * Skip to the end of the animation\n * @public\n */\n skipToEnd () {\n this.showAllContent();\n },\n\n /**\n * Show all content immediately in its resting state\n */\n showAllContent () {\n this.finishAnimation();\n this.isPaused = false;\n this.schedule(0, () => this.$emit('complete'));\n },\n\n finishAnimation () {\n this.clearTimeouts();\n this.isAnimating = false;\n this.isComplete = true;\n },\n\n restartIfAnimating () {\n if (!this.isAnimating) return;\n\n this.reset();\n this.$nextTick(() => this.start());\n },\n\n /**\n * End of a cycle. Looped animations keep animating through the hold before restarting.\n */\n completeAnimation () {\n this.$emit('complete');\n if (!this.loop) this.finishAnimation();\n },\n\n /**\n * Drop the CSS animations for one style pass so they replay from their first frame on the same\n * elements, keeping text selection and not re-inserting anything into the aria-live region.\n */\n replayAnimations (callback) {\n this.isRestarting = true;\n\n this.$nextTick(() => {\n // Flush styles while the animations are removed\n this.$el?.getBoundingClientRect?.();\n this.isRestarting = false;\n callback?.();\n });\n },\n\n /**\n * Restart a looped animation: everything returns to its starting state at once\n */\n restartCycle () {\n if (this.isUnmounted) return;\n\n this.clearTimeouts();\n this.replayAnimations(() => {\n this.measureWords();\n this.timelineElapsed = 0;\n this.$emit('start');\n this.runTimeline();\n });\n },\n\n /**\n * Initialize content based on text prop or slot content\n */\n initializeContent () {\n this.words = splitWords(this.text || this.getSlotText());\n this.wordWidths = [];\n\n // Whole-text modes start even while empty, e.g. a slot that streams its content in\n if (this.autoStart && (this.isWholeText || this.words.length > 0)) {\n this.$nextTick(() => this.start());\n }\n },\n },\n};\n</script>\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});function e(e){return(e?.match(/\S+\s*/g)||[]).map(e=>{let t=e.trimEnd();return{text:t,space:e.slice(t.length)}})}function t(e,t=!1){let n=e.reduce((e,t)=>e+t,0),r=0;return e.map(e=>{let i=t?n-r-e:r;return r+=e,e>0?{size:`${n/e*100}% 100%`,position:n>e?`${i/(n-e)*100}% 0%`:`0% 0%`}:null})}exports.getGradientSlices=t,exports.splitWords=e;
2
+ //# sourceMappingURL=utils.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.cjs","names":[],"sources":["../../../components/MotionText/utils.js"],"sourcesContent":["/**\n * Split text into words, keeping the whitespace that follows each one (spaces, line breaks) so\n * the consumer's `white-space` setting still applies between words.\n * @param {string} text\n * @returns {Array<{ text: string, space: string }>}\n */\nexport function splitWords (text) {\n return (text?.match(/\\S+\\s*/g) || []).map(segment => {\n const word = segment.trimEnd();\n return { text: word, space: segment.slice(word.length) };\n });\n}\n\n/**\n * The slice of one continuous gradient each word shows, as background-size / background-position.\n * Spaces between words are excluded (matching the Figma spec). The gradient runs left to right\n * like other Ai gradient treatments, so in RTL, where the first word sits on the right, slices\n * are mirrored to keep it continuous across the line.\n * @param {number[]} widths rendered word widths, in reading order\n * @param {boolean} isRtl\n * @returns {Array<{ size: string, position: string } | null>} null for words without a width\n */\nexport function getGradientSlices (widths, isRtl = false) {\n const totalWidth = widths.reduce((sum, width) => sum + width, 0);\n let offset = 0;\n\n return widths.map(width => {\n const start = isRtl ? totalWidth - offset - width : offset;\n offset += width;\n\n if (!(width > 0)) return null;\n\n return {\n size: `${(totalWidth / width) * 100}% 100%`,\n position: totalWidth > width ? `${(start / (totalWidth - width)) * 100}% 0%` : '0% 0%',\n };\n });\n}\n"],"mappings":"mEAMA,SAAgB,EAAY,EAAM,CAChC,OAAQ,GAAM,MAAM,UAAU,EAAI,EAAE,EAAE,IAAI,GAAW,CACnD,IAAM,EAAO,EAAQ,SAAS,CAC9B,MAAO,CAAE,KAAM,EAAM,MAAO,EAAQ,MAAM,EAAK,OAAO,CAAE,EACxD,CAYJ,SAAgB,EAAmB,EAAQ,EAAQ,GAAO,CACxD,IAAM,EAAa,EAAO,QAAQ,EAAK,IAAU,EAAM,EAAO,EAAE,CAC5D,EAAS,EAEb,OAAO,EAAO,IAAI,GAAS,CACzB,IAAM,EAAQ,EAAQ,EAAa,EAAS,EAAQ,EAKpD,MAJA,IAAU,EAEJ,EAAQ,EAEP,CACL,KAAM,GAAI,EAAa,EAAS,IAAI,QACpC,SAAU,EAAa,EAAQ,GAAI,GAAS,EAAa,GAAU,IAAI,MAAQ,QAChF,CALwB,MAMzB"}
@@ -0,0 +1,24 @@
1
+ //#region components/MotionText/utils.js
2
+ function e(e) {
3
+ return (e?.match(/\S+\s*/g) || []).map((e) => {
4
+ let t = e.trimEnd();
5
+ return {
6
+ text: t,
7
+ space: e.slice(t.length)
8
+ };
9
+ });
10
+ }
11
+ function t(e, t = !1) {
12
+ let n = e.reduce((e, t) => e + t, 0), r = 0;
13
+ return e.map((e) => {
14
+ let i = t ? n - r - e : r;
15
+ return r += e, e > 0 ? {
16
+ size: `${n / e * 100}% 100%`,
17
+ position: n > e ? `${i / (n - e) * 100}% 0%` : "0% 0%"
18
+ } : null;
19
+ });
20
+ }
21
+ //#endregion
22
+ export { t as getGradientSlices, e as splitWords };
23
+
24
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","names":[],"sources":["../../../components/MotionText/utils.js"],"sourcesContent":["/**\n * Split text into words, keeping the whitespace that follows each one (spaces, line breaks) so\n * the consumer's `white-space` setting still applies between words.\n * @param {string} text\n * @returns {Array<{ text: string, space: string }>}\n */\nexport function splitWords (text) {\n return (text?.match(/\\S+\\s*/g) || []).map(segment => {\n const word = segment.trimEnd();\n return { text: word, space: segment.slice(word.length) };\n });\n}\n\n/**\n * The slice of one continuous gradient each word shows, as background-size / background-position.\n * Spaces between words are excluded (matching the Figma spec). The gradient runs left to right\n * like other Ai gradient treatments, so in RTL, where the first word sits on the right, slices\n * are mirrored to keep it continuous across the line.\n * @param {number[]} widths rendered word widths, in reading order\n * @param {boolean} isRtl\n * @returns {Array<{ size: string, position: string } | null>} null for words without a width\n */\nexport function getGradientSlices (widths, isRtl = false) {\n const totalWidth = widths.reduce((sum, width) => sum + width, 0);\n let offset = 0;\n\n return widths.map(width => {\n const start = isRtl ? totalWidth - offset - width : offset;\n offset += width;\n\n if (!(width > 0)) return null;\n\n return {\n size: `${(totalWidth / width) * 100}% 100%`,\n position: totalWidth > width ? `${(start / (totalWidth - width)) * 100}% 0%` : '0% 0%',\n };\n });\n}\n"],"mappings":";AAMA,SAAgB,EAAY,GAAM;AAChC,SAAQ,GAAM,MAAM,UAAU,IAAI,EAAE,EAAE,KAAI,MAAW;EACnD,IAAM,IAAO,EAAQ,SAAS;AAC9B,SAAO;GAAE,MAAM;GAAM,OAAO,EAAQ,MAAM,EAAK,OAAO;GAAE;GACxD;;AAYJ,SAAgB,EAAmB,GAAQ,IAAQ,IAAO;CACxD,IAAM,IAAa,EAAO,QAAQ,GAAK,MAAU,IAAM,GAAO,EAAE,EAC5D,IAAS;AAEb,QAAO,EAAO,KAAI,MAAS;EACzB,IAAM,IAAQ,IAAQ,IAAa,IAAS,IAAQ;AAKpD,SAJA,KAAU,GAEJ,IAAQ,IAEP;GACL,MAAM,GAAI,IAAa,IAAS,IAAI;GACpC,UAAU,IAAa,IAAQ,GAAI,KAAS,IAAa,KAAU,IAAI,QAAQ;GAChF,GALwB;GAMzB"}
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../../ForceLinkify-CI1tkUBf.cjs`);exports.forceLinkifyPendingText=e.t,exports.isValidLinkStructure=e.n,exports.rangeFullyLinked=e.r;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../../ForceLinkify-kQ_kWKVm.cjs`);exports.forceLinkifyPendingText=e.t,exports.isValidLinkStructure=e.n,exports.rangeFullyLinked=e.r;
@@ -1,2 +1,2 @@
1
- import { n as e, r as t, t as n } from "../../ForceLinkify-bO3ug94b.js";
1
+ import { n as e, r as t, t as n } from "../../ForceLinkify-DuAo3TMB.js";
2
2
  export { n as forceLinkifyPendingText, e as isValidLinkStructure, t as rangeFullyLinked };
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../../RichTextEditor-EHgahp8r.cjs`),t=require(`./rich-text-editor-constants.cjs`);exports.DtRichTextEditor=e.t,exports.RICH_TEXT_EDITOR_AUTOFOCUS_TYPES=t.RICH_TEXT_EDITOR_AUTOFOCUS_TYPES,exports.RICH_TEXT_EDITOR_OUTPUT_FORMATS=t.RICH_TEXT_EDITOR_OUTPUT_FORMATS;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../../RichTextEditor-7eY8gy9u.cjs`),t=require(`./rich-text-editor-constants.cjs`);exports.DtRichTextEditor=e.t,exports.RICH_TEXT_EDITOR_AUTOFOCUS_TYPES=t.RICH_TEXT_EDITOR_AUTOFOCUS_TYPES,exports.RICH_TEXT_EDITOR_OUTPUT_FORMATS=t.RICH_TEXT_EDITOR_OUTPUT_FORMATS;
@@ -1,3 +1,3 @@
1
- import { t as e } from "../../RichTextEditor-Cz2VXb7-.js";
1
+ import { t as e } from "../../RichTextEditor-DaOHmXD_.js";
2
2
  import { RICH_TEXT_EDITOR_AUTOFOCUS_TYPES as t, RICH_TEXT_EDITOR_OUTPUT_FORMATS as n } from "./rich-text-editor-constants.js";
3
3
  export { e as DtRichTextEditor, t as RICH_TEXT_EDITOR_AUTOFOCUS_TYPES, n as RICH_TEXT_EDITOR_OUTPUT_FORMATS };
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../../MarkdownRenderer-B6oyniLV.cjs`);exports.renderEditorToMarkdown=e.t;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../../MarkdownRenderer-C5wdjC5_.cjs`);exports.renderEditorToMarkdown=e.t;
@@ -1,2 +1,2 @@
1
- import { t as e } from "../../MarkdownRenderer-D-EV50_M.js";
1
+ import { t as e } from "../../MarkdownRenderer-eMwmPygx.js";
2
2
  export { e as renderEditorToMarkdown };
@@ -1 +1 @@
1
- Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require(`../../RichTextEditor-EHgahp8r.cjs`);exports.default=e.t;
1
+ Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require(`../../RichTextEditor-7eY8gy9u.cjs`);exports.default=e.t;
@@ -1,2 +1,2 @@
1
- import { t as e } from "../../RichTextEditor-Cz2VXb7-.js";
1
+ import { t as e } from "../../RichTextEditor-DaOHmXD_.js";
2
2
  export { e as default };
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../../Scroller-Du2kJsTR.cjs`);exports.DtScroller=e.t;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../../Scroller-pAU8UWIH.cjs`);exports.DtScroller=e.t;
@@ -1,2 +1,2 @@
1
- import { t as e } from "../../Scroller-JDoDYC5V.js";
1
+ import { t as e } from "../../Scroller-B1xwv6TG.js";
2
2
  export { e as DtScroller };
@@ -1 +1 @@
1
- Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require(`../../Scroller-Du2kJsTR.cjs`);exports.default=e.t;
1
+ Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require(`../../Scroller-pAU8UWIH.cjs`);exports.default=e.t;