@dialpad/dialtone-vue 4.4.1 → 4.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (196) 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/component-documentation.json +1 -1
  42. package/dist/components/ButtonGroup/ButtonGroup.vue.d.ts.map +1 -1
  43. package/dist/components/Codeblock/Codeblock.vue.d.ts.map +1 -1
  44. package/dist/components/Datepicker/Datepicker.vue.d.ts.map +1 -1
  45. package/dist/components/Datepicker/Modules/Calendar.vue.d.ts.map +1 -1
  46. package/dist/components/Datepicker/Modules/MonthYearPicker.vue.d.ts.map +1 -1
  47. package/dist/components/DescriptionList/DescriptionList.vue.d.ts.map +1 -1
  48. package/dist/components/Emoji/Emoji.vue.d.ts.map +1 -1
  49. package/dist/components/EmojiPicker/EmojiPicker.vue.d.ts.map +1 -1
  50. package/dist/components/EmojiPicker/Modules/EmojiDescription.vue.d.ts.map +1 -1
  51. package/dist/components/EmojiPicker/Modules/EmojiSearch.vue.d.ts.map +1 -1
  52. package/dist/components/EmojiPicker/Modules/EmojiSelector.vue.d.ts.map +1 -1
  53. package/dist/components/EmojiPicker/Modules/EmojiSkinSelector.vue.d.ts.map +1 -1
  54. package/dist/components/EmojiPicker/Modules/EmojiTabset.vue.d.ts.map +1 -1
  55. package/dist/components/EmptyState/EmptyState.vue.d.ts.map +1 -1
  56. package/dist/components/KeyboardShortcut/KeyboardShortcut.vue.d.ts.map +1 -1
  57. package/dist/components/LazyShow/LazyShow.vue.d.ts.map +1 -1
  58. package/dist/components/ModeIsland/ModeIsland.vue.d.ts.map +1 -1
  59. package/dist/components/MotionText/MotionText.vue.d.ts.map +1 -1
  60. package/dist/components/MotionText/MotionTextConstants.d.ts +72 -0
  61. package/dist/components/MotionText/MotionTextConstants.d.ts.map +1 -1
  62. package/dist/components/MotionText/index.d.ts +1 -1
  63. package/dist/components/MotionText/utils.d.ts +9 -0
  64. package/dist/components/MotionText/utils.d.ts.map +1 -0
  65. package/dist/components/Skeleton/Skeleton.vue.d.ts.map +1 -1
  66. package/dist/components/Slider/Composables/UseSliderCollisionAvoidance.d.ts +25 -0
  67. package/dist/components/Slider/Composables/UseSliderCollisionAvoidance.d.ts.map +1 -0
  68. package/dist/components/Slider/Composables/UseSliderDevWarnings.d.ts +5 -0
  69. package/dist/components/Slider/Composables/UseSliderDevWarnings.d.ts.map +1 -0
  70. package/dist/components/Slider/Composables/UseSliderDirection.d.ts +4 -0
  71. package/dist/components/Slider/Composables/UseSliderDirection.d.ts.map +1 -0
  72. package/dist/components/Slider/Composables/UseSliderGeometry.d.ts +88 -0
  73. package/dist/components/Slider/Composables/UseSliderGeometry.d.ts.map +1 -0
  74. package/dist/components/Slider/Composables/UseSliderInteraction.d.ts +33 -0
  75. package/dist/components/Slider/Composables/UseSliderInteraction.d.ts.map +1 -0
  76. package/dist/components/Slider/Composables/UseSliderMagneticSnap.d.ts +8 -0
  77. package/dist/components/Slider/Composables/UseSliderMagneticSnap.d.ts.map +1 -0
  78. package/dist/components/Slider/Composables/UseSliderMarksAndTicks.d.ts +13 -0
  79. package/dist/components/Slider/Composables/UseSliderMarksAndTicks.d.ts.map +1 -0
  80. package/dist/components/Slider/Composables/UseSliderTooltipReadout.d.ts +10 -0
  81. package/dist/components/Slider/Composables/UseSliderTooltipReadout.d.ts.map +1 -0
  82. package/dist/components/Slider/Composables/UseSliderValue.d.ts +16 -0
  83. package/dist/components/Slider/Composables/UseSliderValue.d.ts.map +1 -0
  84. package/dist/components/Slider/Slider.vue.d.ts +304 -0
  85. package/dist/components/Slider/Slider.vue.d.ts.map +1 -0
  86. package/dist/components/Slider/SliderConstants.d.ts +7 -0
  87. package/dist/components/Slider/SliderConstants.d.ts.map +1 -0
  88. package/dist/components/Slider/index.d.ts +3 -0
  89. package/dist/components/Slider/index.d.ts.map +1 -0
  90. package/dist/components/Slider/utils.d.ts +8 -0
  91. package/dist/components/Slider/utils.d.ts.map +1 -0
  92. package/dist/dialtone-vue.cjs +1 -1
  93. package/dist/dialtone-vue.js +26 -24
  94. package/dist/floating-ui.dom-D2zQ_96p.cjs +2 -0
  95. package/dist/floating-ui.dom-D2zQ_96p.cjs.map +1 -0
  96. package/dist/floating-ui.dom-j5GI2lJG.js +963 -0
  97. package/dist/floating-ui.dom-j5GI2lJG.js.map +1 -0
  98. package/dist/index.d.ts +1 -0
  99. package/dist/lib/button-group/button-group.cjs +1 -1
  100. package/dist/lib/button-group/button-group.cjs.map +1 -1
  101. package/dist/lib/button-group/button-group.js +2 -1
  102. package/dist/lib/button-group/button-group.js.map +1 -1
  103. package/dist/lib/codeblock/codeblock.cjs +1 -1
  104. package/dist/lib/codeblock/codeblock.cjs.map +1 -1
  105. package/dist/lib/codeblock/codeblock.js +7 -1
  106. package/dist/lib/codeblock/codeblock.js.map +1 -1
  107. package/dist/lib/datepicker/datepicker.cjs +1 -1
  108. package/dist/lib/datepicker/datepicker.js +1 -1
  109. package/dist/lib/datepicker/index.cjs +1 -1
  110. package/dist/lib/datepicker/index.js +1 -1
  111. package/dist/lib/description-list/description-list.cjs +1 -1
  112. package/dist/lib/description-list/description-list.cjs.map +1 -1
  113. package/dist/lib/description-list/description-list.js +14 -5
  114. package/dist/lib/description-list/description-list.js.map +1 -1
  115. package/dist/lib/emoji/emoji.cjs +1 -1
  116. package/dist/lib/emoji/emoji.cjs.map +1 -1
  117. package/dist/lib/emoji/emoji.js +5 -1
  118. package/dist/lib/emoji/emoji.js.map +1 -1
  119. package/dist/lib/emoji-picker/emoji-picker.cjs +1 -1
  120. package/dist/lib/emoji-picker/emoji-picker.js +1 -1
  121. package/dist/lib/emoji-picker/index.cjs +1 -1
  122. package/dist/lib/emoji-picker/index.js +1 -1
  123. package/dist/lib/empty-state/empty-state.cjs +1 -1
  124. package/dist/lib/empty-state/empty-state.cjs.map +1 -1
  125. package/dist/lib/empty-state/empty-state.js +6 -3
  126. package/dist/lib/empty-state/empty-state.js.map +1 -1
  127. package/dist/lib/keyboard-shortcut/keyboard-shortcut.cjs +1 -1
  128. package/dist/lib/keyboard-shortcut/keyboard-shortcut.cjs.map +1 -1
  129. package/dist/lib/keyboard-shortcut/keyboard-shortcut.js +8 -2
  130. package/dist/lib/keyboard-shortcut/keyboard-shortcut.js.map +1 -1
  131. package/dist/lib/lazy-show/lazy-show.cjs +1 -1
  132. package/dist/lib/lazy-show/lazy-show.cjs.map +1 -1
  133. package/dist/lib/lazy-show/lazy-show.js +10 -10
  134. package/dist/lib/lazy-show/lazy-show.js.map +1 -1
  135. package/dist/lib/mode-island/mode-island.cjs +1 -1
  136. package/dist/lib/mode-island/mode-island.cjs.map +1 -1
  137. package/dist/lib/mode-island/mode-island.js +1 -0
  138. package/dist/lib/mode-island/mode-island.js.map +1 -1
  139. package/dist/lib/motion-text/index.cjs +1 -1
  140. package/dist/lib/motion-text/index.js +3 -3
  141. package/dist/lib/motion-text/motion-text-constants.cjs +1 -1
  142. package/dist/lib/motion-text/motion-text-constants.cjs.map +1 -1
  143. package/dist/lib/motion-text/motion-text-constants.js +64 -2
  144. package/dist/lib/motion-text/motion-text-constants.js.map +1 -1
  145. package/dist/lib/motion-text/motion-text.cjs +1 -1
  146. package/dist/lib/motion-text/motion-text.cjs.map +1 -1
  147. package/dist/lib/motion-text/motion-text.js +186 -146
  148. package/dist/lib/motion-text/motion-text.js.map +1 -1
  149. package/dist/lib/motion-text/utils.cjs +2 -0
  150. package/dist/lib/motion-text/utils.cjs.map +1 -0
  151. package/dist/lib/motion-text/utils.js +24 -0
  152. package/dist/lib/motion-text/utils.js.map +1 -0
  153. package/dist/lib/rich-text-editor/force-linkify.cjs +1 -1
  154. package/dist/lib/rich-text-editor/force-linkify.js +1 -1
  155. package/dist/lib/rich-text-editor/index.cjs +1 -1
  156. package/dist/lib/rich-text-editor/index.js +1 -1
  157. package/dist/lib/rich-text-editor/markdown-renderer.cjs +1 -1
  158. package/dist/lib/rich-text-editor/markdown-renderer.js +1 -1
  159. package/dist/lib/rich-text-editor/rich-text-editor.cjs +1 -1
  160. package/dist/lib/rich-text-editor/rich-text-editor.js +1 -1
  161. package/dist/lib/scroller/index.cjs +1 -1
  162. package/dist/lib/scroller/index.js +1 -1
  163. package/dist/lib/scroller/scroller.cjs +1 -1
  164. package/dist/lib/scroller/scroller.js +1 -1
  165. package/dist/lib/skeleton/skeleton.cjs +1 -1
  166. package/dist/lib/skeleton/skeleton.cjs.map +1 -1
  167. package/dist/lib/skeleton/skeleton.js +1 -0
  168. package/dist/lib/skeleton/skeleton.js.map +1 -1
  169. package/dist/lib/slider/index.cjs +1 -0
  170. package/dist/lib/slider/index.js +2 -0
  171. package/dist/lib/slider/slider.cjs +1 -0
  172. package/dist/lib/slider/slider.js +2 -0
  173. package/dist/lib/slider/utils.cjs +2 -0
  174. package/dist/lib/slider/utils.cjs.map +1 -0
  175. package/dist/lib/slider/utils.js +32 -0
  176. package/dist/lib/slider/utils.js.map +1 -0
  177. package/dist/lib/text-list/index.cjs +1 -1
  178. package/dist/lib/text-list/index.js +2 -2
  179. package/dist/lib/text-list/text-list-item.cjs +1 -1
  180. package/dist/lib/text-list/text-list-item.js +1 -1
  181. package/dist/lib/text-list/text-list.cjs +1 -1
  182. package/dist/lib/text-list/text-list.js +1 -1
  183. package/dist/lib/toast/index.cjs +1 -1
  184. package/dist/lib/toast/index.js +1 -1
  185. package/dist/lib/toast/toast.cjs +1 -1
  186. package/dist/lib/toast/toast.js +1 -1
  187. package/package.json +5 -5
  188. package/dist/Datepicker-CGFa1nGm.js.map +0 -1
  189. package/dist/Datepicker-DkGmnVc8.cjs +0 -2
  190. package/dist/Datepicker-DkGmnVc8.cjs.map +0 -1
  191. package/dist/EmojiPicker-BllVwJf4.js.map +0 -1
  192. package/dist/EmojiPicker-KO1yhODv.cjs +0 -2
  193. package/dist/EmojiPicker-KO1yhODv.cjs.map +0 -1
  194. package/dist/RichTextEditor-Cz2VXb7-.js.map +0 -1
  195. package/dist/RichTextEditor-EHgahp8r.cjs +0 -11
  196. package/dist/RichTextEditor-EHgahp8r.cjs.map +0 -1
