base-ui-vue 0.2.0 → 0.4.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 (109) hide show
  1. package/dist/button/ToolbarButton.cjs +6 -0
  2. package/dist/button/ToolbarButton.js +1 -1
  3. package/dist/content/ScrollAreaContent.cjs +168 -0
  4. package/dist/content/ScrollAreaContent.cjs.map +1 -0
  5. package/dist/content/ScrollAreaContent.js +133 -0
  6. package/dist/content/ScrollAreaContent.js.map +1 -0
  7. package/dist/control/SliderControl.js +2 -2
  8. package/dist/corner/ScrollAreaCorner.cjs +77 -0
  9. package/dist/corner/ScrollAreaCorner.cjs.map +1 -0
  10. package/dist/corner/ScrollAreaCorner.js +72 -0
  11. package/dist/corner/ScrollAreaCorner.js.map +1 -0
  12. package/dist/decrement/NumberFieldDecrement.cjs +861 -0
  13. package/dist/decrement/NumberFieldDecrement.cjs.map +1 -0
  14. package/dist/decrement/NumberFieldDecrement.js +700 -0
  15. package/dist/decrement/NumberFieldDecrement.js.map +1 -0
  16. package/dist/fallback/AvatarFallback.cjs +2 -46
  17. package/dist/fallback/AvatarFallback.cjs.map +1 -1
  18. package/dist/fallback/AvatarFallback.js +3 -41
  19. package/dist/fallback/AvatarFallback.js.map +1 -1
  20. package/dist/group/NumberFieldGroup.cjs +72 -0
  21. package/dist/group/NumberFieldGroup.cjs.map +1 -0
  22. package/dist/group/NumberFieldGroup.js +67 -0
  23. package/dist/group/NumberFieldGroup.js.map +1 -0
  24. package/dist/increment/NumberFieldIncrement.cjs +112 -0
  25. package/dist/increment/NumberFieldIncrement.cjs.map +1 -0
  26. package/dist/increment/NumberFieldIncrement.js +107 -0
  27. package/dist/increment/NumberFieldIncrement.js.map +1 -0
  28. package/dist/index.cjs +52 -0
  29. package/dist/index.d.cts +1761 -430
  30. package/dist/index.d.cts.map +1 -1
  31. package/dist/index.d.ts +1761 -430
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +7 -2
  34. package/dist/index2.cjs +4065 -60
  35. package/dist/index2.cjs.map +1 -1
  36. package/dist/index2.js +3955 -184
  37. package/dist/index2.js.map +1 -1
  38. package/package.json +1 -1
  39. package/src/index.ts +6 -0
  40. package/src/input/Input.vue +37 -0
  41. package/src/input/InputDataAttributes.ts +30 -0
  42. package/src/input/index.ts +4 -0
  43. package/src/meter/index.ts +16 -0
  44. package/src/meter/indicator/MeterIndicator.vue +65 -0
  45. package/src/meter/label/MeterLabel.vue +63 -0
  46. package/src/meter/root/MeterRoot.vue +131 -0
  47. package/src/meter/root/MeterRootContext.ts +41 -0
  48. package/src/meter/track/MeterTrack.vue +46 -0
  49. package/src/meter/value/MeterValue.vue +85 -0
  50. package/src/number-field/decrement/NumberFieldDecrement.vue +109 -0
  51. package/src/number-field/group/NumberFieldGroup.vue +47 -0
  52. package/src/number-field/increment/NumberFieldIncrement.vue +109 -0
  53. package/src/number-field/index.ts +42 -0
  54. package/src/number-field/input/NumberFieldInput.vue +455 -0
  55. package/src/number-field/root/NumberFieldRoot.vue +626 -0
  56. package/src/number-field/root/NumberFieldRootContext.ts +94 -0
  57. package/src/number-field/root/useNumberFieldButton.ts +171 -0
  58. package/src/number-field/scrub-area/NumberFieldScrubArea.vue +359 -0
  59. package/src/number-field/scrub-area/NumberFieldScrubAreaContext.ts +26 -0
  60. package/src/number-field/scrub-area-cursor/NumberFieldScrubAreaCursor.vue +75 -0
  61. package/src/number-field/utils/constants.ts +4 -0
  62. package/src/number-field/utils/getViewportRect.ts +34 -0
  63. package/src/number-field/utils/parse.ts +248 -0
  64. package/src/number-field/utils/stateAttributesMapping.ts +9 -0
  65. package/src/number-field/utils/subscribeToVisualViewportResize.ts +27 -0
  66. package/src/number-field/utils/types.ts +24 -0
  67. package/src/number-field/utils/validate.ts +120 -0
  68. package/src/otp-field/index.ts +22 -0
  69. package/src/otp-field/input/OtpFieldInput.vue +336 -0
  70. package/src/otp-field/root/OtpFieldRoot.vue +583 -0
  71. package/src/otp-field/root/OtpFieldRootContext.ts +81 -0
  72. package/src/otp-field/utils/otp.ts +135 -0
  73. package/src/otp-field/utils/stateAttributesMapping.ts +16 -0
  74. package/src/progress/index.ts +23 -0
  75. package/src/progress/indicator/ProgressIndicator.vue +74 -0
  76. package/src/progress/label/ProgressLabel.vue +63 -0
  77. package/src/progress/root/ProgressRoot.vue +160 -0
  78. package/src/progress/root/ProgressRootContext.ts +51 -0
  79. package/src/progress/root/ProgressRootDataAttributes.ts +14 -0
  80. package/src/progress/root/stateAttributesMapping.ts +18 -0
  81. package/src/progress/track/ProgressTrack.vue +48 -0
  82. package/src/progress/value/ProgressValue.vue +92 -0
  83. package/src/scroll-area/constants.ts +2 -0
  84. package/src/scroll-area/content/ScrollAreaContent.vue +87 -0
  85. package/src/scroll-area/corner/ScrollAreaCorner.vue +64 -0
  86. package/src/scroll-area/index.ts +25 -0
  87. package/src/scroll-area/root/ScrollAreaRoot.vue +297 -0
  88. package/src/scroll-area/root/ScrollAreaRootContext.ts +89 -0
  89. package/src/scroll-area/root/ScrollAreaRootCssVars.ts +4 -0
  90. package/src/scroll-area/root/ScrollAreaRootDataAttributes.ts +9 -0
  91. package/src/scroll-area/root/stateAttributes.ts +14 -0
  92. package/src/scroll-area/scrollbar/ScrollAreaScrollbar.vue +263 -0
  93. package/src/scroll-area/scrollbar/ScrollAreaScrollbarContext.ts +20 -0
  94. package/src/scroll-area/scrollbar/ScrollAreaScrollbarCssVars.ts +4 -0
  95. package/src/scroll-area/scrollbar/ScrollAreaScrollbarDataAttributes.ts +11 -0
  96. package/src/scroll-area/thumb/ScrollAreaThumb.vue +120 -0
  97. package/src/scroll-area/thumb/ScrollAreaThumbDataAttributes.ts +3 -0
  98. package/src/scroll-area/utils/getOffset.ts +34 -0
  99. package/src/scroll-area/viewport/ScrollAreaViewport.vue +379 -0
  100. package/src/scroll-area/viewport/ScrollAreaViewportContext.ts +20 -0
  101. package/src/scroll-area/viewport/ScrollAreaViewportCssVars.ts +6 -0
  102. package/src/scroll-area/viewport/ScrollAreaViewportDataAttributes.ts +9 -0
  103. package/src/utils/detectBrowser.ts +15 -0
  104. package/src/utils/formatNumber.ts +60 -2
  105. package/src/utils/scrollEdges.ts +33 -0
  106. package/src/utils/styles.ts +28 -0
  107. package/src/utils/useInterval.ts +45 -0
  108. package/src/utils/usePressAndHold.ts +260 -0
  109. package/src/utils/useValueChanged.ts +21 -0
package/dist/index2.js CHANGED
@@ -2,14 +2,16 @@ import { EMPTY_OBJECT, compositeRootContextKey, error, mergeProps as mergeProps$
2
2
  import { CollapsiblePanelDataAttributes, accordionItemContextKey, accordionStateAttributesMapping, collapsibleOpenStateMapping, triggerOpenStateMapping, useAccordionItemContext } from "./header/AccordionHeader.js";
3
3
  import { AnimationFrame, REASONS, createChangeEventDetails, createGenericEventDetails, fieldItemContextKey, transitionStatusMapping, useAnimationFrame, useAnimationsFinished, useAriaLabelledBy, useOpenChangeComplete, useTransitionStatus, visuallyHidden, visuallyHiddenInput } from "./checkbox/index.js";
4
4
  import { DEFAULT_VALIDITY_STATE, fieldRootContextKey, fieldValidityMapping, getCombinedFieldValidityData, labelableContextKey, useBaseUiId, useCheckboxGroupContext, useControllableState, useField, useFieldRootContext, useFormContext, useLabelableContext } from "./checkbox-group/CheckboxGroup.js";
5
- import { CompositeItem_default, compositeListContextKey, toolbarRootContextKey, useCompositeListItem, useToolbarGroupContext, useToolbarRootContext } from "./button/ToolbarButton.js";
6
- import { activeElement, clamp, contains, getMidpoint, getTarget, ownerDocument, roundValueToStep, sliderRootContextKey, sliderStateAttributesMapping, useDirection, useSliderRootContext, validateMinimumDistance } from "./control/SliderControl.js";
5
+ import { CompositeItem_default, IndexGuessBehavior, compositeListContextKey, toolbarRootContextKey, useCompositeListItem, useToolbarGroupContext, useToolbarRootContext } from "./button/ToolbarButton.js";
6
+ import { activeElement, clamp, contains, getMidpoint, getTarget, ownerDocument, ownerWindow, roundValueToStep, sliderRootContextKey, sliderStateAttributesMapping, useDirection, useSliderRootContext, validateMinimumDistance } from "./control/SliderControl.js";
7
7
  import { ALL_KEYS, ARROW_DOWN as ARROW_DOWN$1, ARROW_KEYS, ARROW_LEFT as ARROW_LEFT$1, ARROW_RIGHT as ARROW_RIGHT$1, ARROW_UP as ARROW_UP$1, COMPOSITE_KEYS, END, HOME, HORIZONTAL_KEYS, HORIZONTAL_KEYS_WITH_EXTRA_KEYS, MODIFIER_KEYS, PAGE_DOWN, PAGE_UP, VERTICAL_KEYS, VERTICAL_KEYS_WITH_EXTRA_KEYS, isNativeInput, scrollIntoViewIfNeeded } from "./composite/composite.js";
8
- import { AvatarRootContextKey, avatarStateAttributesMapping, useTimeout } from "./fallback/AvatarFallback.js";
8
+ import { ANY_MINUS_DETECT_RE, ANY_MINUS_RE, ANY_PLUS_DETECT_RE, ANY_PLUS_RE, ARABIC_DETECT_RE, BASE_NON_NUMERIC_SYMBOLS, DEFAULT_STEP, FULLWIDTH_DETECT_RE, HAN_DETECT_RE, MINUS_SIGNS_WITH_ASCII, PERCENTAGES, PERMILLE, PERSIAN_DETECT_RE, PLUS_SIGNS_WITH_ASCII, SPACE_SEPARATOR_RE, formatNumber, formatNumberMaxPrecision, formatNumberValue, getFormatter, getNumberLocaleDetails, numberFieldRootContextKey, parseNumber, stateAttributesMapping as stateAttributesMapping$1, useNumberFieldRootContext, useTimeout } from "./decrement/NumberFieldDecrement.js";
9
+ import { AvatarRootContextKey, avatarStateAttributesMapping } from "./fallback/AvatarFallback.js";
9
10
  import { useCSPContext } from "./csp-provider/CSPContext.js";
10
- import { useLabelableId } from "./control/FieldControl.js";
11
+ import { FieldControl_default, useLabelableId } from "./control/FieldControl.js";
12
+ import { scrollAreaRootContextKey, scrollAreaStateAttributesMapping, scrollAreaViewportContextKey, useScrollAreaRootContext } from "./content/ScrollAreaContent.js";
11
13
  import { ACTIVE_COMPOSITE_ITEM } from "./composite/constants.js";
12
- import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createTextVNode, defineComponent, getCurrentInstance, guardReactiveProps, inject, mergeProps, normalizeClass, normalizeProps, normalizeStyle, onBeforeUnmount, onMounted, onUnmounted, openBlock, provide, reactive, readonly, ref, renderSlot, resolveDynamicComponent, shallowReadonly, shallowRef, toDisplayString, toValue, unref, useAttrs, watch, watchEffect, watchSyncEffect, withCtx } from "vue";
14
+ import { Fragment, Teleport, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createTextVNode, defineComponent, getCurrentInstance, guardReactiveProps, inject, mergeProps, normalizeClass, normalizeProps, normalizeStyle, onBeforeUnmount, onMounted, onUnmounted, openBlock, provide, reactive, readonly, ref, renderSlot, resolveDynamicComponent, shallowReadonly, shallowRef, toDisplayString, toValue, unref, useAttrs, watch, watchEffect, watchSyncEffect, withCtx } from "vue";
13
15
  import { isHTMLElement } from "@floating-ui/utils/dom";
14
16
  import { floor } from "@floating-ui/utils";
15
17
 
@@ -822,7 +824,7 @@ var CompositeList_default = CompositeList_vue_vue_type_script_setup_true_lang_de
822
824
 
823
825
  //#endregion
824
826
  //#region src/accordion/root/stateAttributesMapping.ts
825
- const rootStateAttributesMapping = { value: () => null };
827
+ const rootStateAttributesMapping$1 = { value: () => null };
826
828
 
827
829
  //#endregion
828
830
  //#region src/accordion/root/AccordionRoot.vue?vue&type=script&setup=true&lang.ts
@@ -958,7 +960,7 @@ var AccordionRoot_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
958
960
  dir: direction.value,
959
961
  role: "region"
960
962
  })),
961
- stateAttributesMapping: rootStateAttributesMapping,
963
+ stateAttributesMapping: rootStateAttributesMapping$1,
962
964
  defaultTagName: "div"
963
965
  });
964
966
  return (_ctx, _cache) => {
@@ -2695,27 +2697,82 @@ var FieldsetRoot_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ d
2695
2697
  var FieldsetRoot_default = FieldsetRoot_vue_vue_type_script_setup_true_lang_default;
2696
2698
 
2697
2699
  //#endregion
2698
- //#region src/separator/Separator.vue?vue&type=script&setup=true&lang.ts
2700
+ //#region src/input/Input.vue?vue&type=script&setup=true&lang.ts
2699
2701
  /**
2700
- * A separator element accessible to screen readers.
2701
- * Renders a `<div>` element.
2702
+ * A native input element that automatically works with
2703
+ * [Field](https://baseui-vue.com/docs/components/field).
2704
+ * Renders an `<input>` element.
2702
2705
  *
2703
- * Documentation: [Base UI Vue Separator](https://baseui-vue.com/docs/components/separator)
2706
+ * Documentation: [Base UI Vue Input](https://baseui-vue.com/docs/components/input)
2704
2707
  */
2705
- var Separator_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
2706
- name: "Separator",
2708
+ var Input_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
2709
+ name: "BaseUIInput",
2707
2710
  inheritAttrs: false,
2708
- __name: "Separator",
2711
+ __name: "Input",
2709
2712
  props: {
2710
- orientation: {
2713
+ id: {
2711
2714
  type: String,
2712
- required: false,
2713
- default: "horizontal"
2715
+ required: false
2716
+ },
2717
+ name: {
2718
+ type: String,
2719
+ required: false
2720
+ },
2721
+ disabled: {
2722
+ type: Boolean,
2723
+ required: false
2724
+ },
2725
+ value: {
2726
+ type: String,
2727
+ required: false
2728
+ },
2729
+ defaultValue: {
2730
+ type: String,
2731
+ required: false
2732
+ },
2733
+ autofocus: {
2734
+ type: Boolean,
2735
+ required: false
2736
+ },
2737
+ type: {
2738
+ type: String,
2739
+ required: false
2740
+ },
2741
+ required: {
2742
+ type: Boolean,
2743
+ required: false
2744
+ },
2745
+ pattern: {
2746
+ type: String,
2747
+ required: false
2748
+ },
2749
+ minlength: {
2750
+ type: Number,
2751
+ required: false
2752
+ },
2753
+ maxlength: {
2754
+ type: Number,
2755
+ required: false
2756
+ },
2757
+ min: {
2758
+ type: [String, Number],
2759
+ required: false
2760
+ },
2761
+ max: {
2762
+ type: [String, Number],
2763
+ required: false
2764
+ },
2765
+ step: {
2766
+ type: [String, Number],
2767
+ required: false
2768
+ },
2769
+ placeholder: {
2770
+ type: String,
2771
+ required: false
2714
2772
  },
2715
2773
  as: {
2716
2774
  type: null,
2717
- required: false,
2718
- default: "div"
2775
+ required: false
2719
2776
  },
2720
2777
  class: {
2721
2778
  type: Function,
@@ -2735,50 +2792,59 @@ var Separator_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defi
2735
2792
  skipCheck: true
2736
2793
  }
2737
2794
  },
2795
+ emits: ["valueChange"],
2738
2796
  setup(__props) {
2739
2797
  const props = __props;
2740
2798
  const attrs = useAttrs();
2741
- const state = computed(() => ({ orientation: props.orientation }));
2742
- const { tag, mergedProps, renderless, ref: renderRef } = useRenderElement({
2743
- componentProps: props,
2744
- state,
2745
- props: computed(() => ({
2746
- ...attrs,
2747
- "role": "separator",
2748
- "aria-orientation": props.orientation
2749
- })),
2750
- defaultTagName: "div"
2751
- });
2752
2799
  return (_ctx, _cache) => {
2753
- return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
2754
- key: 0,
2755
- ref: unref(renderRef),
2756
- props: unref(mergedProps),
2757
- state: state.value
2758
- }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), mergeProps({
2759
- key: 1,
2760
- ref: unref(renderRef)
2761
- }, unref(mergedProps)), {
2762
- default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: state.value })]),
2763
- _: 3
2764
- }, 16));
2800
+ return openBlock(), createBlock(FieldControl_default, mergeProps({
2801
+ ...props,
2802
+ ...unref(attrs)
2803
+ }, { onValueChange: _cache[0] || (_cache[0] = (v, e) => _ctx.$emit("valueChange", v, e)) }), createSlots({ _: 2 }, [_ctx.$slots.default ? {
2804
+ name: "default",
2805
+ fn: withCtx((slotProps) => [renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(slotProps)))]),
2806
+ key: "0"
2807
+ } : void 0]), 1040);
2765
2808
  };
2766
2809
  }
2767
2810
  });
2768
2811
 
2769
2812
  //#endregion
2770
- //#region src/separator/Separator.vue
2771
- var Separator_default = Separator_vue_vue_type_script_setup_true_lang_default;
2813
+ //#region src/input/Input.vue
2814
+ var Input_default = Input_vue_vue_type_script_setup_true_lang_default;
2772
2815
 
2773
2816
  //#endregion
2774
- //#region src/separator/SeparatorDataAttributes.ts
2775
- let SeparatorDataAttributes = /* @__PURE__ */ function(SeparatorDataAttributes) {
2817
+ //#region src/input/InputDataAttributes.ts
2818
+ let InputDataAttributes = /* @__PURE__ */ function(InputDataAttributes) {
2776
2819
  /**
2777
- * Indicates the orientation of the separator.
2778
- * @type {'horizontal' | 'vertical'}
2820
+ * Present when the input is disabled.
2779
2821
  */
2780
- SeparatorDataAttributes["orientation"] = "data-orientation";
2781
- return SeparatorDataAttributes;
2822
+ InputDataAttributes["disabled"] = "data-disabled";
2823
+ /**
2824
+ * Present when the input is in a valid state (when wrapped in FieldRoot).
2825
+ */
2826
+ InputDataAttributes["valid"] = "data-valid";
2827
+ /**
2828
+ * Present when the input is in an invalid state (when wrapped in FieldRoot).
2829
+ */
2830
+ InputDataAttributes["invalid"] = "data-invalid";
2831
+ /**
2832
+ * Present when the input has been touched (when wrapped in FieldRoot).
2833
+ */
2834
+ InputDataAttributes["touched"] = "data-touched";
2835
+ /**
2836
+ * Present when the input's value has changed (when wrapped in FieldRoot).
2837
+ */
2838
+ InputDataAttributes["dirty"] = "data-dirty";
2839
+ /**
2840
+ * Present when the input is filled (when wrapped in FieldRoot).
2841
+ */
2842
+ InputDataAttributes["filled"] = "data-filled";
2843
+ /**
2844
+ * Present when the input is focused (when wrapped in FieldRoot).
2845
+ */
2846
+ InputDataAttributes["focused"] = "data-focused";
2847
+ return InputDataAttributes;
2782
2848
  }({});
2783
2849
 
2784
2850
  //#endregion
@@ -2789,17 +2855,26 @@ function valueToPercent(value, min, max) {
2789
2855
  }
2790
2856
 
2791
2857
  //#endregion
2792
- //#region src/slider/indicator/SliderIndicator.vue?vue&type=script&setup=true&lang.ts
2858
+ //#region src/meter/root/MeterRootContext.ts
2859
+ const meterRootContextKey = Symbol("MeterRootContext");
2860
+ function useMeterRootContext(optional = false) {
2861
+ const context = inject(meterRootContextKey, void 0);
2862
+ if (!context && !optional) throw new Error("Base UI Vue: MeterRootContext is missing. Meter parts must be placed within <MeterRoot>.");
2863
+ return context;
2864
+ }
2865
+
2866
+ //#endregion
2867
+ //#region src/meter/indicator/MeterIndicator.vue?vue&type=script&setup=true&lang.ts
2793
2868
  /**
2794
- * Visualizes the current value of the slider.
2869
+ * Visualizes the position of the value along the range.
2795
2870
  * Renders a `<div>` element.
2796
2871
  *
2797
- * Documentation: [Base UI Vue Slider](https://baseui-vue.com/docs/components/slider)
2872
+ * Documentation: [Base UI Vue Meter](https://baseui-vue.com/docs/components/meter)
2798
2873
  */
2799
- var SliderIndicator_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
2800
- name: "SliderIndicator",
2874
+ var MeterIndicator_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
2875
+ name: "MeterIndicator",
2801
2876
  inheritAttrs: false,
2802
- __name: "SliderIndicator",
2877
+ __name: "MeterIndicator",
2803
2878
  props: {
2804
2879
  as: {
2805
2880
  type: null,
@@ -2826,74 +2901,27 @@ var SliderIndicator_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ *
2826
2901
  },
2827
2902
  setup(__props) {
2828
2903
  const props = __props;
2829
- function getInsetStyles(vertical, range, start, end, renderBeforeHydration, mounted) {
2830
- const visibility = start === void 0 || range && end === void 0 ? "hidden" : void 0;
2831
- const startEdge = vertical ? "bottom" : "insetInlineStart";
2832
- const mainSide = vertical ? "height" : "width";
2833
- const styles = {
2834
- visibility: renderBeforeHydration && !mounted ? "hidden" : visibility,
2835
- position: vertical ? "absolute" : "relative",
2836
- [vertical ? "width" : "height"]: "inherit"
2837
- };
2838
- styles["--start-position"] = `${start ?? 0}%`;
2839
- if (!range) {
2840
- styles[startEdge] = 0;
2841
- styles[mainSide] = "var(--start-position)";
2842
- return styles;
2843
- }
2844
- styles["--relative-size"] = `${(end ?? 0) - (start ?? 0)}%`;
2845
- styles[startEdge] = "var(--start-position)";
2846
- styles[mainSide] = "var(--relative-size)";
2847
- return styles;
2848
- }
2849
- function getCenteredStyles(vertical, range, start, end) {
2850
- const startEdge = vertical ? "bottom" : "insetInlineStart";
2851
- const mainSide = vertical ? "height" : "width";
2852
- const styles = {
2853
- position: vertical ? "absolute" : "relative",
2854
- [vertical ? "width" : "height"]: "inherit"
2855
- };
2856
- if (!range) {
2857
- styles[startEdge] = 0;
2858
- styles[mainSide] = `${start}%`;
2859
- return styles;
2860
- }
2861
- styles[startEdge] = `${start}%`;
2862
- styles[mainSide] = `${end - start}%`;
2863
- return styles;
2864
- }
2865
2904
  const attrs = useAttrs();
2866
- const rootContext = useSliderRootContext();
2867
- const isMounted = ref(false);
2868
- onMounted(() => {
2869
- isMounted.value = true;
2870
- });
2871
- const vertical = computed(() => rootContext.orientation.value === "vertical");
2872
- const range = computed(() => rootContext.values.value.length > 1);
2873
- const style = computed(() => rootContext.inset.value ? getInsetStyles(vertical.value, range.value, rootContext.indicatorPosition.value[0], rootContext.indicatorPosition.value[1], rootContext.renderBeforeHydration.value, isMounted.value) : getCenteredStyles(vertical.value, range.value, valueToPercent(rootContext.values.value[0], rootContext.min.value, rootContext.max.value), valueToPercent(rootContext.values.value[rootContext.values.value.length - 1], rootContext.min.value, rootContext.max.value)));
2874
- const indicatorProps = computed(() => mergeProps$1(attrs, {
2875
- "data-base-ui-slider-indicator": rootContext.renderBeforeHydration.value ? "" : void 0,
2876
- "style": style.value,
2877
- "suppressHydrationWarning": rootContext.renderBeforeHydration.value || void 0
2878
- }));
2879
- const { tag, mergedProps, renderless, ref: renderRef } = useRenderElement({
2905
+ const rootContext = useMeterRootContext();
2906
+ const percentageWidth = computed(() => valueToPercent(rootContext.value.value, rootContext.min.value, rootContext.max.value));
2907
+ const state = computed(() => ({}));
2908
+ const { tag, mergedProps, renderless } = useRenderElement({
2880
2909
  componentProps: props,
2881
- state: rootContext.state,
2882
- props: indicatorProps,
2883
- defaultTagName: "div",
2884
- stateAttributesMapping: sliderStateAttributesMapping
2910
+ state,
2911
+ props: computed(() => mergeProps$1({ style: {
2912
+ insetInlineStart: 0,
2913
+ height: "inherit",
2914
+ width: `${percentageWidth.value}%`
2915
+ } }, attrs)),
2916
+ defaultTagName: "div"
2885
2917
  });
2886
2918
  return (_ctx, _cache) => {
2887
2919
  return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
2888
2920
  key: 0,
2889
- ref: unref(renderRef),
2890
2921
  props: unref(mergedProps),
2891
- state: unref(rootContext).state
2892
- }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), mergeProps({
2893
- key: 1,
2894
- ref: unref(renderRef)
2895
- }, unref(mergedProps)), {
2896
- default: withCtx(() => [renderSlot(_ctx.$slots, "default")]),
2922
+ state: state.value
2923
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), normalizeProps(mergeProps({ key: 1 }, unref(mergedProps))), {
2924
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: state.value })]),
2897
2925
  _: 3
2898
2926
  }, 16));