@@ -0,0 +1,2 @@
1
+ require(`./chunk-Bmb41Sf3.cjs`);const e=require(`./common/utils/index.cjs`),t=require(`./lib/text/text-constants.cjs`),n=require(`./lib/text/text.cjs`),r=require(`./floating-ui.dom-D2zQ_96p.cjs`),i=require(`./lib/slider/utils.cjs`);let a=require(`vue`);var o=[`horizontal`,`vertical`],s=[`always`,`never`,`tooltip`],c=[`start`,`end`],l=10,u=32,d=0;function f(e,{isRange:t,hasAccessibleName:n}){process.env.NODE_ENV!==`production`&&((0,a.watch)(()=>t.value&&!e.getValueText,e=>{e&&console.info(`[Dialtone] DtSlider in range mode: provide getValueText to give each thumb a distinct screen-reader description.`)},{immediate:!0}),(0,a.watch)(()=>n.value,e=>{e||console.info(`[Dialtone] DtSlider: provide a label prop (set showLabel to false to hide it visually) or aria-label for accessibility.`)},{immediate:!0}),(0,a.watch)(()=>e.minGapSteps!==Math.round(e.minGapSteps),t=>{t&&console.info(`[Dialtone] DtSlider: minGapSteps (${e.minGapSteps}) is not a whole number — it will be rounded to ${Math.round(e.minGapSteps)}.`)},{immediate:!0}),(0,a.watch)(()=>e.min>e.max,t=>{t&&console.info(`[Dialtone] DtSlider: min (${e.min}) is greater than max (${e.max}) — every value will collapse to max.`)},{immediate:!0}))}function p(e){let t=(0,a.ref)(!1);function n(){t.value=!!e.value&&getComputedStyle(e.value).direction===`rtl`}let r=null;return(0,a.onMounted)(()=>{if(n(),typeof MutationObserver<`u`&&e.value){r=new MutationObserver(n);let t={attributes:!0,attributeFilter:[`dir`,`style`,`class`]};for(let n=e.value;n;n=n.parentElement)r.observe(n,t);r.observe(document.documentElement,t)}}),(0,a.onBeforeUnmount)(()=>{r?.disconnect()}),{isRtl:t}}function m(e,t,{isRange:n,activeSnapValue:r}){function i(e,t){return r?.value[e]===t}function o(e){let t=String(e),n=t.search(/e/i);if(n!==-1){let e=t.slice(0,n),r=parseInt(t.slice(n+1),10),i=e.indexOf(`.`),a=i===-1?0:e.length-i-1;return Math.max(0,a-r)}let r=t.indexOf(`.`);return r===-1?0:t.length-r-1}function s(t){return Math.min(e.max,Math.max(e.min,t))}function c(t){if(e.step<=0)return Math.min(e.max,Math.max(e.min,t));let n=Math.round((t-e.min)/e.step),r=Math.max(o(e.min),o(e.step));return Math.min(e.max,Math.max(e.min,parseFloat((e.min+n*e.step).toFixed(r))))}function l(e){return e.length===2&&e[0]>e[1]?[e[1],e[0]]:e}function u(t,n=null){if(t.length!==2)return t;let r=Math.round(e.minGapSteps)*e.step;if(r<=0)return t;let[i,a]=t;if(a-i>=r)return t;n===0?a=Math.min(e.max,i+r):n===1?i=Math.max(e.min,a-r):i+r<=e.max?a=i+r:a-r>=e.min?i=a-r:(a=e.max,i=Math.max(e.min,a-r));let s=Math.max(o(e.min),o(e.max),o(e.step),n===null?0:o(t[n]));return n!==0&&(i=Math.min(e.max,Math.max(e.min,parseFloat(i.toFixed(s))))),n!==1&&(a=Math.min(e.max,Math.max(e.min,parseFloat(a.toFixed(s))))),[i,a]}function d(e,t=null){let n=e.map((e,n)=>n===t||Number.isFinite(e)?e:f());return n=n.map((e,n)=>n===t?e:s(e)),n=n.map((e,n)=>n===t?e:c(e)),n=n.length===2&&t===null?l(n):n,u(n,t)}function f(){return(e.min+e.max)/2}function p(e,t=null){let n;return n=Array.isArray(e)?e.length>=2?[e[0],e[1]]:e.length===1?[e[0]]:[f()]:e==null?[f()]:[e],d(n,t)}let m=(0,a.ref)(p(e.modelValue)),h=(0,a.ref)([...m.value]),g=(0,a.computed)(()=>n.value?[...m.value]:m.value[0]);function _(t){return e.max===e.min?0:(t-e.min)/(e.max-e.min)*100}function v(t,n){if(e.step<=0)return t;let r=(t-e.min)/e.step,i=n?Math.ceil(r-1e-9):Math.floor(r+1e-9);return e.min+i*e.step}function y(t){if(!n.value||t!==1||m.value.length<2)return e.min;let r=Math.round(e.minGapSteps)*e.step,i=Math.min(e.max,m.value[0]+r);return Math.min(e.max,v(i,!0))}function b(t){if(!n.value||t!==0||m.value.length<2)return e.max;let r=Math.round(e.minGapSteps)*e.step,i=Math.max(e.min,m.value[1]-r);return Math.max(e.min,v(i,!1))}function x(t){if(e.step<=0)return`any`;let n=m.value[t];if(n===void 0)return e.step;let r=(n-e.min)/e.step;return Math.abs(r-Math.round(r))>1e-9?`any`:e.step}let S=!1;function C(e){process.env.NODE_ENV===`production`||S||(S=!0,console.info(`[Dialtone] DtSlider: ${e}`))}function w(t,n){if(e.getValueText)try{let r=e.getValueText(t,n);if(typeof r==`string`)return r;C(`getValueText must return a string synchronously (got ${typeof r}) — falling back to the raw value.`)}catch(e){C(`getValueText threw — falling back to the raw value. ${e}`)}return`${e.prefix}${t}${e.suffix}`}return(0,a.watch)(()=>e.modelValue,e=>{if(e==null)return;let n=m.value,r=Array.isArray(e)?e:[e],a=n.findIndex((e,t)=>r[t]===e&&i(t,e)),o=p(e,a===-1?null:a);if(o.length!==n.length||o.some((e,t)=>e!==n[t])){let e=n.length!==h.value.length||n.some((e,t)=>e!==h.value[t]);m.value=o,e||(h.value=[...o])}(o.length!==r.length||o.some((e,t)=>e!==r[t]))&&t(`update:modelValue`,Array.isArray(e)?[...o]:o[0])},{deep:!0}),(0,a.watch)(()=>[e.min,e.max,e.step,e.minGapSteps],()=>{let r=m.value,a=r.length!==h.value.length||r.some((e,t)=>e!==h.value[t]),o=r.findIndex((t,n)=>i(n,t)&&t>=e.min&&t<=e.max),s=d(r,o===-1?null:o);if(s.length!==r.length||s.some((e,t)=>e!==r[t])){m.value=s;let e=n.value?[...s]:s[0];if(t(`update:modelValue`,e),a)return;h.value=[...s],t(`change`,e)}}),(0,a.onMounted)(()=>{if(e.modelValue===void 0||e.modelValue===null)return;let n=Array.isArray(e.modelValue)?e.modelValue:[e.modelValue],r=m.value;(r.length!==n.length||r.some((e,t)=>e!==n[t]))&&t(`update:modelValue`,Array.isArray(e.modelValue)?[...r]:r[0])}),{internalValues:m,lastCommittedValues:h,currentValue:g,decimalPlaces:o,snapToStep:c,thumbPercent:_,thumbNativeMin:y,thumbNativeMax:b,thumbNativeStep:x,formatValue:w}}var h=10,g=2;function _(e,{controlRef:t,isVertical:n}){let r=(0,a.computed)(()=>{if(e.snapPoints==null)return[];if(typeof e.snapPoints==`number`){let t=e.snapPoints;return!Number.isFinite(t)||t<=0?[]:i.generateInterval(e.min,e.max,t,`snapPoints`)}return Array.isArray(e.snapPoints)?e.snapPoints.filter(t=>Number.isFinite(t)&&t>=e.min&&t<=e.max):[]}),o=(0,a.ref)({});function s(i,a){let s=r.value;if(!s.length||!t.value)return delete o.value[a],null;let c=t.value.getBoundingClientRect(),l=n.value?c.height:c.width;if(!l)return null;let u=h/l*(e.max-e.min),d=o.value[a];if(d!=null&&s.includes(d)){let e=u*g;if(Math.abs(d-i)<=e)return d}let f=null,p=1/0;for(let e of s){let t=Math.abs(e-i);t<=u&&t<p&&(f=e,p=t)}return f==null?delete o.value[a]:o.value[a]=f,f}return{activeSnapValue:o,findMagneticSnapPoint:s}}var v=new Set([`ArrowUp`,`ArrowDown`,`ArrowLeft`,`ArrowRight`,`Home`,`End`,`PageUp`,`PageDown`]);function y(e,t,{controlRef:n,thumbRefs:r,internalValues:o,isRange:s,isVertical:c,decimalPlaces:l,snapToStep:u,lastCommittedValues:d,findMagneticSnapPoint:f,activeSnapValue:p,isRtl:m}){let h=(0,a.ref)(!1),g=(0,a.ref)(null),_=(0,a.ref)(null),y=(0,a.ref)(null),b=(0,a.ref)(null),x=(0,a.ref)(null),S=!1,C=null,w=!1;(0,a.watch)(()=>e.disabled,e=>{e&&(y.value=null,b.value=null)}),(0,a.watch)(()=>o.value.length,(e,t)=>{let n=y.value===1||document.activeElement===r.value[1];e===1&&t===2&&n&&(0,a.nextTick)(()=>r.value[0]?.focus()),g.value!==null&&g.value>=e&&(g.value=null)});function T(n,i,{allowSnap:a=!1}={}){let c=Math.min(e.max,Math.max(e.min,i)),d=a?f(c,n):null;c=d??u(c);let m=[...o.value];if(s.value){let t=Math.max(0,Math.round(e.minGapSteps)*e.step);if(c=n===0?Math.min(c,(m[1]??e.max)-t):Math.max(c,(m[0]??e.min)+t),!(d!=null&&c===d)){let t=Math.max(l(e.min),l(e.step));c=parseFloat(c.toFixed(t)),c=Math.min(e.max,Math.max(e.min,c))}d!=null&&c!==d&&delete p.value[n]}if(m[n]===c){let e=r.value[n];e&&e.value!==String(c)&&(e.value=String(c));return}m[n]=c,o.value=m,t(`update:modelValue`,s.value?[...m]:m[0])}function E(){let e=o.value,n=d.value;(e.length!==n.length||e.some((e,t)=>e!==n[t]))&&(d.value=[...e],t(`change`,s.value?[...e]:e[0]))}let D=0;function O(t){let r=n.value.getBoundingClientRect(),i=c.value?r.height:r.width,a=i-2*D,o;if(c.value){let e=r.bottom-t.clientY;o=a>0?(e-D)/a:e/i}else{let e=t.clientX-r.left;o=a>0?(e-D)/a:e/i,m.value&&(o=1-o)}return o=Math.min(1,Math.max(0,o)),e.min+o*(e.max-e.min)}function k(e){if(!s.value||o.value.length<2)return 0;let[t,n]=o.value;return t===n?_.value===0?1:0:Math.abs(e-t)<=Math.abs(e-n)?0:1}function A(e,t){if(!s.value)return e;let[n,r]=o.value;return n===r?e===0&&t>n?1:e===1&&t<r?0:e:e}function j(t){if(e.disabled||t.pointerType===`mouse`&&t.button!==0||h.value&&t.pointerId!==C)return;t.preventDefault(),D=i.measureEdgeInsetPx(n.value);let a=O(t),c=k(a),[l,u]=o.value;w=s.value&&o.value.length===2&&l===u,x.value===c&&(x.value=null),g.value=c,_.value=c,h.value=!0,C=t.pointerId,n.value.setPointerCapture(t.pointerId),b.value=null,T(c,a,{allowSnap:!0});let d=r.value[c];d&&document.activeElement!==d?(S=!0,d.focus()):y.value===c&&(y.value=null)}function M(t){if(!h.value||g.value===null||t.pointerId!==C)return;if(e.disabled){P();return}if(t.buttons===0){P();return}let n=O(t),r=w?A(g.value,n):g.value;r!==g.value&&(delete p.value[g.value],x.value===r&&(x.value=null),g.value=r,_.value=r),T(r,n,{allowSnap:!0})}function N(t){if(e.step<=0)return!1;let n=(t-e.min)/e.step;return Math.abs(n-Math.round(n))>1e-9}function P(e){if(!h.value||e&&e.pointerId!==C)return;h.value=!1,C=null;let t=g.value;t!==null&&N(o.value[t])&&T(t,o.value[t]),E(),g.value=null,p.value={}}function F(e,t){T(e,Number(t.target.value))}function I(e,t,n,r){return e===`PageUp`?1:e===`PageDown`?-1:t?e===`ArrowUp`||e===n?1:e===`ArrowDown`||e===r?-1:0:0}function L(){return e.step<=0?e.largeStep:Math.max(1,Math.round(e.largeStep/e.step))*e.step}function R(e,t){y.value!==e&&(y.value=e);let n=m.value,r=n?`ArrowLeft`:`ArrowRight`,i=n?`ArrowRight`:`ArrowLeft`,a=I(t.key,t.shiftKey,r,i);a!==0&&(t.preventDefault(),T(e,o.value[e]+a*L())),t.key===`Escape`?x.value=e:v.has(t.key)&&x.value===e&&(x.value=null)}function z(e,n){S?S=!1:(x.value===e&&(x.value=null),y.value=e),t(`focus`,n)}function B(e,n){y.value=null,E(),t(`blur`,n)}function ee(e){x.value===e&&(x.value=null),b.value=e}function te(e){b.value===e&&(b.value=null)}function V(t){return e.readout===`always`?!0:x.value===t?!1:g.value===t||y.value===t||b.value===t}return{isDragging:h,activeThumbIndex:g,focusedThumbIndex:y,hoveredThumbIndex:b,updateThumbValue:T,commitIfChanged:E,onPointerDown:j,onPointerMove:M,onPointerUp:P,onThumbInput:F,onThumbKeydown:R,onThumbFocus:z,onThumbBlur:B,onThumbHitPointerEnter:ee,onThumbHitPointerLeave:te,isReadoutOpen:V}}function b(e,{isVertical:t,isRange:n,internalValues:r,thumbPercent:i,isRtl:o,markEdgeOffsetPx:s,formatValue:c}){function l(e,n){let r=t.value?{bottom:`${e}%`}:{insetInlineStart:`${e}%`};return n&&(r.transform=n),r}function u(){return o.value?`50%`:`-50%`}let d=`var(--slider-edge-inset)`,f=`calc(${d} + (100% - ${d} * 2) * `;function p(e){return`${f}${e/100})`}function m(e){return`calc((100% - ${d} * 2) * ${e/100})`}function h(e,{verticalTransform:n,horizontalTransform:r}){let a=i(e);return t.value?{bottom:p(a),transform:n}:{insetInlineStart:p(a),transform:r}}function g(e){return h(e,{verticalTransform:`translate(${u()}, 50%)`,horizontalTransform:`translate(${u()}, -50%)`})}function _(e){return h(e,{verticalTransform:`translateY(50%)`,horizontalTransform:`translateX(${u()})`})}function v(e){let t=o.value?-1:1;return e===`start`?`translateX(${t}px)`:`translateX(calc(${o.value?`100%`:`-100%`} + ${-t}px))`}function y(e,n){let r=t.value?{bottom:p(e)}:{insetInlineStart:p(e)};return n&&(r.transform=n),r}function b(e,n,r){if(r&&!t.value)return l(e,v(r));let i=t.value?0:s.value[n];return i?y(e,`translateX(calc(${u()} + ${i}px))`):y(e)}function x(e,n,r){if(r&&!t.value)return l(e,v(r));let i=t.value?0:n;return i?y(e,`translateX(calc(${u()} + ${i}px))`):y(e)}return{thumbPositionStyle:g,tickPositionStyle:_,markStyle:b,readoutStyle:x,mergedReadoutPct:(0,a.computed)(()=>{if(!n.value||r.value.length!==2)return 0;let[e,t]=r.value;return(i(e)+i(t))/2}),mergedReadoutText:(0,a.computed)(()=>{if(!n.value||r.value.length!==2)return``;let[e,t]=r.value;return`${c(e,0)}–${c(t,1)}`}),indicatorStyle:(0,a.computed)(()=>{if(n.value&&r.value.length===2){let[e,n]=r.value,a=i(e),o=i(n);return t.value?{bottom:p(a),height:m(o-a)}:{insetInlineStart:p(a),width:m(o-a)}}let a=i(r.value[0]??e.min);if(typeof e.fillOrigin==`number`){let n=i(Math.min(e.max,Math.max(e.min,e.fillOrigin))),r=Math.min(a,n),o=Math.abs(a-n);return t.value?{bottom:p(r),height:m(o)}:{insetInlineStart:p(r),width:m(o)}}let o=e.fillOrigin===`end`;return t.value?o?{top:0,height:`calc(100% - ${p(a)})`}:{bottom:0,height:p(a)}:o?{insetInlineEnd:0,width:`calc(100% - ${p(a)})`}:{insetInlineStart:0,width:p(a)}})}}function x(e,{isVertical:t,thumbPercent:n}){let r=(0,a.computed)(()=>{let t=typeof e.showTicks==`number`?e.showTicks:e.step;return!t||t<=0?[]:i.generateInterval(e.min,e.max,t,`ticks`)});function o(t){return`${e.prefix}${t}${e.suffix}`}let s=(0,a.computed)(()=>{let t=e.showMarks===!0?[e.min,e.max]:e.showMarks;return Array.isArray(t)?t.filter(i.isValidMark).map(t=>{let r=typeof t==`number`?t:t.value,i=typeof t==`number`?o(t):t.text??o(r),a=r===e.min?`start`:r===e.max?`end`:null;return{text:i,pct:n(r),edge:a}}):[]});return{computedTickValues:r,computedMarks:s,reservesAnnotationSpace:(0,a.computed)(()=>!t.value&&(s.value.length>0||e.readout===`always`))}}function S(e,{controlRef:t,isVertical:n,isRange:r,internalValues:o,thumbPercent:s,isRtl:c,isReadoutOpen:l,computedMarks:u,formatValue:d}){let f=(0,a.ref)([]),p=(0,a.ref)([]),m=(0,a.ref)(null),h=(0,a.ref)([]),g=(0,a.ref)([]),_=(0,a.ref)(!1),v=(0,a.ref)([]),y=(0,a.ref)([]),b=(0,a.ref)(0);function x(e,t,n=0){return!(e.right+n<t.left||e.left-n>t.right||e.bottom+n<t.top||e.top-n>t.bottom)}let S=0,C=0;function w(e,r){if(!r||!t.value)return null;let a=r.getBoundingClientRect(),o=t.value.getBoundingClientRect(),s=C;if(n.value){let t=a.bottom-a.top,n=s+(o.bottom-o.top-2*s)*(e/100),r=o.bottom-n;return{left:a.left,right:a.right,top:r-t/2,bottom:r+t/2}}let l=a.right-a.left,u=s+(o.right-o.left-2*s)*(i.mirrorPct(e,c.value)/100),d=o.left+u;return{left:d-l/2,right:d+l/2,top:a.top,bottom:a.bottom}}function T(e){return p.value.find(t=>t&&Number(t.dataset.readoutIndex)===e)}function E(t,n){return e.readout===`tooltip`?h.value[n]?.getBoundingClientRect()??null:w(s(t),T(n))}async function D(){let n=++S;if(await(0,a.nextTick)(),n!==S)return;t.value&&(C=i.measureEdgeInsetPx(t.value));let c=_.value;if(e.readout!==`tooltip`&&r.value&&o.value.length===2&&l(0)&&l(1)){let[e,t]=o.value,n=w(s(e),T(0)),r=w(s(t),T(1));_.value=!!(n&&r&&x(n,r,4))}else _.value=!1;_.value!==c&&(await(0,a.nextTick)(),n!==S)||(j(),O())}function O(){let r=e.readout===`always`&&!!t.value&&!n.value,a=r?t.value.getBoundingClientRect():null;function s(e,t){if(!e||!r)return 0;let n=e.getBoundingClientRect();return i.edgeClampOffset(n.left-t,n.right-t,a,0)}function c(){let e=s(m.value,b.value);e!==b.value&&(b.value=e),y.value.some(Boolean)&&(y.value=o.value.map(()=>0))}function u(){b.value&&(b.value=0);let e=o.value.map((e,t)=>l(t)?s(T(t),y.value[t]||0):0);i.sameValues(e,y.value)||(y.value=e)}_.value?c():u()}function k(){let[e,t]=o.value;return(s(e)+s(t))/2}function A(){if(_.value){let e=w(k(),m.value);return e?[e]:[]}return o.value.map((e,t)=>l(t)?E(e,t):null).filter(Boolean)}function j(){let e=f.value;if(!e.length)return;let r=A(),a=u.value.map(()=>!1),o=u.value.map(()=>0),s=!!t.value&&!n.value,c=s?t.value.getBoundingClientRect():null;e.forEach(e=>{if(!e)return;let t=Number(e.dataset.markIndex),n=v.value[t]||0,l=e.getBoundingClientRect(),u=l.left-n,d=l.right-n,f=s?i.edgeClampOffset(u,d,c,32):0;if(o[t]=f,r.length){let e={top:l.top,bottom:l.bottom,left:u+f,right:d+f};a[t]=r.some(t=>x(e,t,4))}}),i.sameValues(a,g.value)||(g.value=a),i.sameValues(o,v.value)||(v.value=o)}let M=(0,a.computed)(()=>o.value.map((e,t)=>l(t))),N=(0,a.computed)(()=>o.value.map((e,t)=>d(e,t))),P=null;return(0,a.watch)([M,u,n,c],()=>D(),{deep:!0}),(0,a.watch)([o,N,()=>e.readoutClass],()=>{e.readout!==`tooltip`&&D()},{deep:!0}),(0,a.onMounted)(()=>{(0,a.nextTick)(D),typeof ResizeObserver<`u`&&t.value&&(P=new ResizeObserver(()=>{D()}),P.observe(t.value))}),(0,a.onBeforeUnmount)(()=>{P?.disconnect()}),{markElRefs:f,readoutElRefs:p,mergedReadoutElRef:m,tooltipElRefs:h,markCollisionHidden:g,readoutMerged:_,markEdgeOffsetPx:v,readoutEdgeOffsetPx:y,mergedReadoutEdgeOffsetPx:b,readoutVisibility:M,formattedValues:N,updateCollisions:D}}var C={visibilityProperty:!0,opacityProperty:!0,checkVisibilityCSS:!0,checkOpacity:!0};function w(e){if(e.checkVisibility)return e.checkVisibility(C);if(!e.getClientRects().length||getComputedStyle(e).visibility!==`visible`)return!1;for(let t=e;t;t=t.parentElement){let e=getComputedStyle(t);if(e.opacity===`0`||e.contentVisibility===`hidden`)return!1}return!0}function T(e,t){return e.left===t.left&&e.top===t.top&&e.right===t.right&&e.bottom===t.bottom}var E=(e,t,n)=>Math.min(n,Math.max(t,e));function D(e,{thumbVisualRefs:t,tooltipElRefs:n,isVertical:o,isRtl:s,readoutVisibility:c,formattedValues:l,onPosition:u}){let d=new Map;function f(t){return e.readout===`tooltip`&&!e.disabled&&c.value[t]}function p(e){let t=d.get(e);t&&(d.delete(e),t.cleanup?.(),t.tooltip.matches(`:popover-open`)&&t.tooltip.hidePopover())}function m(e,t,n){if(typeof n.showPopover!=`function`)return;let a=0,c=!0,l=null,m=null,h,g={anchor:t,tooltip:n,update:b,cleanup:null},_=()=>d.get(e)===g;function v(){return c||!w(t)?`hidden`:`visible`}function y(){n.style.visibility=`hidden`,n.showPopover()}async function b(){if(!_())return;if(!n.matches(`:popover-open`)){if(!f(e)||!t.isConnected||!n.isConnected||!w(t)){p(e);return}y()}let d=++a,h=t.getBoundingClientRect();l=h;let g=parseFloat(getComputedStyle(n).paddingBlockStart)||0,b={boundary:[],padding:g*2},x=n.firstElementChild,S=()=>_()&&d===a,C=await r.i(t,n,{strategy:`fixed`,placement:o.value?s.value?`left`:`right`:`top`,middleware:[r.c(g),r.a(b),r.l(b),r.u({...b,apply({availableWidth:e,availableHeight:t}){S()&&(x.style.maxInlineSize=`${Math.max(0,e-g*2)}px`,x.style.maxBlockSize=`${Math.max(0,t-g*2)}px`)}}),r.o()]});if(!S())return;let T=n.offsetWidth,D=n.offsetHeight,O=C.placement;c=C.middlewareData.hide?.referenceHidden;let k=v();n.dataset.side=O,Object.assign(n.style,{left:`${C.x}px`,top:`${C.y}px`,visibility:k}),O===`top`||O===`bottom`?n.style.setProperty(`--slider-tooltip-arrow-x`,`${E(h.left+h.width/2-C.x,g,T-g)}px`):n.style.setProperty(`--slider-tooltip-arrow-y`,`${E(h.top+h.height/2-C.y,g,D-g)}px`);let A=[C.x,C.y,T,D,O,k];(!m||!i.sameValues(A,m))&&(m=A,u())}function x(){!n.matches(`:popover-open`)||!l||!T(t.getBoundingClientRect(),l)?b():n.style.visibility=v(),_()&&(h=requestAnimationFrame(x))}d.set(e,g),y();let S=r.r(t,n,b,{layoutShift:!1});x(),g.cleanup=()=>{S(),cancelAnimationFrame(h)}}function h(){for(let[e,r]of d)(!f(e)||t.value[e]!==r.anchor||n.value[e]!==r.tooltip)&&p(e);c.value.forEach((e,r)=>{let i=t.value[r],a=n.value[r];!i||!a||!f(r)||(d.has(r)?d.get(r).update():m(r,i,a))})}(0,a.watch)([()=>e.readout,()=>e.disabled,o,s,l,c],h,{flush:`post`}),(0,a.onMounted)(h),(0,a.onBeforeUnmount)(()=>{for(let e of d.keys())p(e)})}var O=[`data-disabled`,`data-orientation`,`data-dragging`],k=[`onPointerenter`,`onPointerleave`],A=[`min`,`max`,`step`,`value`,`disabled`,`name`,`aria-labelledby`,`aria-label`,`aria-describedby`,`aria-errormessage`,`aria-details`,`aria-invalid`,`aria-valuetext`,`aria-orientation`,`onInput`,`onKeydown`,`onFocus`,`onBlur`],j=[`data-mark-index`],M=[`data-readout-index`],N={class:`d-slider__tooltip-content`},P=(0,a.defineComponent)({name:`DtSlider`,inheritAttrs:!1,__name:`Slider`,props:{modelValue:{type:[Number,Array],default:void 0,validator:e=>!Array.isArray(e)||e.length===2},min:{type:Number,default:0,validator:Number.isFinite},max:{type:Number,default:100,validator:Number.isFinite},step:{type:Number,default:1,validator:Number.isFinite},snapPoints:{type:[Number,Array],default:void 0,validator:e=>Number.isFinite(e)||Array.isArray(e)&&e.every(Number.isFinite)},disabled:{type:Boolean,default:!1},orientation:{type:String,default:`horizontal`,validator:e=>o.includes(e)},fillOrigin:{type:[Number,String],default:`start`,validator:e=>typeof e==`number`||c.includes(e)},showTicks:{type:[Boolean,Number],default:!1},minGapSteps:{type:Number,default:0},label:{type:String,default:``},showLabel:{type:Boolean,default:!0},labelSize:{type:[String,Number],default:null,validator:e=>t.TEXT_SIZE_MODIFIERS.label.includes(String(e))},labelStrength:{type:String,default:null,validator:e=>Object.keys(t.TEXT_STRENGTH_MODIFIERS).includes(e)},getValueText:{type:Function,default:null},prefix:{type:String,default:``},suffix:{type:String,default:``},name:{type:String,default:``},largeStep:{type:Number,default:10},bodyClass:{type:[String,Array,Object],default:``},labelClass:{type:[String,Array,Object],default:``},startClass:{type:[String,Array,Object],default:``},endClass:{type:[String,Array,Object],default:``},readout:{type:String,default:`tooltip`,validator:e=>s.includes(e)},readoutClass:{type:[String,Array,Object],default:``},showMarks:{type:[Array,Boolean],default:!1,validator:e=>typeof e==`boolean`||Array.isArray(e)&&e.every(i.isValidMark)}},emits:[`update:modelValue`,`change`,`focus`,`blur`],setup(t,{expose:r,emit:i}){let o=t,s=i,c=(0,a.useSlots)(),l=(0,a.useAttrs)(),u=`slider-label-${e.getUniqueString()}`,d=(0,a.ref)(null),h=(0,a.ref)([]),g=(0,a.ref)([]),v=(0,a.computed)(()=>Array.isArray(o.modelValue)),C=(0,a.computed)(()=>o.orientation===`vertical`),{isRtl:w}=p(d),{activeSnapValue:T,findMagneticSnapPoint:E}=_(o,{controlRef:d,isVertical:C}),{internalValues:P,lastCommittedValues:F,currentValue:I,decimalPlaces:L,snapToStep:R,thumbPercent:z,thumbNativeMin:B,thumbNativeMax:ee,thumbNativeStep:te,formatValue:V}=m(o,s,{isRange:v,activeSnapValue:T});function H(e){return e.some(e=>{if(typeof e==`string`)return e.trim()!==``;if(e.type===a.Comment)return!1;if(typeof e.children==`string`)return e.children.trim()!==``;if(Array.isArray(e.children))return H(e.children);if(e.children&&typeof e.children.default==`function`){let t=e.children.default();return H(Array.isArray(t)?t:[t])}return!1})}let ne=(0,a.computed)(()=>c.label?H(c.label({value:I.value})):!!o.label?.trim()),U=(0,a.computed)(()=>o.showLabel&&ne.value),W=(0,a.computed)(()=>U.value?u:l[`aria-labelledby`]),G=(0,a.computed)(()=>{if(!U.value)return!o.showLabel&&o.label?o.label:l[`aria-label`]}),re=(0,a.computed)(()=>U.value||!!(String(G.value??``).trim()||String(W.value??``).trim())),ie=(0,a.computed)(()=>o.labelSize??300),ae=[`aria-label`,`aria-labelledby`,`aria-describedby`,`aria-errormessage`,`aria-details`,`aria-invalid`],oe=(0,a.computed)(()=>{let t=e.removeClassStyleAttrs(l);return Object.fromEntries(Object.entries(t).filter(([e])=>!ae.includes(e)))}),{isDragging:K,activeThumbIndex:se,focusedThumbIndex:ce,onPointerDown:q,onPointerMove:J,onPointerUp:Y,onThumbInput:le,onThumbKeydown:ue,onThumbFocus:de,onThumbBlur:fe,onThumbHitPointerEnter:pe,onThumbHitPointerLeave:me,isReadoutOpen:he}=y(o,s,{controlRef:d,thumbRefs:h,internalValues:P,isRange:v,isVertical:C,decimalPlaces:L,snapToStep:R,lastCommittedValues:F,findMagneticSnapPoint:E,activeSnapValue:T,isRtl:w}),{computedTickValues:ge,computedMarks:X,reservesAnnotationSpace:_e}=x(o,{isVertical:C,thumbPercent:z}),{markElRefs:ve,readoutElRefs:ye,mergedReadoutElRef:be,tooltipElRefs:Z,markCollisionHidden:xe,readoutMerged:Q,markEdgeOffsetPx:Se,readoutEdgeOffsetPx:Ce,mergedReadoutEdgeOffsetPx:we,readoutVisibility:Te,formattedValues:Ee,updateCollisions:De}=S(o,{controlRef:d,isVertical:C,isRange:v,internalValues:P,thumbPercent:z,isRtl:w,isReadoutOpen:he,computedMarks:X,formatValue:V}),{thumbPositionStyle:$,tickPositionStyle:Oe,markStyle:ke,readoutStyle:Ae,mergedReadoutPct:je,mergedReadoutText:Me,indicatorStyle:Ne}=b(o,{isVertical:C,isRange:v,internalValues:P,thumbPercent:z,isRtl:w,markEdgeOffsetPx:Se,formatValue:V});function Pe(e){return e===o.min?`start`:e===o.max?`end`:null}D(o,{thumbVisualRefs:g,tooltipElRefs:Z,isVertical:C,isRtl:w,readoutVisibility:Te,formattedValues:Ee,onPosition:De}),f(o,{isRange:v,hasAccessibleName:re});function Fe(){h.value[0]?.focus()}function Ie(){h.value.find(e=>e===document.activeElement)?.blur()}return r({focus:Fe,blur:Ie}),(r,i)=>((0,a.openBlock)(),(0,a.createElementBlock)(`div`,(0,a.mergeProps)(oe.value,{class:[`d-slider`,r.$attrs.class,{"d-slider--disabled":t.disabled,"d-slider--vertical":C.value,"d-slider--inverted":t.fillOrigin===`end`,"d-slider--dragging":(0,a.unref)(K)}],style:r.$attrs.style,"data-disabled":t.disabled||void 0,"data-orientation":t.orientation,"data-dragging":(0,a.unref)(K)||void 0,"data-qa":`dt-slider`}),[t.showLabel?((0,a.openBlock)(),(0,a.createElementBlock)(`div`,{key:0,id:u,class:(0,a.normalizeClass)([`d-slider__label`,t.labelClass]),"data-qa":`dt-slider-label`},[(0,a.renderSlot)(r.$slots,`label`,{value:(0,a.unref)(I)},()=>[t.label?((0,a.openBlock)(),(0,a.createBlock)((0,a.unref)(n.default),{key:0,kind:`label`,size:ie.value,strength:t.labelStrength,tone:t.disabled?`disabled`:`secondary`},{default:(0,a.withCtx)(()=>[(0,a.createTextVNode)((0,a.toDisplayString)(t.label),1)]),_:1},8,[`size`,`strength`,`tone`])):(0,a.createCommentVNode)(``,!0)])],2)):(0,a.createCommentVNode)(``,!0),(0,a.createElementVNode)(`div`,{class:(0,a.normalizeClass)([`d-slider__body`,t.bodyClass,{"d-slider__body--reserve-annotation-space":(0,a.unref)(_e)}]),"data-qa":`dt-slider-body`},[(0,a.unref)(e.hasSlotContent)(r.$slots.start)?((0,a.openBlock)(),(0,a.createElementBlock)(`div`,{key:0,class:(0,a.normalizeClass)([`d-slider__start`,t.startClass]),"data-qa":`dt-slider-start`},[(0,a.renderSlot)(r.$slots,`start`)],2)):(0,a.createCommentVNode)(``,!0),(0,a.createElementVNode)(`div`,{ref_key:`controlRef`,ref:d,class:`d-slider__control`,style:(0,a.normalizeStyle)(C.value?{touchAction:`pan-x`}:{touchAction:`pan-y`}),"data-qa":`dt-slider-control`,onPointerdown:i[0]||(i[0]=(...e)=>(0,a.unref)(q)&&(0,a.unref)(q)(...e)),onPointermove:i[1]||(i[1]=(...e)=>(0,a.unref)(J)&&(0,a.unref)(J)(...e)),onPointerup:i[2]||(i[2]=(...e)=>(0,a.unref)(Y)&&(0,a.unref)(Y)(...e)),onPointercancel:i[3]||(i[3]=(...e)=>(0,a.unref)(Y)&&(0,a.unref)(Y)(...e))},[i[4]||(i[4]=(0,a.createElementVNode)(`div`,{class:`d-slider__track`,"data-qa":`dt-slider-track`},null,-1)),(0,a.createElementVNode)(`div`,{class:`d-slider__indicator`,style:(0,a.normalizeStyle)((0,a.unref)(Ne)),"data-qa":`dt-slider-indicator`},null,4),t.showTicks?((0,a.openBlock)(!0),(0,a.createElementBlock)(a.Fragment,{key:0},(0,a.renderList)((0,a.unref)(ge),(e,t)=>((0,a.openBlock)(),(0,a.createElementBlock)(`div`,{key:t,class:`d-slider__tick`,style:(0,a.normalizeStyle)((0,a.unref)(Oe)(e)),"data-qa":`dt-slider-tick`},null,4))),128)):(0,a.createCommentVNode)(``,!0),((0,a.openBlock)(!0),(0,a.createElementBlock)(a.Fragment,null,(0,a.renderList)((0,a.unref)(P),(e,t)=>((0,a.openBlock)(),(0,a.createElementBlock)(`div`,{key:`thumb-visual-${t}`,ref_for:!0,ref:e=>{g.value[t]=e},class:(0,a.normalizeClass)([`d-slider__thumb-visual`,{"d-slider__thumb-visual--focused":(0,a.unref)(ce)===t,"d-slider__thumb-visual--active":(0,a.unref)(se)===t}]),style:(0,a.normalizeStyle)((0,a.unref)($)(e)),"data-qa":`dt-slider-thumb-visual`},null,6))),128)),((0,a.openBlock)(!0),(0,a.createElementBlock)(a.Fragment,null,(0,a.renderList)((0,a.unref)(P),(e,t)=>((0,a.openBlock)(),(0,a.createElementBlock)(`div`,{key:`thumb-hit-${t}`,class:`d-slider__thumb-hit`,style:(0,a.normalizeStyle)({...(0,a.unref)($)(e),touchAction:C.value?`pan-x`:`pan-y`}),"data-qa":`dt-slider-thumb-hit`,onPointerenter:e=>(0,a.unref)(pe)(t),onPointerleave:e=>(0,a.unref)(me)(t)},null,44,k))),128)),((0,a.openBlock)(!0),(0,a.createElementBlock)(a.Fragment,null,(0,a.renderList)((0,a.unref)(P),(e,n)=>((0,a.openBlock)(),(0,a.createElementBlock)(`input`,{key:`thumb-input-${n}`,ref_for:!0,ref:e=>{h.value[n]=e},type:`range`,class:`d-slider__thumb`,min:(0,a.unref)(B)(n),max:(0,a.unref)(ee)(n),step:(0,a.unref)(te)(n),value:e,disabled:t.disabled,name:t.name||void 0,"aria-labelledby":W.value,"aria-label":G.value,"aria-describedby":(0,a.unref)(l)[`aria-describedby`],"aria-errormessage":(0,a.unref)(l)[`aria-errormessage`],"aria-details":(0,a.unref)(l)[`aria-details`],"aria-invalid":(0,a.unref)(l)[`aria-invalid`],"aria-valuetext":(0,a.unref)(V)(e,n),"aria-orientation":C.value?`vertical`:void 0,"data-qa":`dt-slider-thumb`,onInput:e=>(0,a.unref)(le)(n,e),onKeydown:e=>(0,a.unref)(ue)(n,e),onFocus:e=>(0,a.unref)(de)(n,e),onBlur:e=>(0,a.unref)(fe)(n,e)},null,40,A))),128)),((0,a.openBlock)(!0),(0,a.createElementBlock)(a.Fragment,null,(0,a.renderList)((0,a.unref)(X),(e,t)=>((0,a.openBlock)(),(0,a.createElementBlock)(`div`,{key:`mark-${t}`,ref_for:!0,ref_key:`markElRefs`,ref:ve,class:(0,a.normalizeClass)([`d-slider__mark`,{"d-slider__mark--collision-hidden":(0,a.unref)(xe)[t]}]),style:(0,a.normalizeStyle)((0,a.unref)(ke)(e.pct,t,e.edge)),"data-mark-index":t,"data-qa":`dt-slider-mark`},(0,a.toDisplayString)(e.text),15,j))),128)),t.readout===`always`?((0,a.openBlock)(),(0,a.createElementBlock)(a.Fragment,{key:1},[((0,a.openBlock)(!0),(0,a.createElementBlock)(a.Fragment,null,(0,a.renderList)((0,a.unref)(P),(e,n)=>((0,a.openBlock)(),(0,a.createElementBlock)(`div`,{key:`readout-${n}`,ref_for:!0,ref_key:`readoutElRefs`,ref:ye,class:(0,a.normalizeClass)([`d-slider__readout`,(0,a.unref)(Q)?`d-slider__readout--hide`:`d-slider__readout--show`,t.readoutClass]),style:(0,a.normalizeStyle)((0,a.unref)(Ae)((0,a.unref)(z)(e),(0,a.unref)(Ce)[n],Pe(e))),"data-readout-index":n,"aria-hidden":`true`,"data-qa":`dt-slider-thumb-readout`},(0,a.toDisplayString)((0,a.unref)(V)(e,n)),15,M))),128)),(0,a.unref)(Q)?((0,a.openBlock)(),(0,a.createElementBlock)(`div`,{key:0,ref_key:`mergedReadoutElRef`,ref:be,class:(0,a.normalizeClass)([`d-slider__readout`,`d-slider__readout--show`,t.readoutClass]),style:(0,a.normalizeStyle)((0,a.unref)(Ae)((0,a.unref)(je),(0,a.unref)(we))),"aria-hidden":`true`,"data-qa":`dt-slider-thumb-readout-merged`},(0,a.toDisplayString)((0,a.unref)(Me)),7)):(0,a.createCommentVNode)(``,!0)],64)):(0,a.createCommentVNode)(``,!0),t.readout===`tooltip`?((0,a.openBlock)(!0),(0,a.createElementBlock)(a.Fragment,{key:2},(0,a.renderList)((0,a.unref)(P),(e,t)=>((0,a.openBlock)(),(0,a.createElementBlock)(`div`,{key:`readout-tooltip-${t}`,ref_for:!0,ref:e=>{(0,a.unref)(Z)[t]=e},class:`d-tooltip d-slider__readout-tooltip`,popover:`manual`,inert:``,"aria-hidden":`true`,"data-qa":`dt-slider-thumb-readout-tooltip`},[(0,a.createElementVNode)(`span`,N,(0,a.toDisplayString)((0,a.unref)(V)(e,t)),1)]))),128)):(0,a.createCommentVNode)(``,!0)],36),(0,a.unref)(e.hasSlotContent)(r.$slots.end)?((0,a.openBlock)(),(0,a.createElementBlock)(`div`,{key:1,class:(0,a.normalizeClass)([`d-slider__end`,t.endClass]),"data-qa":`dt-slider-end`},[(0,a.renderSlot)(r.$slots,`end`)],2)):(0,a.createCommentVNode)(``,!0)],2)],16,O))}});Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return P}});
2
+ //# sourceMappingURL=Slider-D2cDYZcJ.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Slider-D2cDYZcJ.cjs","names":["generateInterval","measureEdgeInsetPx","generateInterval","isValidMark","mirrorPct","measureEdgeInsetPx","edgeClampOffset","sameValues","computePosition","offset","flip","shift","size","hide","sameValues","autoUpdate","$attrs","$slots"],"sources":["../components/Slider/SliderConstants.ts","../components/Slider/Composables/UseSliderDevWarnings.js","../components/Slider/Composables/UseSliderDirection.js","../components/Slider/Composables/UseSliderValue.js","../components/Slider/Composables/UseSliderMagneticSnap.js","../components/Slider/Composables/UseSliderInteraction.js","../components/Slider/Composables/UseSliderGeometry.js","../components/Slider/Composables/UseSliderMarksAndTicks.js","../components/Slider/Composables/UseSliderCollisionAvoidance.js","../components/Slider/Composables/UseSliderTooltipReadout.js","../components/Slider/Slider.vue","../components/Slider/Slider.vue"],"sourcesContent":["export const SLIDER_ORIENTATIONS = ['horizontal', 'vertical'] as const;\n\nexport const SLIDER_READOUT_MODES = ['always', 'never', 'tooltip'] as const;\n\nexport const SLIDER_FILL_ORIGINS = ['start', 'end'] as const;\n\nexport const SLIDER_DEFAULT_LARGE_STEP = 10;\n\n// Marks nudge inward beyond this allowance; match the control's own\n// overflow-clip-margin in slider.less. Floating tooltip readouts use the\n// viewport as their boundary instead.\nexport const SLIDER_EDGE_CLAMP_TOLERANCE_PX = 32;\n\n// readout=\"always\" pills get no such allowance: unlike a mark (a small dot\n// the control's own overflow-clip-margin is sized to cover), a readout's\n// text can be arbitrarily wide (locale, suffix, a long getValueText), and a\n// consumer's own wrapper can clip tighter than the control's margin — the\n// 90/120 and \"119 min\" clipping reports both overflowed the control's edge\n// by well under 32px. Zero tolerance nudges a readout inward the instant it\n// would overflow the control's own edge at all, for any value approaching\n// an edge, not only one sitting exactly at min/max (which takes the\n// separate, measurement-free flush-edge path instead).\nexport const SLIDER_READOUT_EDGE_CLAMP_TOLERANCE_PX = 0;\n","import { watch } from 'vue';\n\n// Boolean-sourced watch()es, not watchEffect — hasLabelContent's probe reads\n// currentValue, which changes every drag tick, so a direct watchEffect would\n// re-log constantly; a boolean only fires when the warning condition flips.\n// { immediate: true } (not onMounted) since label/getValueText can legitimately\n// change after mount. Guarded by NODE_ENV per this repo's dev-warning\n// convention (DtButton, DtTextList, DtProse) — consumers' production builds\n// shouldn't log library console calls.\nexport function useSliderDevWarnings(props, { isRange, hasAccessibleName }) {\n if (process.env.NODE_ENV === 'production') return;\n\n watch(\n () => isRange.value && !props.getValueText,\n (missingValueText) => {\n if (missingValueText) {\n console.info(\n '[Dialtone] DtSlider in range mode: provide getValueText to give each thumb a distinct screen-reader description.',\n );\n }\n },\n { immediate: true },\n );\n\n watch(\n () => hasAccessibleName.value,\n (hasName) => {\n if (!hasName) {\n console.info(\n '[Dialtone] DtSlider: provide a label prop (set showLabel to false to hide it visually) or aria-label for accessibility.',\n );\n }\n },\n { immediate: true },\n );\n\n // Every gap computation (UseSliderValue, UseSliderInteraction) rounds\n // minGapSteps to the nearest integer before multiplying by step — a\n // fractional value is silently coerced rather than rejected, so warn\n // instead of leaving the mismatch undiscoverable.\n watch(\n () => props.minGapSteps !== Math.round(props.minGapSteps),\n (isFractional) => {\n if (isFractional) {\n console.info(\n `[Dialtone] DtSlider: minGapSteps (${props.minGapSteps}) is not a whole number — it will be rounded to ${Math.round(props.minGapSteps)}.`,\n );\n }\n },\n { immediate: true },\n );\n\n // clampToRange (UseSliderValue) silently collapses every value to max when\n // min > max, with no indication anything's wrong — this is almost always a\n // prop-wiring bug upstream, not an intentional inverted range.\n watch(\n () => props.min > props.max,\n (isInverted) => {\n if (isInverted) {\n console.info(\n `[Dialtone] DtSlider: min (${props.min}) is greater than max (${props.max}) — every value will collapse to max.`,\n );\n }\n },\n { immediate: true },\n );\n}\n","import { ref, onMounted, onBeforeUnmount } from 'vue';\n\n// RTL/LTR direction tracking, shared by UseSliderInteraction (pointer math,\n// keyboard direction-relative keys), UseSliderGeometry (centerInlineTransform),\n// and UseSliderCollisionAvoidance (mirroring the analytical collision rect) —\n// all three need to agree on the same reactively-cached value instead of each\n// doing its own point-in-time getComputedStyle() read.\nexport function useSliderDirection(controlRef) {\n // Cached, reactive mirror of a live DOM read — getComputedStyle itself\n // isn't reactive, so a runtime dir change on any ancestor (dir is\n // ambient/inherited) would otherwise never re-trigger the template's\n // transform bindings between mount and the next unrelated render. Exposed\n // as isRtl, matching the sibling isRange/isVertical computed-ref shape.\n const isRtl = ref(false);\n\n // Re-reads the control's resolved text direction off the DOM and caches it\n // in isRtl above. Called once on mount, and again whenever dirObserver\n // below sees a relevant dir attribute change.\n function syncDirection() {\n isRtl.value = !!controlRef.value && getComputedStyle(controlRef.value).direction === 'rtl';\n }\n\n // dir is ambient — inherited from ANY ancestor, not just controlRef's direct\n // parent — so every actual ancestor needs its own watch, not just this\n // component's own subtree. Also watches style/class, not just dir — the\n // resolved direction can come from CSS (an inline `direction: rtl` or a\n // class) just as easily, and an attribute-only filter left isRtl stuck\n // stale once the DOM had already mirrored.\n let dirObserver = null;\n\n onMounted(() => {\n syncDirection();\n if (typeof MutationObserver !== 'undefined' && controlRef.value) {\n dirObserver = new MutationObserver(syncDirection);\n const options = { attributes: true, attributeFilter: ['dir', 'style', 'class'] };\n // Only nodes in controlRef's own ancestor chain can affect its\n // resolved direction via CSS cascade — watching the whole document\n // (subtree: true on documentElement) re-ran this on every class/style\n // mutation anywhere on the page, including unrelated siblings, with no\n // debounce.\n for (let node = controlRef.value; node; node = node.parentElement) {\n dirObserver.observe(node, options);\n }\n // Always also watched explicitly, even when not reached by the walk\n // above (e.g. a detached-then-teleported mount) — dir/class toggled on\n // <html> itself is the most common real-world way an app sets RTL.\n dirObserver.observe(document.documentElement, options);\n }\n });\n\n onBeforeUnmount(() => {\n dirObserver?.disconnect();\n });\n\n return { isRtl };\n}\n","import { ref, computed, watch, onMounted } from 'vue';\n\n// Normalizes a possibly-uncontrolled, out-of-contract modelValue into\n// internalValues — clamped, step-snapped, range-ordered, gap-enforced. isRange\n// is prop-derived state, not value normalization, so it's passed in rather\n// than owned here.\nexport function useSliderValue(props, emit, { isRange, activeSnapValue }) {\n // Whether thumbIndex currently holds an active magnetic snap at exactly\n // its present value — reapplying step/gap constraints to it would destroy\n // the (intentionally off-grid) hold for no reason; held values are already\n // clamped within [min, max] by findMagneticSnapPoint itself.\n function isActivelyHeld(thumbIndex, val) {\n return activeSnapValue?.value[thumbIndex] === val;\n }\n // JS stringifies a tiny number in exponential notation (\"5e-7\", not\n // \"0.0000005\") — no \".\" for the plain branch below to find, so this used\n // to report 0 decimal places and silently truncate valid tiny values.\n function decimalPlaces(n) {\n const str = String(n);\n const eIndex = str.search(/e/i);\n if (eIndex !== -1) {\n const mantissa = str.slice(0, eIndex);\n const exponent = parseInt(str.slice(eIndex + 1), 10);\n const mantissaDot = mantissa.indexOf('.');\n const mantissaDecimals = mantissaDot === -1 ? 0 : mantissa.length - mantissaDot - 1;\n return Math.max(0, mantissaDecimals - exponent);\n }\n const dot = str.indexOf('.');\n return dot === -1 ? 0 : str.length - dot - 1;\n }\n\n function clampToRange(val) {\n return Math.min(props.max, Math.max(props.min, val));\n }\n\n // Without this, an off-grid value (from a controlled modelValue or a\n // magnetic snap point) renders correctly in Vue's state but gets silently\n // rounded by the browser the moment it hits the native input's .value —\n // splitting Vue's state from the native control. A non-positive step has no\n // valid grid, so just clamp.\n function snapToStep(val) {\n if (props.step <= 0) return Math.min(props.max, Math.max(props.min, val));\n const steps = Math.round((val - props.min) / props.step);\n const dp = Math.max(decimalPlaces(props.min), decimalPlaces(props.step));\n return Math.min(props.max, Math.max(props.min, parseFloat((props.min + steps * props.step).toFixed(dp))));\n }\n\n // The low thumb's value can never exceed the high thumb's — swap rather than\n // clamp so an inverted pair (e.g. a consumer-supplied [70, 30]) still keeps\n // its intended width instead of collapsing to a single point.\n function normalizeRangeValues(values) {\n if (values.length === 2 && values[0] > values[1]) {\n return [values[1], values[0]];\n }\n return values;\n }\n\n // updateThumbValue (UseSliderInteraction) enforces this gap during drags,\n // but a controlled modelValue or a reactive min/max/step/minGapSteps change\n // bypasses that — this is what keeps those paths honoring the same gap.\n // heldIndex (0 or 1, or null) marks a thumb whose value must be treated as\n // a FIXED anchor — an actively-held magnetic snap, deliberately off-grid —\n // rather than something this function may round or move. Computing the\n // adjustment against the held thumb's raw value (not a snapped stand-in)\n // and skipping the final rounding on it is what keeps the enforced gap\n // accurate; patching the held value back in afterward, once this function\n // already picked a sibling position based on a different number, cannot.\n function enforceRangeGap(values, heldIndex = null) {\n if (values.length !== 2) return values;\n // Rounded — minGapSteps is a COUNT of steps; a fractional value would\n // make the gap not an exact multiple of props.step, breaking the\n // on-grid guarantee every other value in this file relies on.\n const gap = Math.round(props.minGapSteps) * props.step;\n if (gap <= 0) return values;\n let [lo, hi] = values;\n if (hi - lo >= gap) return values;\n if (heldIndex === 0) {\n hi = Math.min(props.max, lo + gap);\n } else if (heldIndex === 1) {\n lo = Math.max(props.min, hi - gap);\n } else if (lo + gap <= props.max) {\n // Try widening hi alone first (lo stays put) — the common case.\n hi = lo + gap;\n } else if (hi - gap >= props.min) {\n // Failing that (it'd overshoot max), shrink lo alone instead of always\n // pinning hi at max: that could freeze a thumb's native min === max\n // even when a less disruptive pair existed, e.g. max=95, step=10,\n // gap=20: [80,90] became [75,95] (frozen) instead of [70,90].\n lo = hi - gap;\n } else {\n // Neither single-ended fix fits the domain at all (dev-warned\n // elsewhere) — only then fall back to pinning hi at max.\n hi = props.max;\n lo = Math.max(props.min, hi - gap);\n }\n // Precision must include max's own decimal places — a hi pinned exactly\n // at a fractional max (e.g. 0.96) rounding at a coarser precision could\n // push it back out of bounds. The clamp after rounding is a second guard\n // against that and ordinary float drift. Skipped for the held index —\n // its whole point is to stay exactly as held, off-grid precision and all.\n // The sibling's computed value inherits whatever precision the held one\n // has (lo + gap, or hi - gap) — a snap point's precision isn't bound by\n // min/max/step at all, so dp must account for it too, or the sibling\n // rounds away digits the held value actually has.\n const dp = Math.max(\n decimalPlaces(props.min), decimalPlaces(props.max), decimalPlaces(props.step),\n heldIndex !== null ? decimalPlaces(values[heldIndex]) : 0,\n );\n if (heldIndex !== 0) lo = Math.min(props.max, Math.max(props.min, parseFloat(lo.toFixed(dp))));\n if (heldIndex !== 1) hi = Math.min(props.max, Math.max(props.min, parseFloat(hi.toFixed(dp))));\n return [lo, hi];\n }\n\n // Every value entering internalValues funnels through here (mount,\n // controlled modelValue changes, reactive min/max/step/minGapSteps changes)\n // so they all get the same guarantees — otherwise an out-of-contract value\n // would split the native input, aria-valuetext, and visual thumb into three\n // disagreeing states. heldIndex (see enforceRangeGap) skips clamping/\n // snapping for that one index too, so its raw value reaches enforceRangeGap\n // unchanged — not just restored afterward, which left the SIBLING'S\n // adjustment computed against a snapped stand-in instead of the real hold.\n function applyValueConstraints(values, heldIndex = null) {\n // A non-finite element (NaN, or a non-numeric value coerced to NaN)\n // would otherwise propagate through Math.min/Math.max in enforceRangeGap\n // and contaminate the OTHER thumb's value too — replace it before\n // anything downstream can see it. Skipped for the held index — a held\n // value is never NaN (it came from a real pointer position).\n let out = values.map((v, i) => (i === heldIndex ? v : (Number.isFinite(v) ? v : defaultValue())));\n out = out.map((v, i) => (i === heldIndex ? v : clampToRange(v)));\n out = out.map((v, i) => (i === heldIndex ? v : snapToStep(v)));\n // A held index can't meaningfully swap sides with its sibling — the\n // crossing clamp that produced the hold in the first place already\n // guarantees it's on the correct side.\n out = out.length === 2 && heldIndex === null ? normalizeRangeValues(out) : out;\n return enforceRangeGap(out, heldIndex);\n }\n\n // Matches native <input type=\"range\">, which defaults an unset value to the\n // midpoint of its range rather than min.\n function defaultValue() {\n return (props.min + props.max) / 2;\n }\n\n function normalizeModelValue(value, heldIndex = null) {\n let raw;\n if (Array.isArray(value)) {\n raw = value.length >= 2 ? [value[0], value[1]] : value.length === 1 ? [value[0]] : [defaultValue()];\n } else {\n raw = value !== undefined && value !== null ? [value] : [defaultValue()];\n }\n return applyValueConstraints(raw, heldIndex);\n }\n\n const internalValues = ref(normalizeModelValue(props.modelValue));\n\n const lastCommittedValues = ref([...internalValues.value]);\n\n // Mirrors the update:modelValue payload shape (Number, or Number[] in range\n // mode) so a custom #label slot can render the live value while dragging.\n const currentValue = computed(() => (isRange.value ? [...internalValues.value] : internalValues.value[0]));\n\n function thumbPercent(val) {\n // A degenerate min === max range has no meaningful position — avoid a\n // division by zero that would otherwise produce NaN and corrupt every\n // positioning/collision calculation downstream.\n if (props.max === props.min) return 0;\n return ((val - props.min) / (props.max - props.min)) * 100;\n }\n\n // Rounds a bound derived from a (possibly off-grid, e.g. an actively held\n // magnetic snap — see thumbNativeStep below) sibling value onto the real\n // step grid, always stricter (min rounds up, max rounds down) so the\n // crossing-prevention guarantee only tightens, never loosens. Without\n // this, native stepMismatch (computed from the input's own min attribute,\n // not props.min) became permanently unsatisfiable for the other thumb.\n // Nothing reachable is lost — the gap between raw and rounded was never\n // on-grid anyway.\n function toGridBound(val, roundUp) {\n if (props.step <= 0) return val;\n const stepsFromMin = (val - props.min) / props.step;\n const rounded = roundUp ? Math.ceil(stepsFromMin - 1e-9) : Math.floor(stepsFromMin + 1e-9);\n return props.min + rounded * props.step;\n }\n\n // The WAI-ARIA multi-thumb pattern requires each thumb's aria-valuemin/max\n // to reflect the OTHER thumb's current position, not a static [min, max] —\n // the low thumb can never reach past (high - gap), and vice versa. Guarded\n // on internalValues having a second thumb at all, not just isRange — an\n // out-of-contract single-element modelValue in range mode must not apply a\n // gap against a thumb that doesn't exist.\n function thumbNativeMin(i) {\n if (!isRange.value || i !== 1 || internalValues.value.length < 2) return props.min;\n const gap = Math.round(props.minGapSteps) * props.step;\n const raw = Math.min(props.max, internalValues.value[0] + gap);\n return Math.min(props.max, toGridBound(raw, true));\n }\n\n function thumbNativeMax(i) {\n if (!isRange.value || i !== 0 || internalValues.value.length < 2) return props.max;\n const gap = Math.round(props.minGapSteps) * props.step;\n const raw = Math.max(props.min, internalValues.value[1] - gap);\n return Math.max(props.min, toGridBound(raw, false));\n }\n\n // internalValues is always on-grid except for one deliberate case: an\n // active magnetic snap point (UseSliderMagneticSnap) intentionally holds an\n // off-grid value while dragging. step=\"any\" for just that thumb, only while\n // off-grid, keeps the browser from fighting it without losing native\n // Home/End/Arrow stepping the rest of the time.\n function thumbNativeStep(i) {\n if (props.step <= 0) return 'any';\n const val = internalValues.value[i];\n if (val === undefined) return props.step;\n const stepsFromMin = (val - props.min) / props.step;\n const isOffGrid = Math.abs(stepsFromMin - Math.round(stepsFromMin)) > 1e-9;\n return isOffGrid ? 'any' : props.step;\n }\n\n // Logged at most once per mount — formatValue runs on every render path\n // (aria-valuetext, every readout style), so an unconditional console.info\n // would flood the console for the whole lifetime of a drag if getValueText\n // keeps misbehaving on every call.\n let hasWarnedGetValueText = false;\n function warnGetValueTextOnce(message) {\n if (process.env.NODE_ENV === 'production' || hasWarnedGetValueText) return;\n hasWarnedGetValueText = true;\n console.info(`[Dialtone] DtSlider: ${message}`);\n }\n\n // Shared by the readout and each thumb's aria-valuetext, so the two always\n // agree on how a value is displayed. Deliberately NOT used for a mark's own\n // auto-generated text — see formatMarkValue (UseSliderMarksAndTicks).\n function formatValue(value, index) {\n if (props.getValueText) {\n try {\n const text = props.getValueText(value, index);\n // A non-string return (e.g. an async getValueText's Promise) would\n // otherwise render literally — String(aPromise) is \"[object Promise]\".\n if (typeof text === 'string') return text;\n warnGetValueTextOnce(`getValueText must return a string synchronously (got ${typeof text}) — falling back to the raw value.`);\n } catch (e) {\n // An uncaught throw here would crash the whole component, not just\n // degrade one value's text.\n warnGetValueTextOnce(`getValueText threw — falling back to the raw value. ${e}`);\n }\n }\n return `${props.prefix}${value}${props.suffix}`;\n }\n\n // ─── Sync controlled modelValue → internalValues ──────────────────────────\n\n watch(\n () => props.modelValue,\n (newVal) => {\n if (newVal === undefined || newVal === null) return;\n const current = internalValues.value;\n const incoming = Array.isArray(newVal) ? newVal : [newVal];\n // A held magnetic snap is intentionally off-grid — normalizeModelValue\n // doesn't know that and re-snaps it onto the step grid regardless. If\n // the parent simply echoed back exactly what we just emitted (the\n // common v-model round trip), there's nothing to correct. Threaded\n // through as heldIndex (not patched on after) so, in range mode, the\n // OTHER thumb's own gap adjustment is computed against the real held\n // value instead of a snapped stand-in. At most one thumb is ever held\n // at a time — a single activePointerId owns any drag.\n const heldIndex = current.findIndex((v, i) => incoming[i] === v && isActivelyHeld(i, v));\n const next = normalizeModelValue(newVal, heldIndex === -1 ? null : heldIndex);\n if (next.length !== current.length || next.some((v, i) => v !== current[i])) {\n // internalValues already diverged from lastCommittedValues means a\n // drag/keyboard interaction is mid-flight and this echo is just our\n // own uncommitted change bouncing back through v-model — overwriting\n // lastCommittedValues here would make that interaction's own commit\n // (commitIfChanged) see no diff and swallow its change event.\n const alreadyUncommitted = current.length !== lastCommittedValues.value.length\n || current.some((v, i) => v !== lastCommittedValues.value[i]);\n internalValues.value = next;\n // An externally-driven value is already \"committed\" — without this,\n // the next blur sees a spurious diff against a stale lastCommittedValues\n // and fires a false change event.\n if (!alreadyUncommitted) {\n lastCommittedValues.value = [...next];\n }\n }\n // normalizeModelValue can rewrite what was passed in (inverted pair,\n // out-of-bounds clamp, invalid length) — that correction must reach the\n // parent's own v-model, or it stays silently out of sync. Safe against\n // feedback loops since normalizeModelValue is idempotent.\n const needsCorrection = next.length !== incoming.length || next.some((v, i) => v !== incoming[i]);\n if (needsCorrection) {\n emit('update:modelValue', Array.isArray(newVal) ? [...next] : next[0]);\n }\n },\n { deep: true },\n );\n\n // Narrowing [min, max], step, or minGapSteps without touching modelValue\n // never fires the watcher above — re-apply the full constraint pipeline so\n // the value can't silently drift out of bounds, off-grid, or inside a\n // now-invalid gap.\n watch(\n () => [props.min, props.max, props.step, props.minGapSteps],\n () => {\n const cur = internalValues.value;\n // If internalValues already differed from lastCommittedValues before\n // this correction, a drag/keyboard interaction is already mid-flight\n // with its own uncommitted delta — this correction is just an\n // intermediate waypoint in that gesture, not a standalone change, so it\n // must not emit 'change' ahead of the interaction's own eventual\n // commit (pointer up / blur).\n const alreadyUncommitted = cur.length !== lastCommittedValues.value.length\n || cur.some((v, i) => v !== lastCommittedValues.value[i]);\n // Same hold-preserving exception as the modelValue watcher above — a\n // held value still within the (possibly just-changed) [min, max]\n // bounds shouldn't be re-snapped onto the grid just because an\n // unrelated reactive prop changed mid-drag. Threaded through as\n // heldIndex so the sibling's gap adjustment is computed correctly too.\n const heldIndex = cur.findIndex((v, i) => isActivelyHeld(i, v) && v >= props.min && v <= props.max);\n const next = applyValueConstraints(cur, heldIndex === -1 ? null : heldIndex);\n if (next.length !== cur.length || next.some((v, i) => v !== cur[i])) {\n internalValues.value = next;\n const payload = isRange.value ? [...next] : next[0];\n emit('update:modelValue', payload);\n if (alreadyUncommitted) return;\n // Unlike the controlled-modelValue watch above, this correction is\n // never something the parent explicitly requested — it's a real,\n // committed change the parent needs to know about (e.g. to persist),\n // not an intermediate drag state. Without this, lastCommittedValues\n // below having already moved on meant the actual transition from the\n // previous value was never reported via 'change' at all.\n lastCommittedValues.value = [...next];\n emit('change', payload);\n }\n },\n );\n\n // The initial modelValue never runs through the watch() above — correct a\n // rewritten starting value back to the parent the same way a later update\n // would, so v-model isn't out of sync from the first paint.\n onMounted(() => {\n if (props.modelValue === undefined || props.modelValue === null) return;\n const incoming = Array.isArray(props.modelValue) ? props.modelValue : [props.modelValue];\n const next = internalValues.value;\n const needsCorrection = next.length !== incoming.length || next.some((v, i) => v !== incoming[i]);\n if (needsCorrection) {\n emit('update:modelValue', Array.isArray(props.modelValue) ? [...next] : next[0]);\n }\n });\n\n return {\n internalValues,\n lastCommittedValues,\n currentValue,\n decimalPlaces,\n snapToStep,\n thumbPercent,\n thumbNativeMin,\n thumbNativeMax,\n thumbNativeStep,\n formatValue,\n };\n}\n","import { ref, computed } from 'vue';\nimport { generateInterval } from '../utils';\n\n// Pixel radius around a snap point where the magnetic pull engages — not\n// exposed as a prop; Brad (PR review) questioned whether consumers would\n// ever need to tune this, and a fixed value keeps the API smaller.\nconst SNAP_THRESHOLD_PX = 10;\n\n// How much wider the release radius is than the entry radius, in units of\n// SNAP_THRESHOLD_PX — lets a snapped thumb resist small jitter near the point\n// instead of flickering in and out right at the entry boundary.\nconst SNAP_RELEASE_MULTIPLIER = 2;\n\nexport function useSliderMagneticSnap(props, { controlRef, isVertical }) {\n // Mirrors computedTickValues' interval generation — a number means \"evenly\n // spaced\", an array is used as-is. [] (snapPoints unset) short-circuits\n // findMagneticSnapPoint below, so this is also what keeps the feature a\n // pure no-op — same code path, same result — for every consumer that\n // doesn't set snapPoints.\n const computedSnapPoints = computed(() => {\n if (props.snapPoints == null) return [];\n if (typeof props.snapPoints === 'number') {\n const interval = props.snapPoints;\n if (!Number.isFinite(interval) || interval <= 0) return [];\n return generateInterval(props.min, props.max, interval, 'snapPoints');\n }\n // A point outside [min, max] can never be a value the thumb is allowed to\n // hold, so it must never be offered as a snap target — otherwise a drag\n // that lands within the snap radius of it would pull the thumb (and the\n // emitted modelValue) out of the slider's own documented range.\n if (!Array.isArray(props.snapPoints)) return [];\n return props.snapPoints.filter((point) => Number.isFinite(point) && point >= props.min && point <= props.max);\n });\n\n // Tracks, per thumb index, the snap point currently held via hysteresis —\n // cleared once a drag moves far enough past SNAP_RELEASE_MULTIPLIER's radius\n // to release it, or once the drag ends.\n const activeSnapValue = ref({});\n\n // Magnetic, not restrictive: only overrides the value within SNAP_THRESHOLD_PX\n // of a point (converted to value-space via the control's rendered size, so\n // the pull feels consistent across any min/max range), else returns null\n // and normal step-quantization proceeds. A pixel radius is what makes this\n // feel like Figma/Photoshop guide-snapping. Releasing needs a wider radius\n // than entering (SNAP_RELEASE_MULTIPLIER) — the \"sticky\" half of that feel.\n function findMagneticSnapPoint(rawVal, thumbIndex) {\n const points = computedSnapPoints.value;\n if (!points.length || !controlRef.value) {\n delete activeSnapValue.value[thumbIndex];\n return null;\n }\n const rect = controlRef.value.getBoundingClientRect();\n const trackSizePx = isVertical.value ? rect.height : rect.width;\n if (!trackSizePx) return null;\n const entryThreshold = (SNAP_THRESHOLD_PX / trackSizePx) * (props.max - props.min);\n\n // Membership check guards a reactive snapPoints change mid-drag —\n // without it, a removed point could stay latched purely because the\n // pointer hadn't yet drifted past its (now-irrelevant) release radius.\n const heldValue = activeSnapValue.value[thumbIndex];\n if (heldValue != null && points.includes(heldValue)) {\n const releaseThreshold = entryThreshold * SNAP_RELEASE_MULTIPLIER;\n if (Math.abs(heldValue - rawVal) <= releaseThreshold) {\n return heldValue;\n }\n }\n\n let closest = null;\n let closestDist = Infinity;\n for (const point of points) {\n const dist = Math.abs(point - rawVal);\n if (dist <= entryThreshold && dist < closestDist) {\n closest = point;\n closestDist = dist;\n }\n }\n\n if (closest == null) {\n delete activeSnapValue.value[thumbIndex];\n } else {\n activeSnapValue.value[thumbIndex] = closest;\n }\n return closest;\n }\n\n return {\n activeSnapValue,\n findMagneticSnapPoint,\n };\n}\n","import { ref, watch, nextTick } from 'vue';\nimport { measureEdgeInsetPx } from '../utils';\n\n// Keys that actually navigate the thumb's value (natively or via\n// largeStepDelta below) — used to scope the Escape-dismissal reopen to real\n// navigation, not every keydown the thumb receives (a bare modifier press\n// like Shift/Control, held with focus but no navigation, shouldn't reopen a\n// tooltip the user just dismissed).\nconst THUMB_NAV_KEYS = new Set([\n 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'Home', 'End', 'PageUp', 'PageDown',\n]);\n\n// Pointer drag, native keyboard events, focus/hover tracking, and the\n// interactive value-update path (updateThumbValue/commitIfChanged) — as\n// opposed to UseSliderValue's normalization of externally-driven changes.\nexport function useSliderInteraction(props, emit, {\n controlRef,\n thumbRefs,\n internalValues,\n isRange,\n isVertical,\n decimalPlaces,\n snapToStep,\n lastCommittedValues,\n findMagneticSnapPoint,\n activeSnapValue,\n isRtl,\n}) {\n const isDragging = ref(false);\n const activeThumbIndex = ref(null);\n // Unlike activeThumbIndex (cleared on pointerup so the --active visual class\n // turns off), this persists across drags — it's what lets a pointerdown on\n // two coincident thumbs route to whichever one wasn't grabbed last time,\n // instead of always defaulting back to the same thumb once they touch.\n const lastActiveThumbIndex = ref(null);\n const focusedThumbIndex = ref(null);\n const hoveredThumbIndex = ref(null);\n // Escape's job is \"suppress until the next real show-trigger\", not \"turn\n // off forever\" — DtTooltip's own onLeaveAnchor does the same thing\n // (internalShow = false, reopens on the next mouseenter/focusin). Reusing\n // focused/hoveredThumbIndex for this would force Escape to blur the thumb\n // to take effect, losing further keyboard nav — so it's tracked separately\n // and cleared by whichever handler fires on the next genuine trigger.\n const escapeDismissedIndex = ref(null);\n // Not reactive on purpose: set synchronously right before a pointer-driven\n // focus() call and read/cleared synchronously in the 'focus' handler it\n // triggers, within the same task. See onPointerDown.\n let isPointerFocus = false;\n\n // Not reactive — which pointer owns the current drag. setPointerCapture\n // only retargets POINTER events for this pointerId; an unrelated second\n // pointer (e.g. a second touch) still reaches the same listeners, and its\n // pointerup could otherwise end and commit the real drag, leaving the\n // owning pointer's further movement silently inert.\n let activePointerId = null;\n\n // Not reactive — whether THIS drag's own pointerdown landed on an already-\n // coincident pair, the only case resolveCoincidentHandoff should apply in.\n // A drag that grabbed a clearly distinct thumb and happens to converge with\n // its sibling mid-gesture should stop there, not hand off mid-flight.\n let dragStartedCoincident = false;\n\n // A consumer can flip :disabled reactively while a thumb is focused or\n // hovered — the native input's own focus ring clears automatically, but\n // focusedThumbIndex/hoveredThumbIndex are separate internal state (also\n // drive the tooltip readout), so without this they'd keep pointing at\n // a thumb that's no longer interactive, leaving its focus ring/readout\n // stuck open.\n watch(\n () => props.disabled,\n (isDisabled) => {\n if (isDisabled) {\n focusedThumbIndex.value = null;\n hoveredThumbIndex.value = null;\n }\n },\n );\n\n // A controlled modelValue switching from range to single mode shrinks\n // internalValues (and thumbRefs, via its self-cleaning function ref) to\n // length 1 — unmounting thumb index 1's native input. If it held focus,\n // the browser drops focus to <body> with nothing to restore it, silently\n // breaking keyboard navigation. Restore it to the one remaining thumb.\n watch(\n () => internalValues.value.length,\n (newLength, oldLength) => {\n // focusedThumbIndex alone misses a pointer-driven drag — onPointerDown\n // deliberately never sets it (see isPointerFocus/onThumbFocus above), so\n // the far more common mouse-drag-then-shrink case needs the real DOM\n // focus as a second signal, checked before the unmount this tick is about\n // to cause moves it to <body>.\n const wasFocused = focusedThumbIndex.value === 1 || document.activeElement === thumbRefs.value[1];\n if (newLength === 1 && oldLength === 2 && wasFocused) {\n nextTick(() => thumbRefs.value[0]?.focus());\n }\n // An external modelValue update mid-drag (e.g. range -> single) can\n // shrink internalValues below the thumb being dragged — the next\n // pointermove would still target that now-gone index (its own guard\n // only checks for null), recreating a second input the public model no\n // longer has. isDragging is left alone; the eventual pointerup/\n // pointercancel still arrives and ends it normally.\n if (activeThumbIndex.value !== null && activeThumbIndex.value >= newLength) {\n activeThumbIndex.value = null;\n }\n },\n );\n\n // ─── Value update ─────────────────────────────────────────────────────────\n\n function updateThumbValue(thumbIndex, newVal, { allowSnap = false } = {}) {\n let clamped = Math.min(props.max, Math.max(props.min, newVal));\n const magneticValue = allowSnap ? findMagneticSnapPoint(clamped, thumbIndex) : null;\n clamped = magneticValue ?? snapToStep(clamped);\n\n const next = [...internalValues.value];\n\n if (isRange.value) {\n // The low thumb can never pass the high thumb (and vice versa) — they\n // may only meet. minGapSteps, when set, widens this into a\n // larger required gap instead of a bare touch. Clamped to 0 — an\n // unvalidated negative minGapSteps would otherwise flip the sign below\n // and invert the crossing clamp instead of disabling it.\n // Rounded — minGapSteps is a COUNT of steps, and a fractional value\n // would make this gap not a multiple of props.step, so the\n // re-quantize in onPointerUp could never land back on-grid once this\n // clamp pulls the value to the boundary.\n const gap = Math.max(0, Math.round(props.minGapSteps) * props.step);\n if (thumbIndex === 0) {\n clamped = Math.min(clamped, (next[1] ?? props.max) - gap);\n } else {\n clamped = Math.max(clamped, (next[0] ?? props.min) + gap);\n }\n\n // Whether the crossing clamp above left an active magnetic snap point\n // untouched — if so, keep that exact (deliberately off-grid) value\n // instead of re-rounding it below, which used to clear a magnetic hold\n // the clamp never actually touched (single-thumb mode has no crossing\n // clamp and always held it correctly).\n const heldMagneticValue = magneticValue != null && clamped === magneticValue;\n if (!heldMagneticValue) {\n // gap is a product of two decimals (e.g. 3 * 0.1) and can carry IEEE-754\n // noise (0.30000000000000004) that snapToStep's rounding, applied\n // earlier in this function, never sees — round it out the same way\n // before it reaches internalValues/the emitted modelValue.\n const dp = Math.max(decimalPlaces(props.min), decimalPlaces(props.step));\n clamped = parseFloat(clamped.toFixed(dp));\n clamped = Math.min(props.max, Math.max(props.min, clamped));\n }\n\n // The crossing clamp above can pull the thumb away from the magnetic\n // point findMagneticSnapPoint just latched hysteresis onto — the thumb\n // never actually reached it. Left uncleared, hysteresis keeps comparing\n // future drag positions against that unreachable point and can freeze\n // the thumb at the other thumb's boundary across a wide swath of the\n // release radius. Clearing it lets the next move re-evaluate fresh.\n if (magneticValue != null && clamped !== magneticValue) {\n delete activeSnapValue.value[thumbIndex];\n }\n }\n\n if (next[thumbIndex] === clamped) {\n // Nothing logically changed, but a native keyboard step (plain Arrow/\n // Home/End) may have already written a different value into the native\n // input's own DOM .value — it isn't range-clamped the way this is.\n // Vue's :value binding won't re-patch an unchanged reactive value, so\n // correct the DOM directly or it silently drifts from internalValues.\n const el = thumbRefs.value[thumbIndex];\n if (el && el.value !== String(clamped)) {\n el.value = String(clamped);\n }\n return;\n }\n next[thumbIndex] = clamped;\n internalValues.value = next;\n\n const payload = isRange.value ? [...next] : next[0];\n emit('update:modelValue', payload);\n }\n\n function commitIfChanged() {\n const cur = internalValues.value;\n const last = lastCommittedValues.value;\n const changed = cur.length !== last.length || cur.some((v, i) => v !== last[i]);\n if (!changed) return;\n lastCommittedValues.value = [...cur];\n const payload = isRange.value ? [...cur] : cur[0];\n emit('change', payload);\n }\n\n // ─── Pointer drag ─────────────────────────────────────────────────────────\n\n // Resolved once per gesture (onPointerDown), not on every pointermove —\n // --slider-edge-inset is effectively static for the duration of a single\n // drag, and remeasuring via a DOM probe on every move event would mean\n // inserting/removing a node per frame.\n let cachedEdgeInsetPx = 0;\n\n function getValueFromPointerEvent(event) {\n const rect = controlRef.value.getBoundingClientRect();\n const sizePx = isVertical.value ? rect.height : rect.width;\n // Mirrors anchorPct's own inset band (UseSliderGeometry) — the thumb's\n // rendered position is compressed into [inset, size - inset], not flush\n // across the control's full true edges, so the inverse (pointer position\n // -> value) has to apply the same compression. Without this, clicking\n // exactly on the rendered thumb at min/max computes a few percent off\n // from 0/100 instead of landing on it, since the raw pointer position\n // spans the whole control while the thumb itself stops short of it.\n const span = sizePx - 2 * cachedEdgeInsetPx;\n let pct;\n if (isVertical.value) {\n // Distance from the bottom edge — matches thumbPositionStyle's own\n // `bottom: anchorPct(pct)`.\n const rawPx = rect.bottom - event.clientY;\n pct = span > 0 ? (rawPx - cachedEdgeInsetPx) / span : rawPx / sizePx;\n } else {\n const rawPx = event.clientX - rect.left;\n pct = span > 0 ? (rawPx - cachedEdgeInsetPx) / span : rawPx / sizePx;\n // The visual track is positioned with insetInlineStart, so the browser\n // already mirrors it under dir=\"rtl\" — min renders on the physical right\n // instead of the left. clientX is always a physical coordinate, so the\n // pointer-to-value mapping has to mirror the same way by hand.\n if (isRtl.value) pct = 1 - pct;\n }\n pct = Math.min(1, Math.max(0, pct));\n return props.min + pct * (props.max - props.min);\n }\n\n function getNearestThumbIndex(val) {\n if (!isRange.value || internalValues.value.length < 2) return 0;\n const [lo, hi] = internalValues.value;\n if (lo === hi) {\n // When thumbs overlap, route to the one opposite last-active\n return lastActiveThumbIndex.value === 0 ? 1 : 0;\n }\n return Math.abs(val - lo) <= Math.abs(val - hi) ? 0 : 1;\n }\n\n // Only meaningful when a drag STARTS on a coincident pair (see\n // dragStartedCoincident in onPointerDown) — which thumb that initial touch\n // actually means to grab is genuinely ambiguous, unlike a drag that picked\n // a clearly distinct thumb and simply happened to reach its sibling along\n // the way (that one should stop there, same as a plain keyboard press).\n // Without this, the active thumb can be pinned at its sibling by the\n // crossing clamp (low can never pass high) with no way to free it for the\n // rest of this same gesture. Hands off to the sibling, which this same\n // move CAN actually satisfy.\n function resolveCoincidentHandoff(idx, rawVal) {\n if (!isRange.value) return idx;\n const [lo, hi] = internalValues.value;\n if (lo !== hi) return idx;\n if (idx === 0 && rawVal > lo) return 1;\n if (idx === 1 && rawVal < hi) return 0;\n return idx;\n }\n\n function onPointerDown(event) {\n if (props.disabled) return;\n // Only handle primary pointer button\n if (event.pointerType === 'mouse' && event.button !== 0) return;\n // A second pointer touching down mid-drag must not steal ownership —\n // the real pointer's own eventual pointerup would then be evaluated\n // against the hijacked activePointerId and silently dropped by the\n // ownership guard in onPointerMove/onPointerUp, stranding the drag with\n // no commit and isDragging stuck true.\n if (isDragging.value && event.pointerId !== activePointerId) return;\n\n // Suppresses the browser's native mousedown default action, which would\n // otherwise shift focus to the nearest scrollable ancestor after our own\n // thumbRefs.focus() call below runs.\n event.preventDefault();\n\n cachedEdgeInsetPx = measureEdgeInsetPx(controlRef.value);\n\n const rawVal = getValueFromPointerEvent(event);\n const idx = getNearestThumbIndex(rawVal);\n const [lo, hi] = internalValues.value;\n dragStartedCoincident = isRange.value && internalValues.value.length === 2 && lo === hi;\n\n if (escapeDismissedIndex.value === idx) escapeDismissedIndex.value = null;\n activeThumbIndex.value = idx;\n lastActiveThumbIndex.value = idx;\n isDragging.value = true;\n activePointerId = event.pointerId;\n controlRef.value.setPointerCapture(event.pointerId);\n // Pointer capture routes every subsequent pointer event to controlRef, so\n // the non-dragged thumb's own pointerenter/pointerleave never fire again\n // once the drag starts — without this, a thumb hovered right before the\n // drag began would keep its tooltip readout stuck open for the rest\n // of the drag. The dragged thumb's own readout is unaffected — it's driven\n // by activeThumbIndex, not hoveredThumbIndex.\n hoveredThumbIndex.value = null;\n\n updateThumbValue(idx, rawVal, { allowSnap: true });\n // Marks the focus() below as pointer-driven so onThumbFocus skips the\n // keyboard-focus ring — :focus-visible can't tell, since browsers treat\n // range inputs as always focus-visible on click. Only call focus() when\n // the thumb isn't already active: an already-focused element fires no\n // 'focus' event, so the flag would never clear and would corrupt the\n // next real keyboard focus.\n const thumbEl = thumbRefs.value[idx];\n if (thumbEl && document.activeElement !== thumbEl) {\n isPointerFocus = true;\n thumbEl.focus();\n } else if (focusedThumbIndex.value === idx) {\n // Already keyboard-focused, so focus() above is skipped (no 'focus'\n // event fires) — clear the ring by hand, or it'd stay combined with\n // the --active drag style even though input switched to pointer.\n focusedThumbIndex.value = null;\n }\n }\n\n function onPointerMove(event) {\n if (!isDragging.value || activeThumbIndex.value === null) return;\n // Pointer capture only retargets the owning pointer's events — an\n // unrelated second pointer's own move/up/cancel still reaches this.\n if (event.pointerId !== activePointerId) return;\n\n // A consumer can flip :disabled reactively mid-drag (e.g. async\n // validation) — stop accepting input immediately rather than waiting for\n // the pointer to be released, matching a native disabled control.\n if (props.disabled) {\n onPointerUp();\n return;\n }\n\n // The primary button can be released outside this document (e.g. over a\n // parent frame, or outside the OS window) without a pointerup ever\n // reaching us, leaving isDragging stuck true. event.buttons reflects the\n // actual current button state, so this self-heals on the next move.\n if (event.buttons === 0) {\n onPointerUp();\n return;\n }\n\n const rawVal = getValueFromPointerEvent(event);\n const idx = dragStartedCoincident\n ? resolveCoincidentHandoff(activeThumbIndex.value, rawVal)\n : activeThumbIndex.value;\n if (idx !== activeThumbIndex.value) {\n // The abandoned thumb is no longer being dragged — updateThumbValue\n // (and the findMagneticSnapPoint call inside it) will never run for\n // its index again this gesture, so its old hold would otherwise sit\n // there stale, read as \"actively held\" by UseSliderValue's watchers\n // long after the handoff moved on.\n delete activeSnapValue.value[activeThumbIndex.value];\n if (escapeDismissedIndex.value === idx) escapeDismissedIndex.value = null;\n activeThumbIndex.value = idx;\n lastActiveThumbIndex.value = idx;\n }\n\n updateThumbValue(idx, rawVal, { allowSnap: true });\n }\n\n // Same off-grid detection as UseSliderValue's thumbNativeStep (duplicated\n // rather than threaded through as a dependency for one caller) — also\n // naturally false for a non-finite value, so it can't misfire there.\n function isOffGrid(val) {\n if (props.step <= 0) return false;\n const stepsFromMin = (val - props.min) / props.step;\n return Math.abs(stepsFromMin - Math.round(stepsFromMin)) > 1e-9;\n }\n\n // event is omitted for the internal end-of-drag calls above (disabled\n // flip, buttons===0 self-heal) — our own decision, not a pointer event to\n // validate. A real pointerup/pointercancel always passes one.\n function onPointerUp(event) {\n if (!isDragging.value) return;\n if (event && event.pointerId !== activePointerId) return;\n isDragging.value = false;\n activePointerId = null;\n // A magnetic snap point can leave the thumb off the step grid (fine\n // while dragging — thumbNativeStep sets step=\"any\" for it) — but left in\n // place, the NEXT plain Arrow-key press is handled natively using\n // step=\"any\"'s own default increment instead of props.step. Re-quantize\n // onto the grid now that the drag has ended.\n const idx = activeThumbIndex.value;\n if (idx !== null && isOffGrid(internalValues.value[idx])) {\n updateThumbValue(idx, internalValues.value[idx]);\n }\n commitIfChanged();\n activeThumbIndex.value = null;\n activeSnapValue.value = {};\n }\n\n // ─── Keyboard events on native inputs ──────────────────────────────────────\n\n function onThumbInput(i, event) {\n // Fires from native arrow keys / Home / End on the hidden input\n updateThumbValue(i, Number(event.target.value));\n }\n\n // +1/-1/0 for a largeStep nudge, or 0 for any other key. increaseKey/\n // decreaseKey are resolved by the caller (onThumbKeydown) rather than here,\n // so this stays a flat, low-complexity lookup — see the comment there for\n // why they're sometimes 'ArrowLeft'/'ArrowRight' and sometimes swapped.\n function largeStepDelta(key, shiftKey, increaseKey, decreaseKey) {\n if (key === 'PageUp') return 1;\n if (key === 'PageDown') return -1;\n if (!shiftKey) return 0;\n if (key === 'ArrowUp' || key === increaseKey) return 1;\n if (key === 'ArrowDown' || key === decreaseKey) return -1;\n return 0;\n }\n\n // Rounding largeStep to the NEAREST step-grid point can round backward to\n // the start value when step is more than ~2x largeStep (step=25,\n // largeStep=10: 100+10=110 rounds back to 100 — a silent no-op). Converting\n // to a whole number of steps first, at least one, guarantees it always moves.\n function largeStepValue() {\n if (props.step <= 0) return props.largeStep;\n const stepsCount = Math.max(1, Math.round(props.largeStep / props.step));\n return stepsCount * props.step;\n }\n\n function onThumbKeydown(i, event) {\n // focus() only fires once per session, so a click-to-focus then keyboard\n // nav would never show the ring without setting this explicitly.\n if (focusedThumbIndex.value !== i) {\n focusedThumbIndex.value = i;\n }\n\n // The native input swaps which of Left/Right increments under dir=\"rtl\" —\n // largeStepDelta's Shift+Arrow must swap the same way, or Shift+ArrowRight\n // would contradict plain ArrowRight on the same key. Up/Down never swap.\n // Applies in vertical mode too — aria-orientation is purely an ARIA hint,\n // the native input is never actually reoriented, so dir still swaps Left/\n // Right there exactly as it does horizontally.\n const rtlKeys = isRtl.value;\n const increaseKey = rtlKeys ? 'ArrowLeft' : 'ArrowRight';\n const decreaseKey = rtlKeys ? 'ArrowRight' : 'ArrowLeft';\n const delta = largeStepDelta(event.key, event.shiftKey, increaseKey, decreaseKey);\n if (delta !== 0) {\n event.preventDefault();\n updateThumbValue(i, internalValues.value[i] + delta * largeStepValue());\n }\n // Matches DtTooltip's own Escape handling: dismiss without moving focus,\n // so nav keys on this thumb still work afterward. A THUMB_NAV_KEYS press\n // (even Home/End/plain arrows, which are handled natively above) is a\n // fresh show-trigger — same convention as onPointerDown/the coincident\n // handoff/onThumbFocus/onThumbHitPointerEnter below, all of which clear\n // the dismissal on their own re-trigger. Scoped to nav keys specifically\n // (not \"any key\") so a bare modifier press — Shift/Control held with\n // focus but no actual navigation — doesn't reopen a tooltip the user just\n // dismissed. Without this, continuing to arrow-step the value after an\n // Escape would leave the readout hidden until blur+refocus or mouse\n // leave+re-enter, unlike drag (which does re-trigger it).\n if (event.key === 'Escape') {\n escapeDismissedIndex.value = i;\n } else if (THUMB_NAV_KEYS.has(event.key) && escapeDismissedIndex.value === i) {\n escapeDismissedIndex.value = null;\n }\n // Plain arrow keys, Home, End handled natively by <input type=\"range\">\n // (also RTL-aware natively, so no extra handling needed here).\n }\n\n function onThumbFocus(i, event) {\n // Skip the keyboard-focus ring and focus-driven tooltip readout for a\n // pointer-driven focus — a mouse drag already gets its own affordance via\n // activeThumbIndex while the pointer is down. Tab/keyboard focus falls\n // through and sets focusedThumbIndex normally.\n if (isPointerFocus) {\n isPointerFocus = false;\n } else {\n if (escapeDismissedIndex.value === i) escapeDismissedIndex.value = null;\n focusedThumbIndex.value = i;\n }\n emit('focus', event);\n }\n\n function onThumbBlur(i, event) {\n focusedThumbIndex.value = null;\n commitIfChanged();\n emit('blur', event);\n }\n\n function onThumbHitPointerEnter(i) {\n if (escapeDismissedIndex.value === i) escapeDismissedIndex.value = null;\n hoveredThumbIndex.value = i;\n }\n\n function onThumbHitPointerLeave(i) {\n if (hoveredThumbIndex.value === i) hoveredThumbIndex.value = null;\n }\n\n function isReadoutOpen(i) {\n if (props.readout === 'always') return true;\n if (escapeDismissedIndex.value === i) return false;\n return activeThumbIndex.value === i || focusedThumbIndex.value === i || hoveredThumbIndex.value === i;\n }\n\n return {\n isDragging,\n activeThumbIndex,\n focusedThumbIndex,\n hoveredThumbIndex,\n updateThumbValue,\n commitIfChanged,\n onPointerDown,\n onPointerMove,\n onPointerUp,\n onThumbInput,\n onThumbKeydown,\n onThumbFocus,\n onThumbBlur,\n onThumbHitPointerEnter,\n onThumbHitPointerLeave,\n isReadoutOpen,\n };\n}\n","import { computed } from 'vue';\n\n// Pure positioning math shared by every element placed along the track\n// (thumb, tick, mark, readout, indicator) — no DOM reads, just props +\n// reactive state from UseSliderValue/UseSliderDirection/\n// UseSliderCollisionAvoidance (markEdgeOffsetPx).\nexport function useSliderGeometry(props, {\n isVertical,\n isRange,\n internalValues,\n thumbPercent,\n isRtl,\n markEdgeOffsetPx,\n formatValue,\n}) {\n // Shared by every track element — they only differ in which transform\n // re-centers them. insetInlineStart (not left) so the browser itself\n // mirrors under dir=\"rtl\"; see UseSliderInteraction for the other two\n // places RTL needs explicit handling instead (pointer math, Shift+Arrow).\n function positionStyle(pct, transform) {\n const style = isVertical.value ? { bottom: `${pct}%` } : { insetInlineStart: `${pct}%` };\n if (transform) style.transform = transform;\n return style;\n }\n\n // translateX(-50%) centers an element on its insetInlineStart anchor — but\n // unlike insetInlineStart, transform never mirrors under dir=\"rtl\", so the\n // shift has to flip sign by hand (+50%) once the anchor itself mirrors, or\n // the element renders a full width away from its anchor. Applies regardless\n // of orientation — insetInlineStart centers the track/thumb on the inline\n // axis even in vertical mode.\n function centerInlineTransform() {\n return isRtl.value ? '50%' : '-50%';\n }\n\n // The usable area the thumb (and ticks, which share its travel band)\n // anchor within — defined once in slider.less (--slider-edge-inset) as the\n // thumb's own worst-case rendered radius (the --active state's 1.05x drag\n // scale bump included; its border is already inside that size, box-sizing:\n // border-box — see --slider-edge-inset's own comment), so the thumb can\n // never render past a consumer's own `overflow: hidden` wrapper.\n // .d-slider__track itself stays flush with the true 0%/100% edges\n // regardless — only the indicator's own thumb-tracking edges reuse this\n // same band (see indicatorStyle), so they land under the thumb instead of\n // poking past it. See --slider-edge-inset's own comment for why this can't\n // just be .d-slider__control's own (much more generous, but internal-only)\n // overflow-clip-margin.\n const EDGE_INSET = 'var(--slider-edge-inset)';\n\n // (100% - inset*2) * pct/100 + inset: a percentage and a px length combine\n // into one calc() value when multiplied by a unitless number, so this\n // rescales [0, 100]% onto [inset, 100% - inset] without ever needing the\n // control's actual measured width. Shared by thumbPositionStyle and\n // tickPositionStyle below — every tick (not just the edge ones) is\n // rescaled onto this same band, so spacing between ticks stays even\n // rather than only the edges standing out as special cases. Prefix/suffix\n // hoisted once since EDGE_INSET's own text never changes between calls.\n const ANCHOR_PCT_PREFIX = `calc(${EDGE_INSET} + (100% - ${EDGE_INSET} * 2) * `;\n const ANCHOR_PCT_SUFFIX = ')';\n\n function anchorPct(pct) {\n return `${ANCHOR_PCT_PREFIX}${pct / 100}${ANCHOR_PCT_SUFFIX}`;\n }\n\n // Width/height between two anchored positions collapses to a pure function\n // of their percentage delta — anchorPct(a) - anchorPct(b), with a - b ==\n // deltaPct, cancels both EDGE_INSET terms down to this. Used by\n // indicatorStyle wherever its span sits between two values on the same\n // anchored scale as the thumb (both thumbs in range mode, or a fillOrigin\n // value and a thumb) — staying on that same scale is what lets the\n // indicator's own edge land under the thumb that's covering it, instead of\n // poking past the thumb's own rendered radius.\n function anchorSpanPct(deltaPct) {\n return `calc((100% - ${EDGE_INSET} * 2) * ${deltaPct / 100})`;\n }\n\n // Shared by thumbPositionStyle and tickPositionStyle — both anchor onto\n // the same inset band regardless of orientation, differing only in which\n // transform re-centers them. Vertical used to fall through to\n // positionStyle's raw pct% (no inset at all) — the thumb's own radius\n // poked past the control's block-start/end edge at 0/100 exactly the same\n // way it did on the inline axis before this inset existed.\n function anchoredPositionStyle(val, { verticalTransform, horizontalTransform }) {\n const pct = thumbPercent(val);\n if (isVertical.value) {\n return { bottom: anchorPct(pct), transform: verticalTransform };\n }\n return {\n insetInlineStart: anchorPct(pct),\n transform: horizontalTransform,\n };\n }\n\n function thumbPositionStyle(val) {\n return anchoredPositionStyle(val, {\n verticalTransform: `translate(${centerInlineTransform()}, 50%)`,\n horizontalTransform: `translate(${centerInlineTransform()}, -50%)`,\n });\n }\n\n function tickPositionStyle(val) {\n return anchoredPositionStyle(val, {\n verticalTransform: 'translateY(50%)',\n horizontalTransform: `translateX(${centerInlineTransform()})`,\n });\n }\n\n // A mark at min/max nudges 1px inward from the true 0%/100% edge instead\n // of centering like every other one — centering ignores the mark's own\n // width, which pokes it ~1px past the edge. Pure flush (an unadorned 0%/\n // 100%) reads as touching the label above it instead of a deliberately\n // placed mark. RTL-mirrored like centerInlineTransform: \"inward\" is a\n // physical direction that flips with which edge actually sits on which\n // side.\n function markEdgeInsetTransform(edge) {\n const inward = isRtl.value ? -1 : 1; // mirrors centerInlineTransform's own RTL flip\n if (edge === 'start') return `translateX(${inward}px)`;\n const flushPct = isRtl.value ? '100%' : '-100%';\n return `translateX(calc(${flushPct} + ${-inward}px))`;\n }\n\n // Shared by markStyle's own non-edge case — a value mark (or the\n // readout='always' pill, which calls markStyle with no index/edge) has to\n // anchor onto the same inset band as the thumb it tracks (anchorPct), not\n // the track's raw flush percentage — otherwise it drifts up to a full\n // --slider-edge-inset away from the thumb it's meant to line up with as\n // the value nears min/max. Mirrors anchoredPositionStyle's horizontal arm;\n // no vertical arm needed since marks/readouts share positionStyle's own\n // bottom-only vertical anchor.\n function anchoredMarkStyle(pct, transform) {\n const style = isVertical.value ? { bottom: anchorPct(pct) } : { insetInlineStart: anchorPct(pct) };\n if (transform) style.transform = transform;\n return style;\n }\n\n // A mark beyond the edge-clamp tolerance of the control's edge (see\n // UseSliderCollisionAvoidance, which measures and populates\n // markEdgeOffsetPx) gets nudged inward by that excess so its text stays\n // legible instead of being clipped. Guarded by !isVertical here (not just\n // where the offset is computed) so a stale offset from a prior horizontal\n // render can never leak into vertical mode's own transform (translateY,\n // not translateX) if orientation changes reactively.\n function markStyle(pct, index, edge) {\n if (edge && !isVertical.value) return positionStyle(pct, markEdgeInsetTransform(edge));\n const offset = !isVertical.value ? markEdgeOffsetPx.value[index] : 0;\n // No transform here — the base case's centering is CSS's own job\n // (.d-slider__mark / .d-slider__readout's own translateX(-50%), flipped\n // under :dir(rtl)), same as it always was; only the anchor position\n // itself needed to change.\n if (!offset) return anchoredMarkStyle(pct);\n return anchoredMarkStyle(pct, `translateX(calc(${centerInlineTransform()} + ${offset}px))`);\n }\n\n // Same anchored positioning + edge-nudge transform as markStyle, for the\n // readout='always' pill(s) — kept separate rather than overloading\n // markStyle's own index-based lookup: marks look their offset up by index\n // into a shared computedMarks-sized array, but a readout's offset is\n // either per-thumb or the merged pill's own scalar (UseSliderCollisionAvoidance's\n // readoutEdgeOffsetPx / mergedReadoutEdgeOffsetPx) — no shared index space\n // between the two, so the caller passes the resolved px value directly.\n //\n // edge mirrors markStyle's own edge case: a readout tracking a thumb\n // sitting exactly at min/max flush-aligns its own edge instead of\n // centering, same as a mark there — the label then only ever extends\n // INWARD from the true edge, never past it, regardless of the label's\n // own (unbounded, locale/suffix/getValueText-dependent) text width. This\n // is what actually fixes clipping against an arbitrary consumer\n // overflow:hidden wrapper structurally, with no measurement needed —\n // readoutEdgeOffsetPx's measured nudge only covers values NEAR but not\n // exactly at an edge, and (being clamped against the control's own edge,\n // not any specific ancestor's) can't fully cover an external wrapper\n // tighter than the control's own overflow-clip-margin tolerance.\n function readoutStyle(pct, offsetPx, edge) {\n if (edge && !isVertical.value) return positionStyle(pct, markEdgeInsetTransform(edge));\n // Same !isVertical.value guard as markStyle's own offset lookup above —\n // UseSliderCollisionAvoidance's offset refs lag a reactive isVertical\n // flip by one tick (its own watcher is async), so without this a stray\n // translateX could leak into one render of the vertical (bottom-based)\n // position before that watcher re-zeroes it.\n const offset = !isVertical.value ? offsetPx : 0;\n if (!offset) return anchoredMarkStyle(pct);\n return anchoredMarkStyle(pct, `translateX(calc(${centerInlineTransform()} + ${offset}px))`);\n }\n\n const mergedReadoutPct = computed(() => {\n if (!isRange.value || internalValues.value.length !== 2) return 0;\n const [lo, hi] = internalValues.value;\n return (thumbPercent(lo) + thumbPercent(hi)) / 2;\n });\n\n const mergedReadoutText = computed(() => {\n if (!isRange.value || internalValues.value.length !== 2) return '';\n const [lo, hi] = internalValues.value;\n return `${formatValue(lo, 0)}–${formatValue(hi, 1)}`;\n });\n\n // Every edge that tracks an actual thumb value anchors onto the same\n // inset band as the thumb itself (anchorPct/anchorSpanPct) — not the raw\n // percentage .d-slider__track uses — so that edge always lands under the\n // thumb's own rendered circle instead of poking a sliver of color past it\n // (the thumb is wide enough to cover the gap this leaves against the\n // track's own flush edge; see --slider-edge-inset's comment in slider.less).\n // The one edge with no thumb anywhere near it — the default mode's fixed\n // fillOrigin end — has nothing to hide a mismatch under, so it stays\n // literally flush at 0/100%, same as the track.\n const indicatorStyle = computed(() => {\n if (isRange.value && internalValues.value.length === 2) {\n const [lo, hi] = internalValues.value;\n const loP = thumbPercent(lo);\n const hiP = thumbPercent(hi);\n if (isVertical.value) {\n return { bottom: anchorPct(loP), height: anchorSpanPct(hiP - loP) };\n }\n return { insetInlineStart: anchorPct(loP), width: anchorSpanPct(hiP - loP) };\n }\n\n const pct = thumbPercent(internalValues.value[0] ?? props.min);\n\n if (typeof props.fillOrigin === 'number') {\n const originPct = thumbPercent(Math.min(props.max, Math.max(props.min, props.fillOrigin)));\n const startPct = Math.min(pct, originPct);\n const sizePct = Math.abs(pct - originPct);\n if (isVertical.value) {\n return { bottom: anchorPct(startPct), height: anchorSpanPct(sizePct) };\n }\n return { insetInlineStart: anchorPct(startPct), width: anchorSpanPct(sizePct) };\n }\n\n const fillsFromEnd = props.fillOrigin === 'end';\n if (isVertical.value) {\n return fillsFromEnd\n ? { top: 0, height: `calc(100% - ${anchorPct(pct)})` }\n : { bottom: 0, height: anchorPct(pct) };\n }\n return fillsFromEnd\n ? { insetInlineEnd: 0, width: `calc(100% - ${anchorPct(pct)})` }\n : { insetInlineStart: 0, width: anchorPct(pct) };\n });\n\n return {\n thumbPositionStyle,\n tickPositionStyle,\n markStyle,\n readoutStyle,\n mergedReadoutPct,\n mergedReadoutText,\n indicatorStyle,\n };\n}\n","import { computed } from 'vue';\nimport { generateInterval, isValidMark } from '../utils';\n\nexport function useSliderMarksAndTicks(props, { isVertical, thumbPercent }) {\n const computedTickValues = computed(() => {\n const interval = typeof props.showTicks === 'number' ? props.showTicks : props.step;\n if (!interval || interval <= 0) return [];\n return generateInterval(props.min, props.max, interval, 'ticks');\n });\n\n // A mark isn't tied to either thumb, so there's no meaningful index for\n // getValueText (its whole purpose is per-thumb meaning, e.g. \"Minimum\"/\n // \"Maximum\"). Only prefix/suffix apply; anything more specific belongs in\n // that mark's own explicit `text`, which bypasses this entirely.\n function formatMarkValue(value) {\n return `${props.prefix}${value}${props.suffix}`;\n }\n\n const computedMarks = computed(() => {\n const source = props.showMarks === true ? [props.min, props.max] : props.showMarks;\n if (!Array.isArray(source)) return [];\n return source.filter(isValidMark).map((item) => {\n const value = typeof item === 'number' ? item : item.value;\n const text = typeof item === 'number' ? formatMarkValue(item) : (item.text ?? formatMarkValue(value));\n // A mark landing exactly on min/max is edge-aligned (flush to the track's\n // own edge) rather than centered — see markStyle (UseSliderGeometry).\n const edge = value === props.min ? 'start' : value === props.max ? 'end' : null;\n return { text, pct: thumbPercent(value), edge };\n });\n });\n\n // Marks/readout are position:absolute (see slider.less) so they don't push\n // following content down on their own, even though they render below the\n // track — a sibling right after <dt-slider> would overlap them. Only relevant\n // horizontally: in vertical mode marks/readout sit to the side of the track,\n // not below it. Ticks don't need this — they sit close enough to the track to\n // stay within the control's own box (see slider.less). A tooltip-styled readout\n // renders above the thumb instead of in this row, so it doesn't need the space\n // either — when nothing else does (no marks, readout isn't in-row), there's\n // nothing below the track to reserve space for; a parent controls spacing/gaps.\n const reservesAnnotationSpace = computed(() => (\n !isVertical.value && (\n computedMarks.value.length > 0 || props.readout === 'always'\n )\n ));\n\n return {\n computedTickValues,\n computedMarks,\n reservesAnnotationSpace,\n };\n}\n","import { ref, computed, watch, nextTick, onMounted, onBeforeUnmount } from 'vue';\nimport { SLIDER_EDGE_CLAMP_TOLERANCE_PX, SLIDER_READOUT_EDGE_CLAMP_TOLERANCE_PX } from '../SliderConstants';\nimport { edgeClampOffset, measureEdgeInsetPx, mirrorPct, sameValues } from '../utils';\n\n// Two kinds of collision: low/high readouts overlapping each other as thumbs\n// converge (merged into one centered \"lo–hi\" pill), and a readout overlapping\n// a static mark (readout wins, mark hides — it's the thing actively\n// communicating current state). Pure rect measurement, recomputed on value/\n// visibility change and control resize — and, for the tooltip readout, each\n// time UseSliderTooltipReadout moves it (Slider.vue's onPosition).\nexport function useSliderCollisionAvoidance(props, {\n controlRef,\n isVertical,\n isRange,\n internalValues,\n thumbPercent,\n isRtl,\n isReadoutOpen,\n computedMarks,\n formatValue,\n}) {\n const markElRefs = ref([]);\n const readoutElRefs = ref([]);\n const mergedReadoutElRef = ref(null);\n const tooltipElRefs = ref([]);\n const markCollisionHidden = ref([]);\n const readoutMerged = ref(false);\n // Owned here (measured and written), read by UseSliderGeometry to build\n // markStyle — returned below rather than threaded in from Slider.vue as a\n // bare shared ref.\n const markEdgeOffsetPx = ref([]);\n // Same edge-clamp protection as markEdgeOffsetPx, but for readout='always'\n // pills — those anchor onto the same inset band as the thumb (so they\n // never poke past the thumb's own radius), but unlike the thumb, a\n // readout's rendered width depends on its TEXT (locale, suffix, a long\n // getValueText override), which the anchored band alone doesn't account\n // for. A consumer wrapping the slider in a narrower overflow:hidden box\n // than the control's own overflow-clip-margin tolerance could clip it.\n // One offset per thumb index (individual pills) plus a separate scalar\n // for the merged pill — never both populated at once (readoutMerged\n // decides which representation is actually rendered).\n const readoutEdgeOffsetPx = ref([]);\n const mergedReadoutEdgeOffsetPx = ref(0);\n const COLLISION_PADDING = 4; // px of breathing room before a mark hides or readouts merge\n // Must match .d-slider__control's own overflow-clip-margin (slider.less) — a\n // mark within that margin already renders fully today (it's what the margin\n // is for), so leave it centered exactly as before. Only once a mark's natural\n // centered position would exceed this margin does it need nudging inward;\n // see markEdgeOffsetPx (UseSliderGeometry's markStyle reads it) below.\n const EDGE_CLAMP_TOLERANCE_PX = SLIDER_EDGE_CLAMP_TOLERANCE_PX;\n // Readouts get no tolerance allowance (unlike marks above) — see\n // SLIDER_READOUT_EDGE_CLAMP_TOLERANCE_PX's own comment for why reusing the\n // mark allowance isn't safe here.\n const READOUT_EDGE_CLAMP_TOLERANCE_PX = SLIDER_READOUT_EDGE_CLAMP_TOLERANCE_PX;\n\n function rectsOverlap(a, b, padding = 0) {\n return !(\n a.right + padding < b.left ||\n a.left - padding > b.right ||\n a.bottom + padding < b.top ||\n a.top - padding > b.bottom\n );\n }\n\n // Two passes: decide whether the readouts should merge, then — after Vue\n // renders the merged pill or removes it — measure whichever representation\n // is actually shown against the marks. The watcher and ResizeObserver below\n // can both call this and overlap across ticks; collisionUpdateId is a\n // generation counter so only the freshest call's result ever applies.\n let collisionUpdateId = 0;\n\n // --slider-edge-inset is effectively static for the component's lifetime\n // (same rationale as UseSliderInteraction's own cachedEdgeInsetPx) —\n // measured once per updateCollisions() pass below, not per\n // analyticalReadoutRect() call. Every call within a single pass (the merge\n // check's rectA/rectB, and updateMarkCollisions's own readout rects) traces\n // back to that one measurement; re-measuring per call would mean inserting\n // and removing a DOM probe — forcing a synchronous layout — up to 4 times\n // in a single collision pass for no benefit, since the value can't have\n // changed between them.\n let cachedInsetPx = 0;\n\n // .d-slider__readout animates position (slider.less), so a mid-transition\n // getBoundingClientRect() can read a stale position — a keyboard nudge or\n // programmatic change doesn't set data-dragging to disable it. Sidesteps\n // this by computing position analytically from the same reactive pct the\n // template uses, only pulling size (never transitioned) from the DOM.\n //\n // Rescaled onto the same inset band the actual render uses (UseSliderGeometry's\n // anchorPct, via markStyle) — not a flush linear pct-to-px mapping across the\n // control's full true edges. The two used to agree (both flush) before\n // markStyle switched marks/readout='always' to anchorPct; left flush here,\n // this would now systematically disagree with where the readout actually\n // renders, worst-case by a full --slider-edge-inset right at the ends —\n // exactly where collision/merge detection matters most.\n function analyticalReadoutRect(pct, el) {\n if (!el || !controlRef.value) return null;\n const elRect = el.getBoundingClientRect();\n const controlRect = controlRef.value.getBoundingClientRect();\n const insetPx = cachedInsetPx;\n if (isVertical.value) {\n const height = elRect.bottom - elRect.top;\n const totalPx = controlRect.bottom - controlRect.top;\n const anchorPx = insetPx + (totalPx - 2 * insetPx) * (pct / 100);\n const centerPx = controlRect.bottom - anchorPx;\n return { left: elRect.left, right: elRect.right, top: centerPx - height / 2, bottom: centerPx + height / 2 };\n }\n const width = elRect.right - elRect.left;\n const totalPx = controlRect.right - controlRect.left;\n const anchorPx = insetPx + (totalPx - 2 * insetPx) * (mirrorPct(pct, isRtl.value) / 100);\n const centerPx = controlRect.left + anchorPx;\n return { left: centerPx - width / 2, right: centerPx + width / 2, top: elRect.top, bottom: elRect.bottom };\n }\n\n // Same rationale as data-mark-index on marks: don't trust readoutElRefs[i]'s\n // array position to correspond to internalValues[i] — look the element up by\n // its own tagged index instead.\n function readoutElByIndex(i) {\n return readoutElRefs.value.find((el) => el && Number(el.dataset.readoutIndex) === i);\n }\n\n // The tooltip readout is positioned by UseSliderTooltipReadout, not by\n // percent math, so its rect is measured directly. Its ref array\n // (tooltipElRefs) is already index-aligned, same pattern as markElRefs.\n function readoutRect(val, i) {\n if (props.readout === 'tooltip') return tooltipElRefs.value[i]?.getBoundingClientRect() ?? null;\n return analyticalReadoutRect(thumbPercent(val), readoutElByIndex(i));\n }\n\n async function updateCollisions() {\n const thisUpdateId = ++collisionUpdateId;\n await nextTick(); // let Vue's own DOM patch (text/value/style) land before measuring\n if (thisUpdateId !== collisionUpdateId) return;\n\n if (controlRef.value) cachedInsetPx = measureEdgeInsetPx(controlRef.value);\n\n const wasMerged = readoutMerged.value;\n // The tooltip readout has no merged-pill fallback UI (unlike the in-row\n // readout) — merging it here would hide both individual bubbles'\n // measurement (collectReadoutRects falls back to the nonexistent merged\n // pill) while nothing fills the gap, silently disabling mark collision\n // avoidance for tooltip mode whenever two bubbles happen to overlap.\n if (props.readout !== 'tooltip' && isRange.value && internalValues.value.length === 2 && isReadoutOpen(0) && isReadoutOpen(1)) {\n const [lo, hi] = internalValues.value;\n const rectA = analyticalReadoutRect(thumbPercent(lo), readoutElByIndex(0));\n const rectB = analyticalReadoutRect(thumbPercent(hi), readoutElByIndex(1));\n readoutMerged.value = !!(rectA && rectB && rectsOverlap(rectA, rectB, COLLISION_PADDING));\n } else {\n readoutMerged.value = false;\n }\n\n // Only worth another wait when the merge state actually flipped this cycle\n // — that's the only time the merged pill is about to mount/unmount, so\n // it's the only time it'd otherwise be measured (for the marks check\n // below) before existing in the DOM at all.\n if (readoutMerged.value !== wasMerged) {\n await nextTick();\n if (thisUpdateId !== collisionUpdateId) return;\n }\n\n updateMarkCollisions();\n updateReadoutEdgeOffsets();\n }\n\n // Mirrors updateMarkCollisions's own edge-clamp loop (same edgeClampOffset\n // helper, same \"back out the previous offset before measuring\" rationale),\n // but for the readout='always' pill(s) instead of static marks — marks and\n // readouts are two different DOM subtrees (only one of which ever renders\n // a merged pill), so this is a parallel pass rather than a shared loop.\n // Deliberately independent of updateMarkCollisions's own mark-vs-readout\n // overlap check above: that check already ran against the readout's\n // un-nudged rect this cycle, and the nudge here is a small, edge-only\n // correction — not worth a second collision pass to chase.\n function updateReadoutEdgeOffsets() {\n const canClampEdges = props.readout === 'always' && !!controlRef.value && !isVertical.value;\n const controlRect = canClampEdges ? controlRef.value.getBoundingClientRect() : null;\n\n function clampOffset(el, prevOffset) {\n if (!el || !canClampEdges) return 0;\n const r = el.getBoundingClientRect();\n return edgeClampOffset(r.left - prevOffset, r.right - prevOffset, controlRect, READOUT_EDGE_CLAMP_TOLERANCE_PX);\n }\n\n function updateMergedOffset() {\n const offset = clampOffset(mergedReadoutElRef.value, mergedReadoutEdgeOffsetPx.value);\n if (offset !== mergedReadoutEdgeOffsetPx.value) mergedReadoutEdgeOffsetPx.value = offset;\n if (readoutEdgeOffsetPx.value.some(Boolean)) readoutEdgeOffsetPx.value = internalValues.value.map(() => 0);\n }\n\n function updateIndividualOffsets() {\n if (mergedReadoutEdgeOffsetPx.value) mergedReadoutEdgeOffsetPx.value = 0;\n const offsets = internalValues.value.map((_, i) => (\n isReadoutOpen(i) ? clampOffset(readoutElByIndex(i), readoutEdgeOffsetPx.value[i] || 0) : 0\n ));\n if (!sameValues(offsets, readoutEdgeOffsetPx.value)) readoutEdgeOffsetPx.value = offsets;\n }\n\n if (readoutMerged.value) updateMergedOffset();\n else updateIndividualOffsets();\n }\n\n // Same formula as UseSliderGeometry's own mergedReadoutPct — recomputed\n // here rather than threaded in, since both values a merge check ever needs\n // (internalValues, thumbPercent) are already inputs to this composable.\n function mergedReadoutPct() {\n const [lo, hi] = internalValues.value;\n return (thumbPercent(lo) + thumbPercent(hi)) / 2;\n }\n\n function collectReadoutRects() {\n if (readoutMerged.value) {\n const rect = analyticalReadoutRect(mergedReadoutPct(), mergedReadoutElRef.value);\n return rect ? [rect] : [];\n }\n return internalValues.value\n .map((val, i) => (isReadoutOpen(i) ? readoutRect(val, i) : null))\n .filter(Boolean);\n }\n\n // Key by each mark's own data-mark-index, not its position in\n // markElRefs.value — that array isn't reliably aligned with computedMarks\n // across renders (confirmed live: can hold the \"100\"/\"0\" marks in opposite\n // order, silently swapping collision results).\n // Measures collision-hiding and edge-clamping in one pass, not two: the\n // collision check must compare against where a mark is ABOUT to render this\n // cycle (post-clamp), not its stale pre-nudge position, or a mark at the\n // boundary gets a wrong hidden/visible state until some later remeasure.\n function updateMarkCollisions() {\n const marks = markElRefs.value;\n if (!marks.length) return;\n const readoutRects = collectReadoutRects();\n const collisionResult = computedMarks.value.map(() => false);\n const offsets = computedMarks.value.map(() => 0);\n // Edge-clamping is only meaningful horizontally — in vertical mode marks\n // sit beside the track, and .d-slider__control's inline-size there is\n // just the thumb's own width (see slider.less's vertical override), so\n // there's no equivalent inline edge to clamp against.\n const canClampEdges = !!controlRef.value && !isVertical.value;\n const controlRect = canClampEdges ? controlRef.value.getBoundingClientRect() : null;\n\n marks.forEach((markEl) => {\n if (!markEl) return;\n const idx = Number(markEl.dataset.markIndex);\n // Measure with any PREVIOUS offset backed out, so this reflects the\n // mark's natural (centered) position, not last render's correction —\n // otherwise a shrinking overflow (e.g. a shorter value swapped in)\n // would compound on top of the old offset instead of being measured\n // fresh each time.\n const prevOffset = markEdgeOffsetPx.value[idx] || 0;\n const r = markEl.getBoundingClientRect();\n const naturalLeft = r.left - prevOffset;\n const naturalRight = r.right - prevOffset;\n\n const offset = canClampEdges\n ? edgeClampOffset(naturalLeft, naturalRight, controlRect, EDGE_CLAMP_TOLERANCE_PX)\n : 0;\n offsets[idx] = offset;\n\n if (readoutRects.length) {\n // The rect this mark is ABOUT to render at this cycle (natural\n // position + the offset just computed above), not markEl's current\n // (pre-update) DOM rect — see this function's own comment for why.\n const correctedRect = {\n top: r.top, bottom: r.bottom, left: naturalLeft + offset, right: naturalRight + offset,\n };\n collisionResult[idx] = readoutRects.some(\n (readoutRect) => rectsOverlap(correctedRect, readoutRect, COLLISION_PADDING),\n );\n }\n });\n\n if (!sameValues(collisionResult, markCollisionHidden.value)) markCollisionHidden.value = collisionResult;\n if (!sameValues(offsets, markEdgeOffsetPx.value)) markEdgeOffsetPx.value = offsets;\n }\n\n const readoutVisibility = computed(() => internalValues.value.map((_, i) => isReadoutOpen(i)));\n\n // Rendered widths change with formatted TEXT (getValueText/prefix/suffix),\n // not just the values — a STABLE getValueText closing over some other\n // reactive value (e.g. a locale ref) can produce different text with its\n // own reference never changing, so this watches the actual output instead.\n const formattedValues = computed(() => internalValues.value.map((v, i) => formatValue(v, i)));\n\n let markCollisionResizeObserver = null;\n\n // isVertical/isRtl are watched too — a runtime orientation or dir flip\n // changes every rect this measures without touching any of the other\n // sources, or without the control's own size changing (the ResizeObserver\n // below only watches that), and neither recomputes on its own otherwise.\n watch(\n [readoutVisibility, computedMarks, isVertical, isRtl],\n () => updateCollisions(),\n { deep: true },\n );\n\n // The tooltip readout re-runs collisions itself once it has moved\n // (Slider.vue's onPosition); measuring here would read its old position.\n watch(\n [internalValues, formattedValues, () => props.readoutClass],\n () => { if (props.readout !== 'tooltip') updateCollisions(); },\n { deep: true },\n );\n\n onMounted(() => {\n nextTick(updateCollisions);\n if (typeof ResizeObserver !== 'undefined' && controlRef.value) {\n markCollisionResizeObserver = new ResizeObserver(() => {\n updateCollisions();\n });\n markCollisionResizeObserver.observe(controlRef.value);\n }\n });\n\n onBeforeUnmount(() => {\n markCollisionResizeObserver?.disconnect();\n });\n\n return {\n markElRefs,\n readoutElRefs,\n mergedReadoutElRef,\n tooltipElRefs,\n markCollisionHidden,\n readoutMerged,\n markEdgeOffsetPx,\n readoutEdgeOffsetPx,\n mergedReadoutEdgeOffsetPx,\n readoutVisibility,\n formattedValues,\n updateCollisions,\n };\n}\n","import { onBeforeUnmount, onMounted, watch } from 'vue';\nimport { autoUpdate, computePosition, flip, hide, offset, shift, size } from '@floating-ui/dom';\nimport { sameValues } from '../utils';\n\nconst VISIBILITY_OPTIONS = {\n visibilityProperty: true,\n opacityProperty: true,\n // Chrome/Edge 114–120 support Popover but only these older option names.\n checkVisibilityCSS: true,\n checkOpacity: true,\n};\n\nfunction isAnchorVisible(anchor) {\n if (anchor.checkVisibility) return anchor.checkVisibility(VISIBILITY_OPTIONS);\n if (!anchor.getClientRects().length) return false;\n if (getComputedStyle(anchor).visibility !== 'visible') return false;\n for (let el = anchor; el; el = el.parentElement) {\n const style = getComputedStyle(el);\n if (style.opacity === '0' || style.contentVisibility === 'hidden') return false;\n }\n return true;\n}\n\nfunction sameRect(a, b) {\n return a.left === b.left && a.top === b.top && a.right === b.right && a.bottom === b.bottom;\n}\n\nconst clamp = (value, min, max) => Math.min(max, Math.max(min, value));\n\nexport function useSliderTooltipReadout(props, {\n thumbVisualRefs,\n tooltipElRefs,\n isVertical,\n isRtl,\n readoutVisibility,\n formattedValues,\n onPosition,\n}) {\n const entries = new Map();\n\n function shouldOpen(index) {\n return props.readout === 'tooltip' && !props.disabled && readoutVisibility.value[index];\n }\n\n function close(index) {\n const entry = entries.get(index);\n if (!entry) return;\n entries.delete(index);\n entry.cleanup?.();\n if (entry.tooltip.matches(':popover-open')) entry.tooltip.hidePopover();\n }\n\n function open(index, anchor, tooltip) {\n if (typeof tooltip.showPopover !== 'function') return;\n let revision = 0;\n let referenceHidden = true;\n let anchorRect = null;\n let geometry = null;\n let frame;\n const entry = { anchor, tooltip, update, cleanup: null };\n const isLive = () => entries.get(index) === entry;\n\n function currentVisibility() {\n return referenceHidden || !isAnchorVisible(anchor) ? 'hidden' : 'visible';\n }\n\n // Shown hidden; the first completed position reveals it.\n function reveal() {\n tooltip.style.visibility = 'hidden';\n tooltip.showPopover();\n }\n\n async function update() {\n if (!isLive()) return;\n if (!tooltip.matches(':popover-open')) {\n if (!shouldOpen(index) || !anchor.isConnected || !tooltip.isConnected || !isAnchorVisible(anchor)) {\n close(index);\n return;\n }\n reveal();\n }\n const current = ++revision;\n const rect = anchor.getBoundingClientRect();\n anchorRect = rect;\n const gap = parseFloat(getComputedStyle(tooltip).paddingBlockStart) || 0;\n const boundary = { boundary: [], padding: gap * 2 };\n const content = tooltip.firstElementChild;\n // A closed/replaced readout must never be revived by an older calculation.\n const isCurrent = () => isLive() && current === revision;\n const result = await computePosition(anchor, tooltip, {\n strategy: 'fixed',\n placement: isVertical.value ? (isRtl.value ? 'left' : 'right') : 'top',\n middleware: [\n offset(gap),\n flip(boundary),\n shift(boundary),\n size({\n ...boundary,\n apply({ availableWidth, availableHeight }) {\n if (!isCurrent()) return;\n content.style.maxInlineSize = `${Math.max(0, availableWidth - gap * 2)}px`;\n content.style.maxBlockSize = `${Math.max(0, availableHeight - gap * 2)}px`;\n },\n }),\n hide(),\n ],\n });\n if (!isCurrent()) return;\n\n // Read before writing: size() and hide() just measured, so layout is clean.\n const width = tooltip.offsetWidth;\n const height = tooltip.offsetHeight;\n // flip() only falls back to the opposite side, so there is no -start/-end suffix.\n const side = result.placement;\n referenceHidden = result.middlewareData.hide?.referenceHidden;\n const visibility = currentVisibility();\n\n tooltip.dataset.side = side;\n // Floating UI returns physical viewport coordinates, including under RTL.\n Object.assign(tooltip.style, { left: `${result.x}px`, top: `${result.y}px`, visibility });\n // Each side's arrow rule (slider.less) reads only the axis it slides along.\n if (side === 'top' || side === 'bottom') {\n tooltip.style.setProperty('--slider-tooltip-arrow-x', `${clamp(rect.left + rect.width / 2 - result.x, gap, width - gap)}px`);\n } else {\n tooltip.style.setProperty('--slider-tooltip-arrow-y', `${clamp(rect.top + rect.height / 2 - result.y, gap, height - gap)}px`);\n }\n const next = [result.x, result.y, width, height, side, visibility];\n if (!geometry || !sameValues(next, geometry)) {\n geometry = next;\n onPosition();\n }\n }\n\n // Value watchers position promptly; this frame check covers transformed\n // anchors and a stationary owner's visibility. Comparing against the rect\n // the last update used skips the frame after a watcher already ran. It\n // also replaces autoUpdate's layoutShift observer, which reacts after paint.\n //\n // This used to throttle to a check every ~100ms instead of every frame,\n // on the theory that a transformed anchor or visibility flip is still\n // within human perception at that rate — but it throttled the reposition\n // itself, not just the measurement: a continuously moving/transformed\n // anchor (e.g. a dragged container) only got repositioned ~10x/sec\n // instead of ~60x/sec, visibly lagging behind by as much as the window\n // itself (Francis measured up to 60px during a drag, vs 5px before).\n // Reverted — the actual expensive step (update()'s computePosition call\n // and DOM writes) was already gated by the sameRect comparison below, so\n // a stationary tooltip was never doing 60/s of real repositioning work;\n // only this cheap rect-read-and-compare ran that often, which is not\n // what was worth trading away responsiveness for.\n function checkFrame() {\n if (!tooltip.matches(':popover-open') || !anchorRect || !sameRect(anchor.getBoundingClientRect(), anchorRect)) update();\n else tooltip.style.visibility = currentVisibility();\n if (isLive()) frame = requestAnimationFrame(checkFrame);\n }\n\n entries.set(index, entry);\n reveal();\n const stopPositioning = autoUpdate(anchor, tooltip, update, { layoutShift: false });\n checkFrame();\n entry.cleanup = () => {\n stopPositioning();\n cancelAnimationFrame(frame);\n };\n }\n\n function sync() {\n for (const [index, entry] of entries) {\n if (!shouldOpen(index) ||\n thumbVisualRefs.value[index] !== entry.anchor || tooltipElRefs.value[index] !== entry.tooltip) {\n close(index);\n }\n }\n readoutVisibility.value.forEach((_, index) => {\n const anchor = thumbVisualRefs.value[index];\n const tooltip = tooltipElRefs.value[index];\n if (!anchor || !tooltip || !shouldOpen(index)) return;\n if (entries.has(index)) entries.get(index).update();\n else open(index, anchor, tooltip);\n });\n }\n\n watch(\n [() => props.readout, () => props.disabled, isVertical, isRtl, formattedValues, readoutVisibility],\n sync,\n { flush: 'post' },\n );\n onMounted(sync);\n onBeforeUnmount(() => { for (const index of entries.keys()) close(index); });\n}\n","<template>\n <div\n v-bind=\"wrapperAttrs\"\n :class=\"[\n 'd-slider',\n $attrs.class,\n {\n 'd-slider--disabled': disabled,\n 'd-slider--vertical': isVertical,\n 'd-slider--inverted': fillOrigin === 'end',\n 'd-slider--dragging': isDragging,\n },\n ]\"\n :style=\"$attrs.style\"\n :data-disabled=\"disabled || undefined\"\n :data-orientation=\"orientation\"\n :data-dragging=\"isDragging || undefined\"\n data-qa=\"dt-slider\"\n >\n <div\n v-if=\"showLabel\"\n :id=\"labelId\"\n :class=\"['d-slider__label', labelClass]\"\n data-qa=\"dt-slider-label\"\n >\n <!-- @slot Slot for the label, defaults to the label prop. Scoped with\n :value (Number, or Number[] in range mode) — the live value(s),\n updating as the thumb is dragged — for labels that echo the\n current value. Required for accessibility; set showLabel to false\n to hide it, and provide the label prop (not just this slot) so its\n text can be promoted to aria-label — a slot's rich markup can't\n collapse to the flat string aria-label requires. -->\n <slot\n name=\"label\"\n :value=\"currentValue\"\n >\n <dt-text\n v-if=\"label\"\n kind=\"label\"\n :size=\"resolvedLabelSize\"\n :strength=\"labelStrength\"\n :tone=\"disabled ? 'disabled' : 'secondary'\"\n >\n {{ label }}\n </dt-text>\n </slot>\n </div>\n <div\n :class=\"['d-slider__body', bodyClass, { 'd-slider__body--reserve-annotation-space': reservesAnnotationSpace }]\"\n data-qa=\"dt-slider-body\"\n >\n <div\n v-if=\"hasSlotContent($slots.start)\"\n :class=\"['d-slider__start', startClass]\"\n data-qa=\"dt-slider-start\"\n >\n <!-- @slot Optional content at the inline-start end of the track (aka left).\n When using icon-only content, add aria-label or hidden text to the icon. -->\n <slot name=\"start\" />\n </div>\n <div\n ref=\"controlRef\"\n class=\"d-slider__control\"\n :style=\"isVertical ? { touchAction: 'pan-x' } : { touchAction: 'pan-y' }\"\n data-qa=\"dt-slider-control\"\n @pointerdown=\"onPointerDown\"\n @pointermove=\"onPointerMove\"\n @pointerup=\"onPointerUp\"\n @pointercancel=\"onPointerUp\"\n >\n <div\n class=\"d-slider__track\"\n data-qa=\"dt-slider-track\"\n />\n <div\n class=\"d-slider__indicator\"\n :style=\"indicatorStyle\"\n data-qa=\"dt-slider-indicator\"\n />\n <!-- .d-slider__indicator's own z-index (slider.less) covers any tick\n that falls within its filled span regardless of template order —\n ticks only show through on the track's own unfilled portion. -->\n <template v-if=\"showTicks\">\n <div\n v-for=\"(tickValue, i) in computedTickValues\"\n :key=\"i\"\n class=\"d-slider__tick\"\n :style=\"tickPositionStyle(tickValue)\"\n data-qa=\"dt-slider-tick\"\n />\n </template>\n <div\n v-for=\"(val, i) in internalValues\"\n :key=\"`thumb-visual-${i}`\"\n :ref=\"(el) => { thumbVisualRefs[i] = el; }\"\n :class=\"[\n 'd-slider__thumb-visual',\n {\n 'd-slider__thumb-visual--focused': focusedThumbIndex === i,\n 'd-slider__thumb-visual--active': activeThumbIndex === i,\n },\n ]\"\n :style=\"thumbPositionStyle(val)\"\n data-qa=\"dt-slider-thumb-visual\"\n />\n <div\n v-for=\"(val, i) in internalValues\"\n :key=\"`thumb-hit-${i}`\"\n class=\"d-slider__thumb-hit\"\n :style=\"{ ...thumbPositionStyle(val), touchAction: isVertical ? 'pan-x' : 'pan-y' }\"\n data-qa=\"dt-slider-thumb-hit\"\n @pointerenter=\"onThumbHitPointerEnter(i)\"\n @pointerleave=\"onThumbHitPointerLeave(i)\"\n />\n <!-- A plain `ref=\"thumbRefs\"` only pushes in patch order (the same\n index-misalignment risk UseSliderCollisionAvoidance documents for\n markElRefs), but onPointerDown/updateThumbValue index into this\n directly — a function ref assigns by the v-for's own index, and\n self-cleans on unmount when range shrinks to single mode.\n Keep :value after :min/:max/:step: Vue patches them in template\n order, and the browser clamps a value set against stale bounds. -->\n <input\n v-for=\"(val, i) in internalValues\"\n :key=\"`thumb-input-${i}`\"\n :ref=\"(el) => { thumbRefs[i] = el; }\"\n type=\"range\"\n class=\"d-slider__thumb\"\n :min=\"thumbNativeMin(i)\"\n :max=\"thumbNativeMax(i)\"\n :step=\"thumbNativeStep(i)\"\n :value=\"val\"\n :disabled=\"disabled\"\n :name=\"name || undefined\"\n :aria-labelledby=\"resolvedAriaLabelledby\"\n :aria-label=\"resolvedAriaLabel\"\n :aria-describedby=\"attrs['aria-describedby']\"\n :aria-errormessage=\"attrs['aria-errormessage']\"\n :aria-details=\"attrs['aria-details']\"\n :aria-invalid=\"attrs['aria-invalid']\"\n :aria-valuetext=\"formatValue(val, i)\"\n :aria-orientation=\"isVertical ? 'vertical' : undefined\"\n data-qa=\"dt-slider-thumb\"\n @input=\"onThumbInput(i, $event)\"\n @keydown=\"onThumbKeydown(i, $event)\"\n @focus=\"onThumbFocus(i, $event)\"\n @blur=\"onThumbBlur(i, $event)\"\n >\n <div\n v-for=\"(mark, i) in computedMarks\"\n :key=\"`mark-${i}`\"\n ref=\"markElRefs\"\n :class=\"['d-slider__mark', { 'd-slider__mark--collision-hidden': markCollisionHidden[i] }]\"\n :style=\"markStyle(mark.pct, i, mark.edge)\"\n :data-mark-index=\"i\"\n data-qa=\"dt-slider-mark\"\n >\n {{ mark.text }}\n </div>\n <!-- Plain, CSS-positioned text — deliberately not a floating tooltip/portal.\n It sits in the same row as marks, positioned by the same value-to-percent\n math, so it never needs JS measurement or a reposition loop that could\n desync from the thumb. -->\n <template v-if=\"readout === 'always'\">\n <div\n v-for=\"(val, i) in internalValues\"\n :key=\"`readout-${i}`\"\n ref=\"readoutElRefs\"\n :class=\"[\n 'd-slider__readout',\n !readoutMerged ? 'd-slider__readout--show' : 'd-slider__readout--hide',\n readoutClass,\n ]\"\n :style=\"readoutStyle(thumbPercent(val), readoutEdgeOffsetPx[i], readoutEdge(val))\"\n :data-readout-index=\"i\"\n aria-hidden=\"true\"\n data-qa=\"dt-slider-thumb-readout\"\n >\n {{ formatValue(val, i) }}\n </div>\n <!-- Range mode only: when the two individual readouts above would overlap,\n they're hidden (still measurable — visibility:hidden) and this single\n merged pill takes over, centered between the thumbs. -->\n <div\n v-if=\"readoutMerged\"\n ref=\"mergedReadoutElRef\"\n :class=\"['d-slider__readout', 'd-slider__readout--show', readoutClass]\"\n :style=\"readoutStyle(mergedReadoutPct, mergedReadoutEdgeOffsetPx)\"\n aria-hidden=\"true\"\n data-qa=\"dt-slider-thumb-readout-merged\"\n >\n {{ mergedReadoutText }}\n </div>\n </template>\n <!-- Keep DOM parentage for inherited themes; native popovers paint\n outside every ancestor's overflow, clip path, and mask. -->\n <template v-if=\"readout === 'tooltip'\">\n <div\n v-for=\"(val, i) in internalValues\"\n :key=\"`readout-tooltip-${i}`\"\n :ref=\"(el) => { tooltipElRefs[i] = el; }\"\n class=\"d-tooltip d-slider__readout-tooltip\"\n popover=\"manual\"\n inert\n aria-hidden=\"true\"\n data-qa=\"dt-slider-thumb-readout-tooltip\"\n >\n <span class=\"d-slider__tooltip-content\">{{ formatValue(val, i) }}</span>\n </div>\n </template>\n </div>\n <div\n v-if=\"hasSlotContent($slots.end)\"\n :class=\"['d-slider__end', endClass]\"\n data-qa=\"dt-slider-end\"\n >\n <!-- @slot Optional content at the inline-end end of the track (aka right).\n When using icon-only content, add aria-label or hidden text to the icon. -->\n <slot name=\"end\" />\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\n// @ts-nocheck\nimport { ref, computed, Comment, useSlots, useAttrs } from 'vue';\nimport { DtText, TEXT_SIZE_MODIFIERS, TEXT_STRENGTH_MODIFIERS } from '@/components/Text';\nimport { getUniqueString, hasSlotContent, removeClassStyleAttrs } from '@/common/utils';\nimport {\n SLIDER_ORIENTATIONS,\n SLIDER_READOUT_MODES,\n SLIDER_DEFAULT_LARGE_STEP,\n SLIDER_FILL_ORIGINS,\n} from './SliderConstants';\nimport { useSliderDevWarnings } from './Composables/UseSliderDevWarnings';\nimport { useSliderDirection } from './Composables/UseSliderDirection';\nimport { useSliderValue } from './Composables/UseSliderValue';\nimport { useSliderMagneticSnap } from './Composables/UseSliderMagneticSnap';\nimport { useSliderInteraction } from './Composables/UseSliderInteraction';\nimport { useSliderGeometry } from './Composables/UseSliderGeometry';\nimport { useSliderMarksAndTicks } from './Composables/UseSliderMarksAndTicks';\nimport { useSliderCollisionAvoidance } from './Composables/UseSliderCollisionAvoidance';\nimport { useSliderTooltipReadout } from './Composables/UseSliderTooltipReadout';\nimport { isValidMark } from './utils';\n\ndefineOptions({ name: 'DtSlider', inheritAttrs: false });\n\nconst props = defineProps({\n /**\n * The current value. A number enables single-thumb mode; an array of two\n * numbers enables range mode. When omitted (or explicitly undefined/null),\n * resolves to the midpoint of [min, max] — matching native\n * <input type=\"range\"> — see normalizeModelValue.\n */\n modelValue: {\n type: [Number, Array],\n default: undefined,\n validator: (value) => !Array.isArray(value) || value.length === 2,\n },\n\n /**\n * The minimum allowed value. Must be finite.\n */\n min: {\n type: Number,\n default: 0,\n validator: Number.isFinite,\n },\n\n /**\n * The maximum allowed value. Must be finite.\n */\n max: {\n type: Number,\n default: 100,\n validator: Number.isFinite,\n },\n\n /**\n * The increment/decrement step. Must be finite.\n */\n step: {\n type: Number,\n default: 1,\n validator: Number.isFinite,\n },\n\n /**\n * Magnetic snap points the thumb pulls toward while dragging — unlike\n * step, this doesn't restrict which values are selectable; a value just\n * outside the snap radius of a snap point stays freely reachable. Pass a\n * number for an evenly spaced interval (e.g. 25), or an array for\n * arbitrary values (e.g. [10, 42, 90]). Pointer drag only — keyboard\n * stepping (step/largeStep) is unaffected.\n * Values must be finite numbers; malformed array entries are ignored.\n */\n snapPoints: {\n type: [Number, Array],\n default: undefined,\n validator: (value) => Number.isFinite(value) || (Array.isArray(value) && value.every(Number.isFinite)),\n },\n\n /**\n * Disables the slider, preventing interaction.\n * @values true, false\n */\n disabled: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Track orientation.\n * @values horizontal, vertical\n */\n orientation: {\n type: String,\n default: 'horizontal',\n validator: (v) => SLIDER_ORIENTATIONS.includes(v),\n },\n\n /**\n * Which end the indicator fills from, toward the thumb: \"start\" (the\n * default, aka left) fills from the min end, \"end\" (aka right) fills from\n * the max end. Pass a Number instead to fill outward from that value\n * toward the thumb — useful for balance controls (aka center-fill) or\n * deviation-from-setpoint displays. A numeric origin is clamped to\n * [min, max]. Ignored in range mode.\n */\n fillOrigin: {\n type: [Number, String],\n default: 'start',\n validator: (v) => typeof v === 'number' || SLIDER_FILL_ORIGINS.includes(v),\n },\n\n /**\n * Renders tick marks along the track. Pass true to put a tick at every step;\n * pass a Number instead to space ticks at that interval (same units as step).\n */\n showTicks: {\n type: [Boolean, Number],\n default: false,\n },\n\n /**\n * Minimum gap, in steps (not raw values), that must remain between the two\n * thumbs in range mode: the actual minimum gap enforced between their\n * values is minGapSteps * step, so the same prop value means a different\n * real gap depending on step (e.g. minGapSteps={5} enforces a gap of 5 with\n * step={1}, but 50 with step={10}).\n */\n minGapSteps: {\n type: Number,\n default: 0,\n },\n\n /**\n * Visible label text. Required for accessibility; if omitted, provide aria-label on the component.\n */\n label: {\n type: String,\n default: '',\n },\n\n /**\n * When false, the label is removed and its text (the label prop, not the\n * #label slot) is promoted to aria-label instead — matching DtInput,\n * DtCheckbox, DtRadio, and DtSelectMenu's own showLabel behavior.\n * @values true, false\n */\n showLabel: {\n type: Boolean,\n default: true,\n },\n\n /**\n * Overrides the label text size.\n * @values 100, 200, 300, 400\n */\n labelSize: {\n type: [String, Number],\n default: null,\n validator: (s) => TEXT_SIZE_MODIFIERS.label.includes(String(s)),\n },\n\n /**\n * Overrides the label font weight.\n * @values bold, semibold, medium, normal\n */\n labelStrength: {\n type: String,\n default: null,\n validator: (s) => Object.keys(TEXT_STRENGTH_MODIFIERS).includes(s),\n },\n\n /**\n * A function returning the user-facing text for a value — shared by the readout and\n * each thumb's aria-valuetext, so the two always agree on how a number is displayed.\n * Signature: (value: number, index?: number) => string. index is the thumb index (use\n * it to differentiate thumbs in range mode, e.g. \"Minimum: 20\" / \"Maximum: 70\").\n * Deliberately NOT used for a mark's own auto-generated text — a mark isn't tied to\n * either thumb, so there's no index this function could meaningfully receive; marks use\n * prefix/suffix instead (see the showMarks prop), or their own explicit text override.\n * Takes precedence over prefix/suffix for the readout and aria-valuetext when set. The\n * default (null) uses the raw number (optionally wrapped in prefix/suffix), which must\n * be i18n-safe for your context.\n */\n getValueText: {\n type: Function,\n default: null,\n },\n\n /**\n * Text prepended to the raw number wherever it's displayed — e.g. prefix=\"$\" for\n * currency. Always applied to marks. Ignored by the readout and aria-valuetext when\n * getValueText is set (see getValueText). A long prefix makes every mark's text\n * longer too — keep it short enough that the first/last mark stays legible near\n * the track's own edges (see showMarks).\n */\n prefix: {\n type: String,\n default: '',\n },\n\n /**\n * Text appended to the raw number wherever it's displayed — e.g. suffix=\"%\" for a\n * percentage. Always applied to marks. Ignored by the readout and aria-valuetext when\n * getValueText is set (see getValueText). Same edge-legibility caveat as prefix\n * applies (see showMarks).\n */\n suffix: {\n type: String,\n default: '',\n },\n\n /**\n * Native name attribute for form submission. In range mode, both inputs share this name.\n * Retrieve both values with FormData.getAll(name).\n */\n name: {\n type: String,\n default: '',\n },\n\n /**\n * Roughly how far to move on Page Up/Page Down or Shift + Arrow, in the\n * same units as step — rounded to the nearest whole number of steps (at\n * least one), so the result always lands on the step grid and always\n * moves, even when step is coarser than largeStep itself.\n */\n largeStep: {\n type: Number,\n default: SLIDER_DEFAULT_LARGE_STEP,\n },\n\n /**\n * Additional class(es) applied to the body wrapper containing the start slot, control, and end slot.\n */\n bodyClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Additional class(es) applied to the label wrapper element.\n */\n labelClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Additional class(es) applied to the inline-start slot wrapper (aka left).\n */\n startClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Additional class(es) applied to the inline-end slot wrapper (aka right).\n */\n endClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Controls the live value readout for each thumb: a tooltip-styled bubble above the\n * thumb shown only while hovering, dragging, or focusing it (the default); always\n * visible below the track; or never shown. Text is formatted via getValueText\n * when set, otherwise prefix/suffix — same as each thumb's aria-valuetext, but\n * unlike a mark's own auto-generated text (see showMarks). The tooltip uses\n * the native Popover API to escape ancestor clipping and stays within the\n * viewport. Browsers without that API do not display the floating readout;\n * use always when a visible value is needed there. The inline readout\n * and the merged two-thumb pill are not edge-clamped, so a long formatted value can render\n * close to or past the track's own edge at those values.\n * @values tooltip, always, never\n */\n readout: {\n type: String,\n default: 'tooltip',\n validator: (v) => SLIDER_READOUT_MODES.includes(v),\n },\n\n /**\n * Additional class(es) applied to the individual and merged inline readouts when readout is 'always'.\n * Ignored when readout is 'tooltip' or 'never'.\n */\n readoutClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Text annotations rendered below the track at specific positions, independent of ticks.\n * Off by default — rendering min/max isn't always wanted. Pass true to label min and max\n * (start and end) only. Pass an array for explicit control: each entry is either a plain\n * number (text defaults to the number itself, formatted with prefix/suffix — NOT\n * getValueText, which has no meaningful index for a position that isn't tied to either\n * thumb) or an object with a required value and optional text override, which is used\n * as-is regardless of prefix/suffix/getValueText.\n * Example: [{ value: 0, text: 'Neutral' }, -100, 100]\n * Mark values must be finite numbers; malformed entries are ignored.\n *\n * Keep mark text (via a short prefix/suffix, or an explicit text override) reasonably\n * short — a mark landing exactly on min or max is edge-aligned rather than centered, and\n * any other mark is nudged inward once it would otherwise render past the track's own\n * edges, but very long text can still end up close to the live readout or an adjacent mark.\n */\n showMarks: {\n type: [Array, Boolean],\n default: false,\n validator: (value) => typeof value === 'boolean' || (Array.isArray(value) && value.every(isValidMark)),\n },\n});\n\nconst emit = defineEmits([\n /**\n * Emitted on every value change (drag, keyboard, track click).\n * @event update:modelValue\n * @type {number | number[]}\n */\n 'update:modelValue',\n\n /**\n * Emitted when a value change commits: pointer up, blur, or a reactive\n * min/max/step/minGapSteps correction that lands outside any in-progress\n * drag. Use this for API calls or persistence.\n * @event change\n * @type {number | number[]}\n */\n 'change',\n\n /**\n * Native focus event on a thumb.\n * @event focus\n * @type {FocusEvent}\n */\n 'focus',\n\n /**\n * Native blur event on a thumb.\n * @event blur\n * @type {FocusEvent}\n */\n 'blur',\n]);\n\n// ─── Internal state ───────────────────────────────────────────────────────────\n\nconst slots = useSlots();\nconst attrs = useAttrs();\nconst labelId = `slider-label-${getUniqueString()}`;\nconst controlRef = ref(null);\nconst thumbRefs = ref([]);\nconst thumbVisualRefs = ref([]);\n\n// Prop-derived, not owned by any one composable — every composable that\n// needs either receives it as a plain argument below.\nconst isRange = computed(() => Array.isArray(props.modelValue));\nconst isVertical = computed(() => props.orientation === 'vertical');\n\nconst { isRtl } = useSliderDirection(controlRef);\n\n// Hoisted above useSliderValue (normally wired in right before\n// useSliderInteraction below) so useSliderValue's own reactive watchers can\n// tell a held magnetic snap apart from a genuinely new external value.\nconst { activeSnapValue, findMagneticSnapPoint } = useSliderMagneticSnap(props, { controlRef, isVertical });\n\nconst {\n internalValues,\n lastCommittedValues,\n currentValue,\n decimalPlaces,\n snapToStep,\n thumbPercent,\n thumbNativeMin,\n thumbNativeMax,\n thumbNativeStep,\n formatValue,\n} = useSliderValue(props, emit, { isRange, activeSnapValue });\n\n// Recurses into slot vnodes for actual TEXT, not just \"something renders\" —\n// an icon-only #label (e.g. a bare <dt-icon> with no text of its own) would\n// otherwise count as providing an accessible name, silently leaving the\n// thumb unnamed with no indication anything's wrong.\nfunction slotHasText(vnodes) {\n return vnodes.some((vnode) => {\n // A text vnode's own `children` is a plain string (handled below), but a\n // slot function (including the recursive default() call below) is only\n // contractually required to return SOME renderable value, not always an\n // array of vnodes — a bare string is valid too.\n if (typeof vnode === 'string') return vnode.trim() !== '';\n if (vnode.type === Comment) return false;\n if (typeof vnode.children === 'string') return vnode.children.trim() !== '';\n if (Array.isArray(vnode.children)) return slotHasText(vnode.children);\n // A child COMPONENT vnode (e.g. <dt-text>{{ label }}</dt-text> in\n // #label — the same pattern this component's own default fallback\n // markup below uses) has `children` as a slots object, not a string or\n // array — recurse into its own default slot to see what it will\n // actually render instead of treating it as textless.\n if (vnode.children && typeof vnode.children.default === 'function') {\n const result = vnode.children.default();\n return slotHasText(Array.isArray(result) ? result : [result]);\n }\n return false;\n });\n}\n\n// Whether what ACTUALLY renders for the label has real text — the #label\n// slot when a consumer provides one (it fully replaces the prop's own\n// fallback markup, so a textless slot, e.g. a bare icon, means no\n// accessible name regardless of the unused prop), otherwise the prop\n// itself. Independent of showLabel, which only controls visibility. Named\n// to match DtCheckbox/DtRadio's own hasLabelContent.\nconst hasLabelContent = computed(() => {\n if (slots.label) return slotHasText(slots.label({ value: currentValue.value }));\n return !!props.label?.trim();\n});\n\n// Each native thumb <input> names itself from the visible label when there\n// is one; otherwise it falls back to whatever aria-label/aria-labelledby a\n// consumer passed in (or, lacking even that, the label prop's own text when\n// it's being used as a hidden accessible name — showLabel false).\nconst usesVisibleLabelAsName = computed(() => props.showLabel && hasLabelContent.value);\nconst resolvedAriaLabelledby = computed(() => (\n usesVisibleLabelAsName.value ? labelId : attrs['aria-labelledby']\n));\nconst resolvedAriaLabel = computed(() => {\n if (usesVisibleLabelAsName.value) return undefined;\n return !props.showLabel && props.label ? props.label : attrs['aria-label'];\n});\n\nconst hasAccessibleName = computed(() => usesVisibleLabelAsName.value || !!(\n String(resolvedAriaLabel.value ?? '').trim() || String(resolvedAriaLabelledby.value ?? '').trim()\n));\n\nconst resolvedLabelSize = computed(() => props.labelSize ?? 300);\n\n// These forward to each native thumb <input> instead — the wrapper <div>\n// isn't a form control, so leaving them here would duplicate the name and\n// strand the rest where assistive tech querying the input would never see them.\nconst THUMB_ARIA_KEYS = ['aria-label', 'aria-labelledby', 'aria-describedby', 'aria-errormessage', 'aria-details', 'aria-invalid'];\nconst wrapperAttrs = computed(() => {\n const base = removeClassStyleAttrs(attrs);\n return Object.fromEntries(Object.entries(base).filter(([key]) => !THUMB_ARIA_KEYS.includes(key)));\n});\n\nconst {\n isDragging,\n activeThumbIndex,\n focusedThumbIndex,\n onPointerDown,\n onPointerMove,\n onPointerUp,\n onThumbInput,\n onThumbKeydown,\n onThumbFocus,\n onThumbBlur,\n onThumbHitPointerEnter,\n onThumbHitPointerLeave,\n isReadoutOpen,\n} = useSliderInteraction(props, emit, {\n controlRef,\n thumbRefs,\n internalValues,\n isRange,\n isVertical,\n decimalPlaces,\n snapToStep,\n lastCommittedValues,\n findMagneticSnapPoint,\n activeSnapValue,\n isRtl,\n});\n\n// ─── Computed visual helpers ──────────────────────────────────────────────────\n\nconst { computedTickValues, computedMarks, reservesAnnotationSpace } = useSliderMarksAndTicks(\n props,\n { isVertical, thumbPercent },\n);\n\nconst {\n markElRefs,\n readoutElRefs,\n mergedReadoutElRef,\n tooltipElRefs,\n markCollisionHidden,\n readoutMerged,\n markEdgeOffsetPx,\n readoutEdgeOffsetPx,\n mergedReadoutEdgeOffsetPx,\n readoutVisibility,\n formattedValues,\n updateCollisions,\n} = useSliderCollisionAvoidance(props, {\n controlRef,\n isVertical,\n isRange,\n internalValues,\n thumbPercent,\n isRtl,\n isReadoutOpen,\n computedMarks,\n formatValue,\n});\n\nconst {\n thumbPositionStyle,\n tickPositionStyle,\n markStyle,\n readoutStyle,\n mergedReadoutPct,\n mergedReadoutText,\n indicatorStyle,\n} = useSliderGeometry(props, {\n isVertical,\n isRange,\n internalValues,\n thumbPercent,\n isRtl,\n markEdgeOffsetPx,\n formatValue,\n});\n\n// Same \"edge\" detection computedMarks (UseSliderMarksAndTicks) uses for its\n// own min/max marks — a readout tracking a thumb sitting exactly at min/max\n// gets the same flush-edge treatment there.\nfunction readoutEdge(val) {\n return val === props.min ? 'start' : val === props.max ? 'end' : null;\n}\n\nuseSliderTooltipReadout(props, {\n thumbVisualRefs,\n tooltipElRefs,\n isVertical,\n isRtl,\n readoutVisibility,\n formattedValues,\n onPosition: updateCollisions,\n});\n\n// ─── Dev warnings ─────────────────────────────────────────────────────────────\n\nuseSliderDevWarnings(props, { isRange, hasAccessibleName });\n\n// ─── Exposed API ──────────────────────────────────────────────────────────────\n\nfunction focus() {\n thumbRefs.value[0]?.focus();\n}\n\nfunction blur() {\n // Whichever thumb actually has focus, not always thumb 0 — in range mode\n // the wrong (unfocused) thumb left the real one's deferred keyboard commit\n // (commitIfChanged) never firing. No-op when nothing is focused.\n thumbRefs.value.find((el) => el === document.activeElement)?.blur();\n}\n\ndefineExpose({ focus, blur });\n</script>\n","<template>\n <div\n v-bind=\"wrapperAttrs\"\n :class=\"[\n 'd-slider',\n $attrs.class,\n {\n 'd-slider--disabled': disabled,\n 'd-slider--vertical': isVertical,\n 'd-slider--inverted': fillOrigin === 'end',\n 'd-slider--dragging': isDragging,\n },\n ]\"\n :style=\"$attrs.style\"\n :data-disabled=\"disabled || undefined\"\n :data-orientation=\"orientation\"\n :data-dragging=\"isDragging || undefined\"\n data-qa=\"dt-slider\"\n >\n <div\n v-if=\"showLabel\"\n :id=\"labelId\"\n :class=\"['d-slider__label', labelClass]\"\n data-qa=\"dt-slider-label\"\n >\n <!-- @slot Slot for the label, defaults to the label prop. Scoped with\n :value (Number, or Number[] in range mode) — the live value(s),\n updating as the thumb is dragged — for labels that echo the\n current value. Required for accessibility; set showLabel to false\n to hide it, and provide the label prop (not just this slot) so its\n text can be promoted to aria-label — a slot's rich markup can't\n collapse to the flat string aria-label requires. -->\n <slot\n name=\"label\"\n :value=\"currentValue\"\n >\n <dt-text\n v-if=\"label\"\n kind=\"label\"\n :size=\"resolvedLabelSize\"\n :strength=\"labelStrength\"\n :tone=\"disabled ? 'disabled' : 'secondary'\"\n >\n {{ label }}\n </dt-text>\n </slot>\n </div>\n <div\n :class=\"['d-slider__body', bodyClass, { 'd-slider__body--reserve-annotation-space': reservesAnnotationSpace }]\"\n data-qa=\"dt-slider-body\"\n >\n <div\n v-if=\"hasSlotContent($slots.start)\"\n :class=\"['d-slider__start', startClass]\"\n data-qa=\"dt-slider-start\"\n >\n <!-- @slot Optional content at the inline-start end of the track (aka left).\n When using icon-only content, add aria-label or hidden text to the icon. -->\n <slot name=\"start\" />\n </div>\n <div\n ref=\"controlRef\"\n class=\"d-slider__control\"\n :style=\"isVertical ? { touchAction: 'pan-x' } : { touchAction: 'pan-y' }\"\n data-qa=\"dt-slider-control\"\n @pointerdown=\"onPointerDown\"\n @pointermove=\"onPointerMove\"\n @pointerup=\"onPointerUp\"\n @pointercancel=\"onPointerUp\"\n >\n <div\n class=\"d-slider__track\"\n data-qa=\"dt-slider-track\"\n />\n <div\n class=\"d-slider__indicator\"\n :style=\"indicatorStyle\"\n data-qa=\"dt-slider-indicator\"\n />\n <!-- .d-slider__indicator's own z-index (slider.less) covers any tick\n that falls within its filled span regardless of template order —\n ticks only show through on the track's own unfilled portion. -->\n <template v-if=\"showTicks\">\n <div\n v-for=\"(tickValue, i) in computedTickValues\"\n :key=\"i\"\n class=\"d-slider__tick\"\n :style=\"tickPositionStyle(tickValue)\"\n data-qa=\"dt-slider-tick\"\n />\n </template>\n <div\n v-for=\"(val, i) in internalValues\"\n :key=\"`thumb-visual-${i}`\"\n :ref=\"(el) => { thumbVisualRefs[i] = el; }\"\n :class=\"[\n 'd-slider__thumb-visual',\n {\n 'd-slider__thumb-visual--focused': focusedThumbIndex === i,\n 'd-slider__thumb-visual--active': activeThumbIndex === i,\n },\n ]\"\n :style=\"thumbPositionStyle(val)\"\n data-qa=\"dt-slider-thumb-visual\"\n />\n <div\n v-for=\"(val, i) in internalValues\"\n :key=\"`thumb-hit-${i}`\"\n class=\"d-slider__thumb-hit\"\n :style=\"{ ...thumbPositionStyle(val), touchAction: isVertical ? 'pan-x' : 'pan-y' }\"\n data-qa=\"dt-slider-thumb-hit\"\n @pointerenter=\"onThumbHitPointerEnter(i)\"\n @pointerleave=\"onThumbHitPointerLeave(i)\"\n />\n <!-- A plain `ref=\"thumbRefs\"` only pushes in patch order (the same\n index-misalignment risk UseSliderCollisionAvoidance documents for\n markElRefs), but onPointerDown/updateThumbValue index into this\n directly — a function ref assigns by the v-for's own index, and\n self-cleans on unmount when range shrinks to single mode.\n Keep :value after :min/:max/:step: Vue patches them in template\n order, and the browser clamps a value set against stale bounds. -->\n <input\n v-for=\"(val, i) in internalValues\"\n :key=\"`thumb-input-${i}`\"\n :ref=\"(el) => { thumbRefs[i] = el; }\"\n type=\"range\"\n class=\"d-slider__thumb\"\n :min=\"thumbNativeMin(i)\"\n :max=\"thumbNativeMax(i)\"\n :step=\"thumbNativeStep(i)\"\n :value=\"val\"\n :disabled=\"disabled\"\n :name=\"name || undefined\"\n :aria-labelledby=\"resolvedAriaLabelledby\"\n :aria-label=\"resolvedAriaLabel\"\n :aria-describedby=\"attrs['aria-describedby']\"\n :aria-errormessage=\"attrs['aria-errormessage']\"\n :aria-details=\"attrs['aria-details']\"\n :aria-invalid=\"attrs['aria-invalid']\"\n :aria-valuetext=\"formatValue(val, i)\"\n :aria-orientation=\"isVertical ? 'vertical' : undefined\"\n data-qa=\"dt-slider-thumb\"\n @input=\"onThumbInput(i, $event)\"\n @keydown=\"onThumbKeydown(i, $event)\"\n @focus=\"onThumbFocus(i, $event)\"\n @blur=\"onThumbBlur(i, $event)\"\n >\n <div\n v-for=\"(mark, i) in computedMarks\"\n :key=\"`mark-${i}`\"\n ref=\"markElRefs\"\n :class=\"['d-slider__mark', { 'd-slider__mark--collision-hidden': markCollisionHidden[i] }]\"\n :style=\"markStyle(mark.pct, i, mark.edge)\"\n :data-mark-index=\"i\"\n data-qa=\"dt-slider-mark\"\n >\n {{ mark.text }}\n </div>\n <!-- Plain, CSS-positioned text — deliberately not a floating tooltip/portal.\n It sits in the same row as marks, positioned by the same value-to-percent\n math, so it never needs JS measurement or a reposition loop that could\n desync from the thumb. -->\n <template v-if=\"readout === 'always'\">\n <div\n v-for=\"(val, i) in internalValues\"\n :key=\"`readout-${i}`\"\n ref=\"readoutElRefs\"\n :class=\"[\n 'd-slider__readout',\n !readoutMerged ? 'd-slider__readout--show' : 'd-slider__readout--hide',\n readoutClass,\n ]\"\n :style=\"readoutStyle(thumbPercent(val), readoutEdgeOffsetPx[i], readoutEdge(val))\"\n :data-readout-index=\"i\"\n aria-hidden=\"true\"\n data-qa=\"dt-slider-thumb-readout\"\n >\n {{ formatValue(val, i) }}\n </div>\n <!-- Range mode only: when the two individual readouts above would overlap,\n they're hidden (still measurable — visibility:hidden) and this single\n merged pill takes over, centered between the thumbs. -->\n <div\n v-if=\"readoutMerged\"\n ref=\"mergedReadoutElRef\"\n :class=\"['d-slider__readout', 'd-slider__readout--show', readoutClass]\"\n :style=\"readoutStyle(mergedReadoutPct, mergedReadoutEdgeOffsetPx)\"\n aria-hidden=\"true\"\n data-qa=\"dt-slider-thumb-readout-merged\"\n >\n {{ mergedReadoutText }}\n </div>\n </template>\n <!-- Keep DOM parentage for inherited themes; native popovers paint\n outside every ancestor's overflow, clip path, and mask. -->\n <template v-if=\"readout === 'tooltip'\">\n <div\n v-for=\"(val, i) in internalValues\"\n :key=\"`readout-tooltip-${i}`\"\n :ref=\"(el) => { tooltipElRefs[i] = el; }\"\n class=\"d-tooltip d-slider__readout-tooltip\"\n popover=\"manual\"\n inert\n aria-hidden=\"true\"\n data-qa=\"dt-slider-thumb-readout-tooltip\"\n >\n <span class=\"d-slider__tooltip-content\">{{ formatValue(val, i) }}</span>\n </div>\n </template>\n </div>\n <div\n v-if=\"hasSlotContent($slots.end)\"\n :class=\"['d-slider__end', endClass]\"\n data-qa=\"dt-slider-end\"\n >\n <!-- @slot Optional content at the inline-end end of the track (aka right).\n When using icon-only content, add aria-label or hidden text to the icon. -->\n <slot name=\"end\" />\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\n// @ts-nocheck\nimport { ref, computed, Comment, useSlots, useAttrs } from 'vue';\nimport { DtText, TEXT_SIZE_MODIFIERS, TEXT_STRENGTH_MODIFIERS } from '@/components/Text';\nimport { getUniqueString, hasSlotContent, removeClassStyleAttrs } from '@/common/utils';\nimport {\n SLIDER_ORIENTATIONS,\n SLIDER_READOUT_MODES,\n SLIDER_DEFAULT_LARGE_STEP,\n SLIDER_FILL_ORIGINS,\n} from './SliderConstants';\nimport { useSliderDevWarnings } from './Composables/UseSliderDevWarnings';\nimport { useSliderDirection } from './Composables/UseSliderDirection';\nimport { useSliderValue } from './Composables/UseSliderValue';\nimport { useSliderMagneticSnap } from './Composables/UseSliderMagneticSnap';\nimport { useSliderInteraction } from './Composables/UseSliderInteraction';\nimport { useSliderGeometry } from './Composables/UseSliderGeometry';\nimport { useSliderMarksAndTicks } from './Composables/UseSliderMarksAndTicks';\nimport { useSliderCollisionAvoidance } from './Composables/UseSliderCollisionAvoidance';\nimport { useSliderTooltipReadout } from './Composables/UseSliderTooltipReadout';\nimport { isValidMark } from './utils';\n\ndefineOptions({ name: 'DtSlider', inheritAttrs: false });\n\nconst props = defineProps({\n /**\n * The current value. A number enables single-thumb mode; an array of two\n * numbers enables range mode. When omitted (or explicitly undefined/null),\n * resolves to the midpoint of [min, max] — matching native\n * <input type=\"range\"> — see normalizeModelValue.\n */\n modelValue: {\n type: [Number, Array],\n default: undefined,\n validator: (value) => !Array.isArray(value) || value.length === 2,\n },\n\n /**\n * The minimum allowed value. Must be finite.\n */\n min: {\n type: Number,\n default: 0,\n validator: Number.isFinite,\n },\n\n /**\n * The maximum allowed value. Must be finite.\n */\n max: {\n type: Number,\n default: 100,\n validator: Number.isFinite,\n },\n\n /**\n * The increment/decrement step. Must be finite.\n */\n step: {\n type: Number,\n default: 1,\n validator: Number.isFinite,\n },\n\n /**\n * Magnetic snap points the thumb pulls toward while dragging — unlike\n * step, this doesn't restrict which values are selectable; a value just\n * outside the snap radius of a snap point stays freely reachable. Pass a\n * number for an evenly spaced interval (e.g. 25), or an array for\n * arbitrary values (e.g. [10, 42, 90]). Pointer drag only — keyboard\n * stepping (step/largeStep) is unaffected.\n * Values must be finite numbers; malformed array entries are ignored.\n */\n snapPoints: {\n type: [Number, Array],\n default: undefined,\n validator: (value) => Number.isFinite(value) || (Array.isArray(value) && value.every(Number.isFinite)),\n },\n\n /**\n * Disables the slider, preventing interaction.\n * @values true, false\n */\n disabled: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Track orientation.\n * @values horizontal, vertical\n */\n orientation: {\n type: String,\n default: 'horizontal',\n validator: (v) => SLIDER_ORIENTATIONS.includes(v),\n },\n\n /**\n * Which end the indicator fills from, toward the thumb: \"start\" (the\n * default, aka left) fills from the min end, \"end\" (aka right) fills from\n * the max end. Pass a Number instead to fill outward from that value\n * toward the thumb — useful for balance controls (aka center-fill) or\n * deviation-from-setpoint displays. A numeric origin is clamped to\n * [min, max]. Ignored in range mode.\n */\n fillOrigin: {\n type: [Number, String],\n default: 'start',\n validator: (v) => typeof v === 'number' || SLIDER_FILL_ORIGINS.includes(v),\n },\n\n /**\n * Renders tick marks along the track. Pass true to put a tick at every step;\n * pass a Number instead to space ticks at that interval (same units as step).\n */\n showTicks: {\n type: [Boolean, Number],\n default: false,\n },\n\n /**\n * Minimum gap, in steps (not raw values), that must remain between the two\n * thumbs in range mode: the actual minimum gap enforced between their\n * values is minGapSteps * step, so the same prop value means a different\n * real gap depending on step (e.g. minGapSteps={5} enforces a gap of 5 with\n * step={1}, but 50 with step={10}).\n */\n minGapSteps: {\n type: Number,\n default: 0,\n },\n\n /**\n * Visible label text. Required for accessibility; if omitted, provide aria-label on the component.\n */\n label: {\n type: String,\n default: '',\n },\n\n /**\n * When false, the label is removed and its text (the label prop, not the\n * #label slot) is promoted to aria-label instead — matching DtInput,\n * DtCheckbox, DtRadio, and DtSelectMenu's own showLabel behavior.\n * @values true, false\n */\n showLabel: {\n type: Boolean,\n default: true,\n },\n\n /**\n * Overrides the label text size.\n * @values 100, 200, 300, 400\n */\n labelSize: {\n type: [String, Number],\n default: null,\n validator: (s) => TEXT_SIZE_MODIFIERS.label.includes(String(s)),\n },\n\n /**\n * Overrides the label font weight.\n * @values bold, semibold, medium, normal\n */\n labelStrength: {\n type: String,\n default: null,\n validator: (s) => Object.keys(TEXT_STRENGTH_MODIFIERS).includes(s),\n },\n\n /**\n * A function returning the user-facing text for a value — shared by the readout and\n * each thumb's aria-valuetext, so the two always agree on how a number is displayed.\n * Signature: (value: number, index?: number) => string. index is the thumb index (use\n * it to differentiate thumbs in range mode, e.g. \"Minimum: 20\" / \"Maximum: 70\").\n * Deliberately NOT used for a mark's own auto-generated text — a mark isn't tied to\n * either thumb, so there's no index this function could meaningfully receive; marks use\n * prefix/suffix instead (see the showMarks prop), or their own explicit text override.\n * Takes precedence over prefix/suffix for the readout and aria-valuetext when set. The\n * default (null) uses the raw number (optionally wrapped in prefix/suffix), which must\n * be i18n-safe for your context.\n */\n getValueText: {\n type: Function,\n default: null,\n },\n\n /**\n * Text prepended to the raw number wherever it's displayed — e.g. prefix=\"$\" for\n * currency. Always applied to marks. Ignored by the readout and aria-valuetext when\n * getValueText is set (see getValueText). A long prefix makes every mark's text\n * longer too — keep it short enough that the first/last mark stays legible near\n * the track's own edges (see showMarks).\n */\n prefix: {\n type: String,\n default: '',\n },\n\n /**\n * Text appended to the raw number wherever it's displayed — e.g. suffix=\"%\" for a\n * percentage. Always applied to marks. Ignored by the readout and aria-valuetext when\n * getValueText is set (see getValueText). Same edge-legibility caveat as prefix\n * applies (see showMarks).\n */\n suffix: {\n type: String,\n default: '',\n },\n\n /**\n * Native name attribute for form submission. In range mode, both inputs share this name.\n * Retrieve both values with FormData.getAll(name).\n */\n name: {\n type: String,\n default: '',\n },\n\n /**\n * Roughly how far to move on Page Up/Page Down or Shift + Arrow, in the\n * same units as step — rounded to the nearest whole number of steps (at\n * least one), so the result always lands on the step grid and always\n * moves, even when step is coarser than largeStep itself.\n */\n largeStep: {\n type: Number,\n default: SLIDER_DEFAULT_LARGE_STEP,\n },\n\n /**\n * Additional class(es) applied to the body wrapper containing the start slot, control, and end slot.\n */\n bodyClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Additional class(es) applied to the label wrapper element.\n */\n labelClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Additional class(es) applied to the inline-start slot wrapper (aka left).\n */\n startClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Additional class(es) applied to the inline-end slot wrapper (aka right).\n */\n endClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Controls the live value readout for each thumb: a tooltip-styled bubble above the\n * thumb shown only while hovering, dragging, or focusing it (the default); always\n * visible below the track; or never shown. Text is formatted via getValueText\n * when set, otherwise prefix/suffix — same as each thumb's aria-valuetext, but\n * unlike a mark's own auto-generated text (see showMarks). The tooltip uses\n * the native Popover API to escape ancestor clipping and stays within the\n * viewport. Browsers without that API do not display the floating readout;\n * use always when a visible value is needed there. The inline readout\n * and the merged two-thumb pill are not edge-clamped, so a long formatted value can render\n * close to or past the track's own edge at those values.\n * @values tooltip, always, never\n */\n readout: {\n type: String,\n default: 'tooltip',\n validator: (v) => SLIDER_READOUT_MODES.includes(v),\n },\n\n /**\n * Additional class(es) applied to the individual and merged inline readouts when readout is 'always'.\n * Ignored when readout is 'tooltip' or 'never'.\n */\n readoutClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Text annotations rendered below the track at specific positions, independent of ticks.\n * Off by default — rendering min/max isn't always wanted. Pass true to label min and max\n * (start and end) only. Pass an array for explicit control: each entry is either a plain\n * number (text defaults to the number itself, formatted with prefix/suffix — NOT\n * getValueText, which has no meaningful index for a position that isn't tied to either\n * thumb) or an object with a required value and optional text override, which is used\n * as-is regardless of prefix/suffix/getValueText.\n * Example: [{ value: 0, text: 'Neutral' }, -100, 100]\n * Mark values must be finite numbers; malformed entries are ignored.\n *\n * Keep mark text (via a short prefix/suffix, or an explicit text override) reasonably\n * short — a mark landing exactly on min or max is edge-aligned rather than centered, and\n * any other mark is nudged inward once it would otherwise render past the track's own\n * edges, but very long text can still end up close to the live readout or an adjacent mark.\n */\n showMarks: {\n type: [Array, Boolean],\n default: false,\n validator: (value) => typeof value === 'boolean' || (Array.isArray(value) && value.every(isValidMark)),\n },\n});\n\nconst emit = defineEmits([\n /**\n * Emitted on every value change (drag, keyboard, track click).\n * @event update:modelValue\n * @type {number | number[]}\n */\n 'update:modelValue',\n\n /**\n * Emitted when a value change commits: pointer up, blur, or a reactive\n * min/max/step/minGapSteps correction that lands outside any in-progress\n * drag. Use this for API calls or persistence.\n * @event change\n * @type {number | number[]}\n */\n 'change',\n\n /**\n * Native focus event on a thumb.\n * @event focus\n * @type {FocusEvent}\n */\n 'focus',\n\n /**\n * Native blur event on a thumb.\n * @event blur\n * @type {FocusEvent}\n */\n 'blur',\n]);\n\n// ─── Internal state ───────────────────────────────────────────────────────────\n\nconst slots = useSlots();\nconst attrs = useAttrs();\nconst labelId = `slider-label-${getUniqueString()}`;\nconst controlRef = ref(null);\nconst thumbRefs = ref([]);\nconst thumbVisualRefs = ref([]);\n\n// Prop-derived, not owned by any one composable — every composable that\n// needs either receives it as a plain argument below.\nconst isRange = computed(() => Array.isArray(props.modelValue));\nconst isVertical = computed(() => props.orientation === 'vertical');\n\nconst { isRtl } = useSliderDirection(controlRef);\n\n// Hoisted above useSliderValue (normally wired in right before\n// useSliderInteraction below) so useSliderValue's own reactive watchers can\n// tell a held magnetic snap apart from a genuinely new external value.\nconst { activeSnapValue, findMagneticSnapPoint } = useSliderMagneticSnap(props, { controlRef, isVertical });\n\nconst {\n internalValues,\n lastCommittedValues,\n currentValue,\n decimalPlaces,\n snapToStep,\n thumbPercent,\n thumbNativeMin,\n thumbNativeMax,\n thumbNativeStep,\n formatValue,\n} = useSliderValue(props, emit, { isRange, activeSnapValue });\n\n// Recurses into slot vnodes for actual TEXT, not just \"something renders\" —\n// an icon-only #label (e.g. a bare <dt-icon> with no text of its own) would\n// otherwise count as providing an accessible name, silently leaving the\n// thumb unnamed with no indication anything's wrong.\nfunction slotHasText(vnodes) {\n return vnodes.some((vnode) => {\n // A text vnode's own `children` is a plain string (handled below), but a\n // slot function (including the recursive default() call below) is only\n // contractually required to return SOME renderable value, not always an\n // array of vnodes — a bare string is valid too.\n if (typeof vnode === 'string') return vnode.trim() !== '';\n if (vnode.type === Comment) return false;\n if (typeof vnode.children === 'string') return vnode.children.trim() !== '';\n if (Array.isArray(vnode.children)) return slotHasText(vnode.children);\n // A child COMPONENT vnode (e.g. <dt-text>{{ label }}</dt-text> in\n // #label — the same pattern this component's own default fallback\n // markup below uses) has `children` as a slots object, not a string or\n // array — recurse into its own default slot to see what it will\n // actually render instead of treating it as textless.\n if (vnode.children && typeof vnode.children.default === 'function') {\n const result = vnode.children.default();\n return slotHasText(Array.isArray(result) ? result : [result]);\n }\n return false;\n });\n}\n\n// Whether what ACTUALLY renders for the label has real text — the #label\n// slot when a consumer provides one (it fully replaces the prop's own\n// fallback markup, so a textless slot, e.g. a bare icon, means no\n// accessible name regardless of the unused prop), otherwise the prop\n// itself. Independent of showLabel, which only controls visibility. Named\n// to match DtCheckbox/DtRadio's own hasLabelContent.\nconst hasLabelContent = computed(() => {\n if (slots.label) return slotHasText(slots.label({ value: currentValue.value }));\n return !!props.label?.trim();\n});\n\n// Each native thumb <input> names itself from the visible label when there\n// is one; otherwise it falls back to whatever aria-label/aria-labelledby a\n// consumer passed in (or, lacking even that, the label prop's own text when\n// it's being used as a hidden accessible name — showLabel false).\nconst usesVisibleLabelAsName = computed(() => props.showLabel && hasLabelContent.value);\nconst resolvedAriaLabelledby = computed(() => (\n usesVisibleLabelAsName.value ? labelId : attrs['aria-labelledby']\n));\nconst resolvedAriaLabel = computed(() => {\n if (usesVisibleLabelAsName.value) return undefined;\n return !props.showLabel && props.label ? props.label : attrs['aria-label'];\n});\n\nconst hasAccessibleName = computed(() => usesVisibleLabelAsName.value || !!(\n String(resolvedAriaLabel.value ?? '').trim() || String(resolvedAriaLabelledby.value ?? '').trim()\n));\n\nconst resolvedLabelSize = computed(() => props.labelSize ?? 300);\n\n// These forward to each native thumb <input> instead — the wrapper <div>\n// isn't a form control, so leaving them here would duplicate the name and\n// strand the rest where assistive tech querying the input would never see them.\nconst THUMB_ARIA_KEYS = ['aria-label', 'aria-labelledby', 'aria-describedby', 'aria-errormessage', 'aria-details', 'aria-invalid'];\nconst wrapperAttrs = computed(() => {\n const base = removeClassStyleAttrs(attrs);\n return Object.fromEntries(Object.entries(base).filter(([key]) => !THUMB_ARIA_KEYS.includes(key)));\n});\n\nconst {\n isDragging,\n activeThumbIndex,\n focusedThumbIndex,\n onPointerDown,\n onPointerMove,\n onPointerUp,\n onThumbInput,\n onThumbKeydown,\n onThumbFocus,\n onThumbBlur,\n onThumbHitPointerEnter,\n onThumbHitPointerLeave,\n isReadoutOpen,\n} = useSliderInteraction(props, emit, {\n controlRef,\n thumbRefs,\n internalValues,\n isRange,\n isVertical,\n decimalPlaces,\n snapToStep,\n lastCommittedValues,\n findMagneticSnapPoint,\n activeSnapValue,\n isRtl,\n});\n\n// ─── Computed visual helpers ──────────────────────────────────────────────────\n\nconst { computedTickValues, computedMarks, reservesAnnotationSpace } = useSliderMarksAndTicks(\n props,\n { isVertical, thumbPercent },\n);\n\nconst {\n markElRefs,\n readoutElRefs,\n mergedReadoutElRef,\n tooltipElRefs,\n markCollisionHidden,\n readoutMerged,\n markEdgeOffsetPx,\n readoutEdgeOffsetPx,\n mergedReadoutEdgeOffsetPx,\n readoutVisibility,\n formattedValues,\n updateCollisions,\n} = useSliderCollisionAvoidance(props, {\n controlRef,\n isVertical,\n isRange,\n internalValues,\n thumbPercent,\n isRtl,\n isReadoutOpen,\n computedMarks,\n formatValue,\n});\n\nconst {\n thumbPositionStyle,\n tickPositionStyle,\n markStyle,\n readoutStyle,\n mergedReadoutPct,\n mergedReadoutText,\n indicatorStyle,\n} = useSliderGeometry(props, {\n isVertical,\n isRange,\n internalValues,\n thumbPercent,\n isRtl,\n markEdgeOffsetPx,\n formatValue,\n});\n\n// Same \"edge\" detection computedMarks (UseSliderMarksAndTicks) uses for its\n// own min/max marks — a readout tracking a thumb sitting exactly at min/max\n// gets the same flush-edge treatment there.\nfunction readoutEdge(val) {\n return val === props.min ? 'start' : val === props.max ? 'end' : null;\n}\n\nuseSliderTooltipReadout(props, {\n thumbVisualRefs,\n tooltipElRefs,\n isVertical,\n isRtl,\n readoutVisibility,\n formattedValues,\n onPosition: updateCollisions,\n});\n\n// ─── Dev warnings ─────────────────────────────────────────────────────────────\n\nuseSliderDevWarnings(props, { isRange, hasAccessibleName });\n\n// ─── Exposed API ──────────────────────────────────────────────────────────────\n\nfunction focus() {\n thumbRefs.value[0]?.focus();\n}\n\nfunction blur() {\n // Whichever thumb actually has focus, not always thumb 0 — in range mode\n // the wrong (unfocused) thumb left the real one's deferred keyboard commit\n // (commitIfChanged) never firing. No-op when nothing is focused.\n thumbRefs.value.find((el) => el === document.activeElement)?.blur();\n}\n\ndefineExpose({ focus, blur });\n</script>\n"],"mappings":"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"}