2899
2927
  };
@@ -2901,65 +2929,30 @@ var SliderIndicator_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ *
2901
2929
  });
2902
2930
 
2903
2931
  //#endregion
2904
- //#region src/slider/indicator/SliderIndicator.vue
2905
- var SliderIndicator_default = SliderIndicator_vue_vue_type_script_setup_true_lang_default;
2906
-
2907
- //#endregion
2908
- //#region src/slider/indicator/SliderIndicatorDataAttributes.ts
2909
- let SliderIndicatorDataAttributes = /* @__PURE__ */ function(SliderIndicatorDataAttributes) {
2910
- /**
2911
- * Present while the user is dragging.
2912
- */
2913
- SliderIndicatorDataAttributes["dragging"] = "data-dragging";
2914
- /**
2915
- * Indicates the orientation of the slider.
2916
- * @type {'horizontal' | 'vertical'}
2917
- */
2918
- SliderIndicatorDataAttributes["orientation"] = "data-orientation";
2919
- /**
2920
- * Present when the slider is disabled.
2921
- */
2922
- SliderIndicatorDataAttributes["disabled"] = "data-disabled";
2923
- /**
2924
- * Present when the slider is in valid state (when wrapped in Field.Root).
2925
- */
2926
- SliderIndicatorDataAttributes["valid"] = "data-valid";
2927
- /**
2928
- * Present when the slider is in invalid state (when wrapped in Field.Root).
2929
- */
2930
- SliderIndicatorDataAttributes["invalid"] = "data-invalid";
2931
- /**
2932
- * Present when the slider has been touched (when wrapped in Field.Root).
2933
- */
2934
- SliderIndicatorDataAttributes["touched"] = "data-touched";
2935
- /**
2936
- * Present when the slider's value has changed (when wrapped in Field.Root).
2937
- */
2938
- SliderIndicatorDataAttributes["dirty"] = "data-dirty";
2939
- /**
2940
- * Present when the slider is focused (when wrapped in Field.Root).
2941
- */
2942
- SliderIndicatorDataAttributes["focused"] = "data-focused";
2943
- return SliderIndicatorDataAttributes;
2944
- }({});
2932
+ //#region src/meter/indicator/MeterIndicator.vue
2933
+ var MeterIndicator_default = MeterIndicator_vue_vue_type_script_setup_true_lang_default;
2945
2934
 
2946
2935
  //#endregion
2947
- //#region src/slider/label/SliderLabel.vue?vue&type=script&setup=true&lang.ts
2936
+ //#region src/meter/label/MeterLabel.vue?vue&type=script&setup=true&lang.ts
2948
2937
  /**
2949
- * An accessible label that is automatically associated with the slider thumbs.
2950
- * Renders a `<div>` element.
2938
+ * An accessible label for the meter.
2939
+ * Renders a `<span>` element.
2951
2940
  *
2952
- * Documentation: [Base UI Vue Slider](https://baseui-vue.com/docs/components/slider)
2941
+ * Documentation: [Base UI Vue Meter](https://baseui-vue.com/docs/components/meter)
2953
2942
  */
2954
- var SliderLabel_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
2955
- name: "SliderLabel",
2943
+ var MeterLabel_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
2944
+ name: "MeterLabel",
2956
2945
  inheritAttrs: false,
2957
- __name: "SliderLabel",
2946
+ __name: "MeterLabel",
2958
2947
  props: {
2948
+ id: {
2949
+ type: String,
2950
+ required: false
2951
+ },
2959
2952
  as: {
2960
2953
  type: null,
2961
2954
  required: false,
2962
- default: "div"
2955
+ default: "span"
2963
2956
  },
2964
2957
  class: {
2965
2958
  type: Function,
@@ -2982,17 +2975,3801 @@ var SliderLabel_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ de
2982
2975
  setup(__props) {
2983
2976
  const props = __props;
2984
2977
  const attrs = useAttrs();
2985
- const rootContext = useSliderRootContext();
2986
- const label = useLabel({
2987
- id: computed(() => rootContext.rootLabelId.value),
2988
- fallbackControlId: computed(() => rootContext.controlRef.value?.id),
2989
- setLabelId: rootContext.setLabelId,
2990
- focusControl(_event, controlId) {
2991
- if (controlId) {
2992
- const controlElement = rootContext.controlRef.value ? ownerDocument(rootContext.controlRef.value)?.getElementById(controlId) : null;
2993
- if (isHTMLElement(controlElement)) {
2994
- focusElementWithVisible(controlElement);
2995
- return;
2978
+ const { setLabelId } = useMeterRootContext();
2979
+ const id = useRegisteredLabelId(() => props.id, setLabelId);
2980
+ const state = computed(() => ({}));
2981
+ const { tag, mergedProps, renderless } = useRenderElement({
2982
+ componentProps: props,
2983
+ state,
2984
+ props: computed(() => ({
2985
+ ...attrs,
2986
+ id: id.value,
2987
+ role: "presentation"
2988
+ })),
2989
+ defaultTagName: "span"
2990
+ });
2991
+ return (_ctx, _cache) => {
2992
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
2993
+ key: 0,
2994
+ props: unref(mergedProps),
2995
+ state: state.value
2996
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), normalizeProps(mergeProps({ key: 1 }, unref(mergedProps))), {
2997
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: state.value })]),
2998
+ _: 3
2999
+ }, 16));
3000
+ };
3001
+ }
3002
+ });
3003
+
3004
+ //#endregion
3005
+ //#region src/meter/label/MeterLabel.vue
3006
+ var MeterLabel_default = MeterLabel_vue_vue_type_script_setup_true_lang_default;
3007
+
3008
+ //#endregion
3009
+ //#region src/meter/root/MeterRoot.vue?vue&type=script&setup=true&lang.ts
3010
+ /**
3011
+ * Groups all parts of the meter and provides the value for screen readers.
3012
+ * Renders a `<div>` element.
3013
+ *
3014
+ * Documentation: [Base UI Vue Meter](https://baseui-vue.com/docs/components/meter)
3015
+ */
3016
+ var MeterRoot_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
3017
+ name: "MeterRoot",
3018
+ inheritAttrs: false,
3019
+ __name: "MeterRoot",
3020
+ props: {
3021
+ ariaValuetext: {
3022
+ type: String,
3023
+ required: false
3024
+ },
3025
+ format: {
3026
+ type: null,
3027
+ required: false
3028
+ },
3029
+ getAriaValueText: {
3030
+ type: Function,
3031
+ required: false
3032
+ },
3033
+ locale: {
3034
+ type: null,
3035
+ required: false
3036
+ },
3037
+ max: {
3038
+ type: Number,
3039
+ required: false,
3040
+ default: 100
3041
+ },
3042
+ min: {
3043
+ type: Number,
3044
+ required: false,
3045
+ default: 0
3046
+ },
3047
+ value: {
3048
+ type: Number,
3049
+ required: true
3050
+ },
3051
+ as: {
3052
+ type: null,
3053
+ required: false,
3054
+ default: "div"
3055
+ },
3056
+ class: {
3057
+ type: Function,
3058
+ required: false,
3059
+ skipCheck: true
3060
+ },
3061
+ style: {
3062
+ type: [
3063
+ Boolean,
3064
+ null,
3065
+ String,
3066
+ Object,
3067
+ Array,
3068
+ Function
3069
+ ],
3070
+ required: false,
3071
+ skipCheck: true
3072
+ }
3073
+ },
3074
+ setup(__props) {
3075
+ const props = __props;
3076
+ const attrs = useAttrs();
3077
+ const labelId = ref(void 0);
3078
+ const formattedValue = computed(() => formatNumberValue(props.value, props.locale, props.format));
3079
+ const ariaValueText = computed(() => {
3080
+ if (props.ariaValuetext !== void 0) return props.ariaValuetext;
3081
+ if (props.getAriaValueText) return props.getAriaValueText(formattedValue.value, props.value);
3082
+ if (props.format) return formattedValue.value;
3083
+ return `${props.value}%`;
3084
+ });
3085
+ provide(meterRootContextKey, {
3086
+ formattedValue,
3087
+ max: computed(() => props.max),
3088
+ min: computed(() => props.min),
3089
+ value: computed(() => props.value),
3090
+ setLabelId(id) {
3091
+ labelId.value = id;
3092
+ }
3093
+ });
3094
+ const state = computed(() => ({}));
3095
+ const { tag, mergedProps, renderless } = useRenderElement({
3096
+ componentProps: props,
3097
+ state,
3098
+ props: computed(() => ({
3099
+ "role": "meter",
3100
+ "aria-labelledby": labelId.value,
3101
+ "aria-valuemax": props.max,
3102
+ "aria-valuemin": props.min,
3103
+ "aria-valuenow": props.value,
3104
+ "aria-valuetext": ariaValueText.value,
3105
+ ...attrs
3106
+ })),
3107
+ defaultTagName: "div"
3108
+ });
3109
+ const visuallyHiddenStyle = visuallyHidden;
3110
+ return (_ctx, _cache) => {
3111
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
3112
+ key: 0,
3113
+ props: unref(mergedProps),
3114
+ state: state.value
3115
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), normalizeProps(mergeProps({ key: 1 }, unref(mergedProps))), {
3116
+ default: withCtx(() => [
3117
+ renderSlot(_ctx.$slots, "default", { state: state.value }),
3118
+ createCommentVNode(" Force NVDA to read the label https://github.com/mui/base-ui/issues/4184 "),
3119
+ createElementVNode("span", {
3120
+ role: "presentation",
3121
+ style: normalizeStyle(unref(visuallyHiddenStyle))
3122
+ }, "x", 4)
3123
+ ]),
3124
+ _: 3
3125
+ }, 16));
3126
+ };
3127
+ }
3128
+ });
3129
+
3130
+ //#endregion
3131
+ //#region src/meter/root/MeterRoot.vue
3132
+ var MeterRoot_default = MeterRoot_vue_vue_type_script_setup_true_lang_default;
3133
+
3134
+ //#endregion
3135
+ //#region src/meter/track/MeterTrack.vue?vue&type=script&setup=true&lang.ts
3136
+ /**
3137
+ * Contains the meter indicator and represents the entire range of the meter.
3138
+ * Renders a `<div>` element.
3139
+ *
3140
+ * Documentation: [Base UI Vue Meter](https://baseui-vue.com/docs/components/meter)
3141
+ */
3142
+ var MeterTrack_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
3143
+ name: "MeterTrack",
3144
+ inheritAttrs: false,
3145
+ __name: "MeterTrack",
3146
+ props: {
3147
+ as: {
3148
+ type: null,
3149
+ required: false,
3150
+ default: "div"
3151
+ },
3152
+ class: {
3153
+ type: Function,
3154
+ required: false,
3155
+ skipCheck: true
3156
+ },
3157
+ style: {
3158
+ type: [
3159
+ Boolean,
3160
+ null,
3161
+ String,
3162
+ Object,
3163
+ Array,
3164
+ Function
3165
+ ],
3166
+ required: false,
3167
+ skipCheck: true
3168
+ }
3169
+ },
3170
+ setup(__props) {
3171
+ const props = __props;
3172
+ const attrs = useAttrs();
3173
+ const state = computed(() => ({}));
3174
+ const { tag, mergedProps, renderless } = useRenderElement({
3175
+ componentProps: props,
3176
+ state,
3177
+ props: computed(() => ({ ...attrs })),
3178
+ defaultTagName: "div"
3179
+ });
3180
+ return (_ctx, _cache) => {
3181
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
3182
+ key: 0,
3183
+ props: unref(mergedProps),
3184
+ state: state.value
3185
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), normalizeProps(mergeProps({ key: 1 }, unref(mergedProps))), {
3186
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: state.value })]),
3187
+ _: 3
3188
+ }, 16));
3189
+ };
3190
+ }
3191
+ });
3192
+
3193
+ //#endregion
3194
+ //#region src/meter/track/MeterTrack.vue
3195
+ var MeterTrack_default = MeterTrack_vue_vue_type_script_setup_true_lang_default;
3196
+
3197
+ //#endregion
3198
+ //#region src/meter/value/MeterValue.vue?vue&type=script&setup=true&lang.ts
3199
+ /**
3200
+ * A text element displaying the current value.
3201
+ * Renders a `<span>` element.
3202
+ *
3203
+ * Documentation: [Base UI Vue Meter](https://baseui-vue.com/docs/components/meter)
3204
+ */
3205
+ var MeterValue_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
3206
+ name: "MeterValue",
3207
+ inheritAttrs: false,
3208
+ __name: "MeterValue",
3209
+ props: {
3210
+ as: {
3211
+ type: null,
3212
+ required: false,
3213
+ default: "span"
3214
+ },
3215
+ class: {
3216
+ type: Function,
3217
+ required: false,
3218
+ skipCheck: true
3219
+ },
3220
+ style: {
3221
+ type: [
3222
+ Boolean,
3223
+ null,
3224
+ String,
3225
+ Object,
3226
+ Array,
3227
+ Function
3228
+ ],
3229
+ required: false,
3230
+ skipCheck: true
3231
+ }
3232
+ },
3233
+ setup(__props) {
3234
+ const props = __props;
3235
+ const attrs = useAttrs();
3236
+ const { value, formattedValue } = useMeterRootContext();
3237
+ const state = computed(() => ({}));
3238
+ const defaultDisplay = computed(() => {
3239
+ if (formattedValue.value) return formattedValue.value;
3240
+ return value.value != null ? String(value.value) : "";
3241
+ });
3242
+ const { tag, mergedProps, renderless } = useRenderElement({
3243
+ componentProps: props,
3244
+ state,
3245
+ props: computed(() => ({
3246
+ "aria-hidden": true,
3247
+ ...attrs
3248
+ })),
3249
+ defaultTagName: "span"
3250
+ });
3251
+ return (_ctx, _cache) => {
3252
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
3253
+ key: 0,
3254
+ props: unref(mergedProps),
3255
+ state: state.value,
3256
+ formattedValue: unref(formattedValue),
3257
+ value: unref(value)
3258
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), normalizeProps(mergeProps({ key: 1 }, unref(mergedProps))), {
3259
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", {
3260
+ formattedValue: unref(formattedValue),
3261
+ value: unref(value)
3262
+ }, () => [createTextVNode(toDisplayString(defaultDisplay.value), 1)])]),
3263
+ _: 3
3264
+ }, 16));
3265
+ };
3266
+ }
3267
+ });
3268
+
3269
+ //#endregion
3270
+ //#region src/meter/value/MeterValue.vue
3271
+ var MeterValue_default = MeterValue_vue_vue_type_script_setup_true_lang_default;
3272
+
3273
+ //#endregion
3274
+ //#region src/utils/useValueChanged.ts
3275
+ /**
3276
+ * Runs `onChange` whenever the watched value changes, passing the previous value.
3277
+ *
3278
+ * Mirrors the React `useValueChanged` helper: the callback fires after the DOM has
3279
+ * been updated (`flush: 'post'`), which makes it safe to read or move focus inside it.
3280
+ */
3281
+ function useValueChanged(source, onChange) {
3282
+ watch(source, (_newValue, previousValue) => {
3283
+ onChange(previousValue);
3284
+ }, { flush: "post" });
3285
+ }
3286
+
3287
+ //#endregion
3288
+ //#region src/number-field/utils/validate.ts
3289
+ const STEP_EPSILON_FACTOR = 1e-10;
3290
+ const DEFAULT_DIGITS = 3;
3291
+ function hasNumberFormatRoundingOptions(format) {
3292
+ return format?.maximumFractionDigits != null || format?.minimumFractionDigits != null || format?.maximumSignificantDigits != null || format?.minimumSignificantDigits != null || format?.roundingIncrement != null || format?.roundingMode != null || format?.roundingPriority != null;
3293
+ }
3294
+ function removeFloatingPointErrors(value, format) {
3295
+ if (!Number.isFinite(value)) return value;
3296
+ if (!hasNumberFormatRoundingOptions(format)) return Number(value.toFixed(DEFAULT_DIGITS));
3297
+ const formatter = getFormatter("en-US", {
3298
+ ...format,
3299
+ signDisplay: "auto",
3300
+ currencySign: "standard",
3301
+ notation: format.notation === "compact" ? "standard" : format.notation,
3302
+ useGrouping: false
3303
+ });
3304
+ const roundedText = formatter.format(value);
3305
+ const roundedValue = parseNumber(roundedText, "en-US", format);
3306
+ if (roundedValue === null) return value;
3307
+ return formatter.format(roundedValue) === roundedText ? roundedValue : value;
3308
+ }
3309
+ function snapToStep(value, base, step, mode = "directional") {
3310
+ const stepSize = Math.abs(step);
3311
+ const direction = Math.sign(step);
3312
+ const tolerance = stepSize * STEP_EPSILON_FACTOR * direction;
3313
+ const rawSteps = value - base + tolerance;
3314
+ if (mode === "nearest") return base + Math.round(rawSteps / step) * step;
3315
+ return base + (direction > 0 ? Math.floor(rawSteps / stepSize) : Math.ceil(rawSteps / stepSize)) * stepSize;
3316
+ }
3317
+ function toValidatedNumber(value, { step, minWithDefault, maxWithDefault, minWithZeroDefault, format, snapOnStep, small, clamp: shouldClamp }) {
3318
+ if (value === null) return value;
3319
+ let nextValue = value;
3320
+ if (step != null && snapOnStep && step !== 0) {
3321
+ const base = small || minWithDefault === Number.MIN_SAFE_INTEGER ? minWithZeroDefault : minWithDefault;
3322
+ nextValue = snapToStep(nextValue, base, step, small ? "nearest" : "directional");
3323
+ }
3324
+ if (shouldClamp) nextValue = clamp(nextValue, minWithDefault, maxWithDefault);
3325
+ const roundedValue = removeFloatingPointErrors(nextValue, format);
3326
+ return shouldClamp ? clamp(roundedValue, minWithDefault, maxWithDefault) : roundedValue;
3327
+ }
3328
+
3329
+ //#endregion
3330
+ //#region src/number-field/input/NumberFieldInput.vue?vue&type=script&setup=true&lang.ts
3331
+ var NumberFieldInput_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
3332
+ name: "NumberFieldInput",
3333
+ inheritAttrs: false,
3334
+ __name: "NumberFieldInput",
3335
+ props: {
3336
+ as: {
3337
+ type: null,
3338
+ required: false
3339
+ },
3340
+ class: {
3341
+ type: Function,
3342
+ required: false,
3343
+ skipCheck: true
3344
+ },
3345
+ style: {
3346
+ type: [
3347
+ Boolean,
3348
+ null,
3349
+ String,
3350
+ Object,
3351
+ Array,
3352
+ Function
3353
+ ],
3354
+ required: false,
3355
+ skipCheck: true
3356
+ }
3357
+ },
3358
+ setup(__props) {
3359
+ const props = __props;
3360
+ const attrsObject = useAttrs();
3361
+ const NAVIGATE_KEYS = new Set([
3362
+ "Backspace",
3363
+ "Delete",
3364
+ "ArrowLeft",
3365
+ "ArrowRight",
3366
+ "Tab",
3367
+ "Enter",
3368
+ "Escape"
3369
+ ]);
3370
+ const { allowInputSyncRef, disabled, formatOptionsRef, getAllowedNonNumericKeys, getStepAmount, id, incrementValue, inputMode, inputValue, max, min, name, readOnly, required, setValue, state, setInputValue, locale, inputRef, value, onValueCommitted, lastChangedValueRef, hasPendingCommitRef, valueRef } = useNumberFieldRootContext();
3371
+ const { clearErrors } = useFormContext();
3372
+ const { validationMode, setTouched, setFocused, invalid, shouldValidateOnChange, validation } = useFieldRootContext();
3373
+ const { labelId } = useLabelableContext();
3374
+ let hasTouchedInput = false;
3375
+ let blockRevalidation = false;
3376
+ function setInputRef(el) {
3377
+ inputRef.value = el;
3378
+ }
3379
+ useValueChanged(value, () => {
3380
+ clearErrors(name.value);
3381
+ if (blockRevalidation && !shouldValidateOnChange()) {
3382
+ blockRevalidation = false;
3383
+ return;
3384
+ }
3385
+ validation.commit(value.value, true);
3386
+ });
3387
+ function onFocus(event) {
3388
+ if (event.defaultPrevented || readOnly.value || disabled.value) return;
3389
+ setFocused(true);
3390
+ if (hasTouchedInput) return;
3391
+ hasTouchedInput = true;
3392
+ const target = event.currentTarget;
3393
+ const length = target.value.length;
3394
+ target.setSelectionRange(length, length);
3395
+ }
3396
+ function onBlur(event) {
3397
+ if (event.defaultPrevented || readOnly.value || disabled.value) return;
3398
+ setTouched(true);
3399
+ setFocused(false);
3400
+ const hadManualInput = !allowInputSyncRef.value;
3401
+ const hadPendingProgrammaticChange = hasPendingCommitRef.value;
3402
+ allowInputSyncRef.value = true;
3403
+ if (inputValue.value.trim() === "") {
3404
+ setValue(null, createChangeEventDetails(REASONS.inputClear, event));
3405
+ if (validationMode.value === "onBlur") validation.commit(null);
3406
+ onValueCommitted(null, createGenericEventDetails(REASONS.inputClear, event));
3407
+ return;
3408
+ }
3409
+ const formatOptions = formatOptionsRef.value;
3410
+ const parsedValue = parseNumber(inputValue.value, locale.value, formatOptions);
3411
+ if (parsedValue === null) return;
3412
+ const hasRoundingOptions = hasNumberFormatRoundingOptions(formatOptions);
3413
+ const committed = hasRoundingOptions ? removeFloatingPointErrors(parsedValue, formatOptions) : parsedValue;
3414
+ const nextEventDetails = createGenericEventDetails(REASONS.inputBlur, event);
3415
+ const shouldUpdateValue = value.value !== committed;
3416
+ const shouldCommit = hadManualInput || shouldUpdateValue || hadPendingProgrammaticChange;
3417
+ let committedValue = committed;
3418
+ if (shouldUpdateValue) {
3419
+ const changeDetails = createChangeEventDetails(REASONS.inputBlur, event);
3420
+ blockRevalidation = true;
3421
+ setValue(committed, changeDetails);
3422
+ if (changeDetails.isCanceled) {
3423
+ blockRevalidation = false;
3424
+ return;
3425
+ }
3426
+ committedValue = lastChangedValueRef.value ?? committed;
3427
+ }
3428
+ if (validationMode.value === "onBlur") validation.commit(committedValue);
3429
+ if (shouldCommit) onValueCommitted(committedValue, nextEventDetails);
3430
+ const canonicalText = formatNumber(committedValue, locale.value, formatOptions);
3431
+ if (!(!hasRoundingOptions && parsedValue === value.value && inputValue.value === formatNumberMaxPrecision(parsedValue, locale.value, formatOptions)) && inputValue.value !== canonicalText) setInputValue(canonicalText);
3432
+ }
3433
+ function onInput(event) {
3434
+ if (event.defaultPrevented) return;
3435
+ allowInputSyncRef.value = false;
3436
+ const targetValue = event.currentTarget.value;
3437
+ if (targetValue.trim() === "") {
3438
+ setInputValue(targetValue);
3439
+ setValue(null, createChangeEventDetails(REASONS.inputClear, event));
3440
+ return;
3441
+ }
3442
+ const allowedNonNumericKeys = getAllowedNonNumericKeys();
3443
+ if (!Array.from(targetValue).every((ch) => {
3444
+ const isAsciiDigit = ch >= "0" && ch <= "9";
3445
+ const isArabicNumeral = ARABIC_DETECT_RE.test(ch);
3446
+ const isHanNumeral = HAN_DETECT_RE.test(ch);
3447
+ const isPersianNumeral = PERSIAN_DETECT_RE.test(ch);
3448
+ const isFullwidthNumeral = FULLWIDTH_DETECT_RE.test(ch);
3449
+ const isMinus = ANY_MINUS_DETECT_RE.test(ch);
3450
+ return isAsciiDigit || isArabicNumeral || isHanNumeral || isPersianNumeral || isFullwidthNumeral || isMinus || allowedNonNumericKeys.has(ch);
3451
+ })) return;
3452
+ const parsedValue = parseNumber(targetValue, locale.value, formatOptionsRef.value);
3453
+ setInputValue(targetValue);
3454
+ if (parsedValue !== null) setValue(parsedValue, createChangeEventDetails(REASONS.inputChange, event));
3455
+ }
3456
+ function onKeydown(event) {
3457
+ if (event.defaultPrevented || readOnly.value || disabled.value) return;
3458
+ allowInputSyncRef.value = true;
3459
+ const allowedNonNumericKeys = getAllowedNonNumericKeys();
3460
+ let isAllowedNonNumericKey = allowedNonNumericKeys.has(event.key);
3461
+ const { decimal, currency, percentSign } = getNumberLocaleDetails(locale.value, formatOptionsRef.value);
3462
+ const target = event.currentTarget;
3463
+ const selectionStart = target.selectionStart;
3464
+ const selectionEnd = target.selectionEnd;
3465
+ const isAllSelected = selectionStart === 0 && selectionEnd === inputValue.value.length;
3466
+ const selectionContainsIndex = (index) => selectionStart != null && selectionEnd != null && index >= selectionStart && index < selectionEnd;
3467
+ if (ANY_MINUS_DETECT_RE.test(event.key) && Array.from(allowedNonNumericKeys).some((k) => ANY_MINUS_DETECT_RE.test(k || ""))) {
3468
+ const existingIndex = inputValue.value.search(ANY_MINUS_RE);
3469
+ const isReplacingExisting = existingIndex != null && existingIndex !== -1 && selectionContainsIndex(existingIndex);
3470
+ isAllowedNonNumericKey = !(ANY_MINUS_DETECT_RE.test(inputValue.value) || ANY_PLUS_DETECT_RE.test(inputValue.value)) || isAllSelected || isReplacingExisting;
3471
+ }
3472
+ if (ANY_PLUS_DETECT_RE.test(event.key) && Array.from(allowedNonNumericKeys).some((k) => ANY_PLUS_DETECT_RE.test(k || ""))) {
3473
+ const existingIndex = inputValue.value.search(ANY_PLUS_RE);
3474
+ const isReplacingExisting = existingIndex != null && existingIndex !== -1 && selectionContainsIndex(existingIndex);
3475
+ isAllowedNonNumericKey = !(ANY_MINUS_DETECT_RE.test(inputValue.value) || ANY_PLUS_DETECT_RE.test(inputValue.value)) || isAllSelected || isReplacingExisting;
3476
+ }
3477
+ [
3478
+ decimal,
3479
+ currency,
3480
+ percentSign
3481
+ ].forEach((symbol) => {
3482
+ if (event.key === symbol && symbol) {
3483
+ const isSymbolHighlighted = selectionContainsIndex(inputValue.value.indexOf(symbol));
3484
+ isAllowedNonNumericKey = !inputValue.value.includes(symbol) || isAllSelected || isSymbolHighlighted;
3485
+ }
3486
+ });
3487
+ const isAsciiDigit = event.key >= "0" && event.key <= "9";
3488
+ const isArabicNumeral = ARABIC_DETECT_RE.test(event.key);
3489
+ const isHanNumeral = HAN_DETECT_RE.test(event.key);
3490
+ const isPersianNumeral = PERSIAN_DETECT_RE.test(event.key);
3491
+ const isFullwidthNumeral = FULLWIDTH_DETECT_RE.test(event.key);
3492
+ const isNavigateKey = NAVIGATE_KEYS.has(event.key);
3493
+ const isStepKey = event.key === "ArrowUp" || event.key === "ArrowDown";
3494
+ if (event.which === 229 || event.altKey && !isStepKey || event.ctrlKey || event.metaKey || isAllowedNonNumericKey || isAsciiDigit || isArabicNumeral || isFullwidthNumeral || isHanNumeral || isPersianNumeral || isNavigateKey) return;
3495
+ const parsedValue = parseNumber(inputValue.value, locale.value, formatOptionsRef.value);
3496
+ const amount = getStepAmount(event) ?? DEFAULT_STEP;
3497
+ stopEvent(event);
3498
+ const commitDetails = createGenericEventDetails(REASONS.keyboard, event);
3499
+ if (event.key === "ArrowUp") {
3500
+ incrementValue(amount, {
3501
+ direction: 1,
3502
+ currentValue: parsedValue,
3503
+ event,
3504
+ reason: REASONS.keyboard
3505
+ });
3506
+ onValueCommitted(lastChangedValueRef.value ?? valueRef.value, commitDetails);
3507
+ } else if (event.key === "ArrowDown") {
3508
+ incrementValue(amount, {
3509
+ direction: -1,
3510
+ currentValue: parsedValue,
3511
+ event,
3512
+ reason: REASONS.keyboard
3513
+ });
3514
+ onValueCommitted(lastChangedValueRef.value ?? valueRef.value, commitDetails);
3515
+ } else if (event.key === "Home" && min.value != null) {
3516
+ setValue(min.value, createChangeEventDetails(REASONS.keyboard, event));
3517
+ onValueCommitted(lastChangedValueRef.value ?? valueRef.value, commitDetails);
3518
+ } else if (event.key === "End" && max.value != null) {
3519
+ setValue(max.value, createChangeEventDetails(REASONS.keyboard, event));
3520
+ onValueCommitted(lastChangedValueRef.value ?? valueRef.value, commitDetails);
3521
+ }
3522
+ }
3523
+ function onPaste(event) {
3524
+ if (event.defaultPrevented || readOnly.value || disabled.value) return;
3525
+ let pastedData = "";
3526
+ try {
3527
+ pastedData = event.clipboardData?.getData("text/plain") ?? "";
3528
+ } catch {
3529
+ if (process.env.NODE_ENV !== "production") warn("<NumberFieldInput> could not read clipboard text during paste handling.");
3530
+ return;
3531
+ }
3532
+ event.preventDefault();
3533
+ const parsedValue = parseNumber(pastedData, locale.value, formatOptionsRef.value);
3534
+ if (parsedValue !== null) {
3535
+ allowInputSyncRef.value = false;
3536
+ setValue(parsedValue, createChangeEventDetails(REASONS.inputPaste, event));
3537
+ setInputValue(pastedData);
3538
+ }
3539
+ }
3540
+ const { tag, mergedProps, renderless, ref: renderRef } = useRenderElement({
3541
+ componentProps: props,
3542
+ state,
3543
+ props: computed(() => mergeProps$1(attrsObject, validation.getValidationProps(), {
3544
+ "id": id.value,
3545
+ "required": required.value,
3546
+ "disabled": disabled.value,
3547
+ "readonly": readOnly.value,
3548
+ "inputmode": inputMode.value,
3549
+ "value": inputValue.value,
3550
+ "type": "text",
3551
+ "autocomplete": "off",
3552
+ "autocorrect": "off",
3553
+ "spellcheck": "false",
3554
+ "aria-roledescription": "Number field",
3555
+ "aria-invalid": !disabled.value && invalid.value ? true : void 0,
3556
+ "aria-labelledby": labelId.value,
3557
+ "onFocus": onFocus,
3558
+ "onBlur": onBlur,
3559
+ "onInput": onInput,
3560
+ "onKeydown": onKeydown,
3561
+ "onPaste": onPaste
3562
+ })),
3563
+ stateAttributesMapping: stateAttributesMapping$1,
3564
+ defaultTagName: "input",
3565
+ ref: setInputRef
3566
+ });
3567
+ return (_ctx, _cache) => {
3568
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
3569
+ key: 0,
3570
+ ref: unref(renderRef),
3571
+ props: unref(mergedProps),
3572
+ state: unref(state)
3573
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), mergeProps({
3574
+ key: 1,
3575
+ ref: unref(renderRef)
3576
+ }, unref(mergedProps)), null, 16));
3577
+ };
3578
+ }
3579
+ });
3580
+
3581
+ //#endregion
3582
+ //#region src/number-field/input/NumberFieldInput.vue
3583
+ var NumberFieldInput_default = NumberFieldInput_vue_vue_type_script_setup_true_lang_default;
3584
+
3585
+ //#endregion
3586
+ //#region src/utils/detectBrowser.ts
3587
+ const ua = typeof navigator !== "undefined" ? navigator.userAgent : "";
3588
+ const platform = typeof navigator !== "undefined" ? navigator.platform : "";
3589
+ const maxTouchPoints = typeof navigator !== "undefined" ? navigator.maxTouchPoints : 0;
3590
+ const isWebKit = typeof CSS !== "undefined" && typeof CSS.supports === "function" ? CSS.supports("-webkit-backdrop-filter:none") && !/chrome|android/i.test(ua) : /\b(?:iphone|ipad|ipod)\b/i.test(ua);
3591
+ const isFirefox = /firefox/i.test(ua);
3592
+ const isIOS = /\b(?:iphone|ipad|ipod)\b/i.test(ua) || platform === "MacIntel" && maxTouchPoints > 1;
3593
+
3594
+ //#endregion
3595
+ //#region src/number-field/root/NumberFieldRoot.vue?vue&type=script&setup=true&lang.ts
3596
+ var NumberFieldRoot_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
3597
+ name: "NumberFieldRoot",
3598
+ inheritAttrs: false,
3599
+ __name: "NumberFieldRoot",
3600
+ props: {
3601
+ id: {
3602
+ type: String,
3603
+ required: false
3604
+ },
3605
+ min: {
3606
+ type: Number,
3607
+ required: false
3608
+ },
3609
+ max: {
3610
+ type: Number,
3611
+ required: false
3612
+ },
3613
+ allowOutOfRange: {
3614
+ type: Boolean,
3615
+ required: false,
3616
+ default: false
3617
+ },
3618
+ smallStep: {
3619
+ type: Number,
3620
+ required: false,
3621
+ default: .1
3622
+ },
3623
+ step: {
3624
+ type: [Number, String],
3625
+ required: false,
3626
+ default: 1
3627
+ },
3628
+ largeStep: {
3629
+ type: Number,
3630
+ required: false,
3631
+ default: 10
3632
+ },
3633
+ required: {
3634
+ type: Boolean,
3635
+ required: false,
3636
+ default: false
3637
+ },
3638
+ disabled: {
3639
+ type: Boolean,
3640
+ required: false,
3641
+ default: false
3642
+ },
3643
+ readOnly: {
3644
+ type: Boolean,
3645
+ required: false,
3646
+ default: false
3647
+ },
3648
+ name: {
3649
+ type: String,
3650
+ required: false
3651
+ },
3652
+ form: {
3653
+ type: String,
3654
+ required: false
3655
+ },
3656
+ value: {
3657
+ type: [Number, null],
3658
+ required: false
3659
+ },
3660
+ defaultValue: {
3661
+ type: Number,
3662
+ required: false
3663
+ },
3664
+ allowWheelScrub: {
3665
+ type: Boolean,
3666
+ required: false,
3667
+ default: false
3668
+ },
3669
+ snapOnStep: {
3670
+ type: Boolean,
3671
+ required: false,
3672
+ default: false
3673
+ },
3674
+ format: {
3675
+ type: null,
3676
+ required: false
3677
+ },
3678
+ locale: {
3679
+ type: null,
3680
+ required: false
3681
+ },
3682
+ as: {
3683
+ type: null,
3684
+ required: false,
3685
+ default: "div"
3686
+ },
3687
+ class: {
3688
+ type: Function,
3689
+ required: false,
3690
+ skipCheck: true
3691
+ },
3692
+ style: {
3693
+ type: [
3694
+ Boolean,
3695
+ null,
3696
+ String,
3697
+ Object,
3698
+ Array,
3699
+ Function
3700
+ ],
3701
+ required: false,
3702
+ skipCheck: true
3703
+ }
3704
+ },
3705
+ emits: ["valueChange", "valueCommitted"],
3706
+ setup(__props, { emit: __emit }) {
3707
+ const props = __props;
3708
+ const emit = __emit;
3709
+ const attrsObject = useAttrs();
3710
+ const { setDirty, validityData, disabled: fieldDisabled, setFilled, invalid, name: fieldName, state: fieldState, validation } = useFieldRootContext();
3711
+ const { clearErrors } = useFormContext();
3712
+ const disabled = computed(() => fieldDisabled.value || props.disabled);
3713
+ const readOnly = computed(() => props.readOnly);
3714
+ const required = computed(() => props.required);
3715
+ const nameProp = computed(() => props.name);
3716
+ const name = computed(() => fieldName.value ?? props.name);
3717
+ const step = computed(() => props.step === "any" ? 1 : props.step);
3718
+ const smallStep = computed(() => props.smallStep);
3719
+ const largeStep = computed(() => props.largeStep);
3720
+ const locale = computed(() => props.locale);
3721
+ const format = computed(() => props.format);
3722
+ const min = computed(() => props.min);
3723
+ const max = computed(() => props.max);
3724
+ const minWithDefault = computed(() => props.min ?? Number.MIN_SAFE_INTEGER);
3725
+ const maxWithDefault = computed(() => props.max ?? Number.MAX_SAFE_INTEGER);
3726
+ const minWithZeroDefault = computed(() => props.min ?? 0);
3727
+ const formatStyle = computed(() => props.format?.style);
3728
+ const isScrubbingRef = ref(false);
3729
+ function setIsScrubbing(value) {
3730
+ isScrubbingRef.value = value;
3731
+ }
3732
+ const inputRef = ref(null);
3733
+ const validationInputRef = ref(null);
3734
+ const id = useLabelableId({ id: computed(() => props.id) });
3735
+ const { value: valueUnwrapped, setValue: setValueUnwrapped } = useControllableState({
3736
+ controlled: () => props.value,
3737
+ default: () => props.defaultValue ?? null,
3738
+ name: "NumberField",
3739
+ state: "value"
3740
+ });
3741
+ const value = computed(() => valueUnwrapped.value ?? null);
3742
+ const valueRef = ref(value.value);
3743
+ watch(value, (next) => {
3744
+ valueRef.value = next;
3745
+ }, { flush: "post" });
3746
+ const formatOptionsRef = format;
3747
+ const hasPendingCommitRef = ref(false);
3748
+ const allowInputSyncRef = ref(true);
3749
+ const lastChangedValueRef = ref(null);
3750
+ function onValueCommitted(nextValue, eventDetails) {
3751
+ hasPendingCommitRef.value = false;
3752
+ emit("valueCommitted", nextValue, eventDetails);
3753
+ }
3754
+ function getControlledInputValue(nextValue) {
3755
+ return hasNumberFormatRoundingOptions(format.value) ? formatNumber(nextValue, locale.value, format.value) : formatNumberMaxPrecision(nextValue, locale.value, format.value);
3756
+ }
3757
+ const inputValue = ref(props.value !== void 0 ? getControlledInputValue(value.value) : formatNumber(value.value, locale.value, format.value));
3758
+ function setInputValue(next) {
3759
+ inputValue.value = next;
3760
+ }
3761
+ const inputMode = ref("numeric");
3762
+ watchEffect(() => {
3763
+ setFilled(value.value !== null);
3764
+ });
3765
+ watchEffect(() => {
3766
+ validation.setInputRef(validationInputRef.value);
3767
+ });
3768
+ useField({
3769
+ enabled: computed(() => !disabled.value),
3770
+ id,
3771
+ name,
3772
+ commit: (v) => validation.commit(v),
3773
+ value,
3774
+ getValue: () => value.value,
3775
+ controlRef: inputRef
3776
+ });
3777
+ function getAllowedNonNumericKeys() {
3778
+ const { decimal, group, currency, literal } = getNumberLocaleDetails(locale.value, format.value);
3779
+ const keys = /* @__PURE__ */ new Set();
3780
+ BASE_NON_NUMERIC_SYMBOLS.forEach((symbol) => keys.add(symbol));
3781
+ if (decimal) keys.add(decimal);
3782
+ if (group) {
3783
+ keys.add(group);
3784
+ if (SPACE_SEPARATOR_RE.test(group)) keys.add(" ");
3785
+ }
3786
+ const allowPercentSymbols = formatStyle.value === "percent" || formatStyle.value === "unit" && format.value?.unit === "percent";
3787
+ const allowPermilleSymbols = formatStyle.value === "percent" || formatStyle.value === "unit" && format.value?.unit === "permille";
3788
+ if (allowPercentSymbols) PERCENTAGES.forEach((key) => keys.add(key));
3789
+ if (allowPermilleSymbols) PERMILLE.forEach((key) => keys.add(key));
3790
+ if (formatStyle.value === "currency" && currency) keys.add(currency);
3791
+ if (literal) {
3792
+ Array.from(literal).forEach((char) => keys.add(char));
3793
+ if (SPACE_SEPARATOR_RE.test(literal)) keys.add(" ");
3794
+ }
3795
+ PLUS_SIGNS_WITH_ASCII.forEach((key) => keys.add(key));
3796
+ if (minWithDefault.value < 0) MINUS_SIGNS_WITH_ASCII.forEach((key) => keys.add(key));
3797
+ return keys;
3798
+ }
3799
+ function getStepAmount(event) {
3800
+ if (event?.altKey) return smallStep.value;
3801
+ if (event?.shiftKey) return largeStep.value;
3802
+ return step.value;
3803
+ }
3804
+ function setValue(unvalidatedValue, details) {
3805
+ const eventWithOptionalKeyState = details.event;
3806
+ const dir = details.direction;
3807
+ const reason = details.reason;
3808
+ const shouldClampValue = !props.allowOutOfRange || !(reason === REASONS.inputChange || reason === REASONS.inputBlur || reason === REASONS.inputPaste || reason === REASONS.inputClear || reason === REASONS.none);
3809
+ const validatedValue = toValidatedNumber(unvalidatedValue, {
3810
+ step: dir ? getStepAmount(eventWithOptionalKeyState) * dir : void 0,
3811
+ format: formatOptionsRef.value,
3812
+ minWithDefault: minWithDefault.value,
3813
+ maxWithDefault: maxWithDefault.value,
3814
+ minWithZeroDefault: minWithZeroDefault.value,
3815
+ snapOnStep: props.snapOnStep,
3816
+ small: eventWithOptionalKeyState?.altKey ?? false,
3817
+ clamp: shouldClampValue
3818
+ });
3819
+ const isInputReason = details.reason === REASONS.inputChange || details.reason === REASONS.inputClear || details.reason === REASONS.inputBlur || details.reason === REASONS.inputPaste || details.reason === REASONS.none;
3820
+ const shouldFireChange = validatedValue !== value.value || isInputReason && (unvalidatedValue !== value.value || allowInputSyncRef.value === false);
3821
+ if (shouldFireChange) {
3822
+ emit("valueChange", validatedValue, details);
3823
+ if (details.isCanceled) return shouldFireChange;
3824
+ setValueUnwrapped(validatedValue);
3825
+ setDirty(validatedValue !== validityData.value.initialValue);
3826
+ hasPendingCommitRef.value = true;
3827
+ }
3828
+ lastChangedValueRef.value = validatedValue;
3829
+ if (allowInputSyncRef.value) setInputValue(props.value !== void 0 ? getControlledInputValue(value.value) : formatNumber(validatedValue, locale.value, format.value));
3830
+ return shouldFireChange;
3831
+ }
3832
+ function incrementValue(amount, { direction, currentValue, event, reason }) {
3833
+ const prevValue = currentValue == null ? valueRef.value : currentValue;
3834
+ return setValue(typeof prevValue === "number" ? prevValue + amount * direction : Math.max(0, props.min ?? 0), createChangeEventDetails(reason, event, void 0, { direction }));
3835
+ }
3836
+ watch([
3837
+ value,
3838
+ locale,
3839
+ format
3840
+ ], () => {
3841
+ if (!allowInputSyncRef.value) return;
3842
+ const nextInputValue = props.value !== void 0 ? getControlledInputValue(value.value) : formatNumber(value.value, locale.value, format.value);
3843
+ if (nextInputValue !== inputValue.value) setInputValue(nextInputValue);
3844
+ }, { flush: "post" });
3845
+ watchEffect(() => {
3846
+ if (!isIOS) return;
3847
+ let computedInputMode = "text";
3848
+ if (minWithDefault.value >= 0) computedInputMode = "decimal";
3849
+ inputMode.value = computedInputMode;
3850
+ });
3851
+ watchEffect((onCleanup) => {
3852
+ const element = inputRef.value;
3853
+ if (disabled.value || readOnly.value || !props.allowWheelScrub || !element) return;
3854
+ function handleWheel(event) {
3855
+ if (event.ctrlKey || activeElement(ownerDocument(inputRef.value)) !== inputRef.value) return;
3856
+ event.preventDefault();
3857
+ allowInputSyncRef.value = true;
3858
+ incrementValue(getStepAmount(event) ?? DEFAULT_STEP, {
3859
+ direction: event.deltaY > 0 ? -1 : 1,
3860
+ event,
3861
+ reason: "wheel"
3862
+ });
3863
+ }
3864
+ element.addEventListener("wheel", handleWheel, { passive: false });
3865
+ onCleanup(() => {
3866
+ element.removeEventListener("wheel", handleWheel);
3867
+ });
3868
+ });
3869
+ const state = computed(() => ({
3870
+ ...fieldState.value,
3871
+ disabled: disabled.value,
3872
+ readOnly: readOnly.value,
3873
+ required: required.value,
3874
+ value: value.value,
3875
+ inputValue: inputValue.value,
3876
+ scrubbing: isScrubbingRef.value
3877
+ }));
3878
+ provide(numberFieldRootContextKey, {
3879
+ inputRef,
3880
+ inputValue,
3881
+ value,
3882
+ minWithDefault,
3883
+ maxWithDefault,
3884
+ disabled,
3885
+ readOnly,
3886
+ id,
3887
+ setValue,
3888
+ incrementValue,
3889
+ getStepAmount,
3890
+ allowInputSyncRef,
3891
+ formatOptionsRef,
3892
+ valueRef,
3893
+ lastChangedValueRef,
3894
+ hasPendingCommitRef,
3895
+ name,
3896
+ nameProp,
3897
+ required,
3898
+ invalid,
3899
+ inputMode,
3900
+ getAllowedNonNumericKeys,
3901
+ min,
3902
+ max,
3903
+ setInputValue,
3904
+ locale,
3905
+ isScrubbing: isScrubbingRef,
3906
+ setIsScrubbing,
3907
+ state,
3908
+ onValueCommitted
3909
+ });
3910
+ const { tag: rootTag, mergedProps: rootMergedProps, renderless: rootRenderless, ref: rootRenderRef } = useRenderElement({
3911
+ componentProps: props,
3912
+ state,
3913
+ props: attrsObject,
3914
+ stateAttributesMapping: stateAttributesMapping$1,
3915
+ defaultTagName: "div",
3916
+ ref: ref(null)
3917
+ });
3918
+ const hiddenInputProps = computed(() => ({
3919
+ ...validation.getValidationProps(),
3920
+ "type": "number",
3921
+ "form": props.form,
3922
+ "name": name.value,
3923
+ "value": value.value ?? "",
3924
+ "min": props.min,
3925
+ "max": props.max,
3926
+ "step": props.step,
3927
+ "disabled": disabled.value,
3928
+ "required": required.value,
3929
+ "aria-hidden": true,
3930
+ "tabindex": -1,
3931
+ "style": name.value ? visuallyHiddenInput : visuallyHidden
3932
+ }));
3933
+ function handleHiddenFocus() {
3934
+ inputRef.value?.focus();
3935
+ }
3936
+ function handleHiddenInput(event) {
3937
+ const target = event.currentTarget;
3938
+ if (event.defaultPrevented || disabled.value || readOnly.value) return;
3939
+ const nextValue = target.valueAsNumber;
3940
+ const parsedValue = Number.isNaN(nextValue) ? null : nextValue;
3941
+ const details = createChangeEventDetails(REASONS.none, event);
3942
+ setDirty(parsedValue !== validityData.value.initialValue);
3943
+ setValue(parsedValue, details);
3944
+ clearErrors(name.value);
3945
+ validation.commit(parsedValue, true);
3946
+ }
3947
+ return (_ctx, _cache) => {
3948
+ return openBlock(), createElementBlock(Fragment, null, [!unref(rootRenderless) ? (openBlock(), createBlock(resolveDynamicComponent(unref(rootTag)), mergeProps({
3949
+ key: 0,
3950
+ ref: unref(rootRenderRef)
3951
+ }, unref(rootMergedProps)), {
3952
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: state.value })]),
3953
+ _: 3
3954
+ }, 16)) : renderSlot(_ctx.$slots, "default", {
3955
+ key: 1,
3956
+ ref: unref(rootRenderRef),
3957
+ props: unref(rootMergedProps),
3958
+ state: state.value
3959
+ }), createElementVNode("input", mergeProps({
3960
+ ref_key: "validationInputRef",
3961
+ ref: validationInputRef
3962
+ }, hiddenInputProps.value, {
3963
+ suppresshydrationwarning: "",
3964
+ onInput: handleHiddenInput,
3965
+ onFocus: handleHiddenFocus
3966
+ }), null, 16)], 64);
3967
+ };
3968
+ }
3969
+ });
3970
+
3971
+ //#endregion
3972
+ //#region src/number-field/root/NumberFieldRoot.vue
3973
+ var NumberFieldRoot_default = NumberFieldRoot_vue_vue_type_script_setup_true_lang_default;
3974
+
3975
+ //#endregion
3976
+ //#region src/number-field/scrub-area/NumberFieldScrubAreaContext.ts
3977
+ const numberFieldScrubAreaContextKey = Symbol("NumberFieldScrubAreaContext");
3978
+ function useNumberFieldScrubAreaContext() {
3979
+ const context = inject(numberFieldScrubAreaContextKey, void 0);
3980
+ if (context === void 0) throw new Error("Base UI Vue: NumberFieldScrubAreaContext is missing. NumberFieldScrubArea parts must be placed within <NumberFieldScrubArea>.");
3981
+ return context;
3982
+ }
3983
+
3984
+ //#endregion
3985
+ //#region src/number-field/scrub-area-cursor/NumberFieldScrubAreaCursor.vue?vue&type=script&setup=true&lang.ts
3986
+ var NumberFieldScrubAreaCursor_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
3987
+ name: "NumberFieldScrubAreaCursor",
3988
+ inheritAttrs: false,
3989
+ __name: "NumberFieldScrubAreaCursor",
3990
+ props: {
3991
+ as: {
3992
+ type: null,
3993
+ required: false
3994
+ },
3995
+ class: {
3996
+ type: Function,
3997
+ required: false,
3998
+ skipCheck: true
3999
+ },
4000
+ style: {
4001
+ type: [
4002
+ Boolean,
4003
+ null,
4004
+ String,
4005
+ Object,
4006
+ Array,
4007
+ Function
4008
+ ],
4009
+ required: false,
4010
+ skipCheck: true
4011
+ }
4012
+ },
4013
+ setup(__props) {
4014
+ const props = __props;
4015
+ const attrsObject = useAttrs();
4016
+ const { state } = useNumberFieldRootContext();
4017
+ const { isScrubbing, isTouchInput, isPointerLockDenied, scrubAreaCursorRef } = useNumberFieldScrubAreaContext();
4018
+ const shouldRender = computed(() => isScrubbing.value && !isWebKit && !isTouchInput.value && !isPointerLockDenied.value);
4019
+ function setCursorRef(el) {
4020
+ scrubAreaCursorRef.value = el;
4021
+ }
4022
+ const { tag, mergedProps, renderless, ref: renderRef } = useRenderElement({
4023
+ componentProps: props,
4024
+ state,
4025
+ props: computed(() => mergeProps$1({
4026
+ role: "presentation",
4027
+ style: {
4028
+ position: "fixed",
4029
+ top: 0,
4030
+ left: 0,
4031
+ pointerEvents: "none"
4032
+ }
4033
+ }, attrsObject)),
4034
+ stateAttributesMapping: stateAttributesMapping$1,
4035
+ defaultTagName: "span",
4036
+ ref: setCursorRef
4037
+ });
4038
+ return (_ctx, _cache) => {
4039
+ return shouldRender.value ? (openBlock(), createBlock(Teleport, {
4040
+ key: 0,
4041
+ to: "body"
4042
+ }, [unref(renderless) ? renderSlot(_ctx.$slots, "default", {
4043
+ key: 0,
4044
+ ref: unref(renderRef),
4045
+ props: unref(mergedProps),
4046
+ state: unref(state)
4047
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), mergeProps({
4048
+ key: 1,
4049
+ ref: unref(renderRef)
4050
+ }, unref(mergedProps)), {
4051
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: unref(state) })]),
4052
+ _: 3
4053
+ }, 16))])) : createCommentVNode("v-if", true);
4054
+ };
4055
+ }
4056
+ });
4057
+
4058
+ //#endregion
4059
+ //#region src/number-field/scrub-area-cursor/NumberFieldScrubAreaCursor.vue
4060
+ var NumberFieldScrubAreaCursor_default = NumberFieldScrubAreaCursor_vue_vue_type_script_setup_true_lang_default;
4061
+
4062
+ //#endregion
4063
+ //#region src/number-field/utils/getViewportRect.ts
4064
+ function getViewportRect(teleportDistance, scrubAreaEl) {
4065
+ const win = ownerWindow(scrubAreaEl);
4066
+ const rect = scrubAreaEl.getBoundingClientRect();
4067
+ if (rect && teleportDistance != null) return {
4068
+ x: rect.left - teleportDistance / 2,
4069
+ y: rect.top - teleportDistance / 2,
4070
+ width: rect.right + teleportDistance / 2,
4071
+ height: rect.bottom + teleportDistance / 2
4072
+ };
4073
+ const vV = win.visualViewport;
4074
+ if (vV) return {
4075
+ x: vV.offsetLeft,
4076
+ y: vV.offsetTop,
4077
+ width: vV.offsetLeft + vV.width,
4078
+ height: vV.offsetTop + vV.height
4079
+ };
4080
+ return {
4081
+ x: 0,
4082
+ y: 0,
4083
+ width: win.document.documentElement.clientWidth,
4084
+ height: win.document.documentElement.clientHeight
4085
+ };
4086
+ }
4087
+
4088
+ //#endregion
4089
+ //#region src/number-field/utils/subscribeToVisualViewportResize.ts
4090
+ function subscribeToVisualViewportResize(element, visualScaleRef) {
4091
+ const vV = ownerWindow(element).visualViewport;
4092
+ if (!vV) return () => {};
4093
+ function handleVisualResize() {
4094
+ if (vV) visualScaleRef.value = vV.scale;
4095
+ }
4096
+ handleVisualResize();
4097
+ vV.addEventListener("resize", handleVisualResize);
4098
+ return () => {
4099
+ vV.removeEventListener("resize", handleVisualResize);
4100
+ };
4101
+ }
4102
+
4103
+ //#endregion
4104
+ //#region src/number-field/scrub-area/NumberFieldScrubArea.vue?vue&type=script&setup=true&lang.ts
4105
+ var NumberFieldScrubArea_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
4106
+ name: "NumberFieldScrubArea",
4107
+ inheritAttrs: false,
4108
+ __name: "NumberFieldScrubArea",
4109
+ props: {
4110
+ direction: {
4111
+ type: String,
4112
+ required: false,
4113
+ default: "horizontal"
4114
+ },
4115
+ pixelSensitivity: {
4116
+ type: Number,
4117
+ required: false,
4118
+ default: 2
4119
+ },
4120
+ teleportDistance: {
4121
+ type: Number,
4122
+ required: false
4123
+ },
4124
+ as: {
4125
+ type: null,
4126
+ required: false,
4127
+ default: "span"
4128
+ },
4129
+ class: {
4130
+ type: Function,
4131
+ required: false,
4132
+ skipCheck: true
4133
+ },
4134
+ style: {
4135
+ type: [
4136
+ Boolean,
4137
+ null,
4138
+ String,
4139
+ Object,
4140
+ Array,
4141
+ Function
4142
+ ],
4143
+ required: false,
4144
+ skipCheck: true
4145
+ }
4146
+ },
4147
+ setup(__props) {
4148
+ const props = __props;
4149
+ const attrsObject = useAttrs();
4150
+ const { state, setIsScrubbing: setRootScrubbing, disabled, readOnly, inputRef, incrementValue, allowInputSyncRef, getStepAmount, onValueCommitted, lastChangedValueRef, valueRef } = useNumberFieldRootContext();
4151
+ const direction = computed(() => props.direction);
4152
+ const pixelSensitivity = computed(() => props.pixelSensitivity);
4153
+ const teleportDistance = computed(() => props.teleportDistance);
4154
+ const scrubAreaRef = ref(null);
4155
+ const scrubAreaCursorRef = ref(null);
4156
+ let isScrubbingInternal = false;
4157
+ let didMove = false;
4158
+ let pointerDownTarget = null;
4159
+ let virtualCursorCoords = {
4160
+ x: 0,
4161
+ y: 0
4162
+ };
4163
+ const visualScaleRef = ref(1);
4164
+ const exitPointerLockTimeout = useTimeout();
4165
+ const isTouchInput = ref(false);
4166
+ const isPointerLockDenied = ref(false);
4167
+ const isScrubbing = ref(false);
4168
+ watch(isScrubbing, (scrubbing, _prev, onCleanup) => {
4169
+ if (!scrubbing || !scrubAreaCursorRef.value) return;
4170
+ onCleanup(subscribeToVisualViewportResize(scrubAreaCursorRef.value, visualScaleRef));
4171
+ }, { flush: "post" });
4172
+ function updateCursorTransform(x, y) {
4173
+ if (scrubAreaCursorRef.value) scrubAreaCursorRef.value.style.transform = `translate3d(${x}px,${y}px,0) scale(${1 / visualScaleRef.value})`;
4174
+ }
4175
+ function onScrub({ movementX, movementY }) {
4176
+ const virtualCursor = scrubAreaCursorRef.value;
4177
+ const scrubAreaEl = scrubAreaRef.value;
4178
+ if (!virtualCursor || !scrubAreaEl) return;
4179
+ const rect = getViewportRect(teleportDistance.value, scrubAreaEl);
4180
+ const coords = virtualCursorCoords;
4181
+ const newCoords = {
4182
+ x: Math.round(coords.x + movementX),
4183
+ y: Math.round(coords.y + movementY)
4184
+ };
4185
+ const cursorWidth = virtualCursor.offsetWidth;
4186
+ const cursorHeight = virtualCursor.offsetHeight;
4187
+ if (newCoords.x + cursorWidth / 2 < rect.x) newCoords.x = rect.width - cursorWidth / 2;
4188
+ else if (newCoords.x + cursorWidth / 2 > rect.width) newCoords.x = rect.x - cursorWidth / 2;
4189
+ if (newCoords.y + cursorHeight / 2 < rect.y) newCoords.y = rect.height - cursorHeight / 2;
4190
+ else if (newCoords.y + cursorHeight / 2 > rect.height) newCoords.y = rect.y - cursorHeight / 2;
4191
+ virtualCursorCoords = newCoords;
4192
+ updateCursorTransform(newCoords.x, newCoords.y);
4193
+ }
4194
+ function onScrubbingChange(scrubbingValue, { clientX, clientY }) {
4195
+ isScrubbing.value = scrubbingValue;
4196
+ setRootScrubbing(scrubbingValue);
4197
+ const virtualCursor = scrubAreaCursorRef.value;
4198
+ if (!virtualCursor || !scrubbingValue) return;
4199
+ const initialCoords = {
4200
+ x: clientX - virtualCursor.offsetWidth / 2,
4201
+ y: clientY - virtualCursor.offsetHeight / 2
4202
+ };
4203
+ virtualCursorCoords = initialCoords;
4204
+ updateCursorTransform(initialCoords.x, initialCoords.y);
4205
+ }
4206
+ watch([
4207
+ isScrubbing,
4208
+ disabled,
4209
+ readOnly
4210
+ ], (_value, _prev, onCleanup) => {
4211
+ if (!inputRef.value || disabled.value || readOnly.value || !isScrubbing.value) return;
4212
+ let cumulativeDelta = 0;
4213
+ function handleScrubPointerUp(event) {
4214
+ function handler() {
4215
+ try {
4216
+ ownerDocument(scrubAreaRef.value)?.exitPointerLock();
4217
+ } catch {} finally {
4218
+ isScrubbingInternal = false;
4219
+ onScrubbingChange(false, event);
4220
+ onValueCommitted(lastChangedValueRef.value ?? valueRef.value, createGenericEventDetails(REASONS.scrub, event));
4221
+ const target = pointerDownTarget;
4222
+ const input = inputRef.value;
4223
+ if (!didMove && target != null && input) target.dispatchEvent(new (ownerWindow(input)).MouseEvent("click", {
4224
+ bubbles: true,
4225
+ cancelable: true
4226
+ }));
4227
+ didMove = false;
4228
+ pointerDownTarget = null;
4229
+ }
4230
+ }
4231
+ if (isFirefox) exitPointerLockTimeout.start(20, handler);
4232
+ else handler();
4233
+ }
4234
+ function handleScrubPointerMove(event) {
4235
+ if (!isScrubbingInternal) return;
4236
+ event.preventDefault();
4237
+ onScrub(event);
4238
+ const { movementX, movementY } = event;
4239
+ cumulativeDelta += direction.value === "vertical" ? movementY : movementX;
4240
+ if (Math.abs(cumulativeDelta) >= pixelSensitivity.value) {
4241
+ cumulativeDelta = 0;
4242
+ didMove = true;
4243
+ const rawAmount = (direction.value === "vertical" ? -movementY : movementX) * (getStepAmount(event) ?? DEFAULT_STEP);
4244
+ if (rawAmount !== 0) {
4245
+ allowInputSyncRef.value = true;
4246
+ incrementValue(Math.abs(rawAmount), {
4247
+ direction: rawAmount >= 0 ? 1 : -1,
4248
+ event,
4249
+ reason: REASONS.scrub
4250
+ });
4251
+ }
4252
+ }
4253
+ }
4254
+ const win = ownerWindow(inputRef.value);
4255
+ win.addEventListener("pointerup", handleScrubPointerUp, true);
4256
+ win.addEventListener("pointermove", handleScrubPointerMove, true);
4257
+ onCleanup(() => {
4258
+ exitPointerLockTimeout.clear();
4259
+ win.removeEventListener("pointerup", handleScrubPointerUp, true);
4260
+ win.removeEventListener("pointermove", handleScrubPointerMove, true);
4261
+ });
4262
+ }, { flush: "post" });
4263
+ onMounted(() => {
4264
+ const element = scrubAreaRef.value;
4265
+ if (!element || disabled.value || readOnly.value) return;
4266
+ function handleTouchStart(event) {
4267
+ if (event.touches.length === 1) event.preventDefault();
4268
+ }
4269
+ element.addEventListener("touchstart", handleTouchStart, { passive: false });
4270
+ });
4271
+ async function onPointerdown(event) {
4272
+ const isMainButton = !event.button || event.button === 0;
4273
+ if (event.defaultPrevented || readOnly.value || !isMainButton || disabled.value) return;
4274
+ const isTouch = event.pointerType === "touch";
4275
+ isTouchInput.value = isTouch;
4276
+ if (event.pointerType === "mouse") {
4277
+ event.preventDefault();
4278
+ inputRef.value?.focus();
4279
+ }
4280
+ isScrubbingInternal = true;
4281
+ didMove = false;
4282
+ pointerDownTarget = getTarget(event);
4283
+ onScrubbingChange(true, event);
4284
+ if (!isTouch && !isWebKit) try {
4285
+ await ownerDocument(scrubAreaRef.value)?.body.requestPointerLock();
4286
+ isPointerLockDenied.value = false;
4287
+ } catch {
4288
+ isPointerLockDenied.value = true;
4289
+ } finally {
4290
+ if (isScrubbingInternal) onScrubbingChange(true, event);
4291
+ }
4292
+ }
4293
+ const defaultProps = computed(() => ({
4294
+ role: "presentation",
4295
+ style: {
4296
+ touchAction: "none",
4297
+ WebkitUserSelect: "none",
4298
+ userSelect: "none"
4299
+ },
4300
+ onPointerdown
4301
+ }));
4302
+ const scrubAreaProps = computed(() => mergeProps$1(defaultProps.value, attrsObject));
4303
+ provide(numberFieldScrubAreaContextKey, {
4304
+ isScrubbing,
4305
+ isTouchInput,
4306
+ isPointerLockDenied,
4307
+ scrubAreaCursorRef,
4308
+ scrubAreaRef,
4309
+ direction,
4310
+ pixelSensitivity,
4311
+ teleportDistance
4312
+ });
4313
+ const { tag, mergedProps, renderless, ref: renderRef } = useRenderElement({
4314
+ componentProps: props,
4315
+ state,
4316
+ props: scrubAreaProps,
4317
+ stateAttributesMapping: stateAttributesMapping$1,
4318
+ defaultTagName: "span",
4319
+ ref: scrubAreaRef
4320
+ });
4321
+ return (_ctx, _cache) => {
4322
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
4323
+ key: 0,
4324
+ ref: unref(renderRef),
4325
+ props: unref(mergedProps),
4326
+ state: unref(state)
4327
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), mergeProps({
4328
+ key: 1,
4329
+ ref: unref(renderRef)
4330
+ }, unref(mergedProps)), {
4331
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: unref(state) })]),
4332
+ _: 3
4333
+ }, 16));
4334
+ };
4335
+ }
4336
+ });
4337
+
4338
+ //#endregion
4339
+ //#region src/number-field/scrub-area/NumberFieldScrubArea.vue
4340
+ var NumberFieldScrubArea_default = NumberFieldScrubArea_vue_vue_type_script_setup_true_lang_default;
4341
+
4342
+ //#endregion
4343
+ //#region src/otp-field/root/OtpFieldRootContext.ts
4344
+ const otpFieldRootContextKey = Symbol("OtpFieldRootContext");
4345
+ function useOtpFieldRootContext() {
4346
+ const context = inject(otpFieldRootContextKey, void 0);
4347
+ if (context === void 0) throw new Error("Base UI Vue: OtpFieldRootContext is missing. OtpField parts must be placed within <OtpFieldRoot>.");
4348
+ return context;
4349
+ }
4350
+ function getOtpFieldInputState(state, value, index) {
4351
+ return {
4352
+ ...state,
4353
+ value,
4354
+ index,
4355
+ filled: value !== ""
4356
+ };
4357
+ }
4358
+
4359
+ //#endregion
4360
+ //#region src/otp-field/utils/otp.ts
4361
+ const OTP_VALIDATION_CONFIG = {
4362
+ numeric: {
4363
+ slotPattern: "\\d{1}",
4364
+ getRootPattern: (length) => `\\d{${length}}`,
4365
+ regexp: /\D/g,
4366
+ inputMode: "numeric"
4367
+ },
4368
+ alpha: {
4369
+ slotPattern: "[a-z]{1}",
4370
+ getRootPattern: (length) => `[a-z]{${length}}`,
4371
+ regexp: /[^a-z]/gi,
4372
+ inputMode: "text"
4373
+ },
4374
+ alphanumeric: {
4375
+ slotPattern: "[a-z0-9]{1}",
4376
+ getRootPattern: (length) => `[a-z0-9]{${length}}`,
4377
+ regexp: /[^a-z0-9]/gi,
4378
+ inputMode: "text"
4379
+ }
4380
+ };
4381
+ function getOTPValidationConfig(validationType) {
4382
+ if (validationType === "none") return null;
4383
+ return OTP_VALIDATION_CONFIG[validationType];
4384
+ }
4385
+ function stripOTPWhitespace(value) {
4386
+ return (value ?? "").replace(/\s/g, "");
4387
+ }
4388
+ function applyOTPValidation(value, validation) {
4389
+ return validation ? value.replace(validation.regexp, "") : value;
4390
+ }
4391
+ /**
4392
+ * Normalizes user-entered OTP text by stripping whitespace, applying validation and custom
4393
+ * normalization, and clamping the final value to the configured slot count.
4394
+ */
4395
+ function normalizeOTPValueWithDetails(value, length, validationType, normalizeValue) {
4396
+ const strippedValue = stripOTPWhitespace(value);
4397
+ const validation = getOTPValidationConfig(validationType);
4398
+ let normalizedValue = applyOTPValidation(strippedValue, validation);
4399
+ let didRejectCharacters = strippedValue.length > normalizedValue.length;
4400
+ if (normalizeValue) {
4401
+ const customNormalizedValue = normalizeValue(normalizedValue);
4402
+ didRejectCharacters ||= normalizedValue.length > customNormalizedValue.length;
4403
+ normalizedValue = applyOTPValidation(customNormalizedValue, validation);
4404
+ didRejectCharacters ||= customNormalizedValue.length > normalizedValue.length;
4405
+ }
4406
+ const maxLength = length < 0 ? 0 : length;
4407
+ const normalizedCharacters = Array.from(normalizedValue);
4408
+ return [normalizedCharacters.slice(0, maxLength).join(""), didRejectCharacters || normalizedCharacters.length > maxLength];
4409
+ }
4410
+ function normalizeOTPValue(value, length, validationType, normalizeValue) {
4411
+ return normalizeOTPValueWithDetails(value, length, validationType, normalizeValue)[0];
4412
+ }
4413
+ function getOTPCharacters(value) {
4414
+ return Array.from(value ?? "");
4415
+ }
4416
+ function getOTPValueLength(value) {
4417
+ return getOTPCharacters(value).length;
4418
+ }
4419
+ function getOTPCharacter(value, index) {
4420
+ return getOTPCharacters(value)[index] ?? "";
4421
+ }
4422
+ /**
4423
+ * Replaces characters starting at the provided slot index, then re-normalizes the final OTP value
4424
+ * so paste and multi-character edits stay contiguous and length-bounded.
4425
+ */
4426
+ function replaceOTPValue(currentValue, index, nextValue, length, validationType, normalizeValue) {
4427
+ const normalizedValue = normalizeOTPValue(nextValue, length, validationType, normalizeValue);
4428
+ const characters = getOTPCharacters(currentValue);
4429
+ const replacementLength = getOTPValueLength(normalizedValue);
4430
+ return normalizeOTPValue(`${characters.slice(0, index).join("")}${normalizedValue}${characters.slice(index + replacementLength).join("")}`, length, validationType, normalizeValue);
4431
+ }
4432
+ function removeOTPCharacter(currentValue, index) {
4433
+ const characters = getOTPCharacters(currentValue);
4434
+ if (index < 0 || index >= characters.length) return currentValue;
4435
+ characters.splice(index, 1);
4436
+ return characters.join("");
4437
+ }
4438
+
4439
+ //#endregion
4440
+ //#region src/otp-field/utils/stateAttributesMapping.ts
4441
+ const rootStateAttributesMapping = {
4442
+ value: () => null,
4443
+ length: () => null,
4444
+ ...fieldValidityMapping
4445
+ };
4446
+ const inputStateAttributesMapping = {
4447
+ value: () => null,
4448
+ index: () => null,
4449
+ ...fieldValidityMapping
4450
+ };
4451
+
4452
+ //#endregion
4453
+ //#region src/otp-field/input/OtpFieldInput.vue?vue&type=script&setup=true&lang.ts
4454
+ var OtpFieldInput_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
4455
+ name: "OtpFieldInput",
4456
+ inheritAttrs: false,
4457
+ __name: "OtpFieldInput",
4458
+ props: {
4459
+ as: {
4460
+ type: null,
4461
+ required: false
4462
+ },
4463
+ class: {
4464
+ type: Function,
4465
+ required: false,
4466
+ skipCheck: true
4467
+ },
4468
+ style: {
4469
+ type: [
4470
+ Boolean,
4471
+ null,
4472
+ String,
4473
+ Object,
4474
+ Array,
4475
+ Function
4476
+ ],
4477
+ required: false,
4478
+ skipCheck: true
4479
+ }
4480
+ },
4481
+ setup(__props) {
4482
+ const props = __props;
4483
+ const attrs = useAttrs();
4484
+ const attrsObject = attrs;
4485
+ const { activeIndex, autoComplete, disabled, form, focusInput, queueFocusInput, getInputId, handleInputBlur, handleInputFocus, inputMode, inputAriaLabelledBy, invalid, length, mask, pattern, reportValueInvalid, readOnly, required, normalizeValue, setValue, state, validationType, value } = useOtpFieldRootContext();
4486
+ const { ref: listItemRef, index } = useCompositeListItem({ indexGuessBehavior: () => IndexGuessBehavior.GuessFromOrder });
4487
+ const inputRef = ref(null);
4488
+ const direction = useDirection();
4489
+ const slotValue = computed(() => getOTPCharacter(value.value, index.value));
4490
+ const inputState = computed(() => getOtpFieldInputState(state.value, slotValue.value, index.value));
4491
+ const externalAriaLabel = computed(() => attrs["aria-label"]);
4492
+ const externalAriaLabelledBy = computed(() => attrs["aria-labelledby"]);
4493
+ const inheritedLabel = computed(() => externalAriaLabelledBy.value ?? inputAriaLabelledBy.value);
4494
+ const ariaLabel = computed(() => index.value === 0 ? void 0 : externalAriaLabel.value);
4495
+ function setInputRef(el) {
4496
+ listItemRef(el);
4497
+ inputRef.value = el;
4498
+ }
4499
+ function onMousedown(event) {
4500
+ if (event.defaultPrevented || disabled.value) return;
4501
+ event.preventDefault();
4502
+ focusInput(index.value);
4503
+ }
4504
+ function onFocus(event) {
4505
+ if (event.defaultPrevented || disabled.value) return;
4506
+ handleInputFocus(index.value, event);
4507
+ }
4508
+ function onBlur(event) {
4509
+ if (event.defaultPrevented) return;
4510
+ handleInputBlur(event);
4511
+ }
4512
+ function onInput(event) {
4513
+ const target = event.target;
4514
+ if (event.defaultPrevented || disabled.value || readOnly.value) return;
4515
+ const rawValue = target.value;
4516
+ const [nextDigits, didRejectCharacters] = normalizeOTPValueWithDetails(rawValue, length.value, validationType.value, normalizeValue.value);
4517
+ if (didRejectCharacters) reportValueInvalid(rawValue, createGenericEventDetails(REASONS.inputChange, event));
4518
+ if (nextDigits === "") {
4519
+ if (rawValue === "") setValue(removeOTPCharacter(value.value, index.value), createChangeEventDetails(REASONS.inputClear, event));
4520
+ target.value = slotValue.value;
4521
+ if (slotValue.value !== "") target.select();
4522
+ return;
4523
+ }
4524
+ const committedValue = setValue(replaceOTPValue(value.value, index.value, nextDigits, length.value, validationType.value, normalizeValue.value), createChangeEventDetails(REASONS.inputChange, event));
4525
+ if (committedValue != null) queueFocusInput(Math.min(index.value + getOTPValueLength(nextDigits), length.value - 1), committedValue);
4526
+ }
4527
+ function onKeydown(event) {
4528
+ if (event.defaultPrevented || disabled.value) return;
4529
+ const firstIndex = 0;
4530
+ const lastIndex = Math.max(length.value - 1, firstIndex);
4531
+ const endTargetIndex = Math.min(getOTPValueLength(value.value), lastIndex);
4532
+ const hasBoundaryModifier = (event.ctrlKey || event.metaKey) && !event.altKey;
4533
+ const isRtl = direction.value === "rtl";
4534
+ const previousKey = isRtl ? "ArrowRight" : "ArrowLeft";
4535
+ const nextKey = isRtl ? "ArrowLeft" : "ArrowRight";
4536
+ if (event.key === previousKey) {
4537
+ stopEvent(event);
4538
+ focusInput(hasBoundaryModifier ? firstIndex : Math.max(firstIndex, index.value - 1));
4539
+ return;
4540
+ }
4541
+ if (event.key === nextKey) {
4542
+ stopEvent(event);
4543
+ focusInput(hasBoundaryModifier ? endTargetIndex : Math.min(lastIndex, index.value + 1));
4544
+ return;
4545
+ }
4546
+ if (event.key === "Home" || event.key === "ArrowUp") {
4547
+ stopEvent(event);
4548
+ focusInput(firstIndex);
4549
+ return;
4550
+ }
4551
+ if (event.key === "End" || event.key === "ArrowDown") {
4552
+ stopEvent(event);
4553
+ focusInput(endTargetIndex);
4554
+ return;
4555
+ }
4556
+ if (readOnly.value) return;
4557
+ function setKeyboardValue(nextValue, targetIndex) {
4558
+ const committedValue = setValue(nextValue, createChangeEventDetails(REASONS.keyboard, event));
4559
+ if (committedValue != null) queueFocusInput(targetIndex, committedValue);
4560
+ }
4561
+ if (event.key === "Backspace" && hasBoundaryModifier) {
4562
+ stopEvent(event);
4563
+ setKeyboardValue("", firstIndex);
4564
+ return;
4565
+ }
4566
+ if (event.key === "Delete") {
4567
+ stopEvent(event);
4568
+ setKeyboardValue(removeOTPCharacter(value.value, index.value), index.value);
4569
+ return;
4570
+ }
4571
+ const target = event.currentTarget;
4572
+ const inputValue = target.value;
4573
+ const fullSelection = target.selectionStart === 0 && target.selectionEnd === inputValue.length;
4574
+ if (getOTPValueLength(event.key) === 1 && fullSelection && slotValue.value === event.key) {
4575
+ stopEvent(event);
4576
+ if (index.value < length.value - 1) focusInput(index.value + 1);
4577
+ return;
4578
+ }
4579
+ if (event.key === "Backspace") {
4580
+ stopEvent(event);
4581
+ const targetIndex = Math.max(firstIndex, index.value - 1);
4582
+ const deleteIndex = slotValue.value === "" ? targetIndex : index.value;
4583
+ setKeyboardValue(removeOTPCharacter(value.value, deleteIndex), targetIndex);
4584
+ }
4585
+ }
4586
+ function onPaste(event) {
4587
+ if (event.defaultPrevented || disabled.value || readOnly.value) return;
4588
+ let rawValue = "";
4589
+ try {
4590
+ rawValue = event.clipboardData?.getData("text/plain") ?? "";
4591
+ } catch {
4592
+ return;
4593
+ }
4594
+ event.preventDefault();
4595
+ const [nextDigits, didRejectCharacters] = normalizeOTPValueWithDetails(rawValue, length.value, validationType.value, normalizeValue.value);
4596
+ if (didRejectCharacters) reportValueInvalid(rawValue, createGenericEventDetails(REASONS.inputPaste, event));
4597
+ if (nextDigits === "") return;
4598
+ const committedValue = setValue(replaceOTPValue(value.value, index.value, nextDigits, length.value, validationType.value, normalizeValue.value), createChangeEventDetails(REASONS.inputPaste, event));
4599
+ if (committedValue != null) queueFocusInput(Math.min(index.value + getOTPValueLength(nextDigits), length.value - 1), committedValue);
4600
+ }
4601
+ const { tag, mergedProps, renderless, ref: renderRef } = useRenderElement({
4602
+ componentProps: props,
4603
+ state: inputState,
4604
+ props: computed(() => mergeProps$1(attrsObject, {
4605
+ "id": getInputId(index.value),
4606
+ "value": slotValue.value,
4607
+ "type": attrsObject.type ?? (mask.value ? "password" : "text"),
4608
+ "inputmode": inputMode.value,
4609
+ "autocomplete": index.value === 0 ? autoComplete.value : "off",
4610
+ "autocorrect": "off",
4611
+ "spellcheck": "false",
4612
+ "enterkeyhint": index.value === length.value - 1 ? "done" : "next",
4613
+ "maxlength": index.value === 0 ? length.value : void 0,
4614
+ "tabindex": activeIndex.value === index.value ? 0 : -1,
4615
+ "disabled": disabled.value,
4616
+ "form": form.value,
4617
+ "pattern": pattern.value,
4618
+ "readonly": readOnly.value,
4619
+ "required": required.value,
4620
+ "aria-labelledby": ariaLabel.value == null ? inheritedLabel.value : void 0,
4621
+ "aria-invalid": !disabled.value && invalid.value ? true : void 0,
4622
+ "aria-label": ariaLabel.value,
4623
+ "onMousedown": onMousedown,
4624
+ "onFocus": onFocus,
4625
+ "onBlur": onBlur,
4626
+ "onInput": onInput,
4627
+ "onKeydown": onKeydown,
4628
+ "onPaste": onPaste
4629
+ })),
4630
+ stateAttributesMapping: inputStateAttributesMapping,
4631
+ defaultTagName: "input",
4632
+ ref: setInputRef
4633
+ });
4634
+ return (_ctx, _cache) => {
4635
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
4636
+ key: 0,
4637
+ ref: unref(renderRef),
4638
+ props: unref(mergedProps),
4639
+ state: inputState.value
4640
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), mergeProps({
4641
+ key: 1,
4642
+ ref: unref(renderRef)
4643
+ }, unref(mergedProps)), null, 16));
4644
+ };
4645
+ }
4646
+ });
4647
+
4648
+ //#endregion
4649
+ //#region src/otp-field/input/OtpFieldInput.vue
4650
+ var OtpFieldInput_default = OtpFieldInput_vue_vue_type_script_setup_true_lang_default;
4651
+
4652
+ //#endregion
4653
+ //#region src/otp-field/root/OtpFieldRoot.vue?vue&type=script&setup=true&lang.ts
4654
+ var OtpFieldRoot_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
4655
+ name: "OtpFieldRoot",
4656
+ inheritAttrs: false,
4657
+ __name: "OtpFieldRoot",
4658
+ props: {
4659
+ id: {
4660
+ type: String,
4661
+ required: false
4662
+ },
4663
+ autoComplete: {
4664
+ type: String,
4665
+ required: false,
4666
+ default: "one-time-code"
4667
+ },
4668
+ form: {
4669
+ type: String,
4670
+ required: false
4671
+ },
4672
+ length: {
4673
+ type: Number,
4674
+ required: true
4675
+ },
4676
+ autoSubmit: {
4677
+ type: Boolean,
4678
+ required: false,
4679
+ default: false
4680
+ },
4681
+ mask: {
4682
+ type: Boolean,
4683
+ required: false,
4684
+ default: false
4685
+ },
4686
+ inputMode: {
4687
+ type: String,
4688
+ required: false
4689
+ },
4690
+ validationType: {
4691
+ type: String,
4692
+ required: false,
4693
+ default: "numeric"
4694
+ },
4695
+ normalizeValue: {
4696
+ type: Function,
4697
+ required: false
4698
+ },
4699
+ required: {
4700
+ type: Boolean,
4701
+ required: false,
4702
+ default: false
4703
+ },
4704
+ disabled: {
4705
+ type: Boolean,
4706
+ required: false,
4707
+ default: false
4708
+ },
4709
+ readOnly: {
4710
+ type: Boolean,
4711
+ required: false,
4712
+ default: false
4713
+ },
4714
+ name: {
4715
+ type: String,
4716
+ required: false
4717
+ },
4718
+ value: {
4719
+ type: String,
4720
+ required: false
4721
+ },
4722
+ defaultValue: {
4723
+ type: String,
4724
+ required: false
4725
+ },
4726
+ as: {
4727
+ type: null,
4728
+ required: false,
4729
+ default: "div"
4730
+ },
4731
+ class: {
4732
+ type: Function,
4733
+ required: false,
4734
+ skipCheck: true
4735
+ },
4736
+ style: {
4737
+ type: [
4738
+ Boolean,
4739
+ null,
4740
+ String,
4741
+ Object,
4742
+ Array,
4743
+ Function
4744
+ ],
4745
+ required: false,
4746
+ skipCheck: true
4747
+ }
4748
+ },
4749
+ emits: [
4750
+ "valueChange",
4751
+ "valueInvalid",
4752
+ "valueComplete"
4753
+ ],
4754
+ setup(__props, { emit: __emit }) {
4755
+ const props = __props;
4756
+ const emit = __emit;
4757
+ const attrs = useAttrs();
4758
+ const attrsObject = attrs;
4759
+ const { setDirty, validityData, disabled: fieldDisabled, setFilled, invalid, name: fieldName, state: fieldState, validation, validationMode, setFocused, setTouched } = useFieldRootContext();
4760
+ const { clearErrors } = useFormContext();
4761
+ const { getDescriptionProps, labelId } = useLabelableContext();
4762
+ const length = computed(() => props.length);
4763
+ const validationType = computed(() => props.validationType);
4764
+ const normalizeValueProp = computed(() => props.normalizeValue);
4765
+ const disabled = computed(() => fieldDisabled.value || props.disabled);
4766
+ const readOnly = computed(() => props.readOnly);
4767
+ const required = computed(() => props.required);
4768
+ const mask = computed(() => props.mask);
4769
+ const autoComplete = computed(() => props.autoComplete);
4770
+ const formProp = computed(() => props.form);
4771
+ const name = computed(() => fieldName.value ?? props.name);
4772
+ const { value: valueUnwrapped, setValue: setValueUnwrapped } = useControllableState({
4773
+ controlled: () => props.value,
4774
+ default: () => props.defaultValue ?? "",
4775
+ name: "OtpField",
4776
+ state: "value"
4777
+ });
4778
+ const value = computed(() => normalizeOTPValue(valueUnwrapped.value, length.value, validationType.value, normalizeValueProp.value));
4779
+ const valueLength = computed(() => getOTPValueLength(value.value));
4780
+ const filled = computed(() => value.value !== "");
4781
+ const rootRef = ref(null);
4782
+ const inputRefsHolder = { elementsRef: ref([]) };
4783
+ const inputRefs = inputRefsHolder.elementsRef;
4784
+ const validationInputRef = ref(null);
4785
+ const firstInputRef = { get value() {
4786
+ return inputRefs.value[0] ?? null;
4787
+ } };
4788
+ let pendingFocus = null;
4789
+ let pendingCompleteValue = null;
4790
+ const inputCount = ref(0);
4791
+ const focusedIndex = ref(Math.min(valueLength.value, length.value - 1));
4792
+ const focused = ref(false);
4793
+ const id = useLabelableId({ id: computed(() => props.id) });
4794
+ const ariaLabelledByAttr = computed(() => attrs["aria-labelledby"]);
4795
+ const ariaLabelledBy = useAriaLabelledBy({
4796
+ ariaLabelledBy: ariaLabelledByAttr,
4797
+ labelId,
4798
+ labelSourceRef: firstInputRef,
4799
+ enableFallback: true,
4800
+ labelSourceId: () => id.value ?? void 0
4801
+ });
4802
+ const inputAriaLabelledBy = computed(() => ariaLabelledByAttr.value == null ? ariaLabelledBy.value : void 0);
4803
+ const ariaDescribedBy = computed(() => mergeAriaIds(attrs["aria-describedby"], getDescriptionProps()["aria-describedby"]));
4804
+ const validationConfig = computed(() => getOTPValidationConfig(validationType.value));
4805
+ const pattern = computed(() => validationConfig.value?.slotPattern);
4806
+ const hiddenInputPattern = computed(() => validationConfig.value?.getRootPattern(length.value));
4807
+ const inputMode = computed(() => props.inputMode ?? validationConfig.value?.inputMode);
4808
+ const hasValidLength = computed(() => Number.isInteger(length.value) && length.value > 0);
4809
+ const activeIndex = computed(() => focused.value ? Math.min(focusedIndex.value, Math.max(length.value - 1, 0)) : Math.min(valueLength.value, length.value - 1));
4810
+ watchEffect(() => {
4811
+ setFilled(filled.value);
4812
+ });
4813
+ watchEffect(() => {
4814
+ validation.setInputRef(validationInputRef.value);
4815
+ });
4816
+ useField({
4817
+ enabled: computed(() => !disabled.value),
4818
+ id,
4819
+ name,
4820
+ commit: (v) => validation.commit(v),
4821
+ value,
4822
+ getValue: () => value.value,
4823
+ controlRef: firstInputRef
4824
+ });
4825
+ function focusInput(index) {
4826
+ const targetIndex = Math.min(Math.max(index, 0), Math.max(inputRefs.value.length - 1, 0));
4827
+ const target = inputRefs.value[targetIndex];
4828
+ target?.focus();
4829
+ target?.select();
4830
+ }
4831
+ function queueFocusInput(index, nextValue) {
4832
+ pendingFocus = {
4833
+ index,
4834
+ value: nextValue
4835
+ };
4836
+ }
4837
+ function requestSubmit() {
4838
+ let formElement = validationInputRef.value?.form ?? inputRefs.value[0]?.form ?? null;
4839
+ if (formProp.value) {
4840
+ const associatedElement = ownerDocument(rootRef.value)?.getElementById(formProp.value);
4841
+ if (associatedElement?.tagName === "FORM") formElement = associatedElement;
4842
+ }
4843
+ if (formElement && typeof formElement.requestSubmit === "function") formElement.requestSubmit();
4844
+ }
4845
+ function completeValue(completedValue, eventDetails) {
4846
+ emit("valueComplete", completedValue, eventDetails);
4847
+ if (props.autoSubmit) requestSubmit();
4848
+ }
4849
+ function getCompleteEventDetails(details) {
4850
+ if (details.reason === REASONS.inputChange || details.reason === REASONS.inputPaste) return createGenericEventDetails(details.reason, details.event);
4851
+ return null;
4852
+ }
4853
+ function setValue(nextValue, details) {
4854
+ const currentValue = value.value;
4855
+ const normalizedValue = normalizeOTPValue(nextValue, length.value, validationType.value, normalizeValueProp.value);
4856
+ const normalizedValueLength = getOTPValueLength(normalizedValue);
4857
+ const completeEventDetails = normalizedValueLength === length.value && (getOTPValueLength(currentValue) !== length.value || details.reason === REASONS.inputPaste) ? getCompleteEventDetails(details) : null;
4858
+ if (normalizedValue === currentValue) {
4859
+ if (completeEventDetails != null) completeValue(normalizedValue, completeEventDetails);
4860
+ return null;
4861
+ }
4862
+ emit("valueChange", normalizedValue, details);
4863
+ if (details.isCanceled) return null;
4864
+ setValueUnwrapped(normalizedValue);
4865
+ if (completeEventDetails != null) pendingCompleteValue = {
4866
+ value: normalizedValue,
4867
+ eventDetails: completeEventDetails
4868
+ };
4869
+ else if (normalizedValueLength !== length.value) pendingCompleteValue = null;
4870
+ return normalizedValue;
4871
+ }
4872
+ function reportValueInvalid(invalidValue, details) {
4873
+ emit("valueInvalid", invalidValue, details);
4874
+ }
4875
+ function handleInputFocus(index, event) {
4876
+ if (index > valueLength.value) {
4877
+ focusInput(Math.min(valueLength.value, length.value - 1));
4878
+ return;
4879
+ }
4880
+ focusedIndex.value = index;
4881
+ focused.value = true;
4882
+ setFocused(true);
4883
+ event.currentTarget.select();
4884
+ }
4885
+ function handleInputBlur(event) {
4886
+ if (contains(rootRef.value, event.relatedTarget)) return;
4887
+ setTouched(true);
4888
+ focused.value = false;
4889
+ setFocused(false);
4890
+ if (validationMode.value === "onBlur") validation.commit(value.value);
4891
+ }
4892
+ function getInputId(index) {
4893
+ if (id.value == null) return;
4894
+ return index === 0 ? id.value : `${id.value}-${index + 1}`;
4895
+ }
4896
+ useValueChanged(value, () => {
4897
+ clearErrors(name.value);
4898
+ setDirty(value.value !== validityData.value.initialValue);
4899
+ validation.commit(value.value, true);
4900
+ if (pendingCompleteValue != null) {
4901
+ const pending = pendingCompleteValue;
4902
+ pendingCompleteValue = null;
4903
+ if (pending.value === value.value) completeValue(value.value, pending.eventDetails);
4904
+ }
4905
+ if (pendingFocus != null) {
4906
+ const pending = pendingFocus;
4907
+ pendingFocus = null;
4908
+ if (pending.value === value.value) focusInput(pending.index);
4909
+ }
4910
+ });
4911
+ const state = computed(() => ({
4912
+ ...fieldState.value,
4913
+ complete: valueLength.value === length.value,
4914
+ disabled: disabled.value,
4915
+ filled: filled.value,
4916
+ focused: focused.value,
4917
+ length: length.value,
4918
+ readOnly: readOnly.value,
4919
+ required: required.value,
4920
+ value: value.value
4921
+ }));
4922
+ provide(otpFieldRootContextKey, {
4923
+ activeIndex,
4924
+ autoComplete,
4925
+ disabled,
4926
+ form: formProp,
4927
+ focusInput,
4928
+ queueFocusInput,
4929
+ getInputId,
4930
+ handleInputBlur,
4931
+ handleInputFocus,
4932
+ inputMode,
4933
+ inputAriaLabelledBy,
4934
+ invalid,
4935
+ length,
4936
+ mask,
4937
+ pattern,
4938
+ reportValueInvalid,
4939
+ readOnly,
4940
+ required,
4941
+ normalizeValue: normalizeValueProp,
4942
+ setValue,
4943
+ state,
4944
+ validationType,
4945
+ value
4946
+ });
4947
+ const { tag, mergedProps, renderless, ref: renderRef } = useRenderElement({
4948
+ componentProps: props,
4949
+ state,
4950
+ props: computed(() => mergeProps$1(attrsObject, {
4951
+ "role": "group",
4952
+ "aria-describedby": ariaDescribedBy.value,
4953
+ "aria-labelledby": ariaLabelledBy.value
4954
+ })),
4955
+ stateAttributesMapping: rootStateAttributesMapping,
4956
+ defaultTagName: "div",
4957
+ ref: rootRef
4958
+ });
4959
+ const hiddenInputProps = computed(() => ({
4960
+ ...validation.getValidationProps(),
4961
+ "type": "text",
4962
+ "id": id.value && name.value == null ? `${id.value}-hidden-input` : void 0,
4963
+ "form": formProp.value,
4964
+ "name": name.value,
4965
+ "value": value.value,
4966
+ "autocomplete": autoComplete.value,
4967
+ "inputmode": inputMode.value,
4968
+ "minlength": length.value,
4969
+ "maxlength": length.value,
4970
+ "pattern": hiddenInputPattern.value,
4971
+ "disabled": disabled.value,
4972
+ "readonly": readOnly.value,
4973
+ "required": required.value,
4974
+ "aria-hidden": true,
4975
+ "tabindex": -1,
4976
+ "style": name.value ? visuallyHiddenInput : visuallyHidden
4977
+ }));
4978
+ function handleHiddenFocus() {
4979
+ focusInput(0);
4980
+ }
4981
+ function handleHiddenInput(event) {
4982
+ const target = event.target;
4983
+ if (event.defaultPrevented || disabled.value || readOnly.value) return;
4984
+ const rawValue = target.value;
4985
+ const [normalizedValue, didRejectCharacters] = normalizeOTPValueWithDetails(rawValue, length.value, validationType.value, normalizeValueProp.value);
4986
+ if (didRejectCharacters) reportValueInvalid(rawValue, createGenericEventDetails(REASONS.inputChange, event));
4987
+ const committedValue = setValue(normalizedValue, createChangeEventDetails(REASONS.inputChange, event));
4988
+ if (committedValue != null && committedValue !== "") queueFocusInput(getOTPValueLength(committedValue) - 1, committedValue);
4989
+ }
4990
+ function mergeAriaIds(...values) {
4991
+ const ids = values.flatMap((v) => v?.split(/\s+/).filter(Boolean) ?? []);
4992
+ return ids.length > 0 ? Array.from(new Set(ids)).join(" ") : void 0;
4993
+ }
4994
+ if (process.env.NODE_ENV !== "production") watchEffect(() => {
4995
+ const len = length.value;
4996
+ if (!Number.isInteger(len) || len <= 0) {
4997
+ warn(`<OtpFieldRoot> \`length\` must be a positive integer. Received \`length={${String(len)}}\`.`);
4998
+ return;
4999
+ }
5000
+ if (inputCount.value !== 0 && inputCount.value !== len) warn(`<OtpFieldRoot> \`length\` must match the number of rendered <OtpFieldInput /> parts. Received \`length={${len}}\` but rendered ${inputCount.value} input${inputCount.value === 1 ? "" : "s"}.`);
5001
+ });
5002
+ function handleMapChange(map) {
5003
+ inputCount.value = map.size;
5004
+ }
5005
+ return (_ctx, _cache) => {
5006
+ return openBlock(), createBlock(CompositeList_default, {
5007
+ "elements-ref": inputRefsHolder.elementsRef,
5008
+ "on-map-change": handleMapChange
5009
+ }, {
5010
+ default: withCtx(() => [unref(renderless) ? renderSlot(_ctx.$slots, "default", {
5011
+ key: 0,
5012
+ ref: unref(renderRef),
5013
+ props: unref(mergedProps),
5014
+ state: state.value
5015
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), mergeProps({
5016
+ key: 1,
5017
+ ref: unref(renderRef)
5018
+ }, unref(mergedProps)), {
5019
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: state.value })]),
5020
+ _: 3
5021
+ }, 16)), hasValidLength.value ? (openBlock(), createElementBlock("input", mergeProps({
5022
+ key: 2,
5023
+ ref_key: "validationInputRef",
5024
+ ref: validationInputRef
5025
+ }, hiddenInputProps.value, {
5026
+ onInput: handleHiddenInput,
5027
+ onFocus: handleHiddenFocus
5028
+ }), null, 16)) : createCommentVNode("v-if", true)]),
5029
+ _: 3
5030
+ }, 8, ["elements-ref"]);
5031
+ };
5032
+ }
5033
+ });
5034
+
5035
+ //#endregion
5036
+ //#region src/otp-field/root/OtpFieldRoot.vue
5037
+ var OtpFieldRoot_default = OtpFieldRoot_vue_vue_type_script_setup_true_lang_default;
5038
+
5039
+ //#endregion
5040
+ //#region src/progress/root/ProgressRootContext.ts
5041
+ const progressRootContextKey = Symbol("ProgressRootContext");
5042
+ function useProgressRootContext(optional = false) {
5043
+ const context = inject(progressRootContextKey, void 0);
5044
+ if (!context && !optional) throw new Error("Base UI Vue: ProgressRootContext is missing. Progress parts must be placed within <ProgressRoot>.");
5045
+ return context;
5046
+ }
5047
+
5048
+ //#endregion
5049
+ //#region src/progress/root/ProgressRootDataAttributes.ts
5050
+ let ProgressRootDataAttributes = /* @__PURE__ */ function(ProgressRootDataAttributes) {
5051
+ /**
5052
+ * Present when the progress has completed.
5053
+ */
5054
+ ProgressRootDataAttributes["complete"] = "data-complete";
5055
+ /**
5056
+ * Present when the progress is in indeterminate state.
5057
+ */
5058
+ ProgressRootDataAttributes["indeterminate"] = "data-indeterminate";
5059
+ /**
5060
+ * Present while the progress is progressing.
5061
+ */
5062
+ ProgressRootDataAttributes["progressing"] = "data-progressing";
5063
+ return ProgressRootDataAttributes;
5064
+ }({});
5065
+
5066
+ //#endregion
5067
+ //#region src/progress/root/stateAttributesMapping.ts
5068
+ const progressStateAttributesMapping = { status(value) {
5069
+ if (value === "progressing") return { [ProgressRootDataAttributes.progressing]: "" };
5070
+ if (value === "complete") return { [ProgressRootDataAttributes.complete]: "" };
5071
+ if (value === "indeterminate") return { [ProgressRootDataAttributes.indeterminate]: "" };
5072
+ return null;
5073
+ } };
5074
+
5075
+ //#endregion
5076
+ //#region src/progress/indicator/ProgressIndicator.vue?vue&type=script&setup=true&lang.ts
5077
+ /**
5078
+ * Visualizes the completion status of the task.
5079
+ * Renders a `<div>` element.
5080
+ *
5081
+ * Documentation: [Base UI Vue Progress](https://baseui-vue.com/docs/components/progress)
5082
+ */
5083
+ var ProgressIndicator_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
5084
+ name: "ProgressIndicator",
5085
+ inheritAttrs: false,
5086
+ __name: "ProgressIndicator",
5087
+ props: {
5088
+ as: {
5089
+ type: null,
5090
+ required: false,
5091
+ default: "div"
5092
+ },
5093
+ class: {
5094
+ type: Function,
5095
+ required: false,
5096
+ skipCheck: true
5097
+ },
5098
+ style: {
5099
+ type: [
5100
+ Boolean,
5101
+ null,
5102
+ String,
5103
+ Object,
5104
+ Array,
5105
+ Function
5106
+ ],
5107
+ required: false,
5108
+ skipCheck: true
5109
+ }
5110
+ },
5111
+ setup(__props) {
5112
+ const props = __props;
5113
+ const attrs = useAttrs();
5114
+ const { value, min, max, state } = useProgressRootContext();
5115
+ const percentage = computed(() => {
5116
+ const v = value.value;
5117
+ if (v == null || !Number.isFinite(v)) return null;
5118
+ return valueToPercent(v, min.value, max.value);
5119
+ });
5120
+ const indicatorStyles = computed(() => {
5121
+ if (percentage.value == null) return {};
5122
+ return {
5123
+ insetInlineStart: 0,
5124
+ height: "inherit",
5125
+ width: `${percentage.value}%`
5126
+ };
5127
+ });
5128
+ const { tag, mergedProps, renderless } = useRenderElement({
5129
+ componentProps: props,
5130
+ state,
5131
+ props: computed(() => mergeProps$1({ style: indicatorStyles.value }, attrs)),
5132
+ defaultTagName: "div",
5133
+ stateAttributesMapping: progressStateAttributesMapping
5134
+ });
5135
+ return (_ctx, _cache) => {
5136
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
5137
+ key: 0,
5138
+ props: unref(mergedProps),
5139
+ state: unref(state)
5140
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), normalizeProps(mergeProps({ key: 1 }, unref(mergedProps))), {
5141
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: unref(state) })]),
5142
+ _: 3
5143
+ }, 16));
5144
+ };
5145
+ }
5146
+ });
5147
+
5148
+ //#endregion
5149
+ //#region src/progress/indicator/ProgressIndicator.vue
5150
+ var ProgressIndicator_default = ProgressIndicator_vue_vue_type_script_setup_true_lang_default;
5151
+
5152
+ //#endregion
5153
+ //#region src/progress/label/ProgressLabel.vue?vue&type=script&setup=true&lang.ts
5154
+ /**
5155
+ * An accessible label for the progress bar.
5156
+ * Renders a `<span>` element.
5157
+ *
5158
+ * Documentation: [Base UI Vue Progress](https://baseui-vue.com/docs/components/progress)
5159
+ */
5160
+ var ProgressLabel_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
5161
+ name: "ProgressLabel",
5162
+ inheritAttrs: false,
5163
+ __name: "ProgressLabel",
5164
+ props: {
5165
+ id: {
5166
+ type: String,
5167
+ required: false
5168
+ },
5169
+ as: {
5170
+ type: null,
5171
+ required: false,
5172
+ default: "span"
5173
+ },
5174
+ class: {
5175
+ type: Function,
5176
+ required: false,
5177
+ skipCheck: true
5178
+ },
5179
+ style: {
5180
+ type: [
5181
+ Boolean,
5182
+ null,
5183
+ String,
5184
+ Object,
5185
+ Array,
5186
+ Function
5187
+ ],
5188
+ required: false,
5189
+ skipCheck: true
5190
+ }
5191
+ },
5192
+ setup(__props) {
5193
+ const props = __props;
5194
+ const attrs = useAttrs();
5195
+ const { setLabelId, state } = useProgressRootContext();
5196
+ const id = useRegisteredLabelId(() => props.id, setLabelId);
5197
+ const { tag, mergedProps, renderless } = useRenderElement({
5198
+ componentProps: props,
5199
+ state,
5200
+ props: computed(() => ({
5201
+ ...attrs,
5202
+ id: id.value,
5203
+ role: "presentation"
5204
+ })),
5205
+ defaultTagName: "span",
5206
+ stateAttributesMapping: progressStateAttributesMapping
5207
+ });
5208
+ return (_ctx, _cache) => {
5209
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
5210
+ key: 0,
5211
+ props: unref(mergedProps),
5212
+ state: unref(state)
5213
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), normalizeProps(mergeProps({ key: 1 }, unref(mergedProps))), {
5214
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: unref(state) })]),
5215
+ _: 3
5216
+ }, 16));
5217
+ };
5218
+ }
5219
+ });
5220
+
5221
+ //#endregion
5222
+ //#region src/progress/label/ProgressLabel.vue
5223
+ var ProgressLabel_default = ProgressLabel_vue_vue_type_script_setup_true_lang_default;
5224
+
5225
+ //#endregion
5226
+ //#region src/progress/root/ProgressRoot.vue?vue&type=script&setup=true&lang.ts
5227
+ /**
5228
+ * Groups all parts of the progress bar and provides the task completion
5229
+ * status to screen readers.
5230
+ * Renders a `<div>` element.
5231
+ *
5232
+ * Documentation: [Base UI Vue Progress](https://baseui-vue.com/docs/components/progress)
5233
+ */
5234
+ var ProgressRoot_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
5235
+ name: "ProgressRoot",
5236
+ inheritAttrs: false,
5237
+ __name: "ProgressRoot",
5238
+ props: {
5239
+ ariaValuetext: {
5240
+ type: String,
5241
+ required: false
5242
+ },
5243
+ format: {
5244
+ type: null,
5245
+ required: false
5246
+ },
5247
+ getAriaValueText: {
5248
+ type: Function,
5249
+ required: false
5250
+ },
5251
+ locale: {
5252
+ type: null,
5253
+ required: false
5254
+ },
5255
+ max: {
5256
+ type: Number,
5257
+ required: false,
5258
+ default: 100
5259
+ },
5260
+ min: {
5261
+ type: Number,
5262
+ required: false,
5263
+ default: 0
5264
+ },
5265
+ value: {
5266
+ type: [Number, null],
5267
+ required: true
5268
+ },
5269
+ as: {
5270
+ type: null,
5271
+ required: false,
5272
+ default: "div"
5273
+ },
5274
+ class: {
5275
+ type: Function,
5276
+ required: false,
5277
+ skipCheck: true
5278
+ },
5279
+ style: {
5280
+ type: [
5281
+ Boolean,
5282
+ null,
5283
+ String,
5284
+ Object,
5285
+ Array,
5286
+ Function
5287
+ ],
5288
+ required: false,
5289
+ skipCheck: true
5290
+ }
5291
+ },
5292
+ setup(__props) {
5293
+ const props = __props;
5294
+ function getDefaultAriaValueText(formattedValue, value) {
5295
+ if (value == null) return "indeterminate progress";
5296
+ return formattedValue || `${value}%`;
5297
+ }
5298
+ const attrs = useAttrs();
5299
+ const labelId = ref(void 0);
5300
+ const status = computed(() => {
5301
+ if (props.value == null || !Number.isFinite(props.value)) return "indeterminate";
5302
+ return props.value === props.max ? "complete" : "progressing";
5303
+ });
5304
+ const formattedValue = computed(() => formatNumberValue(props.value, props.locale, props.format));
5305
+ const ariaValueText = computed(() => {
5306
+ if (props.ariaValuetext !== void 0) return props.ariaValuetext;
5307
+ const formatted = props.value == null ? null : formattedValue.value;
5308
+ if (props.getAriaValueText) return props.getAriaValueText(formatted, props.value);
5309
+ return getDefaultAriaValueText(formatted, props.value);
5310
+ });
5311
+ const state = computed(() => ({ status: status.value }));
5312
+ provide(progressRootContextKey, {
5313
+ formattedValue,
5314
+ max: computed(() => props.max),
5315
+ min: computed(() => props.min),
5316
+ value: computed(() => props.value),
5317
+ status,
5318
+ state,
5319
+ setLabelId(id) {
5320
+ labelId.value = id;
5321
+ }
5322
+ });
5323
+ const { tag, mergedProps, renderless } = useRenderElement({
5324
+ componentProps: props,
5325
+ state,
5326
+ props: computed(() => ({
5327
+ "role": "progressbar",
5328
+ "aria-labelledby": labelId.value,
5329
+ "aria-valuemax": props.max,
5330
+ "aria-valuemin": props.min,
5331
+ "aria-valuenow": props.value ?? void 0,
5332
+ "aria-valuetext": ariaValueText.value,
5333
+ ...attrs
5334
+ })),
5335
+ defaultTagName: "div",
5336
+ stateAttributesMapping: progressStateAttributesMapping
5337
+ });
5338
+ const visuallyHiddenStyle = visuallyHidden;
5339
+ return (_ctx, _cache) => {
5340
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
5341
+ key: 0,
5342
+ props: unref(mergedProps),
5343
+ state: state.value
5344
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), normalizeProps(mergeProps({ key: 1 }, unref(mergedProps))), {
5345
+ default: withCtx(() => [
5346
+ renderSlot(_ctx.$slots, "default", { state: state.value }),
5347
+ createCommentVNode(" Force NVDA to read the label https://github.com/mui/base-ui/issues/4184 "),
5348
+ createElementVNode("span", {
5349
+ role: "presentation",
5350
+ style: normalizeStyle(unref(visuallyHiddenStyle))
5351
+ }, "x", 4)
5352
+ ]),
5353
+ _: 3
5354
+ }, 16));
5355
+ };
5356
+ }
5357
+ });
5358
+
5359
+ //#endregion
5360
+ //#region src/progress/root/ProgressRoot.vue
5361
+ var ProgressRoot_default = ProgressRoot_vue_vue_type_script_setup_true_lang_default;
5362
+
5363
+ //#endregion
5364
+ //#region src/progress/track/ProgressTrack.vue?vue&type=script&setup=true&lang.ts
5365
+ /**
5366
+ * Contains the progress bar indicator.
5367
+ * Renders a `<div>` element.
5368
+ *
5369
+ * Documentation: [Base UI Vue Progress](https://baseui-vue.com/docs/components/progress)
5370
+ */
5371
+ var ProgressTrack_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
5372
+ name: "ProgressTrack",
5373
+ inheritAttrs: false,
5374
+ __name: "ProgressTrack",
5375
+ props: {
5376
+ as: {
5377
+ type: null,
5378
+ required: false,
5379
+ default: "div"
5380
+ },
5381
+ class: {
5382
+ type: Function,
5383
+ required: false,
5384
+ skipCheck: true
5385
+ },
5386
+ style: {
5387
+ type: [
5388
+ Boolean,
5389
+ null,
5390
+ String,
5391
+ Object,
5392
+ Array,
5393
+ Function
5394
+ ],
5395
+ required: false,
5396
+ skipCheck: true
5397
+ }
5398
+ },
5399
+ setup(__props) {
5400
+ const props = __props;
5401
+ const attrs = useAttrs();
5402
+ const { state } = useProgressRootContext();
5403
+ const { tag, mergedProps, renderless } = useRenderElement({
5404
+ componentProps: props,
5405
+ state,
5406
+ props: attrs,
5407
+ defaultTagName: "div",
5408
+ stateAttributesMapping: progressStateAttributesMapping
5409
+ });
5410
+ return (_ctx, _cache) => {
5411
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
5412
+ key: 0,
5413
+ props: unref(mergedProps),
5414
+ state: unref(state)
5415
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), normalizeProps(mergeProps({ key: 1 }, unref(mergedProps))), {
5416
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: unref(state) })]),
5417
+ _: 3
5418
+ }, 16));
5419
+ };
5420
+ }
5421
+ });
5422
+
5423
+ //#endregion
5424
+ //#region src/progress/track/ProgressTrack.vue
5425
+ var ProgressTrack_default = ProgressTrack_vue_vue_type_script_setup_true_lang_default;
5426
+
5427
+ //#endregion
5428
+ //#region src/progress/value/ProgressValue.vue?vue&type=script&setup=true&lang.ts
5429
+ /**
5430
+ * A text label displaying the current value.
5431
+ * Renders a `<span>` element.
5432
+ *
5433
+ * Documentation: [Base UI Vue Progress](https://baseui-vue.com/docs/components/progress)
5434
+ */
5435
+ var ProgressValue_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
5436
+ name: "ProgressValue",
5437
+ inheritAttrs: false,
5438
+ __name: "ProgressValue",
5439
+ props: {
5440
+ as: {
5441
+ type: null,
5442
+ required: false,
5443
+ default: "span"
5444
+ },
5445
+ class: {
5446
+ type: Function,
5447
+ required: false,
5448
+ skipCheck: true
5449
+ },
5450
+ style: {
5451
+ type: [
5452
+ Boolean,
5453
+ null,
5454
+ String,
5455
+ Object,
5456
+ Array,
5457
+ Function
5458
+ ],
5459
+ required: false,
5460
+ skipCheck: true
5461
+ }
5462
+ },
5463
+ setup(__props) {
5464
+ const props = __props;
5465
+ const attrs = useAttrs();
5466
+ const { value, formattedValue, state } = useProgressRootContext();
5467
+ const slotFormattedValue = computed(() => value.value == null ? "indeterminate" : formattedValue.value);
5468
+ const defaultDisplay = computed(() => value.value == null ? "" : formattedValue.value);
5469
+ const { tag, mergedProps, renderless } = useRenderElement({
5470
+ componentProps: props,
5471
+ state,
5472
+ props: computed(() => ({
5473
+ "aria-hidden": true,
5474
+ ...attrs
5475
+ })),
5476
+ defaultTagName: "span",
5477
+ stateAttributesMapping: progressStateAttributesMapping
5478
+ });
5479
+ return (_ctx, _cache) => {
5480
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
5481
+ key: 0,
5482
+ props: unref(mergedProps),
5483
+ state: unref(state),
5484
+ formattedValue: slotFormattedValue.value,
5485
+ value: unref(value)
5486
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), normalizeProps(mergeProps({ key: 1 }, unref(mergedProps))), {
5487
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", {
5488
+ formattedValue: slotFormattedValue.value,
5489
+ value: unref(value)
5490
+ }, () => [createTextVNode(toDisplayString(defaultDisplay.value), 1)])]),
5491
+ _: 3
5492
+ }, 16));
5493
+ };
5494
+ }
5495
+ });
5496
+
5497
+ //#endregion
5498
+ //#region src/progress/value/ProgressValue.vue
5499
+ var ProgressValue_default = ProgressValue_vue_vue_type_script_setup_true_lang_default;
5500
+
5501
+ //#endregion
5502
+ //#region src/utils/styles.ts
5503
+ const DISABLE_SCROLLBAR_CLASS_NAME = "base-ui-disable-scrollbar";
5504
+ const STYLE_ELEMENT_ID = `style-${DISABLE_SCROLLBAR_CLASS_NAME}`;
5505
+ const styleDisableScrollbar = {
5506
+ className: DISABLE_SCROLLBAR_CLASS_NAME,
5507
+ inject(nonce, disableStyleElements) {
5508
+ if (disableStyleElements) return;
5509
+ if (typeof document === "undefined") return;
5510
+ if (document.getElementById(STYLE_ELEMENT_ID)) return;
5511
+ const style = document.createElement("style");
5512
+ style.id = STYLE_ELEMENT_ID;
5513
+ if (nonce) style.nonce = nonce;
5514
+ style.textContent = `.${DISABLE_SCROLLBAR_CLASS_NAME}{scrollbar-width:none}.${DISABLE_SCROLLBAR_CLASS_NAME}::-webkit-scrollbar{display:none}`;
5515
+ document.head.appendChild(style);
5516
+ }
5517
+ };
5518
+
5519
+ //#endregion
5520
+ //#region src/scroll-area/constants.ts
5521
+ const SCROLL_TIMEOUT = 500;
5522
+ const MIN_THUMB_SIZE = 16;
5523
+
5524
+ //#endregion
5525
+ //#region src/scroll-area/scrollbar/ScrollAreaScrollbarDataAttributes.ts
5526
+ let ScrollAreaScrollbarDataAttributes = /* @__PURE__ */ function(ScrollAreaScrollbarDataAttributes) {
5527
+ ScrollAreaScrollbarDataAttributes["orientation"] = "data-orientation";
5528
+ ScrollAreaScrollbarDataAttributes["hovering"] = "data-hovering";
5529
+ ScrollAreaScrollbarDataAttributes["scrolling"] = "data-scrolling";
5530
+ ScrollAreaScrollbarDataAttributes["hasOverflowX"] = "data-has-overflow-x";
5531
+ ScrollAreaScrollbarDataAttributes["hasOverflowY"] = "data-has-overflow-y";
5532
+ ScrollAreaScrollbarDataAttributes["overflowXStart"] = "data-overflow-x-start";
5533
+ ScrollAreaScrollbarDataAttributes["overflowXEnd"] = "data-overflow-x-end";
5534
+ ScrollAreaScrollbarDataAttributes["overflowYStart"] = "data-overflow-y-start";
5535
+ ScrollAreaScrollbarDataAttributes["overflowYEnd"] = "data-overflow-y-end";
5536
+ return ScrollAreaScrollbarDataAttributes;
5537
+ }({});
5538
+
5539
+ //#endregion
5540
+ //#region src/scroll-area/utils/getOffset.ts
5541
+ function getOffset(element, prop, axis) {
5542
+ if (!element) return 0;
5543
+ const styles = getComputedStyle(element);
5544
+ const propAxis = axis === "x" ? "Inline" : "Block";
5545
+ const start = getStyleNumber(styles, `${prop}${propAxis}Start`);
5546
+ const end = getStyleNumber(styles, `${prop}${propAxis}End`);
5547
+ if (axis === "x" && prop === "margin" && styles.direction === "rtl" && isSafari()) return start * 2;
5548
+ return start + end;
5549
+ }
5550
+ function getStyleNumber(styles, prop) {
5551
+ return Number.parseFloat(styles[prop]) || 0;
5552
+ }
5553
+ function isSafari() {
5554
+ if (typeof navigator === "undefined") return false;
5555
+ return /AppleWebKit/.test(navigator.userAgent) && !/Chrome|Chromium|Edg\//.test(navigator.userAgent);
5556
+ }
5557
+
5558
+ //#endregion
5559
+ //#region src/scroll-area/root/ScrollAreaRootCssVars.ts
5560
+ let ScrollAreaRootCssVars = /* @__PURE__ */ function(ScrollAreaRootCssVars) {
5561
+ ScrollAreaRootCssVars["scrollAreaCornerHeight"] = "--scroll-area-corner-height";
5562
+ ScrollAreaRootCssVars["scrollAreaCornerWidth"] = "--scroll-area-corner-width";
5563
+ return ScrollAreaRootCssVars;
5564
+ }({});
5565
+
5566
+ //#endregion
5567
+ //#region src/scroll-area/root/ScrollAreaRoot.vue?vue&type=script&setup=true&lang.ts
5568
+ var ScrollAreaRoot_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
5569
+ name: "ScrollAreaRoot",
5570
+ inheritAttrs: false,
5571
+ __name: "ScrollAreaRoot",
5572
+ props: {
5573
+ overflowEdgeThreshold: {
5574
+ type: [Number, Object],
5575
+ required: false
5576
+ },
5577
+ as: {
5578
+ type: null,
5579
+ required: false,
5580
+ default: "div"
5581
+ },
5582
+ class: {
5583
+ type: Function,
5584
+ required: false,
5585
+ skipCheck: true
5586
+ },
5587
+ style: {
5588
+ type: [
5589
+ Boolean,
5590
+ null,
5591
+ String,
5592
+ Object,
5593
+ Array,
5594
+ Function
5595
+ ],
5596
+ required: false,
5597
+ skipCheck: true
5598
+ }
5599
+ },
5600
+ setup(__props) {
5601
+ const props = __props;
5602
+ const DEFAULT_SIZE = {
5603
+ width: 0,
5604
+ height: 0
5605
+ };
5606
+ const DEFAULT_OVERFLOW_EDGES = {
5607
+ xStart: false,
5608
+ xEnd: false,
5609
+ yStart: false,
5610
+ yEnd: false
5611
+ };
5612
+ const DEFAULT_HIDDEN_STATE = {
5613
+ x: true,
5614
+ y: true,
5615
+ corner: true
5616
+ };
5617
+ const DEFAULT_COORDS = {
5618
+ x: 0,
5619
+ y: 0
5620
+ };
5621
+ const attrs = useAttrs();
5622
+ const overflowEdgeThreshold = computed(() => normalizeOverflowEdgeThreshold(props.overflowEdgeThreshold));
5623
+ const rootId = useBaseUiId();
5624
+ const { nonce, disableStyleElements } = useCSPContext();
5625
+ const hovering = ref(false);
5626
+ const scrollingX = ref(false);
5627
+ const scrollingY = ref(false);
5628
+ const touchModality = ref(false);
5629
+ const hasMeasuredScrollbar = ref(false);
5630
+ const cornerSize = ref({ ...DEFAULT_SIZE });
5631
+ const thumbSize = ref({ ...DEFAULT_SIZE });
5632
+ const overflowEdges = ref({ ...DEFAULT_OVERFLOW_EDGES });
5633
+ const hiddenState = ref({ ...DEFAULT_HIDDEN_STATE });
5634
+ const rootRef = shallowRef(null);
5635
+ const viewportRef = shallowRef(null);
5636
+ const scrollbarYRef = shallowRef(null);
5637
+ const scrollbarXRef = shallowRef(null);
5638
+ const thumbYRef = shallowRef(null);
5639
+ const thumbXRef = shallowRef(null);
5640
+ const cornerRef = shallowRef(null);
5641
+ let scrollYTimeoutId;
5642
+ let scrollXTimeoutId;
5643
+ const thumbDragging = { current: false };
5644
+ const startY = { current: 0 };
5645
+ const startX = { current: 0 };
5646
+ const startScrollTop = { current: 0 };
5647
+ const startScrollLeft = { current: 0 };
5648
+ const currentOrientation = { current: "vertical" };
5649
+ const scrollPosition = { current: { ...DEFAULT_COORDS } };
5650
+ function handleScroll(pos) {
5651
+ const offsetX = pos.x - scrollPosition.current.x;
5652
+ const offsetY = pos.y - scrollPosition.current.y;
5653
+ scrollPosition.current = pos;
5654
+ if (offsetY !== 0) {
5655
+ scrollingY.value = true;
5656
+ clearTimeout(scrollYTimeoutId);
5657
+ scrollYTimeoutId = setTimeout(() => {
5658
+ scrollingY.value = false;
5659
+ }, SCROLL_TIMEOUT);
5660
+ }
5661
+ if (offsetX !== 0) {
5662
+ scrollingX.value = true;
5663
+ clearTimeout(scrollXTimeoutId);
5664
+ scrollXTimeoutId = setTimeout(() => {
5665
+ scrollingX.value = false;
5666
+ }, SCROLL_TIMEOUT);
5667
+ }
5668
+ }
5669
+ function handlePointerDown(event) {
5670
+ if (event.button !== 0) return;
5671
+ thumbDragging.current = true;
5672
+ startY.current = event.clientY;
5673
+ startX.current = event.clientX;
5674
+ currentOrientation.current = event.currentTarget.getAttribute(ScrollAreaScrollbarDataAttributes.orientation);
5675
+ if (viewportRef.value) {
5676
+ startScrollTop.current = viewportRef.value.scrollTop;
5677
+ startScrollLeft.current = viewportRef.value.scrollLeft;
5678
+ }
5679
+ if (thumbYRef.value && currentOrientation.current === "vertical") thumbYRef.value.setPointerCapture(event.pointerId);
5680
+ if (thumbXRef.value && currentOrientation.current === "horizontal") thumbXRef.value.setPointerCapture(event.pointerId);
5681
+ }
5682
+ function handlePointerMove(event) {
5683
+ if (!thumbDragging.current) return;
5684
+ const deltaY = event.clientY - startY.current;
5685
+ const deltaX = event.clientX - startX.current;
5686
+ if (viewportRef.value) {
5687
+ const scrollableContentHeight = viewportRef.value.scrollHeight;
5688
+ const viewportHeight = viewportRef.value.clientHeight;
5689
+ const scrollableContentWidth = viewportRef.value.scrollWidth;
5690
+ const viewportWidth = viewportRef.value.clientWidth;
5691
+ if (thumbYRef.value && scrollbarYRef.value && currentOrientation.current === "vertical") {
5692
+ const scrollbarYOffset = getOffset(scrollbarYRef.value, "padding", "y");
5693
+ const thumbYOffset = getOffset(thumbYRef.value, "margin", "y");
5694
+ const thumbHeight = thumbYRef.value.offsetHeight;
5695
+ const scrollRatioY = deltaY / (scrollbarYRef.value.offsetHeight - thumbHeight - scrollbarYOffset - thumbYOffset);
5696
+ viewportRef.value.scrollTop = startScrollTop.current + scrollRatioY * (scrollableContentHeight - viewportHeight);
5697
+ event.preventDefault();
5698
+ scrollingY.value = true;
5699
+ clearTimeout(scrollYTimeoutId);
5700
+ scrollYTimeoutId = setTimeout(() => {
5701
+ scrollingY.value = false;
5702
+ }, SCROLL_TIMEOUT);
5703
+ }
5704
+ if (thumbXRef.value && scrollbarXRef.value && currentOrientation.current === "horizontal") {
5705
+ const scrollbarXOffset = getOffset(scrollbarXRef.value, "padding", "x");
5706
+ const thumbXOffset = getOffset(thumbXRef.value, "margin", "x");
5707
+ const thumbWidth = thumbXRef.value.offsetWidth;
5708
+ const scrollRatioX = deltaX / (scrollbarXRef.value.offsetWidth - thumbWidth - scrollbarXOffset - thumbXOffset);
5709
+ viewportRef.value.scrollLeft = startScrollLeft.current + scrollRatioX * (scrollableContentWidth - viewportWidth);
5710
+ event.preventDefault();
5711
+ scrollingX.value = true;
5712
+ clearTimeout(scrollXTimeoutId);
5713
+ scrollXTimeoutId = setTimeout(() => {
5714
+ scrollingX.value = false;
5715
+ }, SCROLL_TIMEOUT);
5716
+ }
5717
+ }
5718
+ }
5719
+ function handlePointerUp(event) {
5720
+ thumbDragging.current = false;
5721
+ if (thumbYRef.value && currentOrientation.current === "vertical") thumbYRef.value.releasePointerCapture(event.pointerId);
5722
+ if (thumbXRef.value && currentOrientation.current === "horizontal") thumbXRef.value.releasePointerCapture(event.pointerId);
5723
+ }
5724
+ function handleTouchModalityChange(event) {
5725
+ touchModality.value = event.pointerType === "touch";
5726
+ }
5727
+ function handlePointerEnterOrMove(event) {
5728
+ handleTouchModalityChange(event);
5729
+ if (event.pointerType !== "touch") hovering.value = contains(rootRef.value, event.target);
5730
+ }
5731
+ const state = computed(() => ({
5732
+ scrolling: scrollingX.value || scrollingY.value,
5733
+ hasOverflowX: !hiddenState.value.x,
5734
+ hasOverflowY: !hiddenState.value.y,
5735
+ overflowXStart: overflowEdges.value.xStart,
5736
+ overflowXEnd: overflowEdges.value.xEnd,
5737
+ overflowYStart: overflowEdges.value.yStart,
5738
+ overflowYEnd: overflowEdges.value.yEnd,
5739
+ cornerHidden: hiddenState.value.corner
5740
+ }));
5741
+ const { tag, mergedProps, renderless, ref: renderRef } = useRenderElement({
5742
+ componentProps: props,
5743
+ state,
5744
+ props: computed(() => mergeProps$1(attrs, {
5745
+ role: "presentation",
5746
+ onPointerenter: handlePointerEnterOrMove,
5747
+ onPointermove: handlePointerEnterOrMove,
5748
+ onPointerdown: handleTouchModalityChange,
5749
+ onPointerleave: () => {
5750
+ hovering.value = false;
5751
+ },
5752
+ style: {
5753
+ position: "relative",
5754
+ [ScrollAreaRootCssVars.scrollAreaCornerHeight]: `${cornerSize.value.height}px`,
5755
+ [ScrollAreaRootCssVars.scrollAreaCornerWidth]: `${cornerSize.value.width}px`
5756
+ }
5757
+ })),
5758
+ stateAttributesMapping: scrollAreaStateAttributesMapping,
5759
+ defaultTagName: "div",
5760
+ ref: rootRef
5761
+ });
5762
+ onMounted(() => {
5763
+ styleDisableScrollbar.inject(nonce.value, disableStyleElements.value);
5764
+ });
5765
+ provide(scrollAreaRootContextKey, {
5766
+ cornerSize,
5767
+ setCornerSize: (size) => {
5768
+ cornerSize.value = size;
5769
+ },
5770
+ thumbSize,
5771
+ setThumbSize: (size) => {
5772
+ thumbSize.value = size;
5773
+ },
5774
+ hasMeasuredScrollbar,
5775
+ setHasMeasuredScrollbar: (value) => {
5776
+ hasMeasuredScrollbar.value = value;
5777
+ },
5778
+ touchModality,
5779
+ hovering,
5780
+ setHovering: (value) => {
5781
+ hovering.value = value;
5782
+ },
5783
+ scrollingX,
5784
+ setScrollingX: (value) => {
5785
+ scrollingX.value = value;
5786
+ },
5787
+ scrollingY,
5788
+ setScrollingY: (value) => {
5789
+ scrollingY.value = value;
5790
+ },
5791
+ viewportRef,
5792
+ rootRef,
5793
+ scrollbarYRef,
5794
+ scrollbarXRef,
5795
+ thumbYRef,
5796
+ thumbXRef,
5797
+ cornerRef,
5798
+ handlePointerDown,
5799
+ handlePointerMove,
5800
+ handlePointerUp,
5801
+ handleScroll,
5802
+ rootId,
5803
+ hiddenState,
5804
+ setHiddenState: (s) => {
5805
+ hiddenState.value = s;
5806
+ },
5807
+ overflowEdges,
5808
+ setOverflowEdges: (e) => {
5809
+ overflowEdges.value = e;
5810
+ },
5811
+ viewportState: state,
5812
+ overflowEdgeThreshold
5813
+ });
5814
+ function normalizeOverflowEdgeThreshold(threshold) {
5815
+ if (typeof threshold === "number") {
5816
+ const value = Math.max(0, threshold);
5817
+ return {
5818
+ xStart: value,
5819
+ xEnd: value,
5820
+ yStart: value,
5821
+ yEnd: value
5822
+ };
5823
+ }
5824
+ return {
5825
+ xStart: Math.max(0, threshold?.xStart || 0),
5826
+ xEnd: Math.max(0, threshold?.xEnd || 0),
5827
+ yStart: Math.max(0, threshold?.yStart || 0),
5828
+ yEnd: Math.max(0, threshold?.yEnd || 0)
5829
+ };
5830
+ }
5831
+ return (_ctx, _cache) => {
5832
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
5833
+ key: 0,
5834
+ ref: unref(renderRef),
5835
+ props: unref(mergedProps),
5836
+ state: state.value
5837
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), mergeProps({
5838
+ key: 1,
5839
+ ref: unref(renderRef)
5840
+ }, unref(mergedProps)), {
5841
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default")]),
5842
+ _: 3
5843
+ }, 16));
5844
+ };
5845
+ }
5846
+ });
5847
+
5848
+ //#endregion
5849
+ //#region src/scroll-area/root/ScrollAreaRoot.vue
5850
+ var ScrollAreaRoot_default = ScrollAreaRoot_vue_vue_type_script_setup_true_lang_default;
5851
+
5852
+ //#endregion
5853
+ //#region src/scroll-area/scrollbar/ScrollAreaScrollbarContext.ts
5854
+ const scrollAreaScrollbarContextKey = Symbol("ScrollAreaScrollbarContext");
5855
+ function useScrollAreaScrollbarContext() {
5856
+ const context = inject(scrollAreaScrollbarContextKey);
5857
+ if (context === void 0) throw new Error("Base UI: ScrollAreaScrollbarContext is missing. ScrollArea.Thumb must be placed within <ScrollAreaScrollbar>.");
5858
+ return context;
5859
+ }
5860
+
5861
+ //#endregion
5862
+ //#region src/scroll-area/scrollbar/ScrollAreaScrollbarCssVars.ts
5863
+ let ScrollAreaScrollbarCssVars = /* @__PURE__ */ function(ScrollAreaScrollbarCssVars) {
5864
+ ScrollAreaScrollbarCssVars["scrollAreaThumbHeight"] = "--scroll-area-thumb-height";
5865
+ ScrollAreaScrollbarCssVars["scrollAreaThumbWidth"] = "--scroll-area-thumb-width";
5866
+ return ScrollAreaScrollbarCssVars;
5867
+ }({});
5868
+
5869
+ //#endregion
5870
+ //#region src/scroll-area/scrollbar/ScrollAreaScrollbar.vue?vue&type=script&setup=true&lang.ts
5871
+ var ScrollAreaScrollbar_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
5872
+ name: "ScrollAreaScrollbar",
5873
+ inheritAttrs: false,
5874
+ __name: "ScrollAreaScrollbar",
5875
+ props: {
5876
+ orientation: {
5877
+ type: String,
5878
+ required: false,
5879
+ default: "vertical"
5880
+ },
5881
+ keepMounted: {
5882
+ type: Boolean,
5883
+ required: false,
5884
+ default: false
5885
+ },
5886
+ as: {
5887
+ type: null,
5888
+ required: false,
5889
+ default: "div"
5890
+ },
5891
+ class: {
5892
+ type: Function,
5893
+ required: false,
5894
+ skipCheck: true
5895
+ },
5896
+ style: {
5897
+ type: [
5898
+ Boolean,
5899
+ null,
5900
+ String,
5901
+ Object,
5902
+ Array,
5903
+ Function
5904
+ ],
5905
+ required: false,
5906
+ skipCheck: true
5907
+ }
5908
+ },
5909
+ setup(__props) {
5910
+ const props = __props;
5911
+ const attrs = useAttrs();
5912
+ const { hovering, scrollingX, scrollingY, hiddenState, overflowEdges, scrollbarYRef, scrollbarXRef, viewportRef, thumbYRef, thumbXRef, handlePointerDown, handlePointerUp, rootId, thumbSize, hasMeasuredScrollbar } = useScrollAreaRootContext();
5913
+ const direction = useDirection();
5914
+ let wheelCleanup;
5915
+ const scrollbarElementRef = shallowRef(null);
5916
+ watch([scrollbarElementRef, () => props.orientation], ([element, orientation], [previousElement, previousOrientation]) => {
5917
+ if (previousElement) {
5918
+ const previousRef = previousOrientation === "vertical" ? scrollbarYRef : scrollbarXRef;
5919
+ if (previousRef.value === previousElement) previousRef.value = null;
5920
+ }
5921
+ if (!element) return;
5922
+ const nextRef = orientation === "vertical" ? scrollbarYRef : scrollbarXRef;
5923
+ nextRef.value = element;
5924
+ });
5925
+ watch([
5926
+ scrollbarElementRef,
5927
+ viewportRef,
5928
+ () => props.orientation
5929
+ ], () => {
5930
+ wheelCleanup?.();
5931
+ wheelCleanup = setupWheelHandler();
5932
+ }, { flush: "post" });
5933
+ onBeforeUnmount(() => {
5934
+ wheelCleanup?.();
5935
+ });
5936
+ function setupWheelHandler() {
5937
+ const viewportEl = viewportRef.value;
5938
+ const scrollbarEl = scrollbarElementRef.value;
5939
+ if (!scrollbarEl) return void 0;
5940
+ function handleWheel(event) {
5941
+ if (!viewportEl || !scrollbarEl || event.ctrlKey) return;
5942
+ if (props.orientation === "vertical") {
5943
+ if (viewportEl.scrollTop === 0 && event.deltaY < 0) return;
5944
+ if (viewportEl.scrollTop === viewportEl.scrollHeight - viewportEl.clientHeight && event.deltaY > 0) return;
5945
+ event.preventDefault();
5946
+ viewportEl.scrollTop += event.deltaY;
5947
+ } else {
5948
+ if (viewportEl.scrollLeft === 0 && event.deltaX < 0) return;
5949
+ if (viewportEl.scrollLeft === viewportEl.scrollWidth - viewportEl.clientWidth && event.deltaX > 0) return;
5950
+ event.preventDefault();
5951
+ viewportEl.scrollLeft += event.deltaX;
5952
+ }
5953
+ }
5954
+ scrollbarEl.addEventListener("wheel", handleWheel, { passive: false });
5955
+ return () => scrollbarEl.removeEventListener("wheel", handleWheel);
5956
+ }
5957
+ function setScrollbarElement(element) {
5958
+ scrollbarElementRef.value = element;
5959
+ }
5960
+ const state = computed(() => ({
5961
+ hovering: hovering.value,
5962
+ scrolling: props.orientation === "horizontal" ? scrollingX.value : scrollingY.value,
5963
+ orientation: props.orientation,
5964
+ hasOverflowX: !hiddenState.value.x,
5965
+ hasOverflowY: !hiddenState.value.y,
5966
+ overflowXStart: overflowEdges.value.xStart,
5967
+ overflowXEnd: overflowEdges.value.xEnd,
5968
+ overflowYStart: overflowEdges.value.yStart,
5969
+ overflowYEnd: overflowEdges.value.yEnd,
5970
+ cornerHidden: hiddenState.value.corner
5971
+ }));
5972
+ const hideTrackUntilMeasured = computed(() => !hasMeasuredScrollbar.value && !props.keepMounted);
5973
+ function onPointerDown(event) {
5974
+ if (event.button !== 0) return;
5975
+ const target = getTarget(event);
5976
+ const thumb = props.orientation === "vertical" ? thumbYRef.value : thumbXRef.value;
5977
+ if (thumb && contains(thumb, target)) return;
5978
+ if (!viewportRef.value) return;
5979
+ if (thumbYRef.value && scrollbarYRef.value && props.orientation === "vertical") {
5980
+ const thumbYOffset = getOffset(thumbYRef.value, "margin", "y");
5981
+ const scrollbarYOffset = getOffset(scrollbarYRef.value, "padding", "y");
5982
+ const thumbHeight = thumbYRef.value.offsetHeight;
5983
+ const trackRectY = scrollbarYRef.value.getBoundingClientRect();
5984
+ const clickY = event.clientY - trackRectY.top - thumbHeight / 2 - scrollbarYOffset + thumbYOffset / 2;
5985
+ const scrollableContentHeight = viewportRef.value.scrollHeight;
5986
+ const viewportHeight = viewportRef.value.clientHeight;
5987
+ const scrollRatioY = clickY / (scrollbarYRef.value.offsetHeight - thumbHeight - scrollbarYOffset - thumbYOffset);
5988
+ viewportRef.value.scrollTop = scrollRatioY * (scrollableContentHeight - viewportHeight);
5989
+ }
5990
+ if (thumbXRef.value && scrollbarXRef.value && props.orientation === "horizontal") {
5991
+ const thumbXOffset = getOffset(thumbXRef.value, "margin", "x");
5992
+ const scrollbarXOffset = getOffset(scrollbarXRef.value, "padding", "x");
5993
+ const thumbWidth = thumbXRef.value.offsetWidth;
5994
+ const trackRectX = scrollbarXRef.value.getBoundingClientRect();
5995
+ const clickX = event.clientX - trackRectX.left - thumbWidth / 2 - scrollbarXOffset + thumbXOffset / 2;
5996
+ const scrollableContentWidth = viewportRef.value.scrollWidth;
5997
+ const viewportWidth = viewportRef.value.clientWidth;
5998
+ const scrollRatioX = clickX / (scrollbarXRef.value.offsetWidth - thumbWidth - scrollbarXOffset - thumbXOffset);
5999
+ let newScrollLeft;
6000
+ if (direction.value === "rtl") {
6001
+ newScrollLeft = (1 - scrollRatioX) * (scrollableContentWidth - viewportWidth);
6002
+ if (viewportRef.value.scrollLeft <= 0) newScrollLeft = -newScrollLeft;
6003
+ } else newScrollLeft = scrollRatioX * (scrollableContentWidth - viewportWidth);
6004
+ viewportRef.value.scrollLeft = newScrollLeft;
6005
+ }
6006
+ handlePointerDown(event);
6007
+ }
6008
+ const { tag, mergedProps, renderless, ref: renderRef } = useRenderElement({
6009
+ componentProps: props,
6010
+ state,
6011
+ props: computed(() => mergeProps$1(attrs, {
6012
+ ...rootId ? { "data-id": `${rootId}-scrollbar` } : {},
6013
+ onPointerdown: onPointerDown,
6014
+ onPointerup: handlePointerUp,
6015
+ style: {
6016
+ position: "absolute",
6017
+ touchAction: "none",
6018
+ WebkitUserSelect: "none",
6019
+ userSelect: "none",
6020
+ visibility: hideTrackUntilMeasured.value ? "hidden" : void 0,
6021
+ ...props.orientation === "vertical" && {
6022
+ top: 0,
6023
+ bottom: `var(${ScrollAreaRootCssVars.scrollAreaCornerHeight})`,
6024
+ insetInlineEnd: 0,
6025
+ [ScrollAreaScrollbarCssVars.scrollAreaThumbHeight]: `${thumbSize.value.height}px`
6026
+ },
6027
+ ...props.orientation === "horizontal" && {
6028
+ insetInlineStart: 0,
6029
+ insetInlineEnd: `var(${ScrollAreaRootCssVars.scrollAreaCornerWidth})`,
6030
+ bottom: 0,
6031
+ [ScrollAreaScrollbarCssVars.scrollAreaThumbWidth]: `${thumbSize.value.width}px`
6032
+ }
6033
+ }
6034
+ })),
6035
+ stateAttributesMapping: scrollAreaStateAttributesMapping,
6036
+ defaultTagName: "div",
6037
+ ref: setScrollbarElement
6038
+ });
6039
+ const isHidden = computed(() => props.orientation === "vertical" ? hiddenState.value.y : hiddenState.value.x);
6040
+ const shouldRender = computed(() => props.keepMounted || !isHidden.value);
6041
+ provide(scrollAreaScrollbarContextKey, { orientation: computed(() => props.orientation) });
6042
+ return (_ctx, _cache) => {
6043
+ return shouldRender.value ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [unref(renderless) ? renderSlot(_ctx.$slots, "default", {
6044
+ key: 0,
6045
+ ref: unref(renderRef),
6046
+ props: unref(mergedProps),
6047
+ state: state.value
6048
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), mergeProps({
6049
+ key: 1,
6050
+ ref: unref(renderRef)
6051
+ }, unref(mergedProps)), {
6052
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default")]),
6053
+ _: 3
6054
+ }, 16))], 64)) : createCommentVNode("v-if", true);
6055
+ };
6056
+ }
6057
+ });
6058
+
6059
+ //#endregion
6060
+ //#region src/scroll-area/scrollbar/ScrollAreaScrollbar.vue
6061
+ var ScrollAreaScrollbar_default = ScrollAreaScrollbar_vue_vue_type_script_setup_true_lang_default;
6062
+
6063
+ //#endregion
6064
+ //#region src/scroll-area/thumb/ScrollAreaThumb.vue?vue&type=script&setup=true&lang.ts
6065
+ var ScrollAreaThumb_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
6066
+ name: "ScrollAreaThumb",
6067
+ inheritAttrs: false,
6068
+ __name: "ScrollAreaThumb",
6069
+ props: {
6070
+ as: {
6071
+ type: null,
6072
+ required: false,
6073
+ default: "div"
6074
+ },
6075
+ class: {
6076
+ type: Function,
6077
+ required: false,
6078
+ skipCheck: true
6079
+ },
6080
+ style: {
6081
+ type: [
6082
+ Boolean,
6083
+ null,
6084
+ String,
6085
+ Object,
6086
+ Array,
6087
+ Function
6088
+ ],
6089
+ required: false,
6090
+ skipCheck: true
6091
+ }
6092
+ },
6093
+ setup(__props) {
6094
+ const props = __props;
6095
+ const attrs = useAttrs();
6096
+ const { thumbYRef, thumbXRef, handlePointerDown, handlePointerMove, handlePointerUp, setScrollingX, setScrollingY, hasMeasuredScrollbar } = useScrollAreaRootContext();
6097
+ const { orientation } = useScrollAreaScrollbarContext();
6098
+ const thumbElementRef = shallowRef(null);
6099
+ watch([thumbElementRef, orientation], ([element, currentOrientation], [previousElement, previousOrientation]) => {
6100
+ if (previousElement) {
6101
+ const previousRef = previousOrientation === "vertical" ? thumbYRef : thumbXRef;
6102
+ if (previousRef.value === previousElement) previousRef.value = null;
6103
+ }
6104
+ if (!element) return;
6105
+ const nextRef = currentOrientation === "vertical" ? thumbYRef : thumbXRef;
6106
+ nextRef.value = element;
6107
+ });
6108
+ const state = computed(() => ({ orientation: orientation.value }));
6109
+ function onPointerUp(event) {
6110
+ if (orientation.value === "vertical") setScrollingY(false);
6111
+ if (orientation.value === "horizontal") setScrollingX(false);
6112
+ handlePointerUp(event);
6113
+ }
6114
+ function setThumbElement(element) {
6115
+ thumbElementRef.value = element;
6116
+ }
6117
+ const { tag, mergedProps, renderless, ref: renderRef } = useRenderElement({
6118
+ componentProps: props,
6119
+ state,
6120
+ props: computed(() => mergeProps$1(attrs, {
6121
+ onPointerdown: handlePointerDown,
6122
+ onPointermove: handlePointerMove,
6123
+ onPointerup: onPointerUp,
6124
+ style: {
6125
+ visibility: hasMeasuredScrollbar.value ? void 0 : "hidden",
6126
+ ...orientation.value === "vertical" && { height: `var(${ScrollAreaScrollbarCssVars.scrollAreaThumbHeight})` },
6127
+ ...orientation.value === "horizontal" && { width: `var(${ScrollAreaScrollbarCssVars.scrollAreaThumbWidth})` }
6128
+ }
6129
+ })),
6130
+ defaultTagName: "div",
6131
+ ref: setThumbElement
6132
+ });
6133
+ return (_ctx, _cache) => {
6134
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
6135
+ key: 0,
6136
+ ref: unref(renderRef),
6137
+ props: unref(mergedProps),
6138
+ state: state.value
6139
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), mergeProps({
6140
+ key: 1,
6141
+ ref: unref(renderRef)
6142
+ }, unref(mergedProps)), null, 16));
6143
+ };
6144
+ }
6145
+ });
6146
+
6147
+ //#endregion
6148
+ //#region src/scroll-area/thumb/ScrollAreaThumb.vue
6149
+ var ScrollAreaThumb_default = ScrollAreaThumb_vue_vue_type_script_setup_true_lang_default;
6150
+
6151
+ //#endregion
6152
+ //#region src/scroll-area/thumb/ScrollAreaThumbDataAttributes.ts
6153
+ let ScrollAreaThumbDataAttributes = /* @__PURE__ */ function(ScrollAreaThumbDataAttributes) {
6154
+ ScrollAreaThumbDataAttributes["orientation"] = "data-orientation";
6155
+ return ScrollAreaThumbDataAttributes;
6156
+ }({});
6157
+
6158
+ //#endregion
6159
+ //#region src/utils/scrollEdges.ts
6160
+ const SCROLL_EDGE_TOLERANCE_PX = 1;
6161
+ function normalizeScrollOffset(value, max) {
6162
+ if (max <= 0) return 0;
6163
+ const clamped = clamp(value, 0, max);
6164
+ const startDistance = clamped;
6165
+ const endDistance = max - clamped;
6166
+ const withinStartTolerance = startDistance <= SCROLL_EDGE_TOLERANCE_PX;
6167
+ const withinEndTolerance = endDistance <= SCROLL_EDGE_TOLERANCE_PX;
6168
+ if (withinStartTolerance && withinEndTolerance) return startDistance <= endDistance ? 0 : max;
6169
+ if (withinStartTolerance) return 0;
6170
+ if (withinEndTolerance) return max;
6171
+ return clamped;
6172
+ }
6173
+
6174
+ //#endregion
6175
+ //#region src/scroll-area/viewport/ScrollAreaViewportCssVars.ts
6176
+ let ScrollAreaViewportCssVars = /* @__PURE__ */ function(ScrollAreaViewportCssVars) {
6177
+ ScrollAreaViewportCssVars["scrollAreaOverflowXStart"] = "--scroll-area-overflow-x-start";
6178
+ ScrollAreaViewportCssVars["scrollAreaOverflowXEnd"] = "--scroll-area-overflow-x-end";
6179
+ ScrollAreaViewportCssVars["scrollAreaOverflowYStart"] = "--scroll-area-overflow-y-start";
6180
+ ScrollAreaViewportCssVars["scrollAreaOverflowYEnd"] = "--scroll-area-overflow-y-end";
6181
+ return ScrollAreaViewportCssVars;
6182
+ }({});
6183
+
6184
+ //#endregion
6185
+ //#region src/scroll-area/viewport/ScrollAreaViewport.vue?vue&type=script&setup=true&lang.ts
6186
+ var ScrollAreaViewport_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
6187
+ name: "ScrollAreaViewport",
6188
+ inheritAttrs: false,
6189
+ __name: "ScrollAreaViewport",
6190
+ props: {
6191
+ as: {
6192
+ type: null,
6193
+ required: false,
6194
+ default: "div"
6195
+ },
6196
+ class: {
6197
+ type: Function,
6198
+ required: false,
6199
+ skipCheck: true
6200
+ },
6201
+ style: {
6202
+ type: [
6203
+ Boolean,
6204
+ null,
6205
+ String,
6206
+ Object,
6207
+ Array,
6208
+ Function
6209
+ ],
6210
+ required: false,
6211
+ skipCheck: true
6212
+ }
6213
+ },
6214
+ setup(__props) {
6215
+ const props = __props;
6216
+ const attrs = useAttrs();
6217
+ const { viewportRef, scrollbarYRef, scrollbarXRef, thumbYRef, thumbXRef, cornerRef, cornerSize, setCornerSize, setThumbSize, rootId, setHiddenState, hiddenState, setHasMeasuredScrollbar, handleScroll, setHovering, setOverflowEdges, overflowEdges, overflowEdgeThreshold, scrollingX, scrollingY } = useScrollAreaRootContext();
6218
+ const direction = useDirection();
6219
+ let programmaticScroll = true;
6220
+ const lastMeasuredViewportMetrics = [
6221
+ NaN,
6222
+ NaN,
6223
+ NaN,
6224
+ NaN
6225
+ ];
6226
+ let scrollEndTimeoutId;
6227
+ let waitForAnimationsTimeoutId;
6228
+ let resizeObserver;
6229
+ let scrollAreaOverflowVarsRegistered = false;
6230
+ function removeCSSVariableInheritance() {
6231
+ if (scrollAreaOverflowVarsRegistered) return;
6232
+ if (typeof navigator !== "undefined" && /AppleWebKit/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent)) return;
6233
+ if (typeof CSS !== "undefined" && "registerProperty" in CSS) {
6234
+ const vars = [
6235
+ ScrollAreaViewportCssVars.scrollAreaOverflowXStart,
6236
+ ScrollAreaViewportCssVars.scrollAreaOverflowXEnd,
6237
+ ScrollAreaViewportCssVars.scrollAreaOverflowYStart,
6238
+ ScrollAreaViewportCssVars.scrollAreaOverflowYEnd
6239
+ ];
6240
+ for (const name of vars) try {
6241
+ CSS.registerProperty({
6242
+ name,
6243
+ syntax: "<length>",
6244
+ inherits: false,
6245
+ initialValue: "0px"
6246
+ });
6247
+ } catch {}
6248
+ }
6249
+ scrollAreaOverflowVarsRegistered = true;
6250
+ }
6251
+ function computeThumbPosition() {
6252
+ const viewportEl = viewportRef.value;
6253
+ const scrollbarYEl = scrollbarYRef.value;
6254
+ const scrollbarXEl = scrollbarXRef.value;
6255
+ const thumbYEl = thumbYRef.value;
6256
+ const thumbXEl = thumbXRef.value;
6257
+ const cornerEl = cornerRef.value;
6258
+ if (!viewportEl) return;
6259
+ const scrollableContentHeight = viewportEl.scrollHeight;
6260
+ const scrollableContentWidth = viewportEl.scrollWidth;
6261
+ const viewportHeight = viewportEl.clientHeight;
6262
+ const viewportWidth = viewportEl.clientWidth;
6263
+ const scrollTop = viewportEl.scrollTop;
6264
+ const scrollLeft = viewportEl.scrollLeft;
6265
+ const isFirstMeasurement = Number.isNaN(lastMeasuredViewportMetrics[0]);
6266
+ lastMeasuredViewportMetrics[0] = viewportHeight;
6267
+ lastMeasuredViewportMetrics[1] = scrollableContentHeight;
6268
+ lastMeasuredViewportMetrics[2] = viewportWidth;
6269
+ lastMeasuredViewportMetrics[3] = scrollableContentWidth;
6270
+ if (isFirstMeasurement) setHasMeasuredScrollbar(true);
6271
+ if (scrollableContentHeight === 0 || scrollableContentWidth === 0) return;
6272
+ const nextHiddenState = getHiddenState(viewportEl);
6273
+ const scrollbarYHidden = nextHiddenState.y;
6274
+ const scrollbarXHidden = nextHiddenState.x;
6275
+ const ratioX = viewportWidth / scrollableContentWidth;
6276
+ const ratioY = viewportHeight / scrollableContentHeight;
6277
+ const maxScrollLeft = Math.max(0, scrollableContentWidth - viewportWidth);
6278
+ const maxScrollTop = Math.max(0, scrollableContentHeight - viewportHeight);
6279
+ let scrollLeftFromStart = 0;
6280
+ let scrollLeftFromEnd = 0;
6281
+ if (!scrollbarXHidden) {
6282
+ let rawScrollLeftFromStart = 0;
6283
+ if (direction.value === "rtl") rawScrollLeftFromStart = scrollLeft < 0 ? -scrollLeft : maxScrollLeft - scrollLeft;
6284
+ else rawScrollLeftFromStart = scrollLeft;
6285
+ rawScrollLeftFromStart = clamp(rawScrollLeftFromStart, 0, maxScrollLeft);
6286
+ scrollLeftFromStart = normalizeScrollOffset(rawScrollLeftFromStart, maxScrollLeft);
6287
+ scrollLeftFromEnd = maxScrollLeft - scrollLeftFromStart;
6288
+ }
6289
+ const rawScrollTopFromStart = !scrollbarYHidden ? clamp(scrollTop, 0, maxScrollTop) : 0;
6290
+ const scrollTopFromStart = !scrollbarYHidden ? normalizeScrollOffset(rawScrollTopFromStart, maxScrollTop) : 0;
6291
+ const scrollTopFromEnd = !scrollbarYHidden ? maxScrollTop - scrollTopFromStart : 0;
6292
+ const nextWidth = scrollbarXHidden ? 0 : viewportWidth;
6293
+ const nextHeight = scrollbarYHidden ? 0 : viewportHeight;
6294
+ let nextCornerWidth = 0;
6295
+ let nextCornerHeight = 0;
6296
+ if (!scrollbarXHidden && !scrollbarYHidden) {
6297
+ nextCornerWidth = scrollbarYEl?.offsetWidth || 0;
6298
+ nextCornerHeight = scrollbarXEl?.offsetHeight || 0;
6299
+ }
6300
+ const cornerNotYetSized = cornerSize.value.width === 0 && cornerSize.value.height === 0;
6301
+ const cornerWidthOffset = cornerNotYetSized ? nextCornerWidth : 0;
6302
+ const cornerHeightOffset = cornerNotYetSized ? nextCornerHeight : 0;
6303
+ const scrollbarXOffset = getOffset(scrollbarXEl, "padding", "x");
6304
+ const scrollbarYOffset = getOffset(scrollbarYEl, "padding", "y");
6305
+ const thumbXOffset = getOffset(thumbXEl, "margin", "x");
6306
+ const thumbYOffset = getOffset(thumbYEl, "margin", "y");
6307
+ const idealNextWidth = nextWidth - scrollbarXOffset - thumbXOffset;
6308
+ const idealNextHeight = nextHeight - scrollbarYOffset - thumbYOffset;
6309
+ const maxNextWidth = scrollbarXEl ? Math.min(scrollbarXEl.offsetWidth - cornerWidthOffset, idealNextWidth) : idealNextWidth;
6310
+ const maxNextHeight = scrollbarYEl ? Math.min(scrollbarYEl.offsetHeight - cornerHeightOffset, idealNextHeight) : idealNextHeight;
6311
+ const clampedNextWidth = Math.max(MIN_THUMB_SIZE, maxNextWidth * ratioX);
6312
+ const clampedNextHeight = Math.max(MIN_THUMB_SIZE, maxNextHeight * ratioY);
6313
+ setThumbSize({
6314
+ width: clampedNextWidth,
6315
+ height: clampedNextHeight
6316
+ });
6317
+ if (scrollbarYEl && thumbYEl) {
6318
+ const maxThumbOffsetY = scrollbarYEl.offsetHeight - clampedNextHeight - scrollbarYOffset - thumbYOffset;
6319
+ const scrollRangeY = scrollableContentHeight - viewportHeight;
6320
+ const scrollRatioY = scrollRangeY === 0 ? 0 : scrollTop / scrollRangeY;
6321
+ const thumbOffsetY = Math.min(maxThumbOffsetY, Math.max(0, scrollRatioY * maxThumbOffsetY));
6322
+ thumbYEl.style.transform = `translate3d(0,${thumbOffsetY}px,0)`;
6323
+ }
6324
+ if (scrollbarXEl && thumbXEl) {
6325
+ const maxThumbOffsetX = scrollbarXEl.offsetWidth - clampedNextWidth - scrollbarXOffset - thumbXOffset;
6326
+ const scrollRangeX = scrollableContentWidth - viewportWidth;
6327
+ const scrollRatioX = scrollRangeX === 0 ? 0 : scrollLeftFromStart / scrollRangeX;
6328
+ const thumbOffsetX = direction.value === "rtl" ? -clamp(scrollRatioX * maxThumbOffsetX, 0, maxThumbOffsetX) : clamp(scrollRatioX * maxThumbOffsetX, 0, maxThumbOffsetX);
6329
+ thumbXEl.style.transform = `translate3d(${thumbOffsetX}px,0,0)`;
6330
+ }
6331
+ const overflowMetricsPx = [
6332
+ [ScrollAreaViewportCssVars.scrollAreaOverflowXStart, scrollLeftFromStart],
6333
+ [ScrollAreaViewportCssVars.scrollAreaOverflowXEnd, scrollLeftFromEnd],
6334
+ [ScrollAreaViewportCssVars.scrollAreaOverflowYStart, scrollTopFromStart],
6335
+ [ScrollAreaViewportCssVars.scrollAreaOverflowYEnd, scrollTopFromEnd]
6336
+ ];
6337
+ for (const [cssVar, value] of overflowMetricsPx) viewportEl.style.setProperty(cssVar, `${value}px`);
6338
+ if (cornerEl) if (scrollbarXHidden || scrollbarYHidden) setCornerSize({
6339
+ width: 0,
6340
+ height: 0
6341
+ });
6342
+ else setCornerSize({
6343
+ width: nextCornerWidth,
6344
+ height: nextCornerHeight
6345
+ });
6346
+ setHiddenState(mergeHiddenState(hiddenState.value, nextHiddenState));
6347
+ const threshold = overflowEdgeThreshold.value;
6348
+ const nextOverflowEdges = {
6349
+ xStart: !scrollbarXHidden && scrollLeftFromStart > threshold.xStart,
6350
+ xEnd: !scrollbarXHidden && scrollLeftFromEnd > threshold.xEnd,
6351
+ yStart: !scrollbarYHidden && scrollTopFromStart > threshold.yStart,
6352
+ yEnd: !scrollbarYHidden && scrollTopFromEnd > threshold.yEnd
6353
+ };
6354
+ const prev = overflowEdges.value;
6355
+ if (prev.xStart !== nextOverflowEdges.xStart || prev.xEnd !== nextOverflowEdges.xEnd || prev.yStart !== nextOverflowEdges.yStart || prev.yEnd !== nextOverflowEdges.yEnd) setOverflowEdges(nextOverflowEdges);
6356
+ }
6357
+ function handleUserInteraction() {
6358
+ programmaticScroll = false;
6359
+ }
6360
+ function onScroll() {
6361
+ if (!viewportRef.value) return;
6362
+ computeThumbPosition();
6363
+ if (!programmaticScroll) handleScroll({
6364
+ x: viewportRef.value.scrollLeft,
6365
+ y: viewportRef.value.scrollTop
6366
+ });
6367
+ clearTimeout(scrollEndTimeoutId);
6368
+ scrollEndTimeoutId = setTimeout(() => {
6369
+ programmaticScroll = true;
6370
+ }, 100);
6371
+ }
6372
+ const viewportState = computed(() => ({
6373
+ scrolling: scrollingX.value || scrollingY.value,
6374
+ hasOverflowX: !hiddenState.value.x,
6375
+ hasOverflowY: !hiddenState.value.y,
6376
+ overflowXStart: overflowEdges.value.xStart,
6377
+ overflowXEnd: overflowEdges.value.xEnd,
6378
+ overflowYStart: overflowEdges.value.yStart,
6379
+ overflowYEnd: overflowEdges.value.yEnd,
6380
+ cornerHidden: hiddenState.value.corner
6381
+ }));
6382
+ const { tag, mergedProps, renderless, ref: renderRef } = useRenderElement({
6383
+ componentProps: props,
6384
+ state: viewportState,
6385
+ props: computed(() => mergeProps$1(attrs, {
6386
+ role: "presentation",
6387
+ ...rootId ? { "data-id": `${rootId}-viewport` } : {},
6388
+ tabindex: hiddenState.value.x && hiddenState.value.y ? -1 : 0,
6389
+ class: styleDisableScrollbar.className,
6390
+ style: { overflow: "scroll" },
6391
+ onScroll,
6392
+ onWheel: handleUserInteraction,
6393
+ onTouchmove: handleUserInteraction,
6394
+ onPointermove: handleUserInteraction,
6395
+ onPointerenter: handleUserInteraction,
6396
+ onKeydown: handleUserInteraction
6397
+ })),
6398
+ stateAttributesMapping: scrollAreaStateAttributesMapping,
6399
+ defaultTagName: "div",
6400
+ ref: viewportRef
6401
+ });
6402
+ onMounted(() => {
6403
+ removeCSSVariableInheritance();
6404
+ if (viewportRef.value?.matches(":hover")) setHovering(true);
6405
+ queueMicrotask(computeThumbPosition);
6406
+ const viewport = viewportRef.value;
6407
+ if (typeof ResizeObserver !== "undefined" && viewport) {
6408
+ let hasInitialized = false;
6409
+ resizeObserver = new ResizeObserver(() => {
6410
+ if (!hasInitialized) {
6411
+ hasInitialized = true;
6412
+ if (lastMeasuredViewportMetrics[0] === viewport.clientHeight && lastMeasuredViewportMetrics[1] === viewport.scrollHeight && lastMeasuredViewportMetrics[2] === viewport.clientWidth && lastMeasuredViewportMetrics[3] === viewport.scrollWidth) return;
6413
+ }
6414
+ computeThumbPosition();
6415
+ });
6416
+ resizeObserver.observe(viewport);
6417
+ waitForAnimationsTimeoutId = setTimeout(() => {
6418
+ const animations = viewport.getAnimations({ subtree: true });
6419
+ if (animations.length === 0) return;
6420
+ Promise.allSettled(animations.map((a) => a.finished)).then(computeThumbPosition);
6421
+ }, 0);
6422
+ }
6423
+ });
6424
+ watch([hiddenState, direction], () => {
6425
+ queueMicrotask(computeThumbPosition);
6426
+ });
6427
+ watch(overflowEdgeThreshold, computeThumbPosition);
6428
+ onBeforeUnmount(() => {
6429
+ resizeObserver?.disconnect();
6430
+ clearTimeout(scrollEndTimeoutId);
6431
+ clearTimeout(waitForAnimationsTimeoutId);
6432
+ });
6433
+ provide(scrollAreaViewportContextKey, { computeThumbPosition });
6434
+ function getHiddenState(viewport) {
6435
+ const y = viewport.clientHeight >= viewport.scrollHeight;
6436
+ const x = viewport.clientWidth >= viewport.scrollWidth;
6437
+ return {
6438
+ y,
6439
+ x,
6440
+ corner: y || x
6441
+ };
6442
+ }
6443
+ function mergeHiddenState(prevState, nextState) {
6444
+ if (prevState.y === nextState.y && prevState.x === nextState.x && prevState.corner === nextState.corner) return prevState;
6445
+ return nextState;
6446
+ }
6447
+ return (_ctx, _cache) => {
6448
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
6449
+ key: 0,
6450
+ ref: unref(renderRef),
6451
+ props: unref(mergedProps),
6452
+ state: viewportState.value
6453
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), mergeProps({
6454
+ key: 1,
6455
+ ref: unref(renderRef)
6456
+ }, unref(mergedProps)), {
6457
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default")]),
6458
+ _: 3
6459
+ }, 16));
6460
+ };
6461
+ }
6462
+ });
6463
+
6464
+ //#endregion
6465
+ //#region src/scroll-area/viewport/ScrollAreaViewport.vue
6466
+ var ScrollAreaViewport_default = ScrollAreaViewport_vue_vue_type_script_setup_true_lang_default;
6467
+
6468
+ //#endregion
6469
+ //#region src/scroll-area/viewport/ScrollAreaViewportDataAttributes.ts
6470
+ let ScrollAreaViewportDataAttributes = /* @__PURE__ */ function(ScrollAreaViewportDataAttributes) {
6471
+ ScrollAreaViewportDataAttributes["scrolling"] = "data-scrolling";
6472
+ ScrollAreaViewportDataAttributes["hasOverflowX"] = "data-has-overflow-x";
6473
+ ScrollAreaViewportDataAttributes["hasOverflowY"] = "data-has-overflow-y";
6474
+ ScrollAreaViewportDataAttributes["overflowXStart"] = "data-overflow-x-start";
6475
+ ScrollAreaViewportDataAttributes["overflowXEnd"] = "data-overflow-x-end";
6476
+ ScrollAreaViewportDataAttributes["overflowYStart"] = "data-overflow-y-start";
6477
+ ScrollAreaViewportDataAttributes["overflowYEnd"] = "data-overflow-y-end";
6478
+ return ScrollAreaViewportDataAttributes;
6479
+ }({});
6480
+
6481
+ //#endregion
6482
+ //#region src/separator/Separator.vue?vue&type=script&setup=true&lang.ts
6483
+ /**
6484
+ * A separator element accessible to screen readers.
6485
+ * Renders a `<div>` element.
6486
+ *
6487
+ * Documentation: [Base UI Vue Separator](https://baseui-vue.com/docs/components/separator)
6488
+ */
6489
+ var Separator_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
6490
+ name: "Separator",
6491
+ inheritAttrs: false,
6492
+ __name: "Separator",
6493
+ props: {
6494
+ orientation: {
6495
+ type: String,
6496
+ required: false,
6497
+ default: "horizontal"
6498
+ },
6499
+ as: {
6500
+ type: null,
6501
+ required: false,
6502
+ default: "div"
6503
+ },
6504
+ class: {
6505
+ type: Function,
6506
+ required: false,
6507
+ skipCheck: true
6508
+ },
6509
+ style: {
6510
+ type: [
6511
+ Boolean,
6512
+ null,
6513
+ String,
6514
+ Object,
6515
+ Array,
6516
+ Function
6517
+ ],
6518
+ required: false,
6519
+ skipCheck: true
6520
+ }
6521
+ },
6522
+ setup(__props) {
6523
+ const props = __props;
6524
+ const attrs = useAttrs();
6525
+ const state = computed(() => ({ orientation: props.orientation }));
6526
+ const { tag, mergedProps, renderless, ref: renderRef } = useRenderElement({
6527
+ componentProps: props,
6528
+ state,
6529
+ props: computed(() => ({
6530
+ ...attrs,
6531
+ "role": "separator",
6532
+ "aria-orientation": props.orientation
6533
+ })),
6534
+ defaultTagName: "div"
6535
+ });
6536
+ return (_ctx, _cache) => {
6537
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
6538
+ key: 0,
6539
+ ref: unref(renderRef),
6540
+ props: unref(mergedProps),
6541
+ state: state.value
6542
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), mergeProps({
6543
+ key: 1,
6544
+ ref: unref(renderRef)
6545
+ }, unref(mergedProps)), {
6546
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: state.value })]),
6547
+ _: 3
6548
+ }, 16));
6549
+ };
6550
+ }
6551
+ });
6552
+
6553
+ //#endregion
6554
+ //#region src/separator/Separator.vue
6555
+ var Separator_default = Separator_vue_vue_type_script_setup_true_lang_default;
6556
+
6557
+ //#endregion
6558
+ //#region src/separator/SeparatorDataAttributes.ts
6559
+ let SeparatorDataAttributes = /* @__PURE__ */ function(SeparatorDataAttributes) {
6560
+ /**
6561
+ * Indicates the orientation of the separator.
6562
+ * @type {'horizontal' | 'vertical'}
6563
+ */
6564
+ SeparatorDataAttributes["orientation"] = "data-orientation";
6565
+ return SeparatorDataAttributes;
6566
+ }({});
6567
+
6568
+ //#endregion
6569
+ //#region src/slider/indicator/SliderIndicator.vue?vue&type=script&setup=true&lang.ts
6570
+ /**
6571
+ * Visualizes the current value of the slider.
6572
+ * Renders a `<div>` element.
6573
+ *
6574
+ * Documentation: [Base UI Vue Slider](https://baseui-vue.com/docs/components/slider)
6575
+ */
6576
+ var SliderIndicator_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
6577
+ name: "SliderIndicator",
6578
+ inheritAttrs: false,
6579
+ __name: "SliderIndicator",
6580
+ props: {
6581
+ as: {
6582
+ type: null,
6583
+ required: false,
6584
+ default: "div"
6585
+ },
6586
+ class: {
6587
+ type: Function,
6588
+ required: false,
6589
+ skipCheck: true
6590
+ },
6591
+ style: {
6592
+ type: [
6593
+ Boolean,
6594
+ null,
6595
+ String,
6596
+ Object,
6597
+ Array,
6598
+ Function
6599
+ ],
6600
+ required: false,
6601
+ skipCheck: true
6602
+ }
6603
+ },
6604
+ setup(__props) {
6605
+ const props = __props;
6606
+ function getInsetStyles(vertical, range, start, end, renderBeforeHydration, mounted) {
6607
+ const visibility = start === void 0 || range && end === void 0 ? "hidden" : void 0;
6608
+ const startEdge = vertical ? "bottom" : "insetInlineStart";
6609
+ const mainSide = vertical ? "height" : "width";
6610
+ const styles = {
6611
+ visibility: renderBeforeHydration && !mounted ? "hidden" : visibility,
6612
+ position: vertical ? "absolute" : "relative",
6613
+ [vertical ? "width" : "height"]: "inherit"
6614
+ };
6615
+ styles["--start-position"] = `${start ?? 0}%`;
6616
+ if (!range) {
6617
+ styles[startEdge] = 0;
6618
+ styles[mainSide] = "var(--start-position)";
6619
+ return styles;
6620
+ }
6621
+ styles["--relative-size"] = `${(end ?? 0) - (start ?? 0)}%`;
6622
+ styles[startEdge] = "var(--start-position)";
6623
+ styles[mainSide] = "var(--relative-size)";
6624
+ return styles;
6625
+ }
6626
+ function getCenteredStyles(vertical, range, start, end) {
6627
+ const startEdge = vertical ? "bottom" : "insetInlineStart";
6628
+ const mainSide = vertical ? "height" : "width";
6629
+ const styles = {
6630
+ position: vertical ? "absolute" : "relative",
6631
+ [vertical ? "width" : "height"]: "inherit"
6632
+ };
6633
+ if (!range) {
6634
+ styles[startEdge] = 0;
6635
+ styles[mainSide] = `${start}%`;
6636
+ return styles;
6637
+ }
6638
+ styles[startEdge] = `${start}%`;
6639
+ styles[mainSide] = `${end - start}%`;
6640
+ return styles;
6641
+ }
6642
+ const attrs = useAttrs();
6643
+ const rootContext = useSliderRootContext();
6644
+ const isMounted = ref(false);
6645
+ onMounted(() => {
6646
+ isMounted.value = true;
6647
+ });
6648
+ const vertical = computed(() => rootContext.orientation.value === "vertical");
6649
+ const range = computed(() => rootContext.values.value.length > 1);
6650
+ const style = computed(() => rootContext.inset.value ? getInsetStyles(vertical.value, range.value, rootContext.indicatorPosition.value[0], rootContext.indicatorPosition.value[1], rootContext.renderBeforeHydration.value, isMounted.value) : getCenteredStyles(vertical.value, range.value, valueToPercent(rootContext.values.value[0], rootContext.min.value, rootContext.max.value), valueToPercent(rootContext.values.value[rootContext.values.value.length - 1], rootContext.min.value, rootContext.max.value)));
6651
+ const indicatorProps = computed(() => mergeProps$1(attrs, {
6652
+ "data-base-ui-slider-indicator": rootContext.renderBeforeHydration.value ? "" : void 0,
6653
+ "style": style.value,
6654
+ "suppressHydrationWarning": rootContext.renderBeforeHydration.value || void 0
6655
+ }));
6656
+ const { tag, mergedProps, renderless, ref: renderRef } = useRenderElement({
6657
+ componentProps: props,
6658
+ state: rootContext.state,
6659
+ props: indicatorProps,
6660
+ defaultTagName: "div",
6661
+ stateAttributesMapping: sliderStateAttributesMapping
6662
+ });
6663
+ return (_ctx, _cache) => {
6664
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
6665
+ key: 0,
6666
+ ref: unref(renderRef),
6667
+ props: unref(mergedProps),
6668
+ state: unref(rootContext).state
6669
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), mergeProps({
6670
+ key: 1,
6671
+ ref: unref(renderRef)
6672
+ }, unref(mergedProps)), {
6673
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default")]),
6674
+ _: 3
6675
+ }, 16));
6676
+ };
6677
+ }
6678
+ });
6679
+
6680
+ //#endregion
6681
+ //#region src/slider/indicator/SliderIndicator.vue
6682
+ var SliderIndicator_default = SliderIndicator_vue_vue_type_script_setup_true_lang_default;
6683
+
6684
+ //#endregion
6685
+ //#region src/slider/indicator/SliderIndicatorDataAttributes.ts
6686
+ let SliderIndicatorDataAttributes = /* @__PURE__ */ function(SliderIndicatorDataAttributes) {
6687
+ /**
6688
+ * Present while the user is dragging.
6689
+ */
6690
+ SliderIndicatorDataAttributes["dragging"] = "data-dragging";
6691
+ /**
6692
+ * Indicates the orientation of the slider.
6693
+ * @type {'horizontal' | 'vertical'}
6694
+ */
6695
+ SliderIndicatorDataAttributes["orientation"] = "data-orientation";
6696
+ /**
6697
+ * Present when the slider is disabled.
6698
+ */
6699
+ SliderIndicatorDataAttributes["disabled"] = "data-disabled";
6700
+ /**
6701
+ * Present when the slider is in valid state (when wrapped in Field.Root).
6702
+ */
6703
+ SliderIndicatorDataAttributes["valid"] = "data-valid";
6704
+ /**
6705
+ * Present when the slider is in invalid state (when wrapped in Field.Root).
6706
+ */
6707
+ SliderIndicatorDataAttributes["invalid"] = "data-invalid";
6708
+ /**
6709
+ * Present when the slider has been touched (when wrapped in Field.Root).
6710
+ */
6711
+ SliderIndicatorDataAttributes["touched"] = "data-touched";
6712
+ /**
6713
+ * Present when the slider's value has changed (when wrapped in Field.Root).
6714
+ */
6715
+ SliderIndicatorDataAttributes["dirty"] = "data-dirty";
6716
+ /**
6717
+ * Present when the slider is focused (when wrapped in Field.Root).
6718
+ */
6719
+ SliderIndicatorDataAttributes["focused"] = "data-focused";
6720
+ return SliderIndicatorDataAttributes;
6721
+ }({});
6722
+
6723
+ //#endregion
6724
+ //#region src/slider/label/SliderLabel.vue?vue&type=script&setup=true&lang.ts
6725
+ /**
6726
+ * An accessible label that is automatically associated with the slider thumbs.
6727
+ * Renders a `<div>` element.
6728
+ *
6729
+ * Documentation: [Base UI Vue Slider](https://baseui-vue.com/docs/components/slider)
6730
+ */
6731
+ var SliderLabel_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
6732
+ name: "SliderLabel",
6733
+ inheritAttrs: false,
6734
+ __name: "SliderLabel",
6735
+ props: {
6736
+ as: {
6737
+ type: null,
6738
+ required: false,
6739
+ default: "div"
6740
+ },
6741
+ class: {
6742
+ type: Function,
6743
+ required: false,
6744
+ skipCheck: true
6745
+ },
6746
+ style: {
6747
+ type: [
6748
+ Boolean,
6749
+ null,
6750
+ String,
6751
+ Object,
6752
+ Array,
6753
+ Function
6754
+ ],
6755
+ required: false,
6756
+ skipCheck: true
6757
+ }
6758
+ },
6759
+ setup(__props) {
6760
+ const props = __props;
6761
+ const attrs = useAttrs();
6762
+ const rootContext = useSliderRootContext();
6763
+ const label = useLabel({
6764
+ id: computed(() => rootContext.rootLabelId.value),
6765
+ fallbackControlId: computed(() => rootContext.controlRef.value?.id),
6766
+ setLabelId: rootContext.setLabelId,
6767
+ focusControl(_event, controlId) {
6768
+ if (controlId) {
6769
+ const controlElement = rootContext.controlRef.value ? ownerDocument(rootContext.controlRef.value)?.getElementById(controlId) : null;
6770
+ if (isHTMLElement(controlElement)) {
6771
+ focusElementWithVisible(controlElement);
6772
+ return;
2996
6773
  }
2997
6774
  }
2998
6775
  const fallbackInputs = rootContext.controlRef.value?.querySelectorAll("input[type=\"range\"]");
@@ -3438,12 +7215,6 @@ let SliderRootDataAttributes = /* @__PURE__ */ function(SliderRootDataAttributes
3438
7215
  return SliderRootDataAttributes;
3439
7216
  }({});
3440
7217
 
3441
- //#endregion
3442
- //#region src/utils/formatNumber.ts
3443
- function formatNumber(value, locale, options) {
3444
- return new Intl.NumberFormat(locale, options).format(value);
3445
- }
3446
-
3447
7218
  //#endregion
3448
7219
  //#region src/slider/thumb/prehydrationScript.min.ts
3449
7220
  const script = "(function prehydration() {\n const firstThumb = document.currentScript?.parentElement\n if (!firstThumb) {\n return\n }\n\n const control = firstThumb.closest('[data-base-ui-slider-control]')\n if (!control) {\n return\n }\n\n const indicator = control.querySelector('[data-base-ui-slider-indicator]')\n const controlRect = control.getBoundingClientRect()\n const vertical = control.getAttribute('data-orientation') === 'vertical'\n const side = vertical ? 'height' : 'width'\n const inputElems = control.querySelectorAll('input[type=\"range\"]')\n const range = inputElems.length > 1\n const lastIndex = inputElems.length - 1\n\n let startPosition = null\n let relativeSize = null\n\n for (let i = 0; i < inputElems.length; i += 1) {\n const input = inputElems[i]\n\n const value = Number.parseFloat(input.getAttribute('value') ?? '')\n\n if (Number.isNaN(value)) {\n return\n }\n\n const thumb = input.parentElement\n if (!thumb) {\n return\n }\n\n const max = Number.parseFloat(input.getAttribute('max') ?? '100')\n const min = Number.parseFloat(input.getAttribute('min') ?? '0')\n\n const thumbRect = thumb?.getBoundingClientRect()\n\n const controlSize = controlRect[side] - thumbRect[side]\n const thumbValuePercent = max === min ? 0 : ((value - min) * 100) / (max - min)\n const thumbOffsetFromControlEdge\n = thumbRect[side] / 2 + (controlSize * thumbValuePercent) / 100\n const percent = (thumbOffsetFromControlEdge / controlRect[side]) * 100\n\n if (Number.isFinite(percent)) {\n thumb.style.setProperty(`--position`, `${percent}%`)\n thumb.style.removeProperty('visibility')\n\n if (indicator) {\n if (i === 0) {\n startPosition = percent\n indicator.style.setProperty('--start-position', `${percent}%`)\n if (!range) {\n indicator.style.removeProperty('visibility')\n }\n }\n else if (i === lastIndex) {\n relativeSize = percent - (startPosition ?? 0)\n indicator.style.setProperty('--end-position', `${percent}%`)\n indicator.style.setProperty('--relative-size', `${relativeSize}%`)\n indicator.style.removeProperty('visibility')\n }\n }\n }\n }\n})()";
@@ -5709,5 +9480,5 @@ const name = "base-ui-vue";
5709
9480
  const version = "0.0.0";
5710
9481
 
5711
9482
  //#endregion
5712
- export { AccordionItem_default, AccordionPanel_default, AccordionRoot_default, AccordionTrigger_default, AvatarRoot_default, CollapsiblePanel_default, CollapsibleRoot_default, CollapsibleTrigger_default, FieldItem_default, FieldLabel_default, FieldRoot_default, FieldValidity_default, FieldsetLegend_default, FieldsetRoot_default, SeparatorDataAttributes, Separator_default, SliderIndicatorDataAttributes, SliderIndicator_default, SliderLabel_default, SliderRootDataAttributes, SliderRoot_default, SliderThumbDataAttributes, SliderThumb_default, SliderTrackDataAttributes, SliderTrack_default, SliderValueDataAttributes, SliderValue_default, SwitchRootDataAttributes, SwitchRoot_default, SwitchThumbDataAttributes, SwitchThumb_default, ToggleDataAttributes, ToggleGroupDataAttributes, ToggleGroup_default, Toggle_default, ToolbarInputDataAttributes, ToolbarInput_default, ToolbarLinkDataAttributes, ToolbarLink_default, ToolbarRootDataAttributes, ToolbarRoot_default, ToolbarSeparatorDataAttributes, ToolbarSeparator_default, accordionRootContextKey, collapsibleRootContextKey, fieldsetRootContextKey, name, switchRootContextKey, toggleGroupContextKey, useAccordionRootContext, useCollapsibleRootContext, useFieldsetRootContext, useRender, useSwitchRootContext, useToggleGroupContext, version };
9483
+ export { AccordionItem_default, AccordionPanel_default, AccordionRoot_default, AccordionTrigger_default, AvatarRoot_default, CollapsiblePanel_default, CollapsibleRoot_default, CollapsibleTrigger_default, FieldItem_default, FieldLabel_default, FieldRoot_default, FieldValidity_default, FieldsetLegend_default, FieldsetRoot_default, InputDataAttributes, Input_default, MeterIndicator_default, MeterLabel_default, MeterRoot_default, MeterTrack_default, MeterValue_default, NumberFieldInput_default, NumberFieldRoot_default, NumberFieldScrubAreaCursor_default, NumberFieldScrubArea_default, OtpFieldInput_default, OtpFieldRoot_default, ProgressIndicator_default, ProgressLabel_default, ProgressRootDataAttributes, ProgressRoot_default, ProgressTrack_default, ProgressValue_default, ScrollAreaRootCssVars, ScrollAreaRoot_default, ScrollAreaScrollbarCssVars, ScrollAreaScrollbarDataAttributes, ScrollAreaScrollbar_default, ScrollAreaThumbDataAttributes, ScrollAreaThumb_default, ScrollAreaViewportCssVars, ScrollAreaViewportDataAttributes, ScrollAreaViewport_default, SeparatorDataAttributes, Separator_default, SliderIndicatorDataAttributes, SliderIndicator_default, SliderLabel_default, SliderRootDataAttributes, SliderRoot_default, SliderThumbDataAttributes, SliderThumb_default, SliderTrackDataAttributes, SliderTrack_default, SliderValueDataAttributes, SliderValue_default, SwitchRootDataAttributes, SwitchRoot_default, SwitchThumbDataAttributes, SwitchThumb_default, ToggleDataAttributes, ToggleGroupDataAttributes, ToggleGroup_default, Toggle_default, ToolbarInputDataAttributes, ToolbarInput_default, ToolbarLinkDataAttributes, ToolbarLink_default, ToolbarRootDataAttributes, ToolbarRoot_default, ToolbarSeparatorDataAttributes, ToolbarSeparator_default, accordionRootContextKey, collapsibleRootContextKey, fieldsetRootContextKey, getOtpFieldInputState, meterRootContextKey, name, numberFieldScrubAreaContextKey, otpFieldRootContextKey, progressRootContextKey, progressStateAttributesMapping, switchRootContextKey, toggleGroupContextKey, useAccordionRootContext, useCollapsibleRootContext, useFieldsetRootContext, useMeterRootContext, useNumberFieldScrubAreaContext, useOtpFieldRootContext, useProgressRootContext, useRender, useSwitchRootContext, useToggleGroupContext, version };
5713
9484
  //# sourceMappingURL=index2.js.map