base-ui-vue 0.2.0 → 0.3.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 (62) hide show
  1. package/dist/content/ScrollAreaContent.cjs +168 -0
  2. package/dist/content/ScrollAreaContent.cjs.map +1 -0
  3. package/dist/content/ScrollAreaContent.js +133 -0
  4. package/dist/content/ScrollAreaContent.js.map +1 -0
  5. package/dist/corner/ScrollAreaCorner.cjs +77 -0
  6. package/dist/corner/ScrollAreaCorner.cjs.map +1 -0
  7. package/dist/corner/ScrollAreaCorner.js +72 -0
  8. package/dist/corner/ScrollAreaCorner.js.map +1 -0
  9. package/dist/index.cjs +33 -0
  10. package/dist/index.d.cts +1067 -352
  11. package/dist/index.d.cts.map +1 -1
  12. package/dist/index.d.ts +1067 -352
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +4 -2
  15. package/dist/index2.cjs +3565 -1373
  16. package/dist/index2.cjs.map +1 -1
  17. package/dist/index2.js +3228 -1204
  18. package/dist/index2.js.map +1 -1
  19. package/package.json +1 -1
  20. package/src/index.ts +4 -0
  21. package/src/input/Input.vue +37 -0
  22. package/src/input/InputDataAttributes.ts +30 -0
  23. package/src/input/index.ts +4 -0
  24. package/src/meter/index.ts +16 -0
  25. package/src/meter/indicator/MeterIndicator.vue +65 -0
  26. package/src/meter/label/MeterLabel.vue +63 -0
  27. package/src/meter/root/MeterRoot.vue +131 -0
  28. package/src/meter/root/MeterRootContext.ts +41 -0
  29. package/src/meter/track/MeterTrack.vue +46 -0
  30. package/src/meter/value/MeterValue.vue +85 -0
  31. package/src/progress/index.ts +23 -0
  32. package/src/progress/indicator/ProgressIndicator.vue +74 -0
  33. package/src/progress/label/ProgressLabel.vue +63 -0
  34. package/src/progress/root/ProgressRoot.vue +160 -0
  35. package/src/progress/root/ProgressRootContext.ts +51 -0
  36. package/src/progress/root/ProgressRootDataAttributes.ts +14 -0
  37. package/src/progress/root/stateAttributesMapping.ts +18 -0
  38. package/src/progress/track/ProgressTrack.vue +48 -0
  39. package/src/progress/value/ProgressValue.vue +92 -0
  40. package/src/scroll-area/constants.ts +2 -0
  41. package/src/scroll-area/content/ScrollAreaContent.vue +87 -0
  42. package/src/scroll-area/corner/ScrollAreaCorner.vue +64 -0
  43. package/src/scroll-area/index.ts +25 -0
  44. package/src/scroll-area/root/ScrollAreaRoot.vue +297 -0
  45. package/src/scroll-area/root/ScrollAreaRootContext.ts +89 -0
  46. package/src/scroll-area/root/ScrollAreaRootCssVars.ts +4 -0
  47. package/src/scroll-area/root/ScrollAreaRootDataAttributes.ts +9 -0
  48. package/src/scroll-area/root/stateAttributes.ts +14 -0
  49. package/src/scroll-area/scrollbar/ScrollAreaScrollbar.vue +263 -0
  50. package/src/scroll-area/scrollbar/ScrollAreaScrollbarContext.ts +20 -0
  51. package/src/scroll-area/scrollbar/ScrollAreaScrollbarCssVars.ts +4 -0
  52. package/src/scroll-area/scrollbar/ScrollAreaScrollbarDataAttributes.ts +11 -0
  53. package/src/scroll-area/thumb/ScrollAreaThumb.vue +120 -0
  54. package/src/scroll-area/thumb/ScrollAreaThumbDataAttributes.ts +3 -0
  55. package/src/scroll-area/utils/getOffset.ts +34 -0
  56. package/src/scroll-area/viewport/ScrollAreaViewport.vue +379 -0
  57. package/src/scroll-area/viewport/ScrollAreaViewportContext.ts +20 -0
  58. package/src/scroll-area/viewport/ScrollAreaViewportCssVars.ts +6 -0
  59. package/src/scroll-area/viewport/ScrollAreaViewportDataAttributes.ts +9 -0
  60. package/src/utils/formatNumber.ts +25 -0
  61. package/src/utils/scrollEdges.ts +33 -0
  62. package/src/utils/styles.ts +28 -0
package/dist/index2.js CHANGED
@@ -7,7 +7,8 @@ import { activeElement, clamp, contains, getMidpoint, getTarget, ownerDocument,
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
8
  import { AvatarRootContextKey, avatarStateAttributesMapping, useTimeout } from "./fallback/AvatarFallback.js";
9
9
  import { useCSPContext } from "./csp-provider/CSPContext.js";
10
- import { useLabelableId } from "./control/FieldControl.js";
10
+ import { FieldControl_default, useLabelableId } from "./control/FieldControl.js";
11
+ import { scrollAreaRootContextKey, scrollAreaStateAttributesMapping, scrollAreaViewportContextKey, useScrollAreaRootContext } from "./content/ScrollAreaContent.js";
11
12
  import { ACTIVE_COMPOSITE_ITEM } from "./composite/constants.js";
12
13
  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";
13
14
  import { isHTMLElement } from "@floating-ui/utils/dom";
@@ -2695,27 +2696,82 @@ var FieldsetRoot_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ d
2695
2696
  var FieldsetRoot_default = FieldsetRoot_vue_vue_type_script_setup_true_lang_default;
2696
2697
 
2697
2698
  //#endregion
2698
- //#region src/separator/Separator.vue?vue&type=script&setup=true&lang.ts
2699
+ //#region src/input/Input.vue?vue&type=script&setup=true&lang.ts
2699
2700
  /**
2700
- * A separator element accessible to screen readers.
2701
- * Renders a `<div>` element.
2701
+ * A native input element that automatically works with
2702
+ * [Field](https://baseui-vue.com/docs/components/field).
2703
+ * Renders an `<input>` element.
2702
2704
  *
2703
- * Documentation: [Base UI Vue Separator](https://baseui-vue.com/docs/components/separator)
2705
+ * Documentation: [Base UI Vue Input](https://baseui-vue.com/docs/components/input)
2704
2706
  */
2705
- var Separator_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
2706
- name: "Separator",
2707
+ var Input_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
2708
+ name: "BaseUIInput",
2707
2709
  inheritAttrs: false,
2708
- __name: "Separator",
2710
+ __name: "Input",
2709
2711
  props: {
2710
- orientation: {
2712
+ id: {
2711
2713
  type: String,
2712
- required: false,
2713
- default: "horizontal"
2714
+ required: false
2715
+ },
2716
+ name: {
2717
+ type: String,
2718
+ required: false
2719
+ },
2720
+ disabled: {
2721
+ type: Boolean,
2722
+ required: false
2723
+ },
2724
+ value: {
2725
+ type: String,
2726
+ required: false
2727
+ },
2728
+ defaultValue: {
2729
+ type: String,
2730
+ required: false
2731
+ },
2732
+ autofocus: {
2733
+ type: Boolean,
2734
+ required: false
2735
+ },
2736
+ type: {
2737
+ type: String,
2738
+ required: false
2739
+ },
2740
+ required: {
2741
+ type: Boolean,
2742
+ required: false
2743
+ },
2744
+ pattern: {
2745
+ type: String,
2746
+ required: false
2747
+ },
2748
+ minlength: {
2749
+ type: Number,
2750
+ required: false
2751
+ },
2752
+ maxlength: {
2753
+ type: Number,
2754
+ required: false
2755
+ },
2756
+ min: {
2757
+ type: [String, Number],
2758
+ required: false
2759
+ },
2760
+ max: {
2761
+ type: [String, Number],
2762
+ required: false
2763
+ },
2764
+ step: {
2765
+ type: [String, Number],
2766
+ required: false
2767
+ },
2768
+ placeholder: {
2769
+ type: String,
2770
+ required: false
2714
2771
  },
2715
2772
  as: {
2716
2773
  type: null,
2717
- required: false,
2718
- default: "div"
2774
+ required: false
2719
2775
  },
2720
2776
  class: {
2721
2777
  type: Function,
@@ -2735,50 +2791,59 @@ var Separator_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defi
2735
2791
  skipCheck: true
2736
2792
  }
2737
2793
  },
2794
+ emits: ["valueChange"],
2738
2795
  setup(__props) {
2739
2796
  const props = __props;
2740
2797
  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
2798
  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));
2799
+ return openBlock(), createBlock(FieldControl_default, mergeProps({
2800
+ ...props,
2801
+ ...unref(attrs)
2802
+ }, { onValueChange: _cache[0] || (_cache[0] = (v, e) => _ctx.$emit("valueChange", v, e)) }), createSlots({ _: 2 }, [_ctx.$slots.default ? {
2803
+ name: "default",
2804
+ fn: withCtx((slotProps) => [renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(slotProps)))]),
2805
+ key: "0"
2806
+ } : void 0]), 1040);
2765
2807
  };
2766
2808
  }
2767
2809
  });
2768
2810
 
2769
2811
  //#endregion
2770
- //#region src/separator/Separator.vue
2771
- var Separator_default = Separator_vue_vue_type_script_setup_true_lang_default;
2812
+ //#region src/input/Input.vue
2813
+ var Input_default = Input_vue_vue_type_script_setup_true_lang_default;
2772
2814
 
2773
2815
  //#endregion
2774
- //#region src/separator/SeparatorDataAttributes.ts
2775
- let SeparatorDataAttributes = /* @__PURE__ */ function(SeparatorDataAttributes) {
2816
+ //#region src/input/InputDataAttributes.ts
2817
+ let InputDataAttributes = /* @__PURE__ */ function(InputDataAttributes) {
2776
2818
  /**
2777
- * Indicates the orientation of the separator.
2778
- * @type {'horizontal' | 'vertical'}
2819
+ * Present when the input is disabled.
2779
2820
  */
2780
- SeparatorDataAttributes["orientation"] = "data-orientation";
2781
- return SeparatorDataAttributes;
2821
+ InputDataAttributes["disabled"] = "data-disabled";
2822
+ /**
2823
+ * Present when the input is in a valid state (when wrapped in FieldRoot).
2824
+ */
2825
+ InputDataAttributes["valid"] = "data-valid";
2826
+ /**
2827
+ * Present when the input is in an invalid state (when wrapped in FieldRoot).
2828
+ */
2829
+ InputDataAttributes["invalid"] = "data-invalid";
2830
+ /**
2831
+ * Present when the input has been touched (when wrapped in FieldRoot).
2832
+ */
2833
+ InputDataAttributes["touched"] = "data-touched";
2834
+ /**
2835
+ * Present when the input's value has changed (when wrapped in FieldRoot).
2836
+ */
2837
+ InputDataAttributes["dirty"] = "data-dirty";
2838
+ /**
2839
+ * Present when the input is filled (when wrapped in FieldRoot).
2840
+ */
2841
+ InputDataAttributes["filled"] = "data-filled";
2842
+ /**
2843
+ * Present when the input is focused (when wrapped in FieldRoot).
2844
+ */
2845
+ InputDataAttributes["focused"] = "data-focused";
2846
+ return InputDataAttributes;
2782
2847
  }({});
2783
2848
 
2784
2849
  //#endregion
@@ -2789,17 +2854,26 @@ function valueToPercent(value, min, max) {
2789
2854
  }
2790
2855
 
2791
2856
  //#endregion
2792
- //#region src/slider/indicator/SliderIndicator.vue?vue&type=script&setup=true&lang.ts
2857
+ //#region src/meter/root/MeterRootContext.ts
2858
+ const meterRootContextKey = Symbol("MeterRootContext");
2859
+ function useMeterRootContext(optional = false) {
2860
+ const context = inject(meterRootContextKey, void 0);
2861
+ if (!context && !optional) throw new Error("Base UI Vue: MeterRootContext is missing. Meter parts must be placed within <MeterRoot>.");
2862
+ return context;
2863
+ }
2864
+
2865
+ //#endregion
2866
+ //#region src/meter/indicator/MeterIndicator.vue?vue&type=script&setup=true&lang.ts
2793
2867
  /**
2794
- * Visualizes the current value of the slider.
2868
+ * Visualizes the position of the value along the range.
2795
2869
  * Renders a `<div>` element.
2796
2870
  *
2797
- * Documentation: [Base UI Vue Slider](https://baseui-vue.com/docs/components/slider)
2871
+ * Documentation: [Base UI Vue Meter](https://baseui-vue.com/docs/components/meter)
2798
2872
  */
2799
- var SliderIndicator_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
2800
- name: "SliderIndicator",
2873
+ var MeterIndicator_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
2874
+ name: "MeterIndicator",
2801
2875
  inheritAttrs: false,
2802
- __name: "SliderIndicator",
2876
+ __name: "MeterIndicator",
2803
2877
  props: {
2804
2878
  as: {
2805
2879
  type: null,
@@ -2826,74 +2900,27 @@ var SliderIndicator_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ *
2826
2900
  },
2827
2901
  setup(__props) {
2828
2902
  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
2903
  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({
2904
+ const rootContext = useMeterRootContext();
2905
+ const percentageWidth = computed(() => valueToPercent(rootContext.value.value, rootContext.min.value, rootContext.max.value));
2906
+ const state = computed(() => ({}));
2907
+ const { tag, mergedProps, renderless } = useRenderElement({
2880
2908
  componentProps: props,
2881
- state: rootContext.state,
2882
- props: indicatorProps,
2883
- defaultTagName: "div",
2884
- stateAttributesMapping: sliderStateAttributesMapping
2909
+ state,
2910
+ props: computed(() => mergeProps$1({ style: {
2911
+ insetInlineStart: 0,
2912
+ height: "inherit",
2913
+ width: `${percentageWidth.value}%`
2914
+ } }, attrs)),
2915
+ defaultTagName: "div"
2885
2916
  });
2886
2917
  return (_ctx, _cache) => {
2887
2918
  return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
2888
2919
  key: 0,
2889
- ref: unref(renderRef),
2890
2920
  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")]),
2921
+ state: state.value
2922
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), normalizeProps(mergeProps({ key: 1 }, unref(mergedProps))), {
2923
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: state.value })]),
2897
2924
  _: 3
2898
2925
  }, 16));
2899
2926
  };
@@ -2901,65 +2928,30 @@ var SliderIndicator_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ *
2901
2928
  });
2902
2929
 
2903
2930
  //#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
- }({});
2931
+ //#region src/meter/indicator/MeterIndicator.vue
2932
+ var MeterIndicator_default = MeterIndicator_vue_vue_type_script_setup_true_lang_default;
2945
2933
 
2946
2934
  //#endregion
2947
- //#region src/slider/label/SliderLabel.vue?vue&type=script&setup=true&lang.ts
2935
+ //#region src/meter/label/MeterLabel.vue?vue&type=script&setup=true&lang.ts
2948
2936
  /**
2949
- * An accessible label that is automatically associated with the slider thumbs.
2950
- * Renders a `<div>` element.
2937
+ * An accessible label for the meter.
2938
+ * Renders a `<span>` element.
2951
2939
  *
2952
- * Documentation: [Base UI Vue Slider](https://baseui-vue.com/docs/components/slider)
2940
+ * Documentation: [Base UI Vue Meter](https://baseui-vue.com/docs/components/meter)
2953
2941
  */
2954
- var SliderLabel_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
2955
- name: "SliderLabel",
2942
+ var MeterLabel_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
2943
+ name: "MeterLabel",
2956
2944
  inheritAttrs: false,
2957
- __name: "SliderLabel",
2945
+ __name: "MeterLabel",
2958
2946
  props: {
2947
+ id: {
2948
+ type: String,
2949
+ required: false
2950
+ },
2959
2951
  as: {
2960
2952
  type: null,
2961
2953
  required: false,
2962
- default: "div"
2954
+ default: "span"
2963
2955
  },
2964
2956
  class: {
2965
2957
  type: Function,
@@ -2982,43 +2974,26 @@ var SliderLabel_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ de
2982
2974
  setup(__props) {
2983
2975
  const props = __props;
2984
2976
  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;
2996
- }
2997
- }
2998
- const fallbackInputs = rootContext.controlRef.value?.querySelectorAll("input[type=\"range\"]");
2999
- const fallbackInput = fallbackInputs?.length === 1 ? fallbackInputs[0] : null;
3000
- if (isHTMLElement(fallbackInput)) focusElementWithVisible(fallbackInput);
3001
- }
3002
- });
3003
- const labelProps = computed(() => mergeProps$1(attrs, label.props.value));
3004
- const { tag, mergedProps, renderless, ref: renderRef } = useRenderElement({
2977
+ const { setLabelId } = useMeterRootContext();
2978
+ const id = useRegisteredLabelId(() => props.id, setLabelId);
2979
+ const state = computed(() => ({}));
2980
+ const { tag, mergedProps, renderless } = useRenderElement({
3005
2981
  componentProps: props,
3006
- state: rootContext.state,
3007
- props: labelProps,
3008
- defaultTagName: "div",
3009
- stateAttributesMapping: sliderStateAttributesMapping
2982
+ state,
2983
+ props: computed(() => ({
2984
+ ...attrs,
2985
+ id: id.value,
2986
+ role: "presentation"
2987
+ })),
2988
+ defaultTagName: "span"
3010
2989
  });
3011
2990
  return (_ctx, _cache) => {
3012
2991
  return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
3013
2992
  key: 0,
3014
- ref: unref(renderRef),
3015
2993
  props: unref(mergedProps),
3016
- state: unref(rootContext).state
3017
- }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), mergeProps({
3018
- key: 1,
3019
- ref: unref(renderRef)
3020
- }, unref(mergedProps)), {
3021
- default: withCtx(() => [renderSlot(_ctx.$slots, "default")]),
2994
+ state: state.value
2995
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), normalizeProps(mergeProps({ key: 1 }, unref(mergedProps))), {
2996
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: state.value })]),
3022
2997
  _: 3
3023
2998
  }, 16));
3024
2999
  };
@@ -3026,74 +3001,54 @@ var SliderLabel_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ de
3026
3001
  });
3027
3002
 
3028
3003
  //#endregion
3029
- //#region src/slider/label/SliderLabel.vue
3030
- var SliderLabel_default = SliderLabel_vue_vue_type_script_setup_true_lang_default;
3031
-
3032
- //#endregion
3033
- //#region src/utils/areArraysEqual.ts
3034
- function areArraysEqual(array1, array2, itemComparer = (a, b) => a === b) {
3035
- return array1.length === array2.length && array1.every((value, index) => itemComparer(value, array2[index]));
3036
- }
3037
-
3038
- //#endregion
3039
- //#region src/utils/resolveAriaLabelledBy.ts
3040
- function getDefaultLabelId(id) {
3041
- return id == null ? void 0 : `${id}-label`;
3042
- }
3043
- function resolveAriaLabelledBy(fieldLabelId, localLabelId) {
3044
- return fieldLabelId ?? localLabelId;
3045
- }
3046
-
3047
- //#endregion
3048
- //#region src/slider/utils/asc.ts
3049
- function asc(a, b) {
3050
- return a - b;
3051
- }
3004
+ //#region src/meter/label/MeterLabel.vue
3005
+ var MeterLabel_default = MeterLabel_vue_vue_type_script_setup_true_lang_default;
3052
3006
 
3053
3007
  //#endregion
3054
- //#region src/slider/utils/replaceArrayItemAtIndex.ts
3055
- function replaceArrayItemAtIndex(array, index, newValue) {
3056
- if (!Number.isInteger(index) || index < 0 || index >= array.length) throw new RangeError(`replaceArrayItemAtIndex index out of bounds: ${index}`);
3057
- const output = array.slice();
3058
- output[index] = newValue;
3059
- return output.sort(asc);
3008
+ //#region src/utils/formatNumber.ts
3009
+ function formatNumber(value, locale, options) {
3010
+ return new Intl.NumberFormat(locale, options).format(value);
3060
3011
  }
3061
-
3062
- //#endregion
3063
- //#region src/slider/utils/getSliderValue.ts
3064
- function getSliderValue(valueInput, index, min, max, range, values) {
3065
- let newValue = valueInput;
3066
- newValue = clamp(newValue, min, max);
3067
- if (range) newValue = replaceArrayItemAtIndex(values, index, clamp(newValue, values[index - 1] ?? -Infinity, values[index + 1] ?? Infinity));
3068
- return newValue;
3012
+ /**
3013
+ * Formats a numeric value for display inside Base UI Vue components.
3014
+ *
3015
+ * When no `format` is provided, the value is interpreted as a percentage
3016
+ * in the 0-100 range (matching React's Base UI semantics for
3017
+ * `<Meter.Root>` / `<Progress.Root>`).
3018
+ *
3019
+ * Returns an empty string when the value is `null`.
3020
+ */
3021
+ function formatNumberValue(value, locale, format) {
3022
+ if (value == null) return "";
3023
+ if (!format) return formatNumber(value / 100, locale, { style: "percent" });
3024
+ return formatNumber(value, locale, format);
3069
3025
  }
3070
3026
 
3071
3027
  //#endregion
3072
- //#region src/slider/root/SliderRoot.vue?vue&type=script&setup=true&lang.ts
3028
+ //#region src/meter/root/MeterRoot.vue?vue&type=script&setup=true&lang.ts
3073
3029
  /**
3074
- * Groups all parts of the slider.
3030
+ * Groups all parts of the meter and provides the value for screen readers.
3075
3031
  * Renders a `<div>` element.
3076
3032
  *
3077
- * Documentation: [Base UI Vue Slider](https://baseui-vue.com/docs/components/slider)
3033
+ * Documentation: [Base UI Vue Meter](https://baseui-vue.com/docs/components/meter)
3078
3034
  */
3079
- var SliderRoot_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
3080
- name: "SliderRoot",
3035
+ var MeterRoot_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
3036
+ name: "MeterRoot",
3081
3037
  inheritAttrs: false,
3082
- __name: "SliderRoot",
3038
+ __name: "MeterRoot",
3083
3039
  props: {
3084
- defaultValue: {
3085
- type: null,
3040
+ ariaValuetext: {
3041
+ type: String,
3086
3042
  required: false
3087
3043
  },
3088
- disabled: {
3089
- type: Boolean,
3090
- required: false,
3091
- default: false
3092
- },
3093
3044
  format: {
3094
3045
  type: null,
3095
3046
  required: false
3096
3047
  },
3048
+ getAriaValueText: {
3049
+ type: Function,
3050
+ required: false
3051
+ },
3097
3052
  locale: {
3098
3053
  type: null,
3099
3054
  required: false
@@ -3108,60 +3063,173 @@ var SliderRoot_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ def
3108
3063
  required: false,
3109
3064
  default: 0
3110
3065
  },
3111
- minStepsBetweenValues: {
3066
+ value: {
3112
3067
  type: Number,
3113
- required: false,
3114
- default: 0
3115
- },
3116
- name: {
3117
- type: String,
3118
- required: false
3119
- },
3120
- form: {
3121
- type: String,
3122
- required: false
3068
+ required: true
3123
3069
  },
3124
- orientation: {
3125
- type: String,
3070
+ as: {
3071
+ type: null,
3126
3072
  required: false,
3127
- default: "horizontal"
3073
+ default: "div"
3128
3074
  },
3129
- step: {
3130
- type: Number,
3075
+ class: {
3076
+ type: Function,
3131
3077
  required: false,
3132
- default: 1
3078
+ skipCheck: true
3133
3079
  },
3134
- largeStep: {
3135
- type: Number,
3080
+ style: {
3081
+ type: [
3082
+ Boolean,
3083
+ null,
3084
+ String,
3085
+ Object,
3086
+ Array,
3087
+ Function
3088
+ ],
3136
3089
  required: false,
3137
- default: 10
3138
- },
3139
- thumbAlignment: {
3140
- type: String,
3090
+ skipCheck: true
3091
+ }
3092
+ },
3093
+ setup(__props) {
3094
+ const props = __props;
3095
+ const attrs = useAttrs();
3096
+ const labelId = ref(void 0);
3097
+ const formattedValue = computed(() => formatNumberValue(props.value, props.locale, props.format));
3098
+ const ariaValueText = computed(() => {
3099
+ if (props.ariaValuetext !== void 0) return props.ariaValuetext;
3100
+ if (props.getAriaValueText) return props.getAriaValueText(formattedValue.value, props.value);
3101
+ if (props.format) return formattedValue.value;
3102
+ return `${props.value}%`;
3103
+ });
3104
+ provide(meterRootContextKey, {
3105
+ formattedValue,
3106
+ max: computed(() => props.max),
3107
+ min: computed(() => props.min),
3108
+ value: computed(() => props.value),
3109
+ setLabelId(id) {
3110
+ labelId.value = id;
3111
+ }
3112
+ });
3113
+ const state = computed(() => ({}));
3114
+ const { tag, mergedProps, renderless } = useRenderElement({
3115
+ componentProps: props,
3116
+ state,
3117
+ props: computed(() => ({
3118
+ "role": "meter",
3119
+ "aria-labelledby": labelId.value,
3120
+ "aria-valuemax": props.max,
3121
+ "aria-valuemin": props.min,
3122
+ "aria-valuenow": props.value,
3123
+ "aria-valuetext": ariaValueText.value,
3124
+ ...attrs
3125
+ })),
3126
+ defaultTagName: "div"
3127
+ });
3128
+ const visuallyHiddenStyle = visuallyHidden;
3129
+ return (_ctx, _cache) => {
3130
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
3131
+ key: 0,
3132
+ props: unref(mergedProps),
3133
+ state: state.value
3134
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), normalizeProps(mergeProps({ key: 1 }, unref(mergedProps))), {
3135
+ default: withCtx(() => [
3136
+ renderSlot(_ctx.$slots, "default", { state: state.value }),
3137
+ createCommentVNode(" Force NVDA to read the label https://github.com/mui/base-ui/issues/4184 "),
3138
+ createElementVNode("span", {
3139
+ role: "presentation",
3140
+ style: normalizeStyle(unref(visuallyHiddenStyle))
3141
+ }, "x", 4)
3142
+ ]),
3143
+ _: 3
3144
+ }, 16));
3145
+ };
3146
+ }
3147
+ });
3148
+
3149
+ //#endregion
3150
+ //#region src/meter/root/MeterRoot.vue
3151
+ var MeterRoot_default = MeterRoot_vue_vue_type_script_setup_true_lang_default;
3152
+
3153
+ //#endregion
3154
+ //#region src/meter/track/MeterTrack.vue?vue&type=script&setup=true&lang.ts
3155
+ /**
3156
+ * Contains the meter indicator and represents the entire range of the meter.
3157
+ * Renders a `<div>` element.
3158
+ *
3159
+ * Documentation: [Base UI Vue Meter](https://baseui-vue.com/docs/components/meter)
3160
+ */
3161
+ var MeterTrack_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
3162
+ name: "MeterTrack",
3163
+ inheritAttrs: false,
3164
+ __name: "MeterTrack",
3165
+ props: {
3166
+ as: {
3167
+ type: null,
3141
3168
  required: false,
3142
- default: "center"
3169
+ default: "div"
3143
3170
  },
3144
- thumbCollisionBehavior: {
3145
- type: String,
3171
+ class: {
3172
+ type: Function,
3146
3173
  required: false,
3147
- default: "push"
3148
- },
3149
- value: {
3150
- type: null,
3151
- required: false
3152
- },
3153
- id: {
3154
- type: String,
3155
- required: false
3156
- },
3157
- ariaLabelledby: {
3158
- type: String,
3159
- required: false
3174
+ skipCheck: true
3160
3175
  },
3176
+ style: {
3177
+ type: [
3178
+ Boolean,
3179
+ null,
3180
+ String,
3181
+ Object,
3182
+ Array,
3183
+ Function
3184
+ ],
3185
+ required: false,
3186
+ skipCheck: true
3187
+ }
3188
+ },
3189
+ setup(__props) {
3190
+ const props = __props;
3191
+ const attrs = useAttrs();
3192
+ const state = computed(() => ({}));
3193
+ const { tag, mergedProps, renderless } = useRenderElement({
3194
+ componentProps: props,
3195
+ state,
3196
+ props: computed(() => ({ ...attrs })),
3197
+ defaultTagName: "div"
3198
+ });
3199
+ return (_ctx, _cache) => {
3200
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
3201
+ key: 0,
3202
+ props: unref(mergedProps),
3203
+ state: state.value
3204
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), normalizeProps(mergeProps({ key: 1 }, unref(mergedProps))), {
3205
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: state.value })]),
3206
+ _: 3
3207
+ }, 16));
3208
+ };
3209
+ }
3210
+ });
3211
+
3212
+ //#endregion
3213
+ //#region src/meter/track/MeterTrack.vue
3214
+ var MeterTrack_default = MeterTrack_vue_vue_type_script_setup_true_lang_default;
3215
+
3216
+ //#endregion
3217
+ //#region src/meter/value/MeterValue.vue?vue&type=script&setup=true&lang.ts
3218
+ /**
3219
+ * A text element displaying the current value.
3220
+ * Renders a `<span>` element.
3221
+ *
3222
+ * Documentation: [Base UI Vue Meter](https://baseui-vue.com/docs/components/meter)
3223
+ */
3224
+ var MeterValue_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
3225
+ name: "MeterValue",
3226
+ inheritAttrs: false,
3227
+ __name: "MeterValue",
3228
+ props: {
3161
3229
  as: {
3162
3230
  type: null,
3163
3231
  required: false,
3164
- default: "div"
3232
+ default: "span"
3165
3233
  },
3166
3234
  class: {
3167
3235
  type: Function,
@@ -3181,371 +3249,275 @@ var SliderRoot_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ def
3181
3249
  skipCheck: true
3182
3250
  }
3183
3251
  },
3184
- emits: ["valueChange", "valueCommitted"],
3185
- setup(__props, { emit: __emit }) {
3252
+ setup(__props) {
3186
3253
  const props = __props;
3187
- const emit = __emit;
3188
3254
  const attrs = useAttrs();
3189
- const attrsObject = attrs;
3190
- const explicitAriaLabelledBy = computed(() => props.ariaLabelledby ?? attrs["aria-labelledby"]);
3191
- const id = useBaseUiId(props.id);
3192
- const idRef = computed(() => id);
3193
- const defaultLabelId = computed(() => getDefaultLabelId(id));
3194
- const { clearErrors } = useFormContext();
3195
- const { state: fieldState, disabled: fieldDisabled, name: fieldName, setTouched, setDirty, validation, validityData, shouldValidateOnChange } = useFieldRootContext();
3196
- const { labelId: fieldLabelId } = useLabelableContext();
3197
- const localLabelId = ref(void 0);
3198
- const ariaLabelledBy = computed(() => explicitAriaLabelledBy.value ?? resolveAriaLabelledBy(fieldLabelId.value, localLabelId.value));
3199
- const disabled = computed(() => fieldDisabled.value || props.disabled);
3200
- const name = computed(() => fieldName.value ?? props.name);
3201
- const controllableValue = useControllableState({
3202
- controlled: () => props.value,
3203
- default: () => props.defaultValue ?? props.min,
3204
- name: "Slider",
3205
- state: "value"
3206
- });
3207
- const valueUnwrapped = controllableValue.value;
3208
- const setValueUnwrapped = controllableValue.setValue;
3209
- const sliderRef = ref(null);
3210
- const controlRef = ref(null);
3211
- const thumbRefs = ref([]);
3212
- const pressedInputRef = ref(null);
3213
- const pressedThumbCenterOffsetRef = ref(null);
3214
- const pressedThumbIndexRef = ref(-1);
3215
- const pressedValuesRef = ref(null);
3216
- const lastChangedValueRef = ref(null);
3217
- const lastChangeReasonRef = ref(REASONS.none);
3218
- const formatOptionsRef = computed(() => props.format);
3219
- const active = ref(-1);
3220
- const lastUsedThumbIndex = ref(-1);
3221
- const dragging = ref(false);
3222
- const thumbMap = shallowRef(/* @__PURE__ */ new Map());
3223
- const indicatorPosition = ref([void 0, void 0]);
3224
- function setActive(value) {
3225
- active.value = value;
3226
- if (value !== -1) lastUsedThumbIndex.value = value;
3227
- }
3228
- function registerFieldControlRef(element) {
3229
- if (element) controlRef.value = element;
3230
- }
3231
- function setThumbMap(nextMap) {
3232
- thumbMap.value = nextMap;
3233
- }
3234
- const compositeListProps = {
3235
- elementsRef: thumbRefs,
3236
- onMapChange: setThumbMap
3237
- };
3238
- const range = computed(() => Array.isArray(valueUnwrapped.value));
3239
- const values = computed(() => {
3240
- if (!range.value) return [clamp(valueUnwrapped.value, props.min, props.max)];
3241
- return [...valueUnwrapped.value].sort(asc);
3242
- });
3243
- useField({
3244
- id: idRef,
3245
- commit: (value) => validation.commit(value),
3246
- value: computed(() => valueUnwrapped.value),
3247
- controlRef,
3248
- name,
3249
- getValue: () => valueUnwrapped.value
3250
- });
3251
- watch(() => valueUnwrapped.value, () => {
3252
- clearErrors(name.value);
3253
- if (shouldValidateOnChange()) validation.commit(valueUnwrapped.value);
3254
- else validation.commit(valueUnwrapped.value, true);
3255
- const initialValue = validityData.value.initialValue;
3256
- let isDirty;
3257
- if (Array.isArray(valueUnwrapped.value) && Array.isArray(initialValue)) isDirty = !areArraysEqual(valueUnwrapped.value, initialValue);
3258
- else isDirty = valueUnwrapped.value !== initialValue;
3259
- setDirty(isDirty);
3260
- });
3261
- function areValuesEqual(newValue, oldValue) {
3262
- if (typeof newValue === "number" && typeof oldValue === "number") return newValue === oldValue;
3263
- if (Array.isArray(newValue) && Array.isArray(oldValue)) return areArraysEqual(newValue, oldValue);
3264
- return false;
3265
- }
3266
- function setValue(newValue, details) {
3267
- if (Number.isNaN(newValue) || areValuesEqual(newValue, valueUnwrapped.value)) return;
3268
- const changeDetails = details ?? createChangeEventDetails(REASONS.none, void 0, void 0, { activeThumbIndex: -1 });
3269
- lastChangeReasonRef.value = changeDetails.reason;
3270
- const nativeEvent = changeDetails.event;
3271
- const clonedEvent = new (nativeEvent.constructor ?? Event)(nativeEvent.type, nativeEvent);
3272
- Object.defineProperty(clonedEvent, "target", {
3273
- writable: true,
3274
- value: {
3275
- value: newValue,
3276
- name: name.value
3277
- }
3278
- });
3279
- changeDetails.event = clonedEvent;
3280
- lastChangedValueRef.value = newValue;
3281
- emit("valueChange", newValue, changeDetails);
3282
- if (changeDetails.isCanceled) return;
3283
- setValueUnwrapped(newValue);
3284
- }
3285
- function getSliderChangeEventReason(event) {
3286
- return event instanceof KeyboardEvent ? REASONS.keyboard : REASONS.inputChange;
3287
- }
3288
- function handleInputChange(valueInput, index, event) {
3289
- const newValue = getSliderValue(valueInput, index, props.min, props.max, range.value, values.value);
3290
- if (validateMinimumDistance(newValue, props.step, props.minStepsBetweenValues)) {
3291
- const reason = getSliderChangeEventReason(event);
3292
- setValue(newValue, createChangeEventDetails(reason, event, void 0, { activeThumbIndex: index }));
3293
- setTouched(true);
3294
- emit("valueCommitted", lastChangedValueRef.value ?? newValue, createGenericEventDetails(reason, event));
3295
- }
3296
- }
3297
- if (process.env.NODE_ENV !== "production" && props.min >= props.max) warn("Slider `max` must be greater than `min`.");
3298
- watch(() => disabled.value, (nextDisabled) => {
3299
- const activeEl = sliderRef.value ? activeElement(ownerDocument(sliderRef.value)) : null;
3300
- if (nextDisabled && activeEl instanceof HTMLElement && contains(sliderRef.value, activeEl)) activeEl.blur();
3301
- if (nextDisabled && active.value !== -1) setActive(-1);
3302
- });
3303
- const state = computed(() => ({
3304
- ...fieldState.value,
3305
- activeThumbIndex: active.value,
3306
- disabled: disabled.value,
3307
- dragging: dragging.value,
3308
- orientation: props.orientation,
3309
- max: props.max,
3310
- min: props.min,
3311
- minStepsBetweenValues: props.minStepsBetweenValues,
3312
- step: props.step,
3313
- values: values.value
3314
- }));
3315
- provide(sliderRootContextKey, {
3316
- active,
3317
- lastUsedThumbIndex,
3318
- controlRef,
3319
- dragging,
3320
- disabled,
3321
- validation,
3322
- formatOptionsRef,
3323
- handleInputChange,
3324
- indicatorPosition,
3325
- inset: computed(() => props.thumbAlignment !== "center"),
3326
- labelId: computed(() => ariaLabelledBy.value),
3327
- rootLabelId: defaultLabelId,
3328
- largeStep: computed(() => props.largeStep),
3329
- lastChangedValueRef,
3330
- lastChangeReasonRef,
3331
- locale: computed(() => props.locale),
3332
- max: computed(() => props.max),
3333
- min: computed(() => props.min),
3334
- minStepsBetweenValues: computed(() => props.minStepsBetweenValues),
3335
- form: computed(() => props.form),
3336
- name,
3337
- onValueCommitted(value, details) {
3338
- emit("valueCommitted", value, details);
3339
- },
3340
- orientation: computed(() => props.orientation),
3341
- pressedInputRef,
3342
- pressedThumbCenterOffsetRef,
3343
- pressedThumbIndexRef,
3344
- pressedValuesRef,
3345
- registerFieldControlRef,
3346
- renderBeforeHydration: computed(() => props.thumbAlignment === "edge"),
3347
- setActive,
3348
- setDragging(value) {
3349
- dragging.value = value;
3350
- },
3351
- setIndicatorPosition(updater) {
3352
- indicatorPosition.value = updater(indicatorPosition.value);
3353
- },
3354
- setLabelId(value) {
3355
- localLabelId.value = value;
3356
- },
3357
- setValue,
3358
- state,
3359
- step: computed(() => props.step),
3360
- thumbCollisionBehavior: computed(() => props.thumbCollisionBehavior),
3361
- thumbMap,
3362
- thumbRefs,
3363
- values
3255
+ const { value, formattedValue } = useMeterRootContext();
3256
+ const state = computed(() => ({}));
3257
+ const defaultDisplay = computed(() => {
3258
+ if (formattedValue.value) return formattedValue.value;
3259
+ return value.value != null ? String(value.value) : "";
3364
3260
  });
3365
- const rootProps = computed(() => mergeProps$1(attrsObject, validation.getValidationProps(), {
3366
- "aria-labelledby": ariaLabelledBy.value,
3367
- "id": id,
3368
- "role": "group"
3369
- }));
3370
- const { tag, mergedProps, renderless, ref: renderRef } = useRenderElement({
3261
+ const { tag, mergedProps, renderless } = useRenderElement({
3371
3262
  componentProps: props,
3372
3263
  state,
3373
- ref: useMergedRefs(sliderRef),
3374
- props: rootProps,
3375
- defaultTagName: "div",
3376
- stateAttributesMapping: sliderStateAttributesMapping
3264
+ props: computed(() => ({
3265
+ "aria-hidden": true,
3266
+ ...attrs
3267
+ })),
3268
+ defaultTagName: "span"
3377
3269
  });
3378
3270
  return (_ctx, _cache) => {
3379
- return openBlock(), createBlock(CompositeList_default, normalizeProps(guardReactiveProps(compositeListProps)), {
3380
- default: withCtx(() => [unref(renderless) ? renderSlot(_ctx.$slots, "default", {
3381
- key: 0,
3382
- ref: unref(renderRef),
3383
- props: unref(mergedProps),
3384
- state: state.value
3385
- }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), mergeProps({
3386
- key: 1,
3387
- ref: unref(renderRef)
3388
- }, unref(mergedProps)), {
3389
- default: withCtx(() => [renderSlot(_ctx.$slots, "default")]),
3390
- _: 3
3391
- }, 16))]),
3271
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
3272
+ key: 0,
3273
+ props: unref(mergedProps),
3274
+ state: state.value,
3275
+ formattedValue: unref(formattedValue),
3276
+ value: unref(value)
3277
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), normalizeProps(mergeProps({ key: 1 }, unref(mergedProps))), {
3278
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", {
3279
+ formattedValue: unref(formattedValue),
3280
+ value: unref(value)
3281
+ }, () => [createTextVNode(toDisplayString(defaultDisplay.value), 1)])]),
3392
3282
  _: 3
3393
- }, 16);
3283
+ }, 16));
3394
3284
  };
3395
3285
  }
3396
3286
  });
3397
3287
 
3398
3288
  //#endregion
3399
- //#region src/slider/root/SliderRoot.vue
3400
- var SliderRoot_default = SliderRoot_vue_vue_type_script_setup_true_lang_default;
3289
+ //#region src/meter/value/MeterValue.vue
3290
+ var MeterValue_default = MeterValue_vue_vue_type_script_setup_true_lang_default;
3401
3291
 
3402
3292
  //#endregion
3403
- //#region src/slider/root/SliderRootDataAttributes.ts
3404
- let SliderRootDataAttributes = /* @__PURE__ */ function(SliderRootDataAttributes) {
3405
- /**
3406
- * Present while the user is dragging.
3407
- */
3408
- SliderRootDataAttributes["dragging"] = "data-dragging";
3409
- /**
3410
- * Indicates the orientation of the slider.
3411
- * @type {'horizontal' | 'vertical'}
3412
- */
3413
- SliderRootDataAttributes["orientation"] = "data-orientation";
3414
- /**
3415
- * Present when the slider is disabled.
3416
- */
3417
- SliderRootDataAttributes["disabled"] = "data-disabled";
3418
- /**
3419
- * Present when the slider is in valid state (when wrapped in Field.Root).
3420
- */
3421
- SliderRootDataAttributes["valid"] = "data-valid";
3422
- /**
3423
- * Present when the slider is in invalid state (when wrapped in Field.Root).
3424
- */
3425
- SliderRootDataAttributes["invalid"] = "data-invalid";
3293
+ //#region src/progress/root/ProgressRootContext.ts
3294
+ const progressRootContextKey = Symbol("ProgressRootContext");
3295
+ function useProgressRootContext(optional = false) {
3296
+ const context = inject(progressRootContextKey, void 0);
3297
+ if (!context && !optional) throw new Error("Base UI Vue: ProgressRootContext is missing. Progress parts must be placed within <ProgressRoot>.");
3298
+ return context;
3299
+ }
3300
+
3301
+ //#endregion
3302
+ //#region src/progress/root/ProgressRootDataAttributes.ts
3303
+ let ProgressRootDataAttributes = /* @__PURE__ */ function(ProgressRootDataAttributes) {
3426
3304
  /**
3427
- * Present when the slider has been touched (when wrapped in Field.Root).
3305
+ * Present when the progress has completed.
3428
3306
  */
3429
- SliderRootDataAttributes["touched"] = "data-touched";
3307
+ ProgressRootDataAttributes["complete"] = "data-complete";
3430
3308
  /**
3431
- * Present when the slider's value has changed (when wrapped in Field.Root).
3309
+ * Present when the progress is in indeterminate state.
3432
3310
  */
3433
- SliderRootDataAttributes["dirty"] = "data-dirty";
3311
+ ProgressRootDataAttributes["indeterminate"] = "data-indeterminate";
3434
3312
  /**
3435
- * Present when the slider is focused (when wrapped in Field.Root).
3313
+ * Present while the progress is progressing.
3436
3314
  */
3437
- SliderRootDataAttributes["focused"] = "data-focused";
3438
- return SliderRootDataAttributes;
3315
+ ProgressRootDataAttributes["progressing"] = "data-progressing";
3316
+ return ProgressRootDataAttributes;
3439
3317
  }({});
3440
3318
 
3441
3319
  //#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
- //#endregion
3448
- //#region src/slider/thumb/prehydrationScript.min.ts
3449
- 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})()";
3320
+ //#region src/progress/root/stateAttributesMapping.ts
3321
+ const progressStateAttributesMapping = { status(value) {
3322
+ if (value === "progressing") return { [ProgressRootDataAttributes.progressing]: "" };
3323
+ if (value === "complete") return { [ProgressRootDataAttributes.complete]: "" };
3324
+ if (value === "indeterminate") return { [ProgressRootDataAttributes.indeterminate]: "" };
3325
+ return null;
3326
+ } };
3450
3327
 
3451
3328
  //#endregion
3452
- //#region src/slider/thumb/SliderThumbDataAttributes.ts
3453
- let SliderThumbDataAttributes = /* @__PURE__ */ function(SliderThumbDataAttributes) {
3454
- /**
3455
- * Indicates the index of the thumb in range sliders.
3456
- */
3457
- SliderThumbDataAttributes["index"] = "data-index";
3458
- /**
3459
- * Present while the user is dragging.
3460
- */
3461
- SliderThumbDataAttributes["dragging"] = "data-dragging";
3462
- /**
3463
- * Indicates the orientation of the slider.
3464
- * @type {'horizontal' | 'vertical'}
3465
- */
3466
- SliderThumbDataAttributes["orientation"] = "data-orientation";
3467
- /**
3468
- * Present when the slider is disabled.
3469
- */
3470
- SliderThumbDataAttributes["disabled"] = "data-disabled";
3471
- /**
3472
- * Present when the slider is in valid state (when wrapped in Field.Root).
3473
- */
3474
- SliderThumbDataAttributes["valid"] = "data-valid";
3475
- /**
3476
- * Present when the slider is in invalid state (when wrapped in Field.Root).
3477
- */
3478
- SliderThumbDataAttributes["invalid"] = "data-invalid";
3479
- /**
3480
- * Present when the slider has been touched (when wrapped in Field.Root).
3481
- */
3482
- SliderThumbDataAttributes["touched"] = "data-touched";
3483
- /**
3484
- * Present when the slider's value has changed (when wrapped in Field.Root).
3485
- */
3486
- SliderThumbDataAttributes["dirty"] = "data-dirty";
3487
- /**
3488
- * Present when the slider is focused (when wrapped in Field.Root).
3489
- */
3490
- SliderThumbDataAttributes["focused"] = "data-focused";
3491
- return SliderThumbDataAttributes;
3492
- }({});
3493
-
3494
- //#endregion
3495
- //#region src/slider/thumb/SliderThumb.vue?vue&type=script&setup=true&lang.ts
3496
- var SliderThumb_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
3497
- name: "SliderThumb",
3329
+ //#region src/progress/indicator/ProgressIndicator.vue?vue&type=script&setup=true&lang.ts
3330
+ /**
3331
+ * Visualizes the completion status of the task.
3332
+ * Renders a `<div>` element.
3333
+ *
3334
+ * Documentation: [Base UI Vue Progress](https://baseui-vue.com/docs/components/progress)
3335
+ */
3336
+ var ProgressIndicator_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
3337
+ name: "ProgressIndicator",
3498
3338
  inheritAttrs: false,
3499
- __name: "SliderThumb",
3339
+ __name: "ProgressIndicator",
3500
3340
  props: {
3501
- disabled: {
3502
- type: Boolean,
3341
+ as: {
3342
+ type: null,
3503
3343
  required: false,
3504
- default: false
3344
+ default: "div"
3505
3345
  },
3506
- getAriaLabel: {
3507
- type: [Function, null],
3508
- required: false
3346
+ class: {
3347
+ type: Function,
3348
+ required: false,
3349
+ skipCheck: true
3509
3350
  },
3510
- getAriaValueText: {
3511
- type: [Function, null],
3351
+ style: {
3352
+ type: [
3353
+ Boolean,
3354
+ null,
3355
+ String,
3356
+ Object,
3357
+ Array,
3358
+ Function
3359
+ ],
3360
+ required: false,
3361
+ skipCheck: true
3362
+ }
3363
+ },
3364
+ setup(__props) {
3365
+ const props = __props;
3366
+ const attrs = useAttrs();
3367
+ const { value, min, max, state } = useProgressRootContext();
3368
+ const percentage = computed(() => {
3369
+ const v = value.value;
3370
+ if (v == null || !Number.isFinite(v)) return null;
3371
+ return valueToPercent(v, min.value, max.value);
3372
+ });
3373
+ const indicatorStyles = computed(() => {
3374
+ if (percentage.value == null) return {};
3375
+ return {
3376
+ insetInlineStart: 0,
3377
+ height: "inherit",
3378
+ width: `${percentage.value}%`
3379
+ };
3380
+ });
3381
+ const { tag, mergedProps, renderless } = useRenderElement({
3382
+ componentProps: props,
3383
+ state,
3384
+ props: computed(() => mergeProps$1({ style: indicatorStyles.value }, attrs)),
3385
+ defaultTagName: "div",
3386
+ stateAttributesMapping: progressStateAttributesMapping
3387
+ });
3388
+ return (_ctx, _cache) => {
3389
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
3390
+ key: 0,
3391
+ props: unref(mergedProps),
3392
+ state: unref(state)
3393
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), normalizeProps(mergeProps({ key: 1 }, unref(mergedProps))), {
3394
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: unref(state) })]),
3395
+ _: 3
3396
+ }, 16));
3397
+ };
3398
+ }
3399
+ });
3400
+
3401
+ //#endregion
3402
+ //#region src/progress/indicator/ProgressIndicator.vue
3403
+ var ProgressIndicator_default = ProgressIndicator_vue_vue_type_script_setup_true_lang_default;
3404
+
3405
+ //#endregion
3406
+ //#region src/progress/label/ProgressLabel.vue?vue&type=script&setup=true&lang.ts
3407
+ /**
3408
+ * An accessible label for the progress bar.
3409
+ * Renders a `<span>` element.
3410
+ *
3411
+ * Documentation: [Base UI Vue Progress](https://baseui-vue.com/docs/components/progress)
3412
+ */
3413
+ var ProgressLabel_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
3414
+ name: "ProgressLabel",
3415
+ inheritAttrs: false,
3416
+ __name: "ProgressLabel",
3417
+ props: {
3418
+ id: {
3419
+ type: String,
3512
3420
  required: false
3513
3421
  },
3514
- index: {
3515
- type: Number,
3516
- required: false
3422
+ as: {
3423
+ type: null,
3424
+ required: false,
3425
+ default: "span"
3517
3426
  },
3518
- inputRef: {
3427
+ class: {
3428
+ type: Function,
3429
+ required: false,
3430
+ skipCheck: true
3431
+ },
3432
+ style: {
3519
3433
  type: [
3520
- Function,
3434
+ Boolean,
3435
+ null,
3436
+ String,
3521
3437
  Object,
3522
- null
3438
+ Array,
3439
+ Function
3523
3440
  ],
3441
+ required: false,
3442
+ skipCheck: true
3443
+ }
3444
+ },
3445
+ setup(__props) {
3446
+ const props = __props;
3447
+ const attrs = useAttrs();
3448
+ const { setLabelId, state } = useProgressRootContext();
3449
+ const id = useRegisteredLabelId(() => props.id, setLabelId);
3450
+ const { tag, mergedProps, renderless } = useRenderElement({
3451
+ componentProps: props,
3452
+ state,
3453
+ props: computed(() => ({
3454
+ ...attrs,
3455
+ id: id.value,
3456
+ role: "presentation"
3457
+ })),
3458
+ defaultTagName: "span",
3459
+ stateAttributesMapping: progressStateAttributesMapping
3460
+ });
3461
+ return (_ctx, _cache) => {
3462
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
3463
+ key: 0,
3464
+ props: unref(mergedProps),
3465
+ state: unref(state)
3466
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), normalizeProps(mergeProps({ key: 1 }, unref(mergedProps))), {
3467
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: unref(state) })]),
3468
+ _: 3
3469
+ }, 16));
3470
+ };
3471
+ }
3472
+ });
3473
+
3474
+ //#endregion
3475
+ //#region src/progress/label/ProgressLabel.vue
3476
+ var ProgressLabel_default = ProgressLabel_vue_vue_type_script_setup_true_lang_default;
3477
+
3478
+ //#endregion
3479
+ //#region src/progress/root/ProgressRoot.vue?vue&type=script&setup=true&lang.ts
3480
+ /**
3481
+ * Groups all parts of the progress bar and provides the task completion
3482
+ * status to screen readers.
3483
+ * Renders a `<div>` element.
3484
+ *
3485
+ * Documentation: [Base UI Vue Progress](https://baseui-vue.com/docs/components/progress)
3486
+ */
3487
+ var ProgressRoot_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
3488
+ name: "ProgressRoot",
3489
+ inheritAttrs: false,
3490
+ __name: "ProgressRoot",
3491
+ props: {
3492
+ ariaValuetext: {
3493
+ type: String,
3524
3494
  required: false
3525
3495
  },
3526
- tabIndex: {
3527
- type: Number,
3496
+ format: {
3497
+ type: null,
3528
3498
  required: false
3529
3499
  },
3530
- id: {
3531
- type: String,
3500
+ getAriaValueText: {
3501
+ type: Function,
3532
3502
  required: false
3533
3503
  },
3534
- ariaLabel: {
3535
- type: String,
3504
+ locale: {
3505
+ type: null,
3536
3506
  required: false
3537
3507
  },
3538
- ariaLabelledby: {
3539
- type: String,
3540
- required: false
3508
+ max: {
3509
+ type: Number,
3510
+ required: false,
3511
+ default: 100
3541
3512
  },
3542
- ariaDescribedby: {
3543
- type: String,
3544
- required: false
3513
+ min: {
3514
+ type: Number,
3515
+ required: false,
3516
+ default: 0
3545
3517
  },
3546
- style: {
3547
- type: [Object, Function],
3548
- required: false
3518
+ value: {
3519
+ type: [Number, null],
3520
+ required: true
3549
3521
  },
3550
3522
  as: {
3551
3523
  type: null,
@@ -3556,67 +3528,1139 @@ var SliderThumb_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ de
3556
3528
  type: Function,
3557
3529
  required: false,
3558
3530
  skipCheck: true
3531
+ },
3532
+ style: {
3533
+ type: [
3534
+ Boolean,
3535
+ null,
3536
+ String,
3537
+ Object,
3538
+ Array,
3539
+ Function
3540
+ ],
3541
+ required: false,
3542
+ skipCheck: true
3559
3543
  }
3560
3544
  },
3561
3545
  setup(__props) {
3562
3546
  const props = __props;
3563
- const ALL_KEYS = new Set([
3564
- ARROW_UP$1,
3565
- ARROW_DOWN$1,
3566
- ARROW_LEFT$1,
3567
- ARROW_RIGHT$1,
3568
- HOME,
3569
- END,
3570
- PAGE_UP,
3571
- PAGE_DOWN
3572
- ]);
3573
- function getDefaultAriaValueText(values, index, format, locale) {
3574
- if (index < 0) return;
3575
- if (values.length === 2) {
3576
- if (index === 0) return `${formatNumber(values[index], locale, format)} start range`;
3577
- return `${formatNumber(values[index], locale, format)} end range`;
3578
- }
3579
- return format ? formatNumber(values[index], locale, format) : void 0;
3580
- }
3581
- function getNewValue(thumbValue, step, direction, min, max) {
3582
- return direction === 1 ? Math.min(thumbValue + step, max) : Math.max(thumbValue - step, min);
3547
+ function getDefaultAriaValueText(formattedValue, value) {
3548
+ if (value == null) return "indeterminate progress";
3549
+ return formattedValue || `${value}%`;
3583
3550
  }
3584
3551
  const attrs = useAttrs();
3585
- const { nonce } = useCSPContext();
3586
- const direction = useDirection();
3587
- const rootContext = useSliderRootContext();
3588
- const { setTouched, setFocused, validationMode, validation } = useFieldRootContext();
3589
- const id = useBaseUiId(props.id);
3590
- const disabled = computed(() => props.disabled || rootContext.disabled.value);
3591
- const range = computed(() => rootContext.values.value.length > 1);
3592
- const vertical = computed(() => rootContext.orientation.value === "vertical");
3593
- const rtl = computed(() => direction.value === "rtl");
3594
- const thumbRef = ref(null);
3595
- const inputRef = ref(null);
3596
- const restoringFocusVisibleRef = ref(false);
3597
- const defaultInputId = useBaseUiId();
3598
- const labelableId = useLabelableId();
3599
- const inputId = computed(() => range.value ? defaultInputId : labelableId.value);
3600
- const { ref: listItemRef, index: compositeIndex } = useCompositeListItem({
3601
- metadata: () => ({ inputId }),
3602
- index: () => props.index
3552
+ const labelId = ref(void 0);
3553
+ const status = computed(() => {
3554
+ if (props.value == null || !Number.isFinite(props.value)) return "indeterminate";
3555
+ return props.value === props.max ? "complete" : "progressing";
3603
3556
  });
3604
- const index = computed(() => !range.value ? 0 : props.index ?? compositeIndex.value);
3605
- const last = computed(() => index.value === rootContext.values.value.length - 1);
3606
- const thumbValue = computed(() => rootContext.values.value[index.value]);
3607
- const thumbValuePercent = computed(() => valueToPercent(thumbValue.value, rootContext.min.value, rootContext.max.value));
3608
- const isMounted = ref(false);
3609
- const positionPercent = ref(void 0);
3610
- onMounted(() => {
3611
- isMounted.value = true;
3557
+ const formattedValue = computed(() => formatNumberValue(props.value, props.locale, props.format));
3558
+ const ariaValueText = computed(() => {
3559
+ if (props.ariaValuetext !== void 0) return props.ariaValuetext;
3560
+ const formatted = props.value == null ? null : formattedValue.value;
3561
+ if (props.getAriaValueText) return props.getAriaValueText(formatted, props.value);
3562
+ return getDefaultAriaValueText(formatted, props.value);
3612
3563
  });
3613
- const safeLastUsedThumbIndex = computed(() => rootContext.lastUsedThumbIndex.value >= 0 && rootContext.lastUsedThumbIndex.value < rootContext.values.value.length ? rootContext.lastUsedThumbIndex.value : -1);
3614
- function setIndicatorPositionForIndex(nextInsetPosition) {
3615
- rootContext.setIndicatorPosition((prevPosition) => {
3616
- const next = [...prevPosition];
3617
- if (index.value === 0) next[0] = nextInsetPosition;
3618
- else if (last.value) next[1] = nextInsetPosition;
3619
- return next;
3564
+ const state = computed(() => ({ status: status.value }));
3565
+ provide(progressRootContextKey, {
3566
+ formattedValue,
3567
+ max: computed(() => props.max),
3568
+ min: computed(() => props.min),
3569
+ value: computed(() => props.value),
3570
+ status,
3571
+ state,
3572
+ setLabelId(id) {
3573
+ labelId.value = id;
3574
+ }
3575
+ });
3576
+ const { tag, mergedProps, renderless } = useRenderElement({
3577
+ componentProps: props,
3578
+ state,
3579
+ props: computed(() => ({
3580
+ "role": "progressbar",
3581
+ "aria-labelledby": labelId.value,
3582
+ "aria-valuemax": props.max,
3583
+ "aria-valuemin": props.min,
3584
+ "aria-valuenow": props.value ?? void 0,
3585
+ "aria-valuetext": ariaValueText.value,
3586
+ ...attrs
3587
+ })),
3588
+ defaultTagName: "div",
3589
+ stateAttributesMapping: progressStateAttributesMapping
3590
+ });
3591
+ const visuallyHiddenStyle = visuallyHidden;
3592
+ return (_ctx, _cache) => {
3593
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
3594
+ key: 0,
3595
+ props: unref(mergedProps),
3596
+ state: state.value
3597
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), normalizeProps(mergeProps({ key: 1 }, unref(mergedProps))), {
3598
+ default: withCtx(() => [
3599
+ renderSlot(_ctx.$slots, "default", { state: state.value }),
3600
+ createCommentVNode(" Force NVDA to read the label https://github.com/mui/base-ui/issues/4184 "),
3601
+ createElementVNode("span", {
3602
+ role: "presentation",
3603
+ style: normalizeStyle(unref(visuallyHiddenStyle))
3604
+ }, "x", 4)
3605
+ ]),
3606
+ _: 3
3607
+ }, 16));
3608
+ };
3609
+ }
3610
+ });
3611
+
3612
+ //#endregion
3613
+ //#region src/progress/root/ProgressRoot.vue
3614
+ var ProgressRoot_default = ProgressRoot_vue_vue_type_script_setup_true_lang_default;
3615
+
3616
+ //#endregion
3617
+ //#region src/progress/track/ProgressTrack.vue?vue&type=script&setup=true&lang.ts
3618
+ /**
3619
+ * Contains the progress bar indicator.
3620
+ * Renders a `<div>` element.
3621
+ *
3622
+ * Documentation: [Base UI Vue Progress](https://baseui-vue.com/docs/components/progress)
3623
+ */
3624
+ var ProgressTrack_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
3625
+ name: "ProgressTrack",
3626
+ inheritAttrs: false,
3627
+ __name: "ProgressTrack",
3628
+ props: {
3629
+ as: {
3630
+ type: null,
3631
+ required: false,
3632
+ default: "div"
3633
+ },
3634
+ class: {
3635
+ type: Function,
3636
+ required: false,
3637
+ skipCheck: true
3638
+ },
3639
+ style: {
3640
+ type: [
3641
+ Boolean,
3642
+ null,
3643
+ String,
3644
+ Object,
3645
+ Array,
3646
+ Function
3647
+ ],
3648
+ required: false,
3649
+ skipCheck: true
3650
+ }
3651
+ },
3652
+ setup(__props) {
3653
+ const props = __props;
3654
+ const attrs = useAttrs();
3655
+ const { state } = useProgressRootContext();
3656
+ const { tag, mergedProps, renderless } = useRenderElement({
3657
+ componentProps: props,
3658
+ state,
3659
+ props: attrs,
3660
+ defaultTagName: "div",
3661
+ stateAttributesMapping: progressStateAttributesMapping
3662
+ });
3663
+ return (_ctx, _cache) => {
3664
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
3665
+ key: 0,
3666
+ props: unref(mergedProps),
3667
+ state: unref(state)
3668
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), normalizeProps(mergeProps({ key: 1 }, unref(mergedProps))), {
3669
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: unref(state) })]),
3670
+ _: 3
3671
+ }, 16));
3672
+ };
3673
+ }
3674
+ });
3675
+
3676
+ //#endregion
3677
+ //#region src/progress/track/ProgressTrack.vue
3678
+ var ProgressTrack_default = ProgressTrack_vue_vue_type_script_setup_true_lang_default;
3679
+
3680
+ //#endregion
3681
+ //#region src/progress/value/ProgressValue.vue?vue&type=script&setup=true&lang.ts
3682
+ /**
3683
+ * A text label displaying the current value.
3684
+ * Renders a `<span>` element.
3685
+ *
3686
+ * Documentation: [Base UI Vue Progress](https://baseui-vue.com/docs/components/progress)
3687
+ */
3688
+ var ProgressValue_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
3689
+ name: "ProgressValue",
3690
+ inheritAttrs: false,
3691
+ __name: "ProgressValue",
3692
+ props: {
3693
+ as: {
3694
+ type: null,
3695
+ required: false,
3696
+ default: "span"
3697
+ },
3698
+ class: {
3699
+ type: Function,
3700
+ required: false,
3701
+ skipCheck: true
3702
+ },
3703
+ style: {
3704
+ type: [
3705
+ Boolean,
3706
+ null,
3707
+ String,
3708
+ Object,
3709
+ Array,
3710
+ Function
3711
+ ],
3712
+ required: false,
3713
+ skipCheck: true
3714
+ }
3715
+ },
3716
+ setup(__props) {
3717
+ const props = __props;
3718
+ const attrs = useAttrs();
3719
+ const { value, formattedValue, state } = useProgressRootContext();
3720
+ const slotFormattedValue = computed(() => value.value == null ? "indeterminate" : formattedValue.value);
3721
+ const defaultDisplay = computed(() => value.value == null ? "" : formattedValue.value);
3722
+ const { tag, mergedProps, renderless } = useRenderElement({
3723
+ componentProps: props,
3724
+ state,
3725
+ props: computed(() => ({
3726
+ "aria-hidden": true,
3727
+ ...attrs
3728
+ })),
3729
+ defaultTagName: "span",
3730
+ stateAttributesMapping: progressStateAttributesMapping
3731
+ });
3732
+ return (_ctx, _cache) => {
3733
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
3734
+ key: 0,
3735
+ props: unref(mergedProps),
3736
+ state: unref(state),
3737
+ formattedValue: slotFormattedValue.value,
3738
+ value: unref(value)
3739
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), normalizeProps(mergeProps({ key: 1 }, unref(mergedProps))), {
3740
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", {
3741
+ formattedValue: slotFormattedValue.value,
3742
+ value: unref(value)
3743
+ }, () => [createTextVNode(toDisplayString(defaultDisplay.value), 1)])]),
3744
+ _: 3
3745
+ }, 16));
3746
+ };
3747
+ }
3748
+ });
3749
+
3750
+ //#endregion
3751
+ //#region src/progress/value/ProgressValue.vue
3752
+ var ProgressValue_default = ProgressValue_vue_vue_type_script_setup_true_lang_default;
3753
+
3754
+ //#endregion
3755
+ //#region src/separator/Separator.vue?vue&type=script&setup=true&lang.ts
3756
+ /**
3757
+ * A separator element accessible to screen readers.
3758
+ * Renders a `<div>` element.
3759
+ *
3760
+ * Documentation: [Base UI Vue Separator](https://baseui-vue.com/docs/components/separator)
3761
+ */
3762
+ var Separator_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
3763
+ name: "Separator",
3764
+ inheritAttrs: false,
3765
+ __name: "Separator",
3766
+ props: {
3767
+ orientation: {
3768
+ type: String,
3769
+ required: false,
3770
+ default: "horizontal"
3771
+ },
3772
+ as: {
3773
+ type: null,
3774
+ required: false,
3775
+ default: "div"
3776
+ },
3777
+ class: {
3778
+ type: Function,
3779
+ required: false,
3780
+ skipCheck: true
3781
+ },
3782
+ style: {
3783
+ type: [
3784
+ Boolean,
3785
+ null,
3786
+ String,
3787
+ Object,
3788
+ Array,
3789
+ Function
3790
+ ],
3791
+ required: false,
3792
+ skipCheck: true
3793
+ }
3794
+ },
3795
+ setup(__props) {
3796
+ const props = __props;
3797
+ const attrs = useAttrs();
3798
+ const state = computed(() => ({ orientation: props.orientation }));
3799
+ const { tag, mergedProps, renderless, ref: renderRef } = useRenderElement({
3800
+ componentProps: props,
3801
+ state,
3802
+ props: computed(() => ({
3803
+ ...attrs,
3804
+ "role": "separator",
3805
+ "aria-orientation": props.orientation
3806
+ })),
3807
+ defaultTagName: "div"
3808
+ });
3809
+ return (_ctx, _cache) => {
3810
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
3811
+ key: 0,
3812
+ ref: unref(renderRef),
3813
+ props: unref(mergedProps),
3814
+ state: state.value
3815
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), mergeProps({
3816
+ key: 1,
3817
+ ref: unref(renderRef)
3818
+ }, unref(mergedProps)), {
3819
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: state.value })]),
3820
+ _: 3
3821
+ }, 16));
3822
+ };
3823
+ }
3824
+ });
3825
+
3826
+ //#endregion
3827
+ //#region src/separator/Separator.vue
3828
+ var Separator_default = Separator_vue_vue_type_script_setup_true_lang_default;
3829
+
3830
+ //#endregion
3831
+ //#region src/separator/SeparatorDataAttributes.ts
3832
+ let SeparatorDataAttributes = /* @__PURE__ */ function(SeparatorDataAttributes) {
3833
+ /**
3834
+ * Indicates the orientation of the separator.
3835
+ * @type {'horizontal' | 'vertical'}
3836
+ */
3837
+ SeparatorDataAttributes["orientation"] = "data-orientation";
3838
+ return SeparatorDataAttributes;
3839
+ }({});
3840
+
3841
+ //#endregion
3842
+ //#region src/slider/indicator/SliderIndicator.vue?vue&type=script&setup=true&lang.ts
3843
+ /**
3844
+ * Visualizes the current value of the slider.
3845
+ * Renders a `<div>` element.
3846
+ *
3847
+ * Documentation: [Base UI Vue Slider](https://baseui-vue.com/docs/components/slider)
3848
+ */
3849
+ var SliderIndicator_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
3850
+ name: "SliderIndicator",
3851
+ inheritAttrs: false,
3852
+ __name: "SliderIndicator",
3853
+ props: {
3854
+ as: {
3855
+ type: null,
3856
+ required: false,
3857
+ default: "div"
3858
+ },
3859
+ class: {
3860
+ type: Function,
3861
+ required: false,
3862
+ skipCheck: true
3863
+ },
3864
+ style: {
3865
+ type: [
3866
+ Boolean,
3867
+ null,
3868
+ String,
3869
+ Object,
3870
+ Array,
3871
+ Function
3872
+ ],
3873
+ required: false,
3874
+ skipCheck: true
3875
+ }
3876
+ },
3877
+ setup(__props) {
3878
+ const props = __props;
3879
+ function getInsetStyles(vertical, range, start, end, renderBeforeHydration, mounted) {
3880
+ const visibility = start === void 0 || range && end === void 0 ? "hidden" : void 0;
3881
+ const startEdge = vertical ? "bottom" : "insetInlineStart";
3882
+ const mainSide = vertical ? "height" : "width";
3883
+ const styles = {
3884
+ visibility: renderBeforeHydration && !mounted ? "hidden" : visibility,
3885
+ position: vertical ? "absolute" : "relative",
3886
+ [vertical ? "width" : "height"]: "inherit"
3887
+ };
3888
+ styles["--start-position"] = `${start ?? 0}%`;
3889
+ if (!range) {
3890
+ styles[startEdge] = 0;
3891
+ styles[mainSide] = "var(--start-position)";
3892
+ return styles;
3893
+ }
3894
+ styles["--relative-size"] = `${(end ?? 0) - (start ?? 0)}%`;
3895
+ styles[startEdge] = "var(--start-position)";
3896
+ styles[mainSide] = "var(--relative-size)";
3897
+ return styles;
3898
+ }
3899
+ function getCenteredStyles(vertical, range, start, end) {
3900
+ const startEdge = vertical ? "bottom" : "insetInlineStart";
3901
+ const mainSide = vertical ? "height" : "width";
3902
+ const styles = {
3903
+ position: vertical ? "absolute" : "relative",
3904
+ [vertical ? "width" : "height"]: "inherit"
3905
+ };
3906
+ if (!range) {
3907
+ styles[startEdge] = 0;
3908
+ styles[mainSide] = `${start}%`;
3909
+ return styles;
3910
+ }
3911
+ styles[startEdge] = `${start}%`;
3912
+ styles[mainSide] = `${end - start}%`;
3913
+ return styles;
3914
+ }
3915
+ const attrs = useAttrs();
3916
+ const rootContext = useSliderRootContext();
3917
+ const isMounted = ref(false);
3918
+ onMounted(() => {
3919
+ isMounted.value = true;
3920
+ });
3921
+ const vertical = computed(() => rootContext.orientation.value === "vertical");
3922
+ const range = computed(() => rootContext.values.value.length > 1);
3923
+ 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)));
3924
+ const indicatorProps = computed(() => mergeProps$1(attrs, {
3925
+ "data-base-ui-slider-indicator": rootContext.renderBeforeHydration.value ? "" : void 0,
3926
+ "style": style.value,
3927
+ "suppressHydrationWarning": rootContext.renderBeforeHydration.value || void 0
3928
+ }));
3929
+ const { tag, mergedProps, renderless, ref: renderRef } = useRenderElement({
3930
+ componentProps: props,
3931
+ state: rootContext.state,
3932
+ props: indicatorProps,
3933
+ defaultTagName: "div",
3934
+ stateAttributesMapping: sliderStateAttributesMapping
3935
+ });
3936
+ return (_ctx, _cache) => {
3937
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
3938
+ key: 0,
3939
+ ref: unref(renderRef),
3940
+ props: unref(mergedProps),
3941
+ state: unref(rootContext).state
3942
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), mergeProps({
3943
+ key: 1,
3944
+ ref: unref(renderRef)
3945
+ }, unref(mergedProps)), {
3946
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default")]),
3947
+ _: 3
3948
+ }, 16));
3949
+ };
3950
+ }
3951
+ });
3952
+
3953
+ //#endregion
3954
+ //#region src/slider/indicator/SliderIndicator.vue
3955
+ var SliderIndicator_default = SliderIndicator_vue_vue_type_script_setup_true_lang_default;
3956
+
3957
+ //#endregion
3958
+ //#region src/slider/indicator/SliderIndicatorDataAttributes.ts
3959
+ let SliderIndicatorDataAttributes = /* @__PURE__ */ function(SliderIndicatorDataAttributes) {
3960
+ /**
3961
+ * Present while the user is dragging.
3962
+ */
3963
+ SliderIndicatorDataAttributes["dragging"] = "data-dragging";
3964
+ /**
3965
+ * Indicates the orientation of the slider.
3966
+ * @type {'horizontal' | 'vertical'}
3967
+ */
3968
+ SliderIndicatorDataAttributes["orientation"] = "data-orientation";
3969
+ /**
3970
+ * Present when the slider is disabled.
3971
+ */
3972
+ SliderIndicatorDataAttributes["disabled"] = "data-disabled";
3973
+ /**
3974
+ * Present when the slider is in valid state (when wrapped in Field.Root).
3975
+ */
3976
+ SliderIndicatorDataAttributes["valid"] = "data-valid";
3977
+ /**
3978
+ * Present when the slider is in invalid state (when wrapped in Field.Root).
3979
+ */
3980
+ SliderIndicatorDataAttributes["invalid"] = "data-invalid";
3981
+ /**
3982
+ * Present when the slider has been touched (when wrapped in Field.Root).
3983
+ */
3984
+ SliderIndicatorDataAttributes["touched"] = "data-touched";
3985
+ /**
3986
+ * Present when the slider's value has changed (when wrapped in Field.Root).
3987
+ */
3988
+ SliderIndicatorDataAttributes["dirty"] = "data-dirty";
3989
+ /**
3990
+ * Present when the slider is focused (when wrapped in Field.Root).
3991
+ */
3992
+ SliderIndicatorDataAttributes["focused"] = "data-focused";
3993
+ return SliderIndicatorDataAttributes;
3994
+ }({});
3995
+
3996
+ //#endregion
3997
+ //#region src/slider/label/SliderLabel.vue?vue&type=script&setup=true&lang.ts
3998
+ /**
3999
+ * An accessible label that is automatically associated with the slider thumbs.
4000
+ * Renders a `<div>` element.
4001
+ *
4002
+ * Documentation: [Base UI Vue Slider](https://baseui-vue.com/docs/components/slider)
4003
+ */
4004
+ var SliderLabel_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
4005
+ name: "SliderLabel",
4006
+ inheritAttrs: false,
4007
+ __name: "SliderLabel",
4008
+ props: {
4009
+ as: {
4010
+ type: null,
4011
+ required: false,
4012
+ default: "div"
4013
+ },
4014
+ class: {
4015
+ type: Function,
4016
+ required: false,
4017
+ skipCheck: true
4018
+ },
4019
+ style: {
4020
+ type: [
4021
+ Boolean,
4022
+ null,
4023
+ String,
4024
+ Object,
4025
+ Array,
4026
+ Function
4027
+ ],
4028
+ required: false,
4029
+ skipCheck: true
4030
+ }
4031
+ },
4032
+ setup(__props) {
4033
+ const props = __props;
4034
+ const attrs = useAttrs();
4035
+ const rootContext = useSliderRootContext();
4036
+ const label = useLabel({
4037
+ id: computed(() => rootContext.rootLabelId.value),
4038
+ fallbackControlId: computed(() => rootContext.controlRef.value?.id),
4039
+ setLabelId: rootContext.setLabelId,
4040
+ focusControl(_event, controlId) {
4041
+ if (controlId) {
4042
+ const controlElement = rootContext.controlRef.value ? ownerDocument(rootContext.controlRef.value)?.getElementById(controlId) : null;
4043
+ if (isHTMLElement(controlElement)) {
4044
+ focusElementWithVisible(controlElement);
4045
+ return;
4046
+ }
4047
+ }
4048
+ const fallbackInputs = rootContext.controlRef.value?.querySelectorAll("input[type=\"range\"]");
4049
+ const fallbackInput = fallbackInputs?.length === 1 ? fallbackInputs[0] : null;
4050
+ if (isHTMLElement(fallbackInput)) focusElementWithVisible(fallbackInput);
4051
+ }
4052
+ });
4053
+ const labelProps = computed(() => mergeProps$1(attrs, label.props.value));
4054
+ const { tag, mergedProps, renderless, ref: renderRef } = useRenderElement({
4055
+ componentProps: props,
4056
+ state: rootContext.state,
4057
+ props: labelProps,
4058
+ defaultTagName: "div",
4059
+ stateAttributesMapping: sliderStateAttributesMapping
4060
+ });
4061
+ return (_ctx, _cache) => {
4062
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
4063
+ key: 0,
4064
+ ref: unref(renderRef),
4065
+ props: unref(mergedProps),
4066
+ state: unref(rootContext).state
4067
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), mergeProps({
4068
+ key: 1,
4069
+ ref: unref(renderRef)
4070
+ }, unref(mergedProps)), {
4071
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default")]),
4072
+ _: 3
4073
+ }, 16));
4074
+ };
4075
+ }
4076
+ });
4077
+
4078
+ //#endregion
4079
+ //#region src/slider/label/SliderLabel.vue
4080
+ var SliderLabel_default = SliderLabel_vue_vue_type_script_setup_true_lang_default;
4081
+
4082
+ //#endregion
4083
+ //#region src/utils/areArraysEqual.ts
4084
+ function areArraysEqual(array1, array2, itemComparer = (a, b) => a === b) {
4085
+ return array1.length === array2.length && array1.every((value, index) => itemComparer(value, array2[index]));
4086
+ }
4087
+
4088
+ //#endregion
4089
+ //#region src/utils/resolveAriaLabelledBy.ts
4090
+ function getDefaultLabelId(id) {
4091
+ return id == null ? void 0 : `${id}-label`;
4092
+ }
4093
+ function resolveAriaLabelledBy(fieldLabelId, localLabelId) {
4094
+ return fieldLabelId ?? localLabelId;
4095
+ }
4096
+
4097
+ //#endregion
4098
+ //#region src/slider/utils/asc.ts
4099
+ function asc(a, b) {
4100
+ return a - b;
4101
+ }
4102
+
4103
+ //#endregion
4104
+ //#region src/slider/utils/replaceArrayItemAtIndex.ts
4105
+ function replaceArrayItemAtIndex(array, index, newValue) {
4106
+ if (!Number.isInteger(index) || index < 0 || index >= array.length) throw new RangeError(`replaceArrayItemAtIndex index out of bounds: ${index}`);
4107
+ const output = array.slice();
4108
+ output[index] = newValue;
4109
+ return output.sort(asc);
4110
+ }
4111
+
4112
+ //#endregion
4113
+ //#region src/slider/utils/getSliderValue.ts
4114
+ function getSliderValue(valueInput, index, min, max, range, values) {
4115
+ let newValue = valueInput;
4116
+ newValue = clamp(newValue, min, max);
4117
+ if (range) newValue = replaceArrayItemAtIndex(values, index, clamp(newValue, values[index - 1] ?? -Infinity, values[index + 1] ?? Infinity));
4118
+ return newValue;
4119
+ }
4120
+
4121
+ //#endregion
4122
+ //#region src/slider/root/SliderRoot.vue?vue&type=script&setup=true&lang.ts
4123
+ /**
4124
+ * Groups all parts of the slider.
4125
+ * Renders a `<div>` element.
4126
+ *
4127
+ * Documentation: [Base UI Vue Slider](https://baseui-vue.com/docs/components/slider)
4128
+ */
4129
+ var SliderRoot_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
4130
+ name: "SliderRoot",
4131
+ inheritAttrs: false,
4132
+ __name: "SliderRoot",
4133
+ props: {
4134
+ defaultValue: {
4135
+ type: null,
4136
+ required: false
4137
+ },
4138
+ disabled: {
4139
+ type: Boolean,
4140
+ required: false,
4141
+ default: false
4142
+ },
4143
+ format: {
4144
+ type: null,
4145
+ required: false
4146
+ },
4147
+ locale: {
4148
+ type: null,
4149
+ required: false
4150
+ },
4151
+ max: {
4152
+ type: Number,
4153
+ required: false,
4154
+ default: 100
4155
+ },
4156
+ min: {
4157
+ type: Number,
4158
+ required: false,
4159
+ default: 0
4160
+ },
4161
+ minStepsBetweenValues: {
4162
+ type: Number,
4163
+ required: false,
4164
+ default: 0
4165
+ },
4166
+ name: {
4167
+ type: String,
4168
+ required: false
4169
+ },
4170
+ form: {
4171
+ type: String,
4172
+ required: false
4173
+ },
4174
+ orientation: {
4175
+ type: String,
4176
+ required: false,
4177
+ default: "horizontal"
4178
+ },
4179
+ step: {
4180
+ type: Number,
4181
+ required: false,
4182
+ default: 1
4183
+ },
4184
+ largeStep: {
4185
+ type: Number,
4186
+ required: false,
4187
+ default: 10
4188
+ },
4189
+ thumbAlignment: {
4190
+ type: String,
4191
+ required: false,
4192
+ default: "center"
4193
+ },
4194
+ thumbCollisionBehavior: {
4195
+ type: String,
4196
+ required: false,
4197
+ default: "push"
4198
+ },
4199
+ value: {
4200
+ type: null,
4201
+ required: false
4202
+ },
4203
+ id: {
4204
+ type: String,
4205
+ required: false
4206
+ },
4207
+ ariaLabelledby: {
4208
+ type: String,
4209
+ required: false
4210
+ },
4211
+ as: {
4212
+ type: null,
4213
+ required: false,
4214
+ default: "div"
4215
+ },
4216
+ class: {
4217
+ type: Function,
4218
+ required: false,
4219
+ skipCheck: true
4220
+ },
4221
+ style: {
4222
+ type: [
4223
+ Boolean,
4224
+ null,
4225
+ String,
4226
+ Object,
4227
+ Array,
4228
+ Function
4229
+ ],
4230
+ required: false,
4231
+ skipCheck: true
4232
+ }
4233
+ },
4234
+ emits: ["valueChange", "valueCommitted"],
4235
+ setup(__props, { emit: __emit }) {
4236
+ const props = __props;
4237
+ const emit = __emit;
4238
+ const attrs = useAttrs();
4239
+ const attrsObject = attrs;
4240
+ const explicitAriaLabelledBy = computed(() => props.ariaLabelledby ?? attrs["aria-labelledby"]);
4241
+ const id = useBaseUiId(props.id);
4242
+ const idRef = computed(() => id);
4243
+ const defaultLabelId = computed(() => getDefaultLabelId(id));
4244
+ const { clearErrors } = useFormContext();
4245
+ const { state: fieldState, disabled: fieldDisabled, name: fieldName, setTouched, setDirty, validation, validityData, shouldValidateOnChange } = useFieldRootContext();
4246
+ const { labelId: fieldLabelId } = useLabelableContext();
4247
+ const localLabelId = ref(void 0);
4248
+ const ariaLabelledBy = computed(() => explicitAriaLabelledBy.value ?? resolveAriaLabelledBy(fieldLabelId.value, localLabelId.value));
4249
+ const disabled = computed(() => fieldDisabled.value || props.disabled);
4250
+ const name = computed(() => fieldName.value ?? props.name);
4251
+ const controllableValue = useControllableState({
4252
+ controlled: () => props.value,
4253
+ default: () => props.defaultValue ?? props.min,
4254
+ name: "Slider",
4255
+ state: "value"
4256
+ });
4257
+ const valueUnwrapped = controllableValue.value;
4258
+ const setValueUnwrapped = controllableValue.setValue;
4259
+ const sliderRef = ref(null);
4260
+ const controlRef = ref(null);
4261
+ const thumbRefs = ref([]);
4262
+ const pressedInputRef = ref(null);
4263
+ const pressedThumbCenterOffsetRef = ref(null);
4264
+ const pressedThumbIndexRef = ref(-1);
4265
+ const pressedValuesRef = ref(null);
4266
+ const lastChangedValueRef = ref(null);
4267
+ const lastChangeReasonRef = ref(REASONS.none);
4268
+ const formatOptionsRef = computed(() => props.format);
4269
+ const active = ref(-1);
4270
+ const lastUsedThumbIndex = ref(-1);
4271
+ const dragging = ref(false);
4272
+ const thumbMap = shallowRef(/* @__PURE__ */ new Map());
4273
+ const indicatorPosition = ref([void 0, void 0]);
4274
+ function setActive(value) {
4275
+ active.value = value;
4276
+ if (value !== -1) lastUsedThumbIndex.value = value;
4277
+ }
4278
+ function registerFieldControlRef(element) {
4279
+ if (element) controlRef.value = element;
4280
+ }
4281
+ function setThumbMap(nextMap) {
4282
+ thumbMap.value = nextMap;
4283
+ }
4284
+ const compositeListProps = {
4285
+ elementsRef: thumbRefs,
4286
+ onMapChange: setThumbMap
4287
+ };
4288
+ const range = computed(() => Array.isArray(valueUnwrapped.value));
4289
+ const values = computed(() => {
4290
+ if (!range.value) return [clamp(valueUnwrapped.value, props.min, props.max)];
4291
+ return [...valueUnwrapped.value].sort(asc);
4292
+ });
4293
+ useField({
4294
+ id: idRef,
4295
+ commit: (value) => validation.commit(value),
4296
+ value: computed(() => valueUnwrapped.value),
4297
+ controlRef,
4298
+ name,
4299
+ getValue: () => valueUnwrapped.value
4300
+ });
4301
+ watch(() => valueUnwrapped.value, () => {
4302
+ clearErrors(name.value);
4303
+ if (shouldValidateOnChange()) validation.commit(valueUnwrapped.value);
4304
+ else validation.commit(valueUnwrapped.value, true);
4305
+ const initialValue = validityData.value.initialValue;
4306
+ let isDirty;
4307
+ if (Array.isArray(valueUnwrapped.value) && Array.isArray(initialValue)) isDirty = !areArraysEqual(valueUnwrapped.value, initialValue);
4308
+ else isDirty = valueUnwrapped.value !== initialValue;
4309
+ setDirty(isDirty);
4310
+ });
4311
+ function areValuesEqual(newValue, oldValue) {
4312
+ if (typeof newValue === "number" && typeof oldValue === "number") return newValue === oldValue;
4313
+ if (Array.isArray(newValue) && Array.isArray(oldValue)) return areArraysEqual(newValue, oldValue);
4314
+ return false;
4315
+ }
4316
+ function setValue(newValue, details) {
4317
+ if (Number.isNaN(newValue) || areValuesEqual(newValue, valueUnwrapped.value)) return;
4318
+ const changeDetails = details ?? createChangeEventDetails(REASONS.none, void 0, void 0, { activeThumbIndex: -1 });
4319
+ lastChangeReasonRef.value = changeDetails.reason;
4320
+ const nativeEvent = changeDetails.event;
4321
+ const clonedEvent = new (nativeEvent.constructor ?? Event)(nativeEvent.type, nativeEvent);
4322
+ Object.defineProperty(clonedEvent, "target", {
4323
+ writable: true,
4324
+ value: {
4325
+ value: newValue,
4326
+ name: name.value
4327
+ }
4328
+ });
4329
+ changeDetails.event = clonedEvent;
4330
+ lastChangedValueRef.value = newValue;
4331
+ emit("valueChange", newValue, changeDetails);
4332
+ if (changeDetails.isCanceled) return;
4333
+ setValueUnwrapped(newValue);
4334
+ }
4335
+ function getSliderChangeEventReason(event) {
4336
+ return event instanceof KeyboardEvent ? REASONS.keyboard : REASONS.inputChange;
4337
+ }
4338
+ function handleInputChange(valueInput, index, event) {
4339
+ const newValue = getSliderValue(valueInput, index, props.min, props.max, range.value, values.value);
4340
+ if (validateMinimumDistance(newValue, props.step, props.minStepsBetweenValues)) {
4341
+ const reason = getSliderChangeEventReason(event);
4342
+ setValue(newValue, createChangeEventDetails(reason, event, void 0, { activeThumbIndex: index }));
4343
+ setTouched(true);
4344
+ emit("valueCommitted", lastChangedValueRef.value ?? newValue, createGenericEventDetails(reason, event));
4345
+ }
4346
+ }
4347
+ if (process.env.NODE_ENV !== "production" && props.min >= props.max) warn("Slider `max` must be greater than `min`.");
4348
+ watch(() => disabled.value, (nextDisabled) => {
4349
+ const activeEl = sliderRef.value ? activeElement(ownerDocument(sliderRef.value)) : null;
4350
+ if (nextDisabled && activeEl instanceof HTMLElement && contains(sliderRef.value, activeEl)) activeEl.blur();
4351
+ if (nextDisabled && active.value !== -1) setActive(-1);
4352
+ });
4353
+ const state = computed(() => ({
4354
+ ...fieldState.value,
4355
+ activeThumbIndex: active.value,
4356
+ disabled: disabled.value,
4357
+ dragging: dragging.value,
4358
+ orientation: props.orientation,
4359
+ max: props.max,
4360
+ min: props.min,
4361
+ minStepsBetweenValues: props.minStepsBetweenValues,
4362
+ step: props.step,
4363
+ values: values.value
4364
+ }));
4365
+ provide(sliderRootContextKey, {
4366
+ active,
4367
+ lastUsedThumbIndex,
4368
+ controlRef,
4369
+ dragging,
4370
+ disabled,
4371
+ validation,
4372
+ formatOptionsRef,
4373
+ handleInputChange,
4374
+ indicatorPosition,
4375
+ inset: computed(() => props.thumbAlignment !== "center"),
4376
+ labelId: computed(() => ariaLabelledBy.value),
4377
+ rootLabelId: defaultLabelId,
4378
+ largeStep: computed(() => props.largeStep),
4379
+ lastChangedValueRef,
4380
+ lastChangeReasonRef,
4381
+ locale: computed(() => props.locale),
4382
+ max: computed(() => props.max),
4383
+ min: computed(() => props.min),
4384
+ minStepsBetweenValues: computed(() => props.minStepsBetweenValues),
4385
+ form: computed(() => props.form),
4386
+ name,
4387
+ onValueCommitted(value, details) {
4388
+ emit("valueCommitted", value, details);
4389
+ },
4390
+ orientation: computed(() => props.orientation),
4391
+ pressedInputRef,
4392
+ pressedThumbCenterOffsetRef,
4393
+ pressedThumbIndexRef,
4394
+ pressedValuesRef,
4395
+ registerFieldControlRef,
4396
+ renderBeforeHydration: computed(() => props.thumbAlignment === "edge"),
4397
+ setActive,
4398
+ setDragging(value) {
4399
+ dragging.value = value;
4400
+ },
4401
+ setIndicatorPosition(updater) {
4402
+ indicatorPosition.value = updater(indicatorPosition.value);
4403
+ },
4404
+ setLabelId(value) {
4405
+ localLabelId.value = value;
4406
+ },
4407
+ setValue,
4408
+ state,
4409
+ step: computed(() => props.step),
4410
+ thumbCollisionBehavior: computed(() => props.thumbCollisionBehavior),
4411
+ thumbMap,
4412
+ thumbRefs,
4413
+ values
4414
+ });
4415
+ const rootProps = computed(() => mergeProps$1(attrsObject, validation.getValidationProps(), {
4416
+ "aria-labelledby": ariaLabelledBy.value,
4417
+ "id": id,
4418
+ "role": "group"
4419
+ }));
4420
+ const { tag, mergedProps, renderless, ref: renderRef } = useRenderElement({
4421
+ componentProps: props,
4422
+ state,
4423
+ ref: useMergedRefs(sliderRef),
4424
+ props: rootProps,
4425
+ defaultTagName: "div",
4426
+ stateAttributesMapping: sliderStateAttributesMapping
4427
+ });
4428
+ return (_ctx, _cache) => {
4429
+ return openBlock(), createBlock(CompositeList_default, normalizeProps(guardReactiveProps(compositeListProps)), {
4430
+ default: withCtx(() => [unref(renderless) ? renderSlot(_ctx.$slots, "default", {
4431
+ key: 0,
4432
+ ref: unref(renderRef),
4433
+ props: unref(mergedProps),
4434
+ state: state.value
4435
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), mergeProps({
4436
+ key: 1,
4437
+ ref: unref(renderRef)
4438
+ }, unref(mergedProps)), {
4439
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default")]),
4440
+ _: 3
4441
+ }, 16))]),
4442
+ _: 3
4443
+ }, 16);
4444
+ };
4445
+ }
4446
+ });
4447
+
4448
+ //#endregion
4449
+ //#region src/slider/root/SliderRoot.vue
4450
+ var SliderRoot_default = SliderRoot_vue_vue_type_script_setup_true_lang_default;
4451
+
4452
+ //#endregion
4453
+ //#region src/slider/root/SliderRootDataAttributes.ts
4454
+ let SliderRootDataAttributes = /* @__PURE__ */ function(SliderRootDataAttributes) {
4455
+ /**
4456
+ * Present while the user is dragging.
4457
+ */
4458
+ SliderRootDataAttributes["dragging"] = "data-dragging";
4459
+ /**
4460
+ * Indicates the orientation of the slider.
4461
+ * @type {'horizontal' | 'vertical'}
4462
+ */
4463
+ SliderRootDataAttributes["orientation"] = "data-orientation";
4464
+ /**
4465
+ * Present when the slider is disabled.
4466
+ */
4467
+ SliderRootDataAttributes["disabled"] = "data-disabled";
4468
+ /**
4469
+ * Present when the slider is in valid state (when wrapped in Field.Root).
4470
+ */
4471
+ SliderRootDataAttributes["valid"] = "data-valid";
4472
+ /**
4473
+ * Present when the slider is in invalid state (when wrapped in Field.Root).
4474
+ */
4475
+ SliderRootDataAttributes["invalid"] = "data-invalid";
4476
+ /**
4477
+ * Present when the slider has been touched (when wrapped in Field.Root).
4478
+ */
4479
+ SliderRootDataAttributes["touched"] = "data-touched";
4480
+ /**
4481
+ * Present when the slider's value has changed (when wrapped in Field.Root).
4482
+ */
4483
+ SliderRootDataAttributes["dirty"] = "data-dirty";
4484
+ /**
4485
+ * Present when the slider is focused (when wrapped in Field.Root).
4486
+ */
4487
+ SliderRootDataAttributes["focused"] = "data-focused";
4488
+ return SliderRootDataAttributes;
4489
+ }({});
4490
+
4491
+ //#endregion
4492
+ //#region src/slider/thumb/prehydrationScript.min.ts
4493
+ 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})()";
4494
+
4495
+ //#endregion
4496
+ //#region src/slider/thumb/SliderThumbDataAttributes.ts
4497
+ let SliderThumbDataAttributes = /* @__PURE__ */ function(SliderThumbDataAttributes) {
4498
+ /**
4499
+ * Indicates the index of the thumb in range sliders.
4500
+ */
4501
+ SliderThumbDataAttributes["index"] = "data-index";
4502
+ /**
4503
+ * Present while the user is dragging.
4504
+ */
4505
+ SliderThumbDataAttributes["dragging"] = "data-dragging";
4506
+ /**
4507
+ * Indicates the orientation of the slider.
4508
+ * @type {'horizontal' | 'vertical'}
4509
+ */
4510
+ SliderThumbDataAttributes["orientation"] = "data-orientation";
4511
+ /**
4512
+ * Present when the slider is disabled.
4513
+ */
4514
+ SliderThumbDataAttributes["disabled"] = "data-disabled";
4515
+ /**
4516
+ * Present when the slider is in valid state (when wrapped in Field.Root).
4517
+ */
4518
+ SliderThumbDataAttributes["valid"] = "data-valid";
4519
+ /**
4520
+ * Present when the slider is in invalid state (when wrapped in Field.Root).
4521
+ */
4522
+ SliderThumbDataAttributes["invalid"] = "data-invalid";
4523
+ /**
4524
+ * Present when the slider has been touched (when wrapped in Field.Root).
4525
+ */
4526
+ SliderThumbDataAttributes["touched"] = "data-touched";
4527
+ /**
4528
+ * Present when the slider's value has changed (when wrapped in Field.Root).
4529
+ */
4530
+ SliderThumbDataAttributes["dirty"] = "data-dirty";
4531
+ /**
4532
+ * Present when the slider is focused (when wrapped in Field.Root).
4533
+ */
4534
+ SliderThumbDataAttributes["focused"] = "data-focused";
4535
+ return SliderThumbDataAttributes;
4536
+ }({});
4537
+
4538
+ //#endregion
4539
+ //#region src/slider/thumb/SliderThumb.vue?vue&type=script&setup=true&lang.ts
4540
+ var SliderThumb_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
4541
+ name: "SliderThumb",
4542
+ inheritAttrs: false,
4543
+ __name: "SliderThumb",
4544
+ props: {
4545
+ disabled: {
4546
+ type: Boolean,
4547
+ required: false,
4548
+ default: false
4549
+ },
4550
+ getAriaLabel: {
4551
+ type: [Function, null],
4552
+ required: false
4553
+ },
4554
+ getAriaValueText: {
4555
+ type: [Function, null],
4556
+ required: false
4557
+ },
4558
+ index: {
4559
+ type: Number,
4560
+ required: false
4561
+ },
4562
+ inputRef: {
4563
+ type: [
4564
+ Function,
4565
+ Object,
4566
+ null
4567
+ ],
4568
+ required: false
4569
+ },
4570
+ tabIndex: {
4571
+ type: Number,
4572
+ required: false
4573
+ },
4574
+ id: {
4575
+ type: String,
4576
+ required: false
4577
+ },
4578
+ ariaLabel: {
4579
+ type: String,
4580
+ required: false
4581
+ },
4582
+ ariaLabelledby: {
4583
+ type: String,
4584
+ required: false
4585
+ },
4586
+ ariaDescribedby: {
4587
+ type: String,
4588
+ required: false
4589
+ },
4590
+ style: {
4591
+ type: [Object, Function],
4592
+ required: false
4593
+ },
4594
+ as: {
4595
+ type: null,
4596
+ required: false,
4597
+ default: "div"
4598
+ },
4599
+ class: {
4600
+ type: Function,
4601
+ required: false,
4602
+ skipCheck: true
4603
+ }
4604
+ },
4605
+ setup(__props) {
4606
+ const props = __props;
4607
+ const ALL_KEYS = new Set([
4608
+ ARROW_UP$1,
4609
+ ARROW_DOWN$1,
4610
+ ARROW_LEFT$1,
4611
+ ARROW_RIGHT$1,
4612
+ HOME,
4613
+ END,
4614
+ PAGE_UP,
4615
+ PAGE_DOWN
4616
+ ]);
4617
+ function getDefaultAriaValueText(values, index, format, locale) {
4618
+ if (index < 0) return;
4619
+ if (values.length === 2) {
4620
+ if (index === 0) return `${formatNumber(values[index], locale, format)} start range`;
4621
+ return `${formatNumber(values[index], locale, format)} end range`;
4622
+ }
4623
+ return format ? formatNumber(values[index], locale, format) : void 0;
4624
+ }
4625
+ function getNewValue(thumbValue, step, direction, min, max) {
4626
+ return direction === 1 ? Math.min(thumbValue + step, max) : Math.max(thumbValue - step, min);
4627
+ }
4628
+ const attrs = useAttrs();
4629
+ const { nonce } = useCSPContext();
4630
+ const direction = useDirection();
4631
+ const rootContext = useSliderRootContext();
4632
+ const { setTouched, setFocused, validationMode, validation } = useFieldRootContext();
4633
+ const id = useBaseUiId(props.id);
4634
+ const disabled = computed(() => props.disabled || rootContext.disabled.value);
4635
+ const range = computed(() => rootContext.values.value.length > 1);
4636
+ const vertical = computed(() => rootContext.orientation.value === "vertical");
4637
+ const rtl = computed(() => direction.value === "rtl");
4638
+ const thumbRef = ref(null);
4639
+ const inputRef = ref(null);
4640
+ const restoringFocusVisibleRef = ref(false);
4641
+ const defaultInputId = useBaseUiId();
4642
+ const labelableId = useLabelableId();
4643
+ const inputId = computed(() => range.value ? defaultInputId : labelableId.value);
4644
+ const { ref: listItemRef, index: compositeIndex } = useCompositeListItem({
4645
+ metadata: () => ({ inputId }),
4646
+ index: () => props.index
4647
+ });
4648
+ const index = computed(() => !range.value ? 0 : props.index ?? compositeIndex.value);
4649
+ const last = computed(() => index.value === rootContext.values.value.length - 1);
4650
+ const thumbValue = computed(() => rootContext.values.value[index.value]);
4651
+ const thumbValuePercent = computed(() => valueToPercent(thumbValue.value, rootContext.min.value, rootContext.max.value));
4652
+ const isMounted = ref(false);
4653
+ const positionPercent = ref(void 0);
4654
+ onMounted(() => {
4655
+ isMounted.value = true;
4656
+ });
4657
+ const safeLastUsedThumbIndex = computed(() => rootContext.lastUsedThumbIndex.value >= 0 && rootContext.lastUsedThumbIndex.value < rootContext.values.value.length ? rootContext.lastUsedThumbIndex.value : -1);
4658
+ function setIndicatorPositionForIndex(nextInsetPosition) {
4659
+ rootContext.setIndicatorPosition((prevPosition) => {
4660
+ const next = [...prevPosition];
4661
+ if (index.value === 0) next[0] = nextInsetPosition;
4662
+ else if (last.value) next[1] = nextInsetPosition;
4663
+ return next;
3620
4664
  });
3621
4665
  }
3622
4666
  function getInsetPosition() {
@@ -3754,128 +4798,476 @@ var SliderThumb_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ de
3754
4798
  event.preventDefault();
3755
4799
  }
3756
4800
  }
3757
- const inputStyle = computed(() => ({
3758
- ...visuallyHidden,
3759
- width: "100%",
3760
- height: "100%",
3761
- writingMode: cssWritingMode.value
3762
- }));
3763
- const inputValidationProps = computed(() => validation.getInputValidationProps());
3764
- const forwardedInputAttrs = computed(() => {
3765
- const attrsObject = attrs;
3766
- return {
3767
- onBlur: attrsObject.onBlur,
3768
- onFocus: attrsObject.onFocus,
3769
- onKeydown: attrsObject.onKeydown
3770
- };
3771
- });
3772
- const thumbAttrs = computed(() => {
3773
- const { onBlur: _onBlur, onFocus: _onFocus, onKeydown: _onKeydown, ...rest } = attrs;
3774
- return rest;
4801
+ const inputStyle = computed(() => ({
4802
+ ...visuallyHidden,
4803
+ width: "100%",
4804
+ height: "100%",
4805
+ writingMode: cssWritingMode.value
4806
+ }));
4807
+ const inputValidationProps = computed(() => validation.getInputValidationProps());
4808
+ const forwardedInputAttrs = computed(() => {
4809
+ const attrsObject = attrs;
4810
+ return {
4811
+ onBlur: attrsObject.onBlur,
4812
+ onFocus: attrsObject.onFocus,
4813
+ onKeydown: attrsObject.onKeydown
4814
+ };
4815
+ });
4816
+ const thumbAttrs = computed(() => {
4817
+ const { onBlur: _onBlur, onFocus: _onFocus, onKeydown: _onKeydown, ...rest } = attrs;
4818
+ return rest;
4819
+ });
4820
+ const inputProps = computed(() => mergeProps$1(inputValidationProps.value, forwardedInputAttrs.value, {
4821
+ "aria-label": ariaLabel.value,
4822
+ "aria-labelledby": props.ariaLabelledby ?? (ariaLabel.value == null ? rootContext.labelId.value : void 0),
4823
+ "aria-describedby": props.ariaDescribedby ?? inputValidationProps.value["aria-describedby"],
4824
+ "aria-orientation": rootContext.orientation.value,
4825
+ "aria-valuenow": thumbValue.value,
4826
+ "aria-valuetext": typeof props.getAriaValueText === "function" ? props.getAriaValueText(formatNumber(thumbValue.value, rootContext.locale.value, rootContext.formatOptionsRef.value), thumbValue.value, index.value) : getDefaultAriaValueText(rootContext.values.value, index.value, rootContext.formatOptionsRef.value, rootContext.locale.value),
4827
+ "disabled": disabled.value,
4828
+ "form": rootContext.form.value,
4829
+ "id": inputId.value,
4830
+ "max": rootContext.max.value,
4831
+ "min": rootContext.min.value,
4832
+ "name": rootContext.name.value,
4833
+ onChange(event) {
4834
+ rootContext.handleInputChange(event.currentTarget.valueAsNumber, index.value, event);
4835
+ },
4836
+ onFocus(event) {
4837
+ const isRestoringFocusVisible = restoringFocusVisibleRef.value;
4838
+ restoringFocusVisibleRef.value = false;
4839
+ rootContext.setActive(index.value);
4840
+ setFocused(true);
4841
+ if (isRestoringFocusVisible) event.stopPropagation();
4842
+ },
4843
+ "onBlur": handleBlur,
4844
+ "onKeydown": handleKeydown,
4845
+ "step": rootContext.step.value,
4846
+ "style": inputStyle.value,
4847
+ "tabIndex": props.tabIndex ?? void 0,
4848
+ "type": "range",
4849
+ "value": thumbValue.value ?? ""
4850
+ }));
4851
+ const mergedRef = useMergedRefs(listItemRef, thumbRef);
4852
+ const thumbProps = computed(() => mergeProps$1(thumbAttrs.value, {
4853
+ [SliderThumbDataAttributes.index]: index.value,
4854
+ id,
4855
+ onPointerdown(event) {
4856
+ rootContext.pressedThumbIndexRef.value = index.value;
4857
+ if (thumbRef.value != null) {
4858
+ const axis = rootContext.orientation.value === "horizontal" ? "x" : "y";
4859
+ const midpoint = getMidpoint(thumbRef.value);
4860
+ const offset = (rootContext.orientation.value === "horizontal" ? event.clientX : event.clientY) - midpoint[axis];
4861
+ rootContext.pressedThumbCenterOffsetRef.value = offset;
4862
+ }
4863
+ if (inputRef.value != null && rootContext.pressedInputRef.value !== inputRef.value) rootContext.pressedInputRef.value = inputRef.value;
4864
+ },
4865
+ style: thumbStyle.value,
4866
+ suppressHydrationWarning: rootContext.renderBeforeHydration.value || void 0
4867
+ }));
4868
+ const { tag, mergedProps, renderless, ref: renderRef } = useRenderElement({
4869
+ componentProps: props,
4870
+ state: rootContext.state,
4871
+ props: thumbProps,
4872
+ defaultTagName: "div",
4873
+ ref: mergedRef,
4874
+ stateAttributesMapping: sliderStateAttributesMapping
4875
+ });
4876
+ watch(() => rootContext.active.value, () => {
4877
+ if (disabled.value && rootContext.active.value === index.value) rootContext.setActive(-1);
4878
+ });
4879
+ return (_ctx, _cache) => {
4880
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
4881
+ key: 0,
4882
+ ref: unref(renderRef),
4883
+ props: unref(mergedProps),
4884
+ state: unref(rootContext).state
4885
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), mergeProps({
4886
+ key: 1,
4887
+ ref: unref(renderRef)
4888
+ }, unref(mergedProps)), {
4889
+ default: withCtx(() => [
4890
+ renderSlot(_ctx.$slots, "default"),
4891
+ createElementVNode("input", mergeProps({ ref: setInputVNodeRef }, inputProps.value), null, 16),
4892
+ createCommentVNode(" eslint-disable-next-line vue/require-component-is "),
4893
+ unref(rootContext).inset.value && !isMounted.value && unref(rootContext).renderBeforeHydration.value && last.value ? (openBlock(), createBlock(resolveDynamicComponent("script"), {
4894
+ key: 0,
4895
+ nonce: unref(nonce),
4896
+ "suppress-hydration-warning": true
4897
+ }, {
4898
+ default: withCtx(() => [createTextVNode(toDisplayString(unref(script)), 1)]),
4899
+ _: 1
4900
+ }, 8, ["nonce"])) : createCommentVNode("v-if", true)
4901
+ ]),
4902
+ _: 3
4903
+ }, 16));
4904
+ };
4905
+ }
4906
+ });
4907
+
4908
+ //#endregion
4909
+ //#region src/slider/thumb/SliderThumb.vue
4910
+ var SliderThumb_default = SliderThumb_vue_vue_type_script_setup_true_lang_default;
4911
+
4912
+ //#endregion
4913
+ //#region src/slider/track/SliderTrack.vue?vue&type=script&setup=true&lang.ts
4914
+ var SliderTrack_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
4915
+ name: "SliderTrack",
4916
+ inheritAttrs: false,
4917
+ __name: "SliderTrack",
4918
+ props: {
4919
+ as: {
4920
+ type: null,
4921
+ required: false,
4922
+ default: "div"
4923
+ },
4924
+ class: {
4925
+ type: Function,
4926
+ required: false,
4927
+ skipCheck: true
4928
+ },
4929
+ style: {
4930
+ type: [
4931
+ Boolean,
4932
+ null,
4933
+ String,
4934
+ Object,
4935
+ Array,
4936
+ Function
4937
+ ],
4938
+ required: false,
4939
+ skipCheck: true
4940
+ }
4941
+ },
4942
+ setup(__props) {
4943
+ const props = __props;
4944
+ const attrs = useAttrs();
4945
+ const rootContext = useSliderRootContext();
4946
+ const trackProps = computed(() => mergeProps$1(attrs, { style: { position: "relative" } }));
4947
+ const { tag, mergedProps, renderless, ref: renderRef } = useRenderElement({
4948
+ componentProps: props,
4949
+ state: rootContext.state,
4950
+ props: trackProps,
4951
+ defaultTagName: "div",
4952
+ stateAttributesMapping: sliderStateAttributesMapping
4953
+ });
4954
+ return (_ctx, _cache) => {
4955
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
4956
+ key: 0,
4957
+ ref: unref(renderRef),
4958
+ props: unref(mergedProps),
4959
+ state: unref(rootContext).state
4960
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), mergeProps({
4961
+ key: 1,
4962
+ ref: unref(renderRef)
4963
+ }, unref(mergedProps)), {
4964
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default")]),
4965
+ _: 3
4966
+ }, 16));
4967
+ };
4968
+ }
4969
+ });
4970
+
4971
+ //#endregion
4972
+ //#region src/slider/track/SliderTrack.vue
4973
+ var SliderTrack_default = SliderTrack_vue_vue_type_script_setup_true_lang_default;
4974
+
4975
+ //#endregion
4976
+ //#region src/slider/track/SliderTrackDataAttributes.ts
4977
+ let SliderTrackDataAttributes = /* @__PURE__ */ function(SliderTrackDataAttributes) {
4978
+ SliderTrackDataAttributes["dragging"] = "data-dragging";
4979
+ SliderTrackDataAttributes["orientation"] = "data-orientation";
4980
+ SliderTrackDataAttributes["disabled"] = "data-disabled";
4981
+ SliderTrackDataAttributes["valid"] = "data-valid";
4982
+ SliderTrackDataAttributes["invalid"] = "data-invalid";
4983
+ SliderTrackDataAttributes["touched"] = "data-touched";
4984
+ SliderTrackDataAttributes["dirty"] = "data-dirty";
4985
+ SliderTrackDataAttributes["focused"] = "data-focused";
4986
+ return SliderTrackDataAttributes;
4987
+ }({});
4988
+
4989
+ //#endregion
4990
+ //#region src/slider/value/SliderValue.vue?vue&type=script&setup=true&lang.ts
4991
+ /**
4992
+ * Displays the current value of the slider as text.
4993
+ * Renders an `<output>` element.
4994
+ *
4995
+ * Documentation: [Base UI Slider](https://baseui-vue.com/docs/components/slider)
4996
+ */
4997
+ var SliderValue_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
4998
+ name: "SliderValue",
4999
+ inheritAttrs: false,
5000
+ __name: "SliderValue",
5001
+ props: {
5002
+ ariaLive: {
5003
+ type: String,
5004
+ required: false,
5005
+ default: "off"
5006
+ },
5007
+ as: {
5008
+ type: null,
5009
+ required: false,
5010
+ default: "output"
5011
+ },
5012
+ class: {
5013
+ type: Function,
5014
+ required: false,
5015
+ skipCheck: true
5016
+ },
5017
+ style: {
5018
+ type: [
5019
+ Boolean,
5020
+ null,
5021
+ String,
5022
+ Object,
5023
+ Array,
5024
+ Function
5025
+ ],
5026
+ required: false,
5027
+ skipCheck: true
5028
+ }
5029
+ },
5030
+ setup(__props) {
5031
+ const props = __props;
5032
+ const attrs = useAttrs();
5033
+ const rootContext = useSliderRootContext();
5034
+ const outputFor = computed(() => {
5035
+ let htmlFor = "";
5036
+ for (const thumbMetadata of rootContext.thumbMap.value.values()) if (thumbMetadata?.inputId) htmlFor += `${thumbMetadata.inputId} `;
5037
+ return htmlFor.trim() === "" ? void 0 : htmlFor.trim();
3775
5038
  });
3776
- const inputProps = computed(() => mergeProps$1(inputValidationProps.value, forwardedInputAttrs.value, {
3777
- "aria-label": ariaLabel.value,
3778
- "aria-labelledby": props.ariaLabelledby ?? (ariaLabel.value == null ? rootContext.labelId.value : void 0),
3779
- "aria-describedby": props.ariaDescribedby ?? inputValidationProps.value["aria-describedby"],
3780
- "aria-orientation": rootContext.orientation.value,
3781
- "aria-valuenow": thumbValue.value,
3782
- "aria-valuetext": typeof props.getAriaValueText === "function" ? props.getAriaValueText(formatNumber(thumbValue.value, rootContext.locale.value, rootContext.formatOptionsRef.value), thumbValue.value, index.value) : getDefaultAriaValueText(rootContext.values.value, index.value, rootContext.formatOptionsRef.value, rootContext.locale.value),
3783
- "disabled": disabled.value,
3784
- "form": rootContext.form.value,
3785
- "id": inputId.value,
3786
- "max": rootContext.max.value,
3787
- "min": rootContext.min.value,
3788
- "name": rootContext.name.value,
3789
- onChange(event) {
3790
- rootContext.handleInputChange(event.currentTarget.valueAsNumber, index.value, event);
3791
- },
3792
- onFocus(event) {
3793
- const isRestoringFocusVisible = restoringFocusVisibleRef.value;
3794
- restoringFocusVisibleRef.value = false;
3795
- rootContext.setActive(index.value);
3796
- setFocused(true);
3797
- if (isRestoringFocusVisible) event.stopPropagation();
3798
- },
3799
- "onBlur": handleBlur,
3800
- "onKeydown": handleKeydown,
3801
- "step": rootContext.step.value,
3802
- "style": inputStyle.value,
3803
- "tabIndex": props.tabIndex ?? void 0,
3804
- "type": "range",
3805
- "value": thumbValue.value ?? ""
3806
- }));
3807
- const mergedRef = useMergedRefs(listItemRef, thumbRef);
3808
- const thumbProps = computed(() => mergeProps$1(thumbAttrs.value, {
3809
- [SliderThumbDataAttributes.index]: index.value,
3810
- id,
3811
- onPointerdown(event) {
3812
- rootContext.pressedThumbIndexRef.value = index.value;
3813
- if (thumbRef.value != null) {
3814
- const axis = rootContext.orientation.value === "horizontal" ? "x" : "y";
3815
- const midpoint = getMidpoint(thumbRef.value);
3816
- const offset = (rootContext.orientation.value === "horizontal" ? event.clientX : event.clientY) - midpoint[axis];
3817
- rootContext.pressedThumbCenterOffsetRef.value = offset;
3818
- }
3819
- if (inputRef.value != null && rootContext.pressedInputRef.value !== inputRef.value) rootContext.pressedInputRef.value = inputRef.value;
3820
- },
3821
- style: thumbStyle.value,
3822
- suppressHydrationWarning: rootContext.renderBeforeHydration.value || void 0
5039
+ const formattedValues = computed(() => rootContext.values.value.map((value) => formatNumber(value, rootContext.locale.value, rootContext.formatOptionsRef.value)));
5040
+ const defaultDisplayValue = computed(() => rootContext.values.value.map((value, index) => formattedValues.value[index] || String(value)).join(" – "));
5041
+ const valueProps = computed(() => mergeProps$1(attrs, {
5042
+ "aria-live": props.ariaLive,
5043
+ "for": outputFor.value
3823
5044
  }));
3824
5045
  const { tag, mergedProps, renderless, ref: renderRef } = useRenderElement({
3825
5046
  componentProps: props,
3826
5047
  state: rootContext.state,
3827
- props: thumbProps,
3828
- defaultTagName: "div",
3829
- ref: mergedRef,
5048
+ props: valueProps,
5049
+ defaultTagName: "output",
3830
5050
  stateAttributesMapping: sliderStateAttributesMapping
3831
5051
  });
3832
- watch(() => rootContext.active.value, () => {
3833
- if (disabled.value && rootContext.active.value === index.value) rootContext.setActive(-1);
3834
- });
3835
5052
  return (_ctx, _cache) => {
3836
5053
  return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
3837
5054
  key: 0,
3838
5055
  ref: unref(renderRef),
3839
5056
  props: unref(mergedProps),
3840
- state: unref(rootContext).state
5057
+ state: unref(rootContext).state,
5058
+ formattedValues: formattedValues.value,
5059
+ values: unref(rootContext).values.value
3841
5060
  }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), mergeProps({
3842
5061
  key: 1,
3843
5062
  ref: unref(renderRef)
3844
5063
  }, unref(mergedProps)), {
3845
- default: withCtx(() => [
3846
- renderSlot(_ctx.$slots, "default"),
3847
- createElementVNode("input", mergeProps({ ref: setInputVNodeRef }, inputProps.value), null, 16),
3848
- createCommentVNode(" eslint-disable-next-line vue/require-component-is "),
3849
- unref(rootContext).inset.value && !isMounted.value && unref(rootContext).renderBeforeHydration.value && last.value ? (openBlock(), createBlock(resolveDynamicComponent("script"), {
3850
- key: 0,
3851
- nonce: unref(nonce),
3852
- "suppress-hydration-warning": true
3853
- }, {
3854
- default: withCtx(() => [createTextVNode(toDisplayString(unref(script)), 1)]),
3855
- _: 1
3856
- }, 8, ["nonce"])) : createCommentVNode("v-if", true)
3857
- ]),
5064
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", {
5065
+ formattedValues: formattedValues.value,
5066
+ values: unref(rootContext).values.value
5067
+ }, () => [createTextVNode(toDisplayString(defaultDisplayValue.value), 1)])]),
3858
5068
  _: 3
3859
5069
  }, 16));
3860
5070
  };
3861
5071
  }
3862
- });
5072
+ });
5073
+
5074
+ //#endregion
5075
+ //#region src/slider/value/SliderValue.vue
5076
+ var SliderValue_default = SliderValue_vue_vue_type_script_setup_true_lang_default;
5077
+
5078
+ //#endregion
5079
+ //#region src/slider/value/SliderValueDataAttributes.ts
5080
+ let SliderValueDataAttributes = /* @__PURE__ */ function(SliderValueDataAttributes) {
5081
+ /**
5082
+ * Present while the user is dragging.
5083
+ */
5084
+ SliderValueDataAttributes["dragging"] = "data-dragging";
5085
+ /**
5086
+ * Indicates the orientation of the slider.
5087
+ * @type {'horizontal' | 'vertical'}
5088
+ */
5089
+ SliderValueDataAttributes["orientation"] = "data-orientation";
5090
+ /**
5091
+ * Present when the slider is disabled.
5092
+ */
5093
+ SliderValueDataAttributes["disabled"] = "data-disabled";
5094
+ /**
5095
+ * Present when the slider is in valid state (when wrapped in Field.Root).
5096
+ */
5097
+ SliderValueDataAttributes["valid"] = "data-valid";
5098
+ /**
5099
+ * Present when the slider is in invalid state (when wrapped in Field.Root).
5100
+ */
5101
+ SliderValueDataAttributes["invalid"] = "data-invalid";
5102
+ /**
5103
+ * Present when the slider has been touched (when wrapped in Field.Root).
5104
+ */
5105
+ SliderValueDataAttributes["touched"] = "data-touched";
5106
+ /**
5107
+ * Present when the slider's value has changed (when wrapped in Field.Root).
5108
+ */
5109
+ SliderValueDataAttributes["dirty"] = "data-dirty";
5110
+ /**
5111
+ * Present when the slider is focused (when wrapped in Field.Root).
5112
+ */
5113
+ SliderValueDataAttributes["focused"] = "data-focused";
5114
+ return SliderValueDataAttributes;
5115
+ }({});
5116
+
5117
+ //#endregion
5118
+ //#region src/switch/root/SwitchRootDataAttributes.ts
5119
+ let SwitchRootDataAttributes = /* @__PURE__ */ function(SwitchRootDataAttributes) {
5120
+ /**
5121
+ * Present when the switch is checked.
5122
+ */
5123
+ SwitchRootDataAttributes["checked"] = "data-checked";
5124
+ /**
5125
+ * Present when the switch is not checked.
5126
+ */
5127
+ SwitchRootDataAttributes["unchecked"] = "data-unchecked";
5128
+ /**
5129
+ * Present when the switch is disabled.
5130
+ */
5131
+ SwitchRootDataAttributes["disabled"] = "data-disabled";
5132
+ /**
5133
+ * Present when the switch is readonly.
5134
+ */
5135
+ SwitchRootDataAttributes["readonly"] = "data-readonly";
5136
+ /**
5137
+ * Present when the switch is required.
5138
+ */
5139
+ SwitchRootDataAttributes["required"] = "data-required";
5140
+ /**
5141
+ * Present when the switch is in valid state (when wrapped in FieldRoot).
5142
+ */
5143
+ SwitchRootDataAttributes["valid"] = "data-valid";
5144
+ /**
5145
+ * Present when the switch is in invalid state (when wrapped in FieldRoot).
5146
+ */
5147
+ SwitchRootDataAttributes["invalid"] = "data-invalid";
5148
+ /**
5149
+ * Present when the switch has been touched (when wrapped in FieldRoot).
5150
+ */
5151
+ SwitchRootDataAttributes["touched"] = "data-touched";
5152
+ /**
5153
+ * Present when the switch's value has changed (when wrapped in FieldRoot).
5154
+ */
5155
+ SwitchRootDataAttributes["dirty"] = "data-dirty";
5156
+ /**
5157
+ * Present when the switch is active (when wrapped in FieldRoot).
5158
+ */
5159
+ SwitchRootDataAttributes["filled"] = "data-filled";
5160
+ /**
5161
+ * Present when the switch is focused (when wrapped in FieldRoot).
5162
+ */
5163
+ SwitchRootDataAttributes["focused"] = "data-focused";
5164
+ return SwitchRootDataAttributes;
5165
+ }({});
5166
+
5167
+ //#endregion
5168
+ //#region src/switch/stateAttributesMapping.ts
5169
+ const CHECKED_ATTRS = { [SwitchRootDataAttributes.checked]: "" };
5170
+ const UNCHECKED_ATTRS = { [SwitchRootDataAttributes.unchecked]: "" };
5171
+ const stateAttributesMapping = {
5172
+ ...fieldValidityMapping,
5173
+ checked(value) {
5174
+ if (value) return CHECKED_ATTRS;
5175
+ return UNCHECKED_ATTRS;
5176
+ }
5177
+ };
3863
5178
 
3864
5179
  //#endregion
3865
- //#region src/slider/thumb/SliderThumb.vue
3866
- var SliderThumb_default = SliderThumb_vue_vue_type_script_setup_true_lang_default;
5180
+ //#region src/switch/root/SwitchRootContext.ts
5181
+ const switchRootContextKey = Symbol("SwitchRootContext");
5182
+ function useSwitchRootContext(optional = false) {
5183
+ const context = inject(switchRootContextKey, void 0);
5184
+ if (!context && !optional) throw new Error("Base UI Vue: SwitchRootContext is missing. Switch parts must be placed within <SwitchRoot>.");
5185
+ return context;
5186
+ }
3867
5187
 
3868
5188
  //#endregion
3869
- //#region src/slider/track/SliderTrack.vue?vue&type=script&setup=true&lang.ts
3870
- var SliderTrack_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
3871
- name: "SliderTrack",
5189
+ //#region src/switch/root/SwitchRoot.vue?vue&type=script&setup=true&lang.ts
5190
+ const _hoisted_1 = [
5191
+ "form",
5192
+ "name",
5193
+ "value"
5194
+ ];
5195
+ /**
5196
+ * Represents the switch itself.
5197
+ * Renders a `<span>` element and a hidden `<input>` beside.
5198
+ *
5199
+ * Documentation: [Base UI Vue Switch](https://baseui-vue.com/docs/components/switch)
5200
+ */
5201
+ var SwitchRoot_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
5202
+ name: "SwitchRoot",
3872
5203
  inheritAttrs: false,
3873
- __name: "SliderTrack",
5204
+ __name: "SwitchRoot",
3874
5205
  props: {
5206
+ id: {
5207
+ type: String,
5208
+ required: false
5209
+ },
5210
+ checked: {
5211
+ type: Boolean,
5212
+ required: false
5213
+ },
5214
+ defaultChecked: {
5215
+ type: Boolean,
5216
+ required: false,
5217
+ default: false
5218
+ },
5219
+ disabled: {
5220
+ type: Boolean,
5221
+ required: false,
5222
+ default: false
5223
+ },
5224
+ inputRef: {
5225
+ type: [
5226
+ Object,
5227
+ Function,
5228
+ null
5229
+ ],
5230
+ required: false
5231
+ },
5232
+ name: {
5233
+ type: String,
5234
+ required: false
5235
+ },
5236
+ form: {
5237
+ type: String,
5238
+ required: false
5239
+ },
5240
+ readOnly: {
5241
+ type: Boolean,
5242
+ required: false,
5243
+ default: false
5244
+ },
5245
+ required: {
5246
+ type: Boolean,
5247
+ required: false,
5248
+ default: false
5249
+ },
5250
+ value: {
5251
+ type: String,
5252
+ required: false
5253
+ },
5254
+ uncheckedValue: {
5255
+ type: String,
5256
+ required: false
5257
+ },
5258
+ "aria-labelledby": {
5259
+ type: String,
5260
+ required: false
5261
+ },
5262
+ nativeButton: {
5263
+ type: Boolean,
5264
+ required: false,
5265
+ default: false
5266
+ },
3875
5267
  as: {
3876
5268
  type: null,
3877
5269
  required: false,
3878
- default: "div"
5270
+ default: "span"
3879
5271
  },
3880
5272
  class: {
3881
5273
  type: Function,
@@ -3895,75 +5287,217 @@ var SliderTrack_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ de
3895
5287
  skipCheck: true
3896
5288
  }
3897
5289
  },
3898
- setup(__props) {
5290
+ emits: ["checkedChange"],
5291
+ setup(__props, { expose: __expose, emit: __emit }) {
3899
5292
  const props = __props;
3900
- const attrs = useAttrs();
3901
- const rootContext = useSliderRootContext();
3902
- const trackProps = computed(() => mergeProps$1(attrs, { style: { position: "relative" } }));
5293
+ const emit = __emit;
5294
+ const attrsObject = useAttrs();
5295
+ const instance = getCurrentInstance();
5296
+ const { clearErrors } = useFormContext();
5297
+ const { disabled: fieldDisabled, name: fieldName, setDirty, setFilled, setFocused, setTouched, state: fieldState, validationMode, validityData, shouldValidateOnChange, validation } = useFieldRootContext();
5298
+ const labelableContext = useLabelableContext();
5299
+ const disabled = computed(() => fieldDisabled.value || props.disabled);
5300
+ const name = computed(() => fieldName.value ?? props.name);
5301
+ const rootElementId = useBaseUiId();
5302
+ const controlId = useLabelableId({ id: () => props.id });
5303
+ const inputId = computed(() => props.nativeButton ? void 0 : controlId.value);
5304
+ const { value: checked, setValue: setCheckedState } = useControllableState({
5305
+ controlled: () => instance?.vnode.props && Object.prototype.hasOwnProperty.call(instance.vnode.props, "checked") ? props.checked : void 0,
5306
+ default: () => props.defaultChecked,
5307
+ name: "Switch",
5308
+ state: "checked"
5309
+ });
5310
+ const controlRef = ref(null);
5311
+ const inputElementRef = ref(null);
5312
+ const mergedInputRef = useMergedRefs(inputElementRef, props.inputRef);
5313
+ useField({
5314
+ id: computed(() => rootElementId),
5315
+ commit: (value) => validation.commit(value),
5316
+ value: checked,
5317
+ controlRef,
5318
+ name,
5319
+ getValue: () => checked.value
5320
+ });
5321
+ const ariaLabelledBy = useAriaLabelledBy({
5322
+ ariaLabelledBy: computed(() => props["aria-labelledby"]),
5323
+ labelId: labelableContext.labelId,
5324
+ labelSourceRef: inputElementRef,
5325
+ enableFallback: !props.nativeButton,
5326
+ labelSourceId: inputId
5327
+ });
5328
+ watchEffect(() => {
5329
+ if (checked.value) setFilled(true);
5330
+ });
5331
+ watchEffect(() => {
5332
+ if (!inputElementRef.value) return;
5333
+ validation.setInputRef(inputElementRef.value);
5334
+ });
5335
+ watch(() => checked.value, (nextChecked) => {
5336
+ clearErrors(name.value);
5337
+ setFilled(nextChecked);
5338
+ setDirty(nextChecked !== validityData.value.initialValue);
5339
+ if (shouldValidateOnChange()) validation.commit(nextChecked);
5340
+ else validation.commit(nextChecked, true);
5341
+ }, { flush: "sync" });
5342
+ const { getButtonProps, buttonRef } = useButton({
5343
+ disabled,
5344
+ native: computed(() => props.nativeButton)
5345
+ });
5346
+ function combineDescriptionProps(localProps, validationProps) {
5347
+ const localDescribedBy = localProps["aria-describedby"];
5348
+ const validationDescribedBy = validationProps["aria-describedby"];
5349
+ const describedBy = Array.from(new Set([localDescribedBy, validationDescribedBy].filter(Boolean).flatMap((value) => String(value).split(/\s+/).filter(Boolean)))).join(" ") || void 0;
5350
+ return {
5351
+ ...localProps,
5352
+ ...validationProps,
5353
+ "aria-describedby": describedBy
5354
+ };
5355
+ }
5356
+ function applyCheckedChange(nextChecked, event, onApplied) {
5357
+ const details = createChangeEventDetails(REASONS.none, event);
5358
+ emit("checkedChange", nextChecked, details);
5359
+ if (details.isCanceled) return false;
5360
+ onApplied?.();
5361
+ setCheckedState(nextChecked);
5362
+ return true;
5363
+ }
5364
+ function handleInputChange(event) {
5365
+ const target = event.currentTarget;
5366
+ if (props.readOnly || disabled.value) {
5367
+ event.preventDefault();
5368
+ event.stopPropagation();
5369
+ target.checked = checked.value;
5370
+ return;
5371
+ }
5372
+ if (!applyCheckedChange(target.checked, event)) target.checked = checked.value;
5373
+ }
5374
+ function handleRootClick(event) {
5375
+ if (props.readOnly || disabled.value) return;
5376
+ event.preventDefault();
5377
+ const nextChecked = !checked.value;
5378
+ applyCheckedChange(nextChecked, event, () => {
5379
+ if (inputElementRef.value) inputElementRef.value.checked = nextChecked;
5380
+ });
5381
+ }
5382
+ function handleFocus() {
5383
+ if (!disabled.value) setFocused(true);
5384
+ }
5385
+ function handleBlur() {
5386
+ if (disabled.value) return;
5387
+ setTouched(true);
5388
+ setFocused(false);
5389
+ if (validationMode.value === "onBlur") validation.commit(checked.value);
5390
+ }
5391
+ const state = computed(() => ({
5392
+ ...fieldState.value,
5393
+ checked: checked.value,
5394
+ disabled: disabled.value,
5395
+ readOnly: props.readOnly,
5396
+ required: props.required
5397
+ }));
5398
+ provide(switchRootContextKey, state);
5399
+ __expose({ element: controlRef });
5400
+ const mergedRootRef = useMergedRefs(buttonRef, controlRef);
5401
+ const buttonInteractionAttrs = computed(() => ({
5402
+ onClick: attrsObject.onClick,
5403
+ onKeydown: attrsObject.onKeydown,
5404
+ onKeyup: attrsObject.onKeyup,
5405
+ onMousedown: attrsObject.onMousedown,
5406
+ onPointerdown: attrsObject.onPointerdown
5407
+ }));
5408
+ const passthroughAttrs = computed(() => {
5409
+ const { onClick, onKeydown, onKeyup, onMousedown, onPointerdown, ...rest } = attrsObject;
5410
+ return rest;
5411
+ });
3903
5412
  const { tag, mergedProps, renderless, ref: renderRef } = useRenderElement({
3904
5413
  componentProps: props,
3905
- state: rootContext.state,
3906
- props: trackProps,
3907
- defaultTagName: "div",
3908
- stateAttributesMapping: sliderStateAttributesMapping
5414
+ state,
5415
+ props: computed(() => {
5416
+ const localDescriptionProps = labelableContext.getDescriptionProps();
5417
+ const validationProps = validation.getValidationProps();
5418
+ return mergeProps$1(getButtonProps(mergeProps$1(buttonInteractionAttrs.value, { onClick: handleRootClick })), combineDescriptionProps(localDescriptionProps, validationProps), {
5419
+ "id": props.nativeButton ? controlId.value : rootElementId,
5420
+ "role": "switch",
5421
+ "aria-checked": checked.value,
5422
+ "aria-readonly": props.readOnly || void 0,
5423
+ "aria-required": props.required || void 0,
5424
+ "aria-labelledby": ariaLabelledBy.value,
5425
+ "onFocus": handleFocus,
5426
+ "onBlur": handleBlur
5427
+ }, passthroughAttrs.value);
5428
+ }),
5429
+ stateAttributesMapping,
5430
+ defaultTagName: "span",
5431
+ ref: mergedRootRef
5432
+ });
5433
+ const inputProps = computed(() => {
5434
+ const localDescriptionProps = labelableContext.getDescriptionProps();
5435
+ const validationProps = validation.getInputValidationProps();
5436
+ return mergeProps$1({
5437
+ "checked": checked.value,
5438
+ "disabled": disabled.value,
5439
+ "form": props.form,
5440
+ "id": props.nativeButton ? void 0 : inputId.value,
5441
+ "name": name.value,
5442
+ "required": props.required,
5443
+ "type": "checkbox",
5444
+ "aria-hidden": true,
5445
+ "tabindex": -1,
5446
+ "style": name.value ? visuallyHiddenInput : visuallyHidden,
5447
+ "onChange": handleInputChange,
5448
+ onFocus() {
5449
+ controlRef.value?.focus();
5450
+ }
5451
+ }, props.value !== void 0 ? { value: props.value } : EMPTY_OBJECT, combineDescriptionProps(localDescriptionProps, validationProps));
3909
5452
  });
3910
5453
  return (_ctx, _cache) => {
3911
- return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
3912
- key: 0,
3913
- ref: unref(renderRef),
3914
- props: unref(mergedProps),
3915
- state: unref(rootContext).state
3916
- }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), mergeProps({
3917
- key: 1,
3918
- ref: unref(renderRef)
3919
- }, unref(mergedProps)), {
3920
- default: withCtx(() => [renderSlot(_ctx.$slots, "default")]),
3921
- _: 3
3922
- }, 16));
5454
+ return openBlock(), createElementBlock(Fragment, null, [
5455
+ unref(renderless) ? renderSlot(_ctx.$slots, "default", {
5456
+ key: 0,
5457
+ ref: unref(renderRef),
5458
+ props: unref(mergedProps),
5459
+ state: state.value
5460
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), mergeProps({
5461
+ key: 1,
5462
+ ref: unref(renderRef)
5463
+ }, unref(mergedProps)), {
5464
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: state.value })]),
5465
+ _: 3
5466
+ }, 16)),
5467
+ !unref(checked) && !disabled.value && name.value && __props.uncheckedValue !== void 0 ? (openBlock(), createElementBlock("input", {
5468
+ key: 2,
5469
+ type: "hidden",
5470
+ form: __props.form,
5471
+ name: name.value,
5472
+ value: __props.uncheckedValue
5473
+ }, null, 8, _hoisted_1)) : createCommentVNode("v-if", true),
5474
+ createElementVNode("input", mergeProps({ ref: unref(mergedInputRef) }, inputProps.value), null, 16)
5475
+ ], 64);
3923
5476
  };
3924
5477
  }
3925
5478
  });
3926
5479
 
3927
5480
  //#endregion
3928
- //#region src/slider/track/SliderTrack.vue
3929
- var SliderTrack_default = SliderTrack_vue_vue_type_script_setup_true_lang_default;
3930
-
3931
- //#endregion
3932
- //#region src/slider/track/SliderTrackDataAttributes.ts
3933
- let SliderTrackDataAttributes = /* @__PURE__ */ function(SliderTrackDataAttributes) {
3934
- SliderTrackDataAttributes["dragging"] = "data-dragging";
3935
- SliderTrackDataAttributes["orientation"] = "data-orientation";
3936
- SliderTrackDataAttributes["disabled"] = "data-disabled";
3937
- SliderTrackDataAttributes["valid"] = "data-valid";
3938
- SliderTrackDataAttributes["invalid"] = "data-invalid";
3939
- SliderTrackDataAttributes["touched"] = "data-touched";
3940
- SliderTrackDataAttributes["dirty"] = "data-dirty";
3941
- SliderTrackDataAttributes["focused"] = "data-focused";
3942
- return SliderTrackDataAttributes;
3943
- }({});
5481
+ //#region src/switch/root/SwitchRoot.vue
5482
+ var SwitchRoot_default = SwitchRoot_vue_vue_type_script_setup_true_lang_default;
3944
5483
 
3945
5484
  //#endregion
3946
- //#region src/slider/value/SliderValue.vue?vue&type=script&setup=true&lang.ts
5485
+ //#region src/switch/thumb/SwitchThumb.vue?vue&type=script&setup=true&lang.ts
3947
5486
  /**
3948
- * Displays the current value of the slider as text.
3949
- * Renders an `<output>` element.
5487
+ * The movable part of the switch that indicates whether the switch is on or off.
5488
+ * Renders a `<span>`.
3950
5489
  *
3951
- * Documentation: [Base UI Slider](https://baseui-vue.com/docs/components/slider)
5490
+ * Documentation: [Base UI Vue Switch](https://baseui-vue.com/docs/components/switch)
3952
5491
  */
3953
- var SliderValue_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
3954
- name: "SliderValue",
5492
+ var SwitchThumb_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
5493
+ name: "SwitchThumb",
3955
5494
  inheritAttrs: false,
3956
- __name: "SliderValue",
5495
+ __name: "SwitchThumb",
3957
5496
  props: {
3958
- ariaLive: {
3959
- type: String,
3960
- required: false,
3961
- default: "off"
3962
- },
3963
5497
  as: {
3964
5498
  type: null,
3965
5499
  required: false,
3966
- default: "output"
5500
+ default: "span"
3967
5501
  },
3968
5502
  class: {
3969
5503
  type: Function,
@@ -3985,42 +5519,31 @@ var SliderValue_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ de
3985
5519
  },
3986
5520
  setup(__props) {
3987
5521
  const props = __props;
3988
- const attrs = useAttrs();
3989
- const rootContext = useSliderRootContext();
3990
- const outputFor = computed(() => {
3991
- let htmlFor = "";
3992
- for (const thumbMetadata of rootContext.thumbMap.value.values()) if (thumbMetadata?.inputId) htmlFor += `${thumbMetadata.inputId} `;
3993
- return htmlFor.trim() === "" ? void 0 : htmlFor.trim();
3994
- });
3995
- const formattedValues = computed(() => rootContext.values.value.map((value) => formatNumber(value, rootContext.locale.value, rootContext.formatOptionsRef.value)));
3996
- const defaultDisplayValue = computed(() => rootContext.values.value.map((value, index) => formattedValues.value[index] || String(value)).join(" – "));
3997
- const valueProps = computed(() => mergeProps$1(attrs, {
3998
- "aria-live": props.ariaLive,
3999
- "for": outputFor.value
5522
+ const attrsObject = useAttrs();
5523
+ const { state: fieldState } = useFieldRootContext();
5524
+ const rootState = useSwitchRootContext();
5525
+ const state = computed(() => ({
5526
+ ...fieldState.value,
5527
+ ...rootState.value
4000
5528
  }));
4001
5529
  const { tag, mergedProps, renderless, ref: renderRef } = useRenderElement({
4002
5530
  componentProps: props,
4003
- state: rootContext.state,
4004
- props: valueProps,
4005
- defaultTagName: "output",
4006
- stateAttributesMapping: sliderStateAttributesMapping
5531
+ state,
5532
+ props: computed(() => attrsObject),
5533
+ stateAttributesMapping,
5534
+ defaultTagName: "span"
4007
5535
  });
4008
5536
  return (_ctx, _cache) => {
4009
5537
  return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
4010
5538
  key: 0,
4011
5539
  ref: unref(renderRef),
4012
5540
  props: unref(mergedProps),
4013
- state: unref(rootContext).state,
4014
- formattedValues: formattedValues.value,
4015
- values: unref(rootContext).values.value
5541
+ state: state.value
4016
5542
  }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), mergeProps({
4017
5543
  key: 1,
4018
5544
  ref: unref(renderRef)
4019
5545
  }, unref(mergedProps)), {
4020
- default: withCtx(() => [renderSlot(_ctx.$slots, "default", {
4021
- formattedValues: formattedValues.value,
4022
- values: unref(rootContext).values.value
4023
- }, () => [createTextVNode(toDisplayString(defaultDisplayValue.value), 1)])]),
5546
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: state.value })]),
4024
5547
  _: 3
4025
5548
  }, 16));
4026
5549
  };
@@ -4028,194 +5551,440 @@ var SliderValue_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ de
4028
5551
  });
4029
5552
 
4030
5553
  //#endregion
4031
- //#region src/slider/value/SliderValue.vue
4032
- var SliderValue_default = SliderValue_vue_vue_type_script_setup_true_lang_default;
4033
-
4034
- //#endregion
4035
- //#region src/slider/value/SliderValueDataAttributes.ts
4036
- let SliderValueDataAttributes = /* @__PURE__ */ function(SliderValueDataAttributes) {
4037
- /**
4038
- * Present while the user is dragging.
4039
- */
4040
- SliderValueDataAttributes["dragging"] = "data-dragging";
4041
- /**
4042
- * Indicates the orientation of the slider.
4043
- * @type {'horizontal' | 'vertical'}
4044
- */
4045
- SliderValueDataAttributes["orientation"] = "data-orientation";
4046
- /**
4047
- * Present when the slider is disabled.
4048
- */
4049
- SliderValueDataAttributes["disabled"] = "data-disabled";
4050
- /**
4051
- * Present when the slider is in valid state (when wrapped in Field.Root).
4052
- */
4053
- SliderValueDataAttributes["valid"] = "data-valid";
4054
- /**
4055
- * Present when the slider is in invalid state (when wrapped in Field.Root).
4056
- */
4057
- SliderValueDataAttributes["invalid"] = "data-invalid";
4058
- /**
4059
- * Present when the slider has been touched (when wrapped in Field.Root).
4060
- */
4061
- SliderValueDataAttributes["touched"] = "data-touched";
4062
- /**
4063
- * Present when the slider's value has changed (when wrapped in Field.Root).
4064
- */
4065
- SliderValueDataAttributes["dirty"] = "data-dirty";
4066
- /**
4067
- * Present when the slider is focused (when wrapped in Field.Root).
4068
- */
4069
- SliderValueDataAttributes["focused"] = "data-focused";
4070
- return SliderValueDataAttributes;
4071
- }({});
5554
+ //#region src/switch/thumb/SwitchThumb.vue
5555
+ var SwitchThumb_default = SwitchThumb_vue_vue_type_script_setup_true_lang_default;
4072
5556
 
4073
5557
  //#endregion
4074
- //#region src/switch/root/SwitchRootDataAttributes.ts
4075
- let SwitchRootDataAttributes = /* @__PURE__ */ function(SwitchRootDataAttributes) {
5558
+ //#region src/switch/thumb/SwitchThumbDataAttributes.ts
5559
+ let SwitchThumbDataAttributes = /* @__PURE__ */ function(SwitchThumbDataAttributes) {
4076
5560
  /**
4077
5561
  * Present when the switch is checked.
4078
5562
  */
4079
- SwitchRootDataAttributes["checked"] = "data-checked";
5563
+ SwitchThumbDataAttributes["checked"] = "data-checked";
4080
5564
  /**
4081
5565
  * Present when the switch is not checked.
4082
5566
  */
4083
- SwitchRootDataAttributes["unchecked"] = "data-unchecked";
5567
+ SwitchThumbDataAttributes["unchecked"] = "data-unchecked";
4084
5568
  /**
4085
5569
  * Present when the switch is disabled.
4086
5570
  */
4087
- SwitchRootDataAttributes["disabled"] = "data-disabled";
5571
+ SwitchThumbDataAttributes["disabled"] = "data-disabled";
4088
5572
  /**
4089
5573
  * Present when the switch is readonly.
4090
5574
  */
4091
- SwitchRootDataAttributes["readonly"] = "data-readonly";
5575
+ SwitchThumbDataAttributes["readonly"] = "data-readonly";
4092
5576
  /**
4093
5577
  * Present when the switch is required.
4094
5578
  */
4095
- SwitchRootDataAttributes["required"] = "data-required";
5579
+ SwitchThumbDataAttributes["required"] = "data-required";
4096
5580
  /**
4097
5581
  * Present when the switch is in valid state (when wrapped in FieldRoot).
4098
5582
  */
4099
- SwitchRootDataAttributes["valid"] = "data-valid";
5583
+ SwitchThumbDataAttributes["valid"] = "data-valid";
4100
5584
  /**
4101
5585
  * Present when the switch is in invalid state (when wrapped in FieldRoot).
4102
5586
  */
4103
- SwitchRootDataAttributes["invalid"] = "data-invalid";
5587
+ SwitchThumbDataAttributes["invalid"] = "data-invalid";
4104
5588
  /**
4105
5589
  * Present when the switch has been touched (when wrapped in FieldRoot).
4106
5590
  */
4107
- SwitchRootDataAttributes["touched"] = "data-touched";
5591
+ SwitchThumbDataAttributes["touched"] = "data-touched";
4108
5592
  /**
4109
5593
  * Present when the switch's value has changed (when wrapped in FieldRoot).
4110
5594
  */
4111
- SwitchRootDataAttributes["dirty"] = "data-dirty";
5595
+ SwitchThumbDataAttributes["dirty"] = "data-dirty";
4112
5596
  /**
4113
5597
  * Present when the switch is active (when wrapped in FieldRoot).
4114
5598
  */
4115
- SwitchRootDataAttributes["filled"] = "data-filled";
5599
+ SwitchThumbDataAttributes["filled"] = "data-filled";
4116
5600
  /**
4117
5601
  * Present when the switch is focused (when wrapped in FieldRoot).
4118
5602
  */
4119
- SwitchRootDataAttributes["focused"] = "data-focused";
4120
- return SwitchRootDataAttributes;
5603
+ SwitchThumbDataAttributes["focused"] = "data-focused";
5604
+ return SwitchThumbDataAttributes;
5605
+ }({});
5606
+
5607
+ //#endregion
5608
+ //#region src/utils/styles.ts
5609
+ const DISABLE_SCROLLBAR_CLASS_NAME = "base-ui-disable-scrollbar";
5610
+ const STYLE_ELEMENT_ID = `style-${DISABLE_SCROLLBAR_CLASS_NAME}`;
5611
+ const styleDisableScrollbar = {
5612
+ className: DISABLE_SCROLLBAR_CLASS_NAME,
5613
+ inject(nonce, disableStyleElements) {
5614
+ if (disableStyleElements) return;
5615
+ if (typeof document === "undefined") return;
5616
+ if (document.getElementById(STYLE_ELEMENT_ID)) return;
5617
+ const style = document.createElement("style");
5618
+ style.id = STYLE_ELEMENT_ID;
5619
+ if (nonce) style.nonce = nonce;
5620
+ style.textContent = `.${DISABLE_SCROLLBAR_CLASS_NAME}{scrollbar-width:none}.${DISABLE_SCROLLBAR_CLASS_NAME}::-webkit-scrollbar{display:none}`;
5621
+ document.head.appendChild(style);
5622
+ }
5623
+ };
5624
+
5625
+ //#endregion
5626
+ //#region src/scroll-area/constants.ts
5627
+ const SCROLL_TIMEOUT = 500;
5628
+ const MIN_THUMB_SIZE = 16;
5629
+
5630
+ //#endregion
5631
+ //#region src/scroll-area/scrollbar/ScrollAreaScrollbarDataAttributes.ts
5632
+ let ScrollAreaScrollbarDataAttributes = /* @__PURE__ */ function(ScrollAreaScrollbarDataAttributes) {
5633
+ ScrollAreaScrollbarDataAttributes["orientation"] = "data-orientation";
5634
+ ScrollAreaScrollbarDataAttributes["hovering"] = "data-hovering";
5635
+ ScrollAreaScrollbarDataAttributes["scrolling"] = "data-scrolling";
5636
+ ScrollAreaScrollbarDataAttributes["hasOverflowX"] = "data-has-overflow-x";
5637
+ ScrollAreaScrollbarDataAttributes["hasOverflowY"] = "data-has-overflow-y";
5638
+ ScrollAreaScrollbarDataAttributes["overflowXStart"] = "data-overflow-x-start";
5639
+ ScrollAreaScrollbarDataAttributes["overflowXEnd"] = "data-overflow-x-end";
5640
+ ScrollAreaScrollbarDataAttributes["overflowYStart"] = "data-overflow-y-start";
5641
+ ScrollAreaScrollbarDataAttributes["overflowYEnd"] = "data-overflow-y-end";
5642
+ return ScrollAreaScrollbarDataAttributes;
5643
+ }({});
5644
+
5645
+ //#endregion
5646
+ //#region src/scroll-area/utils/getOffset.ts
5647
+ function getOffset(element, prop, axis) {
5648
+ if (!element) return 0;
5649
+ const styles = getComputedStyle(element);
5650
+ const propAxis = axis === "x" ? "Inline" : "Block";
5651
+ const start = getStyleNumber(styles, `${prop}${propAxis}Start`);
5652
+ const end = getStyleNumber(styles, `${prop}${propAxis}End`);
5653
+ if (axis === "x" && prop === "margin" && styles.direction === "rtl" && isSafari()) return start * 2;
5654
+ return start + end;
5655
+ }
5656
+ function getStyleNumber(styles, prop) {
5657
+ return Number.parseFloat(styles[prop]) || 0;
5658
+ }
5659
+ function isSafari() {
5660
+ if (typeof navigator === "undefined") return false;
5661
+ return /AppleWebKit/.test(navigator.userAgent) && !/Chrome|Chromium|Edg\//.test(navigator.userAgent);
5662
+ }
5663
+
5664
+ //#endregion
5665
+ //#region src/scroll-area/root/ScrollAreaRootCssVars.ts
5666
+ let ScrollAreaRootCssVars = /* @__PURE__ */ function(ScrollAreaRootCssVars) {
5667
+ ScrollAreaRootCssVars["scrollAreaCornerHeight"] = "--scroll-area-corner-height";
5668
+ ScrollAreaRootCssVars["scrollAreaCornerWidth"] = "--scroll-area-corner-width";
5669
+ return ScrollAreaRootCssVars;
4121
5670
  }({});
4122
5671
 
4123
5672
  //#endregion
4124
- //#region src/switch/stateAttributesMapping.ts
4125
- const CHECKED_ATTRS = { [SwitchRootDataAttributes.checked]: "" };
4126
- const UNCHECKED_ATTRS = { [SwitchRootDataAttributes.unchecked]: "" };
4127
- const stateAttributesMapping = {
4128
- ...fieldValidityMapping,
4129
- checked(value) {
4130
- if (value) return CHECKED_ATTRS;
4131
- return UNCHECKED_ATTRS;
4132
- }
4133
- };
5673
+ //#region src/scroll-area/root/ScrollAreaRoot.vue?vue&type=script&setup=true&lang.ts
5674
+ var ScrollAreaRoot_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
5675
+ name: "ScrollAreaRoot",
5676
+ inheritAttrs: false,
5677
+ __name: "ScrollAreaRoot",
5678
+ props: {
5679
+ overflowEdgeThreshold: {
5680
+ type: [Number, Object],
5681
+ required: false
5682
+ },
5683
+ as: {
5684
+ type: null,
5685
+ required: false,
5686
+ default: "div"
5687
+ },
5688
+ class: {
5689
+ type: Function,
5690
+ required: false,
5691
+ skipCheck: true
5692
+ },
5693
+ style: {
5694
+ type: [
5695
+ Boolean,
5696
+ null,
5697
+ String,
5698
+ Object,
5699
+ Array,
5700
+ Function
5701
+ ],
5702
+ required: false,
5703
+ skipCheck: true
5704
+ }
5705
+ },
5706
+ setup(__props) {
5707
+ const props = __props;
5708
+ const DEFAULT_SIZE = {
5709
+ width: 0,
5710
+ height: 0
5711
+ };
5712
+ const DEFAULT_OVERFLOW_EDGES = {
5713
+ xStart: false,
5714
+ xEnd: false,
5715
+ yStart: false,
5716
+ yEnd: false
5717
+ };
5718
+ const DEFAULT_HIDDEN_STATE = {
5719
+ x: true,
5720
+ y: true,
5721
+ corner: true
5722
+ };
5723
+ const DEFAULT_COORDS = {
5724
+ x: 0,
5725
+ y: 0
5726
+ };
5727
+ const attrs = useAttrs();
5728
+ const overflowEdgeThreshold = computed(() => normalizeOverflowEdgeThreshold(props.overflowEdgeThreshold));
5729
+ const rootId = useBaseUiId();
5730
+ const { nonce, disableStyleElements } = useCSPContext();
5731
+ const hovering = ref(false);
5732
+ const scrollingX = ref(false);
5733
+ const scrollingY = ref(false);
5734
+ const touchModality = ref(false);
5735
+ const hasMeasuredScrollbar = ref(false);
5736
+ const cornerSize = ref({ ...DEFAULT_SIZE });
5737
+ const thumbSize = ref({ ...DEFAULT_SIZE });
5738
+ const overflowEdges = ref({ ...DEFAULT_OVERFLOW_EDGES });
5739
+ const hiddenState = ref({ ...DEFAULT_HIDDEN_STATE });
5740
+ const rootRef = shallowRef(null);
5741
+ const viewportRef = shallowRef(null);
5742
+ const scrollbarYRef = shallowRef(null);
5743
+ const scrollbarXRef = shallowRef(null);
5744
+ const thumbYRef = shallowRef(null);
5745
+ const thumbXRef = shallowRef(null);
5746
+ const cornerRef = shallowRef(null);
5747
+ let scrollYTimeoutId;
5748
+ let scrollXTimeoutId;
5749
+ const thumbDragging = { current: false };
5750
+ const startY = { current: 0 };
5751
+ const startX = { current: 0 };
5752
+ const startScrollTop = { current: 0 };
5753
+ const startScrollLeft = { current: 0 };
5754
+ const currentOrientation = { current: "vertical" };
5755
+ const scrollPosition = { current: { ...DEFAULT_COORDS } };
5756
+ function handleScroll(pos) {
5757
+ const offsetX = pos.x - scrollPosition.current.x;
5758
+ const offsetY = pos.y - scrollPosition.current.y;
5759
+ scrollPosition.current = pos;
5760
+ if (offsetY !== 0) {
5761
+ scrollingY.value = true;
5762
+ clearTimeout(scrollYTimeoutId);
5763
+ scrollYTimeoutId = setTimeout(() => {
5764
+ scrollingY.value = false;
5765
+ }, SCROLL_TIMEOUT);
5766
+ }
5767
+ if (offsetX !== 0) {
5768
+ scrollingX.value = true;
5769
+ clearTimeout(scrollXTimeoutId);
5770
+ scrollXTimeoutId = setTimeout(() => {
5771
+ scrollingX.value = false;
5772
+ }, SCROLL_TIMEOUT);
5773
+ }
5774
+ }
5775
+ function handlePointerDown(event) {
5776
+ if (event.button !== 0) return;
5777
+ thumbDragging.current = true;
5778
+ startY.current = event.clientY;
5779
+ startX.current = event.clientX;
5780
+ currentOrientation.current = event.currentTarget.getAttribute(ScrollAreaScrollbarDataAttributes.orientation);
5781
+ if (viewportRef.value) {
5782
+ startScrollTop.current = viewportRef.value.scrollTop;
5783
+ startScrollLeft.current = viewportRef.value.scrollLeft;
5784
+ }
5785
+ if (thumbYRef.value && currentOrientation.current === "vertical") thumbYRef.value.setPointerCapture(event.pointerId);
5786
+ if (thumbXRef.value && currentOrientation.current === "horizontal") thumbXRef.value.setPointerCapture(event.pointerId);
5787
+ }
5788
+ function handlePointerMove(event) {
5789
+ if (!thumbDragging.current) return;
5790
+ const deltaY = event.clientY - startY.current;
5791
+ const deltaX = event.clientX - startX.current;
5792
+ if (viewportRef.value) {
5793
+ const scrollableContentHeight = viewportRef.value.scrollHeight;
5794
+ const viewportHeight = viewportRef.value.clientHeight;
5795
+ const scrollableContentWidth = viewportRef.value.scrollWidth;
5796
+ const viewportWidth = viewportRef.value.clientWidth;
5797
+ if (thumbYRef.value && scrollbarYRef.value && currentOrientation.current === "vertical") {
5798
+ const scrollbarYOffset = getOffset(scrollbarYRef.value, "padding", "y");
5799
+ const thumbYOffset = getOffset(thumbYRef.value, "margin", "y");
5800
+ const thumbHeight = thumbYRef.value.offsetHeight;
5801
+ const scrollRatioY = deltaY / (scrollbarYRef.value.offsetHeight - thumbHeight - scrollbarYOffset - thumbYOffset);
5802
+ viewportRef.value.scrollTop = startScrollTop.current + scrollRatioY * (scrollableContentHeight - viewportHeight);
5803
+ event.preventDefault();
5804
+ scrollingY.value = true;
5805
+ clearTimeout(scrollYTimeoutId);
5806
+ scrollYTimeoutId = setTimeout(() => {
5807
+ scrollingY.value = false;
5808
+ }, SCROLL_TIMEOUT);
5809
+ }
5810
+ if (thumbXRef.value && scrollbarXRef.value && currentOrientation.current === "horizontal") {
5811
+ const scrollbarXOffset = getOffset(scrollbarXRef.value, "padding", "x");
5812
+ const thumbXOffset = getOffset(thumbXRef.value, "margin", "x");
5813
+ const thumbWidth = thumbXRef.value.offsetWidth;
5814
+ const scrollRatioX = deltaX / (scrollbarXRef.value.offsetWidth - thumbWidth - scrollbarXOffset - thumbXOffset);
5815
+ viewportRef.value.scrollLeft = startScrollLeft.current + scrollRatioX * (scrollableContentWidth - viewportWidth);
5816
+ event.preventDefault();
5817
+ scrollingX.value = true;
5818
+ clearTimeout(scrollXTimeoutId);
5819
+ scrollXTimeoutId = setTimeout(() => {
5820
+ scrollingX.value = false;
5821
+ }, SCROLL_TIMEOUT);
5822
+ }
5823
+ }
5824
+ }
5825
+ function handlePointerUp(event) {
5826
+ thumbDragging.current = false;
5827
+ if (thumbYRef.value && currentOrientation.current === "vertical") thumbYRef.value.releasePointerCapture(event.pointerId);
5828
+ if (thumbXRef.value && currentOrientation.current === "horizontal") thumbXRef.value.releasePointerCapture(event.pointerId);
5829
+ }
5830
+ function handleTouchModalityChange(event) {
5831
+ touchModality.value = event.pointerType === "touch";
5832
+ }
5833
+ function handlePointerEnterOrMove(event) {
5834
+ handleTouchModalityChange(event);
5835
+ if (event.pointerType !== "touch") hovering.value = contains(rootRef.value, event.target);
5836
+ }
5837
+ const state = computed(() => ({
5838
+ scrolling: scrollingX.value || scrollingY.value,
5839
+ hasOverflowX: !hiddenState.value.x,
5840
+ hasOverflowY: !hiddenState.value.y,
5841
+ overflowXStart: overflowEdges.value.xStart,
5842
+ overflowXEnd: overflowEdges.value.xEnd,
5843
+ overflowYStart: overflowEdges.value.yStart,
5844
+ overflowYEnd: overflowEdges.value.yEnd,
5845
+ cornerHidden: hiddenState.value.corner
5846
+ }));
5847
+ const { tag, mergedProps, renderless, ref: renderRef } = useRenderElement({
5848
+ componentProps: props,
5849
+ state,
5850
+ props: computed(() => mergeProps$1(attrs, {
5851
+ role: "presentation",
5852
+ onPointerenter: handlePointerEnterOrMove,
5853
+ onPointermove: handlePointerEnterOrMove,
5854
+ onPointerdown: handleTouchModalityChange,
5855
+ onPointerleave: () => {
5856
+ hovering.value = false;
5857
+ },
5858
+ style: {
5859
+ position: "relative",
5860
+ [ScrollAreaRootCssVars.scrollAreaCornerHeight]: `${cornerSize.value.height}px`,
5861
+ [ScrollAreaRootCssVars.scrollAreaCornerWidth]: `${cornerSize.value.width}px`
5862
+ }
5863
+ })),
5864
+ stateAttributesMapping: scrollAreaStateAttributesMapping,
5865
+ defaultTagName: "div",
5866
+ ref: rootRef
5867
+ });
5868
+ onMounted(() => {
5869
+ styleDisableScrollbar.inject(nonce.value, disableStyleElements.value);
5870
+ });
5871
+ provide(scrollAreaRootContextKey, {
5872
+ cornerSize,
5873
+ setCornerSize: (size) => {
5874
+ cornerSize.value = size;
5875
+ },
5876
+ thumbSize,
5877
+ setThumbSize: (size) => {
5878
+ thumbSize.value = size;
5879
+ },
5880
+ hasMeasuredScrollbar,
5881
+ setHasMeasuredScrollbar: (value) => {
5882
+ hasMeasuredScrollbar.value = value;
5883
+ },
5884
+ touchModality,
5885
+ hovering,
5886
+ setHovering: (value) => {
5887
+ hovering.value = value;
5888
+ },
5889
+ scrollingX,
5890
+ setScrollingX: (value) => {
5891
+ scrollingX.value = value;
5892
+ },
5893
+ scrollingY,
5894
+ setScrollingY: (value) => {
5895
+ scrollingY.value = value;
5896
+ },
5897
+ viewportRef,
5898
+ rootRef,
5899
+ scrollbarYRef,
5900
+ scrollbarXRef,
5901
+ thumbYRef,
5902
+ thumbXRef,
5903
+ cornerRef,
5904
+ handlePointerDown,
5905
+ handlePointerMove,
5906
+ handlePointerUp,
5907
+ handleScroll,
5908
+ rootId,
5909
+ hiddenState,
5910
+ setHiddenState: (s) => {
5911
+ hiddenState.value = s;
5912
+ },
5913
+ overflowEdges,
5914
+ setOverflowEdges: (e) => {
5915
+ overflowEdges.value = e;
5916
+ },
5917
+ viewportState: state,
5918
+ overflowEdgeThreshold
5919
+ });
5920
+ function normalizeOverflowEdgeThreshold(threshold) {
5921
+ if (typeof threshold === "number") {
5922
+ const value = Math.max(0, threshold);
5923
+ return {
5924
+ xStart: value,
5925
+ xEnd: value,
5926
+ yStart: value,
5927
+ yEnd: value
5928
+ };
5929
+ }
5930
+ return {
5931
+ xStart: Math.max(0, threshold?.xStart || 0),
5932
+ xEnd: Math.max(0, threshold?.xEnd || 0),
5933
+ yStart: Math.max(0, threshold?.yStart || 0),
5934
+ yEnd: Math.max(0, threshold?.yEnd || 0)
5935
+ };
5936
+ }
5937
+ return (_ctx, _cache) => {
5938
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
5939
+ key: 0,
5940
+ ref: unref(renderRef),
5941
+ props: unref(mergedProps),
5942
+ state: state.value
5943
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), mergeProps({
5944
+ key: 1,
5945
+ ref: unref(renderRef)
5946
+ }, unref(mergedProps)), {
5947
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default")]),
5948
+ _: 3
5949
+ }, 16));
5950
+ };
5951
+ }
5952
+ });
5953
+
5954
+ //#endregion
5955
+ //#region src/scroll-area/root/ScrollAreaRoot.vue
5956
+ var ScrollAreaRoot_default = ScrollAreaRoot_vue_vue_type_script_setup_true_lang_default;
4134
5957
 
4135
5958
  //#endregion
4136
- //#region src/switch/root/SwitchRootContext.ts
4137
- const switchRootContextKey = Symbol("SwitchRootContext");
4138
- function useSwitchRootContext(optional = false) {
4139
- const context = inject(switchRootContextKey, void 0);
4140
- if (!context && !optional) throw new Error("Base UI Vue: SwitchRootContext is missing. Switch parts must be placed within <SwitchRoot>.");
5959
+ //#region src/scroll-area/scrollbar/ScrollAreaScrollbarContext.ts
5960
+ const scrollAreaScrollbarContextKey = Symbol("ScrollAreaScrollbarContext");
5961
+ function useScrollAreaScrollbarContext() {
5962
+ const context = inject(scrollAreaScrollbarContextKey);
5963
+ if (context === void 0) throw new Error("Base UI: ScrollAreaScrollbarContext is missing. ScrollArea.Thumb must be placed within <ScrollAreaScrollbar>.");
4141
5964
  return context;
4142
5965
  }
4143
5966
 
4144
5967
  //#endregion
4145
- //#region src/switch/root/SwitchRoot.vue?vue&type=script&setup=true&lang.ts
4146
- const _hoisted_1 = [
4147
- "form",
4148
- "name",
4149
- "value"
4150
- ];
4151
- /**
4152
- * Represents the switch itself.
4153
- * Renders a `<span>` element and a hidden `<input>` beside.
4154
- *
4155
- * Documentation: [Base UI Vue Switch](https://baseui-vue.com/docs/components/switch)
4156
- */
4157
- var SwitchRoot_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
4158
- name: "SwitchRoot",
5968
+ //#region src/scroll-area/scrollbar/ScrollAreaScrollbarCssVars.ts
5969
+ let ScrollAreaScrollbarCssVars = /* @__PURE__ */ function(ScrollAreaScrollbarCssVars) {
5970
+ ScrollAreaScrollbarCssVars["scrollAreaThumbHeight"] = "--scroll-area-thumb-height";
5971
+ ScrollAreaScrollbarCssVars["scrollAreaThumbWidth"] = "--scroll-area-thumb-width";
5972
+ return ScrollAreaScrollbarCssVars;
5973
+ }({});
5974
+
5975
+ //#endregion
5976
+ //#region src/scroll-area/scrollbar/ScrollAreaScrollbar.vue?vue&type=script&setup=true&lang.ts
5977
+ var ScrollAreaScrollbar_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
5978
+ name: "ScrollAreaScrollbar",
4159
5979
  inheritAttrs: false,
4160
- __name: "SwitchRoot",
5980
+ __name: "ScrollAreaScrollbar",
4161
5981
  props: {
4162
- id: {
4163
- type: String,
4164
- required: false
4165
- },
4166
- checked: {
4167
- type: Boolean,
4168
- required: false
4169
- },
4170
- defaultChecked: {
4171
- type: Boolean,
4172
- required: false,
4173
- default: false
4174
- },
4175
- disabled: {
4176
- type: Boolean,
4177
- required: false,
4178
- default: false
4179
- },
4180
- inputRef: {
4181
- type: [
4182
- Object,
4183
- Function,
4184
- null
4185
- ],
4186
- required: false
4187
- },
4188
- name: {
4189
- type: String,
4190
- required: false
4191
- },
4192
- form: {
5982
+ orientation: {
4193
5983
  type: String,
4194
- required: false
4195
- },
4196
- readOnly: {
4197
- type: Boolean,
4198
- required: false,
4199
- default: false
4200
- },
4201
- required: {
4202
- type: Boolean,
4203
5984
  required: false,
4204
- default: false
4205
- },
4206
- value: {
4207
- type: String,
4208
- required: false
4209
- },
4210
- uncheckedValue: {
4211
- type: String,
4212
- required: false
4213
- },
4214
- "aria-labelledby": {
4215
- type: String,
4216
- required: false
5985
+ default: "vertical"
4217
5986
  },
4218
- nativeButton: {
5987
+ keepMounted: {
4219
5988
  type: Boolean,
4220
5989
  required: false,
4221
5990
  default: false
@@ -4223,7 +5992,7 @@ var SwitchRoot_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ def
4223
5992
  as: {
4224
5993
  type: null,
4225
5994
  required: false,
4226
- default: "span"
5995
+ default: "div"
4227
5996
  },
4228
5997
  class: {
4229
5998
  type: Function,
@@ -4243,217 +6012,292 @@ var SwitchRoot_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ def
4243
6012
  skipCheck: true
4244
6013
  }
4245
6014
  },
4246
- emits: ["checkedChange"],
4247
- setup(__props, { expose: __expose, emit: __emit }) {
6015
+ setup(__props) {
4248
6016
  const props = __props;
4249
- const emit = __emit;
4250
- const attrsObject = useAttrs();
4251
- const instance = getCurrentInstance();
4252
- const { clearErrors } = useFormContext();
4253
- const { disabled: fieldDisabled, name: fieldName, setDirty, setFilled, setFocused, setTouched, state: fieldState, validationMode, validityData, shouldValidateOnChange, validation } = useFieldRootContext();
4254
- const labelableContext = useLabelableContext();
4255
- const disabled = computed(() => fieldDisabled.value || props.disabled);
4256
- const name = computed(() => fieldName.value ?? props.name);
4257
- const rootElementId = useBaseUiId();
4258
- const controlId = useLabelableId({ id: () => props.id });
4259
- const inputId = computed(() => props.nativeButton ? void 0 : controlId.value);
4260
- const { value: checked, setValue: setCheckedState } = useControllableState({
4261
- controlled: () => instance?.vnode.props && Object.prototype.hasOwnProperty.call(instance.vnode.props, "checked") ? props.checked : void 0,
4262
- default: () => props.defaultChecked,
4263
- name: "Switch",
4264
- state: "checked"
4265
- });
4266
- const controlRef = ref(null);
4267
- const inputElementRef = ref(null);
4268
- const mergedInputRef = useMergedRefs(inputElementRef, props.inputRef);
4269
- useField({
4270
- id: computed(() => rootElementId),
4271
- commit: (value) => validation.commit(value),
4272
- value: checked,
4273
- controlRef,
4274
- name,
4275
- getValue: () => checked.value
4276
- });
4277
- const ariaLabelledBy = useAriaLabelledBy({
4278
- ariaLabelledBy: computed(() => props["aria-labelledby"]),
4279
- labelId: labelableContext.labelId,
4280
- labelSourceRef: inputElementRef,
4281
- enableFallback: !props.nativeButton,
4282
- labelSourceId: inputId
4283
- });
4284
- watchEffect(() => {
4285
- if (checked.value) setFilled(true);
4286
- });
4287
- watchEffect(() => {
4288
- if (!inputElementRef.value) return;
4289
- validation.setInputRef(inputElementRef.value);
6017
+ const attrs = useAttrs();
6018
+ const { hovering, scrollingX, scrollingY, hiddenState, overflowEdges, scrollbarYRef, scrollbarXRef, viewportRef, thumbYRef, thumbXRef, handlePointerDown, handlePointerUp, rootId, thumbSize, hasMeasuredScrollbar } = useScrollAreaRootContext();
6019
+ const direction = useDirection();
6020
+ let wheelCleanup;
6021
+ const scrollbarElementRef = shallowRef(null);
6022
+ watch([scrollbarElementRef, () => props.orientation], ([element, orientation], [previousElement, previousOrientation]) => {
6023
+ if (previousElement) {
6024
+ const previousRef = previousOrientation === "vertical" ? scrollbarYRef : scrollbarXRef;
6025
+ if (previousRef.value === previousElement) previousRef.value = null;
6026
+ }
6027
+ if (!element) return;
6028
+ const nextRef = orientation === "vertical" ? scrollbarYRef : scrollbarXRef;
6029
+ nextRef.value = element;
4290
6030
  });
4291
- watch(() => checked.value, (nextChecked) => {
4292
- clearErrors(name.value);
4293
- setFilled(nextChecked);
4294
- setDirty(nextChecked !== validityData.value.initialValue);
4295
- if (shouldValidateOnChange()) validation.commit(nextChecked);
4296
- else validation.commit(nextChecked, true);
4297
- }, { flush: "sync" });
4298
- const { getButtonProps, buttonRef } = useButton({
4299
- disabled,
4300
- native: computed(() => props.nativeButton)
6031
+ watch([
6032
+ scrollbarElementRef,
6033
+ viewportRef,
6034
+ () => props.orientation
6035
+ ], () => {
6036
+ wheelCleanup?.();
6037
+ wheelCleanup = setupWheelHandler();
6038
+ }, { flush: "post" });
6039
+ onBeforeUnmount(() => {
6040
+ wheelCleanup?.();
4301
6041
  });
4302
- function combineDescriptionProps(localProps, validationProps) {
4303
- const localDescribedBy = localProps["aria-describedby"];
4304
- const validationDescribedBy = validationProps["aria-describedby"];
4305
- const describedBy = Array.from(new Set([localDescribedBy, validationDescribedBy].filter(Boolean).flatMap((value) => String(value).split(/\s+/).filter(Boolean)))).join(" ") || void 0;
4306
- return {
4307
- ...localProps,
4308
- ...validationProps,
4309
- "aria-describedby": describedBy
4310
- };
6042
+ function setupWheelHandler() {
6043
+ const viewportEl = viewportRef.value;
6044
+ const scrollbarEl = scrollbarElementRef.value;
6045
+ if (!scrollbarEl) return void 0;
6046
+ function handleWheel(event) {
6047
+ if (!viewportEl || !scrollbarEl || event.ctrlKey) return;
6048
+ if (props.orientation === "vertical") {
6049
+ if (viewportEl.scrollTop === 0 && event.deltaY < 0) return;
6050
+ if (viewportEl.scrollTop === viewportEl.scrollHeight - viewportEl.clientHeight && event.deltaY > 0) return;
6051
+ event.preventDefault();
6052
+ viewportEl.scrollTop += event.deltaY;
6053
+ } else {
6054
+ if (viewportEl.scrollLeft === 0 && event.deltaX < 0) return;
6055
+ if (viewportEl.scrollLeft === viewportEl.scrollWidth - viewportEl.clientWidth && event.deltaX > 0) return;
6056
+ event.preventDefault();
6057
+ viewportEl.scrollLeft += event.deltaX;
6058
+ }
6059
+ }
6060
+ scrollbarEl.addEventListener("wheel", handleWheel, { passive: false });
6061
+ return () => scrollbarEl.removeEventListener("wheel", handleWheel);
4311
6062
  }
4312
- function applyCheckedChange(nextChecked, event, onApplied) {
4313
- const details = createChangeEventDetails(REASONS.none, event);
4314
- emit("checkedChange", nextChecked, details);
4315
- if (details.isCanceled) return false;
4316
- onApplied?.();
4317
- setCheckedState(nextChecked);
4318
- return true;
6063
+ function setScrollbarElement(element) {
6064
+ scrollbarElementRef.value = element;
6065
+ }
6066
+ const state = computed(() => ({
6067
+ hovering: hovering.value,
6068
+ scrolling: props.orientation === "horizontal" ? scrollingX.value : scrollingY.value,
6069
+ orientation: props.orientation,
6070
+ hasOverflowX: !hiddenState.value.x,
6071
+ hasOverflowY: !hiddenState.value.y,
6072
+ overflowXStart: overflowEdges.value.xStart,
6073
+ overflowXEnd: overflowEdges.value.xEnd,
6074
+ overflowYStart: overflowEdges.value.yStart,
6075
+ overflowYEnd: overflowEdges.value.yEnd,
6076
+ cornerHidden: hiddenState.value.corner
6077
+ }));
6078
+ const hideTrackUntilMeasured = computed(() => !hasMeasuredScrollbar.value && !props.keepMounted);
6079
+ function onPointerDown(event) {
6080
+ if (event.button !== 0) return;
6081
+ const target = getTarget(event);
6082
+ const thumb = props.orientation === "vertical" ? thumbYRef.value : thumbXRef.value;
6083
+ if (thumb && contains(thumb, target)) return;
6084
+ if (!viewportRef.value) return;
6085
+ if (thumbYRef.value && scrollbarYRef.value && props.orientation === "vertical") {
6086
+ const thumbYOffset = getOffset(thumbYRef.value, "margin", "y");
6087
+ const scrollbarYOffset = getOffset(scrollbarYRef.value, "padding", "y");
6088
+ const thumbHeight = thumbYRef.value.offsetHeight;
6089
+ const trackRectY = scrollbarYRef.value.getBoundingClientRect();
6090
+ const clickY = event.clientY - trackRectY.top - thumbHeight / 2 - scrollbarYOffset + thumbYOffset / 2;
6091
+ const scrollableContentHeight = viewportRef.value.scrollHeight;
6092
+ const viewportHeight = viewportRef.value.clientHeight;
6093
+ const scrollRatioY = clickY / (scrollbarYRef.value.offsetHeight - thumbHeight - scrollbarYOffset - thumbYOffset);
6094
+ viewportRef.value.scrollTop = scrollRatioY * (scrollableContentHeight - viewportHeight);
6095
+ }
6096
+ if (thumbXRef.value && scrollbarXRef.value && props.orientation === "horizontal") {
6097
+ const thumbXOffset = getOffset(thumbXRef.value, "margin", "x");
6098
+ const scrollbarXOffset = getOffset(scrollbarXRef.value, "padding", "x");
6099
+ const thumbWidth = thumbXRef.value.offsetWidth;
6100
+ const trackRectX = scrollbarXRef.value.getBoundingClientRect();
6101
+ const clickX = event.clientX - trackRectX.left - thumbWidth / 2 - scrollbarXOffset + thumbXOffset / 2;
6102
+ const scrollableContentWidth = viewportRef.value.scrollWidth;
6103
+ const viewportWidth = viewportRef.value.clientWidth;
6104
+ const scrollRatioX = clickX / (scrollbarXRef.value.offsetWidth - thumbWidth - scrollbarXOffset - thumbXOffset);
6105
+ let newScrollLeft;
6106
+ if (direction.value === "rtl") {
6107
+ newScrollLeft = (1 - scrollRatioX) * (scrollableContentWidth - viewportWidth);
6108
+ if (viewportRef.value.scrollLeft <= 0) newScrollLeft = -newScrollLeft;
6109
+ } else newScrollLeft = scrollRatioX * (scrollableContentWidth - viewportWidth);
6110
+ viewportRef.value.scrollLeft = newScrollLeft;
6111
+ }
6112
+ handlePointerDown(event);
6113
+ }
6114
+ const { tag, mergedProps, renderless, ref: renderRef } = useRenderElement({
6115
+ componentProps: props,
6116
+ state,
6117
+ props: computed(() => mergeProps$1(attrs, {
6118
+ ...rootId ? { "data-id": `${rootId}-scrollbar` } : {},
6119
+ onPointerdown: onPointerDown,
6120
+ onPointerup: handlePointerUp,
6121
+ style: {
6122
+ position: "absolute",
6123
+ touchAction: "none",
6124
+ WebkitUserSelect: "none",
6125
+ userSelect: "none",
6126
+ visibility: hideTrackUntilMeasured.value ? "hidden" : void 0,
6127
+ ...props.orientation === "vertical" && {
6128
+ top: 0,
6129
+ bottom: `var(${ScrollAreaRootCssVars.scrollAreaCornerHeight})`,
6130
+ insetInlineEnd: 0,
6131
+ [ScrollAreaScrollbarCssVars.scrollAreaThumbHeight]: `${thumbSize.value.height}px`
6132
+ },
6133
+ ...props.orientation === "horizontal" && {
6134
+ insetInlineStart: 0,
6135
+ insetInlineEnd: `var(${ScrollAreaRootCssVars.scrollAreaCornerWidth})`,
6136
+ bottom: 0,
6137
+ [ScrollAreaScrollbarCssVars.scrollAreaThumbWidth]: `${thumbSize.value.width}px`
6138
+ }
6139
+ }
6140
+ })),
6141
+ stateAttributesMapping: scrollAreaStateAttributesMapping,
6142
+ defaultTagName: "div",
6143
+ ref: setScrollbarElement
6144
+ });
6145
+ const isHidden = computed(() => props.orientation === "vertical" ? hiddenState.value.y : hiddenState.value.x);
6146
+ const shouldRender = computed(() => props.keepMounted || !isHidden.value);
6147
+ provide(scrollAreaScrollbarContextKey, { orientation: computed(() => props.orientation) });
6148
+ return (_ctx, _cache) => {
6149
+ return shouldRender.value ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [unref(renderless) ? renderSlot(_ctx.$slots, "default", {
6150
+ key: 0,
6151
+ ref: unref(renderRef),
6152
+ props: unref(mergedProps),
6153
+ state: state.value
6154
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), mergeProps({
6155
+ key: 1,
6156
+ ref: unref(renderRef)
6157
+ }, unref(mergedProps)), {
6158
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default")]),
6159
+ _: 3
6160
+ }, 16))], 64)) : createCommentVNode("v-if", true);
6161
+ };
6162
+ }
6163
+ });
6164
+
6165
+ //#endregion
6166
+ //#region src/scroll-area/scrollbar/ScrollAreaScrollbar.vue
6167
+ var ScrollAreaScrollbar_default = ScrollAreaScrollbar_vue_vue_type_script_setup_true_lang_default;
6168
+
6169
+ //#endregion
6170
+ //#region src/scroll-area/thumb/ScrollAreaThumb.vue?vue&type=script&setup=true&lang.ts
6171
+ var ScrollAreaThumb_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
6172
+ name: "ScrollAreaThumb",
6173
+ inheritAttrs: false,
6174
+ __name: "ScrollAreaThumb",
6175
+ props: {
6176
+ as: {
6177
+ type: null,
6178
+ required: false,
6179
+ default: "div"
6180
+ },
6181
+ class: {
6182
+ type: Function,
6183
+ required: false,
6184
+ skipCheck: true
6185
+ },
6186
+ style: {
6187
+ type: [
6188
+ Boolean,
6189
+ null,
6190
+ String,
6191
+ Object,
6192
+ Array,
6193
+ Function
6194
+ ],
6195
+ required: false,
6196
+ skipCheck: true
4319
6197
  }
4320
- function handleInputChange(event) {
4321
- const target = event.currentTarget;
4322
- if (props.readOnly || disabled.value) {
4323
- event.preventDefault();
4324
- event.stopPropagation();
4325
- target.checked = checked.value;
4326
- return;
6198
+ },
6199
+ setup(__props) {
6200
+ const props = __props;
6201
+ const attrs = useAttrs();
6202
+ const { thumbYRef, thumbXRef, handlePointerDown, handlePointerMove, handlePointerUp, setScrollingX, setScrollingY, hasMeasuredScrollbar } = useScrollAreaRootContext();
6203
+ const { orientation } = useScrollAreaScrollbarContext();
6204
+ const thumbElementRef = shallowRef(null);
6205
+ watch([thumbElementRef, orientation], ([element, currentOrientation], [previousElement, previousOrientation]) => {
6206
+ if (previousElement) {
6207
+ const previousRef = previousOrientation === "vertical" ? thumbYRef : thumbXRef;
6208
+ if (previousRef.value === previousElement) previousRef.value = null;
4327
6209
  }
4328
- if (!applyCheckedChange(target.checked, event)) target.checked = checked.value;
4329
- }
4330
- function handleRootClick(event) {
4331
- if (props.readOnly || disabled.value) return;
4332
- event.preventDefault();
4333
- const nextChecked = !checked.value;
4334
- applyCheckedChange(nextChecked, event, () => {
4335
- if (inputElementRef.value) inputElementRef.value.checked = nextChecked;
4336
- });
4337
- }
4338
- function handleFocus() {
4339
- if (!disabled.value) setFocused(true);
6210
+ if (!element) return;
6211
+ const nextRef = currentOrientation === "vertical" ? thumbYRef : thumbXRef;
6212
+ nextRef.value = element;
6213
+ });
6214
+ const state = computed(() => ({ orientation: orientation.value }));
6215
+ function onPointerUp(event) {
6216
+ if (orientation.value === "vertical") setScrollingY(false);
6217
+ if (orientation.value === "horizontal") setScrollingX(false);
6218
+ handlePointerUp(event);
4340
6219
  }
4341
- function handleBlur() {
4342
- if (disabled.value) return;
4343
- setTouched(true);
4344
- setFocused(false);
4345
- if (validationMode.value === "onBlur") validation.commit(checked.value);
6220
+ function setThumbElement(element) {
6221
+ thumbElementRef.value = element;
4346
6222
  }
4347
- const state = computed(() => ({
4348
- ...fieldState.value,
4349
- checked: checked.value,
4350
- disabled: disabled.value,
4351
- readOnly: props.readOnly,
4352
- required: props.required
4353
- }));
4354
- provide(switchRootContextKey, state);
4355
- __expose({ element: controlRef });
4356
- const mergedRootRef = useMergedRefs(buttonRef, controlRef);
4357
- const buttonInteractionAttrs = computed(() => ({
4358
- onClick: attrsObject.onClick,
4359
- onKeydown: attrsObject.onKeydown,
4360
- onKeyup: attrsObject.onKeyup,
4361
- onMousedown: attrsObject.onMousedown,
4362
- onPointerdown: attrsObject.onPointerdown
4363
- }));
4364
- const passthroughAttrs = computed(() => {
4365
- const { onClick, onKeydown, onKeyup, onMousedown, onPointerdown, ...rest } = attrsObject;
4366
- return rest;
4367
- });
4368
6223
  const { tag, mergedProps, renderless, ref: renderRef } = useRenderElement({
4369
6224
  componentProps: props,
4370
6225
  state,
4371
- props: computed(() => {
4372
- const localDescriptionProps = labelableContext.getDescriptionProps();
4373
- const validationProps = validation.getValidationProps();
4374
- return mergeProps$1(getButtonProps(mergeProps$1(buttonInteractionAttrs.value, { onClick: handleRootClick })), combineDescriptionProps(localDescriptionProps, validationProps), {
4375
- "id": props.nativeButton ? controlId.value : rootElementId,
4376
- "role": "switch",
4377
- "aria-checked": checked.value,
4378
- "aria-readonly": props.readOnly || void 0,
4379
- "aria-required": props.required || void 0,
4380
- "aria-labelledby": ariaLabelledBy.value,
4381
- "onFocus": handleFocus,
4382
- "onBlur": handleBlur
4383
- }, passthroughAttrs.value);
4384
- }),
4385
- stateAttributesMapping,
4386
- defaultTagName: "span",
4387
- ref: mergedRootRef
4388
- });
4389
- const inputProps = computed(() => {
4390
- const localDescriptionProps = labelableContext.getDescriptionProps();
4391
- const validationProps = validation.getInputValidationProps();
4392
- return mergeProps$1({
4393
- "checked": checked.value,
4394
- "disabled": disabled.value,
4395
- "form": props.form,
4396
- "id": props.nativeButton ? void 0 : inputId.value,
4397
- "name": name.value,
4398
- "required": props.required,
4399
- "type": "checkbox",
4400
- "aria-hidden": true,
4401
- "tabindex": -1,
4402
- "style": name.value ? visuallyHiddenInput : visuallyHidden,
4403
- "onChange": handleInputChange,
4404
- onFocus() {
4405
- controlRef.value?.focus();
6226
+ props: computed(() => mergeProps$1(attrs, {
6227
+ onPointerdown: handlePointerDown,
6228
+ onPointermove: handlePointerMove,
6229
+ onPointerup: onPointerUp,
6230
+ style: {
6231
+ visibility: hasMeasuredScrollbar.value ? void 0 : "hidden",
6232
+ ...orientation.value === "vertical" && { height: `var(${ScrollAreaScrollbarCssVars.scrollAreaThumbHeight})` },
6233
+ ...orientation.value === "horizontal" && { width: `var(${ScrollAreaScrollbarCssVars.scrollAreaThumbWidth})` }
4406
6234
  }
4407
- }, props.value !== void 0 ? { value: props.value } : EMPTY_OBJECT, combineDescriptionProps(localDescriptionProps, validationProps));
6235
+ })),
6236
+ defaultTagName: "div",
6237
+ ref: setThumbElement
4408
6238
  });
4409
6239
  return (_ctx, _cache) => {
4410
- return openBlock(), createElementBlock(Fragment, null, [
4411
- unref(renderless) ? renderSlot(_ctx.$slots, "default", {
4412
- key: 0,
4413
- ref: unref(renderRef),
4414
- props: unref(mergedProps),
4415
- state: state.value
4416
- }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), mergeProps({
4417
- key: 1,
4418
- ref: unref(renderRef)
4419
- }, unref(mergedProps)), {
4420
- default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: state.value })]),
4421
- _: 3
4422
- }, 16)),
4423
- !unref(checked) && !disabled.value && name.value && __props.uncheckedValue !== void 0 ? (openBlock(), createElementBlock("input", {
4424
- key: 2,
4425
- type: "hidden",
4426
- form: __props.form,
4427
- name: name.value,
4428
- value: __props.uncheckedValue
4429
- }, null, 8, _hoisted_1)) : createCommentVNode("v-if", true),
4430
- createElementVNode("input", mergeProps({ ref: unref(mergedInputRef) }, inputProps.value), null, 16)
4431
- ], 64);
6240
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
6241
+ key: 0,
6242
+ ref: unref(renderRef),
6243
+ props: unref(mergedProps),
6244
+ state: state.value
6245
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), mergeProps({
6246
+ key: 1,
6247
+ ref: unref(renderRef)
6248
+ }, unref(mergedProps)), null, 16));
4432
6249
  };
4433
6250
  }
4434
6251
  });
4435
6252
 
4436
6253
  //#endregion
4437
- //#region src/switch/root/SwitchRoot.vue
4438
- var SwitchRoot_default = SwitchRoot_vue_vue_type_script_setup_true_lang_default;
6254
+ //#region src/scroll-area/thumb/ScrollAreaThumb.vue
6255
+ var ScrollAreaThumb_default = ScrollAreaThumb_vue_vue_type_script_setup_true_lang_default;
4439
6256
 
4440
6257
  //#endregion
4441
- //#region src/switch/thumb/SwitchThumb.vue?vue&type=script&setup=true&lang.ts
4442
- /**
4443
- * The movable part of the switch that indicates whether the switch is on or off.
4444
- * Renders a `<span>`.
4445
- *
4446
- * Documentation: [Base UI Vue Switch](https://baseui-vue.com/docs/components/switch)
4447
- */
4448
- var SwitchThumb_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
4449
- name: "SwitchThumb",
6258
+ //#region src/scroll-area/thumb/ScrollAreaThumbDataAttributes.ts
6259
+ let ScrollAreaThumbDataAttributes = /* @__PURE__ */ function(ScrollAreaThumbDataAttributes) {
6260
+ ScrollAreaThumbDataAttributes["orientation"] = "data-orientation";
6261
+ return ScrollAreaThumbDataAttributes;
6262
+ }({});
6263
+
6264
+ //#endregion
6265
+ //#region src/utils/scrollEdges.ts
6266
+ const SCROLL_EDGE_TOLERANCE_PX = 1;
6267
+ function normalizeScrollOffset(value, max) {
6268
+ if (max <= 0) return 0;
6269
+ const clamped = clamp(value, 0, max);
6270
+ const startDistance = clamped;
6271
+ const endDistance = max - clamped;
6272
+ const withinStartTolerance = startDistance <= SCROLL_EDGE_TOLERANCE_PX;
6273
+ const withinEndTolerance = endDistance <= SCROLL_EDGE_TOLERANCE_PX;
6274
+ if (withinStartTolerance && withinEndTolerance) return startDistance <= endDistance ? 0 : max;
6275
+ if (withinStartTolerance) return 0;
6276
+ if (withinEndTolerance) return max;
6277
+ return clamped;
6278
+ }
6279
+
6280
+ //#endregion
6281
+ //#region src/scroll-area/viewport/ScrollAreaViewportCssVars.ts
6282
+ let ScrollAreaViewportCssVars = /* @__PURE__ */ function(ScrollAreaViewportCssVars) {
6283
+ ScrollAreaViewportCssVars["scrollAreaOverflowXStart"] = "--scroll-area-overflow-x-start";
6284
+ ScrollAreaViewportCssVars["scrollAreaOverflowXEnd"] = "--scroll-area-overflow-x-end";
6285
+ ScrollAreaViewportCssVars["scrollAreaOverflowYStart"] = "--scroll-area-overflow-y-start";
6286
+ ScrollAreaViewportCssVars["scrollAreaOverflowYEnd"] = "--scroll-area-overflow-y-end";
6287
+ return ScrollAreaViewportCssVars;
6288
+ }({});
6289
+
6290
+ //#endregion
6291
+ //#region src/scroll-area/viewport/ScrollAreaViewport.vue?vue&type=script&setup=true&lang.ts
6292
+ var ScrollAreaViewport_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
6293
+ name: "ScrollAreaViewport",
4450
6294
  inheritAttrs: false,
4451
- __name: "SwitchThumb",
6295
+ __name: "ScrollAreaViewport",
4452
6296
  props: {
4453
6297
  as: {
4454
6298
  type: null,
4455
6299
  required: false,
4456
- default: "span"
6300
+ default: "div"
4457
6301
  },
4458
6302
  class: {
4459
6303
  type: Function,
@@ -4475,31 +6319,248 @@ var SwitchThumb_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ de
4475
6319
  },
4476
6320
  setup(__props) {
4477
6321
  const props = __props;
4478
- const attrsObject = useAttrs();
4479
- const { state: fieldState } = useFieldRootContext();
4480
- const rootState = useSwitchRootContext();
4481
- const state = computed(() => ({
4482
- ...fieldState.value,
4483
- ...rootState.value
6322
+ const attrs = useAttrs();
6323
+ const { viewportRef, scrollbarYRef, scrollbarXRef, thumbYRef, thumbXRef, cornerRef, cornerSize, setCornerSize, setThumbSize, rootId, setHiddenState, hiddenState, setHasMeasuredScrollbar, handleScroll, setHovering, setOverflowEdges, overflowEdges, overflowEdgeThreshold, scrollingX, scrollingY } = useScrollAreaRootContext();
6324
+ const direction = useDirection();
6325
+ let programmaticScroll = true;
6326
+ const lastMeasuredViewportMetrics = [
6327
+ NaN,
6328
+ NaN,
6329
+ NaN,
6330
+ NaN
6331
+ ];
6332
+ let scrollEndTimeoutId;
6333
+ let waitForAnimationsTimeoutId;
6334
+ let resizeObserver;
6335
+ let scrollAreaOverflowVarsRegistered = false;
6336
+ function removeCSSVariableInheritance() {
6337
+ if (scrollAreaOverflowVarsRegistered) return;
6338
+ if (typeof navigator !== "undefined" && /AppleWebKit/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent)) return;
6339
+ if (typeof CSS !== "undefined" && "registerProperty" in CSS) {
6340
+ const vars = [
6341
+ ScrollAreaViewportCssVars.scrollAreaOverflowXStart,
6342
+ ScrollAreaViewportCssVars.scrollAreaOverflowXEnd,
6343
+ ScrollAreaViewportCssVars.scrollAreaOverflowYStart,
6344
+ ScrollAreaViewportCssVars.scrollAreaOverflowYEnd
6345
+ ];
6346
+ for (const name of vars) try {
6347
+ CSS.registerProperty({
6348
+ name,
6349
+ syntax: "<length>",
6350
+ inherits: false,
6351
+ initialValue: "0px"
6352
+ });
6353
+ } catch {}
6354
+ }
6355
+ scrollAreaOverflowVarsRegistered = true;
6356
+ }
6357
+ function computeThumbPosition() {
6358
+ const viewportEl = viewportRef.value;
6359
+ const scrollbarYEl = scrollbarYRef.value;
6360
+ const scrollbarXEl = scrollbarXRef.value;
6361
+ const thumbYEl = thumbYRef.value;
6362
+ const thumbXEl = thumbXRef.value;
6363
+ const cornerEl = cornerRef.value;
6364
+ if (!viewportEl) return;
6365
+ const scrollableContentHeight = viewportEl.scrollHeight;
6366
+ const scrollableContentWidth = viewportEl.scrollWidth;
6367
+ const viewportHeight = viewportEl.clientHeight;
6368
+ const viewportWidth = viewportEl.clientWidth;
6369
+ const scrollTop = viewportEl.scrollTop;
6370
+ const scrollLeft = viewportEl.scrollLeft;
6371
+ const isFirstMeasurement = Number.isNaN(lastMeasuredViewportMetrics[0]);
6372
+ lastMeasuredViewportMetrics[0] = viewportHeight;
6373
+ lastMeasuredViewportMetrics[1] = scrollableContentHeight;
6374
+ lastMeasuredViewportMetrics[2] = viewportWidth;
6375
+ lastMeasuredViewportMetrics[3] = scrollableContentWidth;
6376
+ if (isFirstMeasurement) setHasMeasuredScrollbar(true);
6377
+ if (scrollableContentHeight === 0 || scrollableContentWidth === 0) return;
6378
+ const nextHiddenState = getHiddenState(viewportEl);
6379
+ const scrollbarYHidden = nextHiddenState.y;
6380
+ const scrollbarXHidden = nextHiddenState.x;
6381
+ const ratioX = viewportWidth / scrollableContentWidth;
6382
+ const ratioY = viewportHeight / scrollableContentHeight;
6383
+ const maxScrollLeft = Math.max(0, scrollableContentWidth - viewportWidth);
6384
+ const maxScrollTop = Math.max(0, scrollableContentHeight - viewportHeight);
6385
+ let scrollLeftFromStart = 0;
6386
+ let scrollLeftFromEnd = 0;
6387
+ if (!scrollbarXHidden) {
6388
+ let rawScrollLeftFromStart = 0;
6389
+ if (direction.value === "rtl") rawScrollLeftFromStart = scrollLeft < 0 ? -scrollLeft : maxScrollLeft - scrollLeft;
6390
+ else rawScrollLeftFromStart = scrollLeft;
6391
+ rawScrollLeftFromStart = clamp(rawScrollLeftFromStart, 0, maxScrollLeft);
6392
+ scrollLeftFromStart = normalizeScrollOffset(rawScrollLeftFromStart, maxScrollLeft);
6393
+ scrollLeftFromEnd = maxScrollLeft - scrollLeftFromStart;
6394
+ }
6395
+ const rawScrollTopFromStart = !scrollbarYHidden ? clamp(scrollTop, 0, maxScrollTop) : 0;
6396
+ const scrollTopFromStart = !scrollbarYHidden ? normalizeScrollOffset(rawScrollTopFromStart, maxScrollTop) : 0;
6397
+ const scrollTopFromEnd = !scrollbarYHidden ? maxScrollTop - scrollTopFromStart : 0;
6398
+ const nextWidth = scrollbarXHidden ? 0 : viewportWidth;
6399
+ const nextHeight = scrollbarYHidden ? 0 : viewportHeight;
6400
+ let nextCornerWidth = 0;
6401
+ let nextCornerHeight = 0;
6402
+ if (!scrollbarXHidden && !scrollbarYHidden) {
6403
+ nextCornerWidth = scrollbarYEl?.offsetWidth || 0;
6404
+ nextCornerHeight = scrollbarXEl?.offsetHeight || 0;
6405
+ }
6406
+ const cornerNotYetSized = cornerSize.value.width === 0 && cornerSize.value.height === 0;
6407
+ const cornerWidthOffset = cornerNotYetSized ? nextCornerWidth : 0;
6408
+ const cornerHeightOffset = cornerNotYetSized ? nextCornerHeight : 0;
6409
+ const scrollbarXOffset = getOffset(scrollbarXEl, "padding", "x");
6410
+ const scrollbarYOffset = getOffset(scrollbarYEl, "padding", "y");
6411
+ const thumbXOffset = getOffset(thumbXEl, "margin", "x");
6412
+ const thumbYOffset = getOffset(thumbYEl, "margin", "y");
6413
+ const idealNextWidth = nextWidth - scrollbarXOffset - thumbXOffset;
6414
+ const idealNextHeight = nextHeight - scrollbarYOffset - thumbYOffset;
6415
+ const maxNextWidth = scrollbarXEl ? Math.min(scrollbarXEl.offsetWidth - cornerWidthOffset, idealNextWidth) : idealNextWidth;
6416
+ const maxNextHeight = scrollbarYEl ? Math.min(scrollbarYEl.offsetHeight - cornerHeightOffset, idealNextHeight) : idealNextHeight;
6417
+ const clampedNextWidth = Math.max(MIN_THUMB_SIZE, maxNextWidth * ratioX);
6418
+ const clampedNextHeight = Math.max(MIN_THUMB_SIZE, maxNextHeight * ratioY);
6419
+ setThumbSize({
6420
+ width: clampedNextWidth,
6421
+ height: clampedNextHeight
6422
+ });
6423
+ if (scrollbarYEl && thumbYEl) {
6424
+ const maxThumbOffsetY = scrollbarYEl.offsetHeight - clampedNextHeight - scrollbarYOffset - thumbYOffset;
6425
+ const scrollRangeY = scrollableContentHeight - viewportHeight;
6426
+ const scrollRatioY = scrollRangeY === 0 ? 0 : scrollTop / scrollRangeY;
6427
+ const thumbOffsetY = Math.min(maxThumbOffsetY, Math.max(0, scrollRatioY * maxThumbOffsetY));
6428
+ thumbYEl.style.transform = `translate3d(0,${thumbOffsetY}px,0)`;
6429
+ }
6430
+ if (scrollbarXEl && thumbXEl) {
6431
+ const maxThumbOffsetX = scrollbarXEl.offsetWidth - clampedNextWidth - scrollbarXOffset - thumbXOffset;
6432
+ const scrollRangeX = scrollableContentWidth - viewportWidth;
6433
+ const scrollRatioX = scrollRangeX === 0 ? 0 : scrollLeftFromStart / scrollRangeX;
6434
+ const thumbOffsetX = direction.value === "rtl" ? -clamp(scrollRatioX * maxThumbOffsetX, 0, maxThumbOffsetX) : clamp(scrollRatioX * maxThumbOffsetX, 0, maxThumbOffsetX);
6435
+ thumbXEl.style.transform = `translate3d(${thumbOffsetX}px,0,0)`;
6436
+ }
6437
+ const overflowMetricsPx = [
6438
+ [ScrollAreaViewportCssVars.scrollAreaOverflowXStart, scrollLeftFromStart],
6439
+ [ScrollAreaViewportCssVars.scrollAreaOverflowXEnd, scrollLeftFromEnd],
6440
+ [ScrollAreaViewportCssVars.scrollAreaOverflowYStart, scrollTopFromStart],
6441
+ [ScrollAreaViewportCssVars.scrollAreaOverflowYEnd, scrollTopFromEnd]
6442
+ ];
6443
+ for (const [cssVar, value] of overflowMetricsPx) viewportEl.style.setProperty(cssVar, `${value}px`);
6444
+ if (cornerEl) if (scrollbarXHidden || scrollbarYHidden) setCornerSize({
6445
+ width: 0,
6446
+ height: 0
6447
+ });
6448
+ else setCornerSize({
6449
+ width: nextCornerWidth,
6450
+ height: nextCornerHeight
6451
+ });
6452
+ setHiddenState(mergeHiddenState(hiddenState.value, nextHiddenState));
6453
+ const threshold = overflowEdgeThreshold.value;
6454
+ const nextOverflowEdges = {
6455
+ xStart: !scrollbarXHidden && scrollLeftFromStart > threshold.xStart,
6456
+ xEnd: !scrollbarXHidden && scrollLeftFromEnd > threshold.xEnd,
6457
+ yStart: !scrollbarYHidden && scrollTopFromStart > threshold.yStart,
6458
+ yEnd: !scrollbarYHidden && scrollTopFromEnd > threshold.yEnd
6459
+ };
6460
+ const prev = overflowEdges.value;
6461
+ if (prev.xStart !== nextOverflowEdges.xStart || prev.xEnd !== nextOverflowEdges.xEnd || prev.yStart !== nextOverflowEdges.yStart || prev.yEnd !== nextOverflowEdges.yEnd) setOverflowEdges(nextOverflowEdges);
6462
+ }
6463
+ function handleUserInteraction() {
6464
+ programmaticScroll = false;
6465
+ }
6466
+ function onScroll() {
6467
+ if (!viewportRef.value) return;
6468
+ computeThumbPosition();
6469
+ if (!programmaticScroll) handleScroll({
6470
+ x: viewportRef.value.scrollLeft,
6471
+ y: viewportRef.value.scrollTop
6472
+ });
6473
+ clearTimeout(scrollEndTimeoutId);
6474
+ scrollEndTimeoutId = setTimeout(() => {
6475
+ programmaticScroll = true;
6476
+ }, 100);
6477
+ }
6478
+ const viewportState = computed(() => ({
6479
+ scrolling: scrollingX.value || scrollingY.value,
6480
+ hasOverflowX: !hiddenState.value.x,
6481
+ hasOverflowY: !hiddenState.value.y,
6482
+ overflowXStart: overflowEdges.value.xStart,
6483
+ overflowXEnd: overflowEdges.value.xEnd,
6484
+ overflowYStart: overflowEdges.value.yStart,
6485
+ overflowYEnd: overflowEdges.value.yEnd,
6486
+ cornerHidden: hiddenState.value.corner
4484
6487
  }));
4485
6488
  const { tag, mergedProps, renderless, ref: renderRef } = useRenderElement({
4486
6489
  componentProps: props,
4487
- state,
4488
- props: computed(() => attrsObject),
4489
- stateAttributesMapping,
4490
- defaultTagName: "span"
6490
+ state: viewportState,
6491
+ props: computed(() => mergeProps$1(attrs, {
6492
+ role: "presentation",
6493
+ ...rootId ? { "data-id": `${rootId}-viewport` } : {},
6494
+ tabindex: hiddenState.value.x && hiddenState.value.y ? -1 : 0,
6495
+ class: styleDisableScrollbar.className,
6496
+ style: { overflow: "scroll" },
6497
+ onScroll,
6498
+ onWheel: handleUserInteraction,
6499
+ onTouchmove: handleUserInteraction,
6500
+ onPointermove: handleUserInteraction,
6501
+ onPointerenter: handleUserInteraction,
6502
+ onKeydown: handleUserInteraction
6503
+ })),
6504
+ stateAttributesMapping: scrollAreaStateAttributesMapping,
6505
+ defaultTagName: "div",
6506
+ ref: viewportRef
4491
6507
  });
6508
+ onMounted(() => {
6509
+ removeCSSVariableInheritance();
6510
+ if (viewportRef.value?.matches(":hover")) setHovering(true);
6511
+ queueMicrotask(computeThumbPosition);
6512
+ const viewport = viewportRef.value;
6513
+ if (typeof ResizeObserver !== "undefined" && viewport) {
6514
+ let hasInitialized = false;
6515
+ resizeObserver = new ResizeObserver(() => {
6516
+ if (!hasInitialized) {
6517
+ hasInitialized = true;
6518
+ if (lastMeasuredViewportMetrics[0] === viewport.clientHeight && lastMeasuredViewportMetrics[1] === viewport.scrollHeight && lastMeasuredViewportMetrics[2] === viewport.clientWidth && lastMeasuredViewportMetrics[3] === viewport.scrollWidth) return;
6519
+ }
6520
+ computeThumbPosition();
6521
+ });
6522
+ resizeObserver.observe(viewport);
6523
+ waitForAnimationsTimeoutId = setTimeout(() => {
6524
+ const animations = viewport.getAnimations({ subtree: true });
6525
+ if (animations.length === 0) return;
6526
+ Promise.allSettled(animations.map((a) => a.finished)).then(computeThumbPosition);
6527
+ }, 0);
6528
+ }
6529
+ });
6530
+ watch([hiddenState, direction], () => {
6531
+ queueMicrotask(computeThumbPosition);
6532
+ });
6533
+ watch(overflowEdgeThreshold, computeThumbPosition);
6534
+ onBeforeUnmount(() => {
6535
+ resizeObserver?.disconnect();
6536
+ clearTimeout(scrollEndTimeoutId);
6537
+ clearTimeout(waitForAnimationsTimeoutId);
6538
+ });
6539
+ provide(scrollAreaViewportContextKey, { computeThumbPosition });
6540
+ function getHiddenState(viewport) {
6541
+ const y = viewport.clientHeight >= viewport.scrollHeight;
6542
+ const x = viewport.clientWidth >= viewport.scrollWidth;
6543
+ return {
6544
+ y,
6545
+ x,
6546
+ corner: y || x
6547
+ };
6548
+ }
6549
+ function mergeHiddenState(prevState, nextState) {
6550
+ if (prevState.y === nextState.y && prevState.x === nextState.x && prevState.corner === nextState.corner) return prevState;
6551
+ return nextState;
6552
+ }
4492
6553
  return (_ctx, _cache) => {
4493
6554
  return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
4494
6555
  key: 0,
4495
6556
  ref: unref(renderRef),
4496
6557
  props: unref(mergedProps),
4497
- state: state.value
6558
+ state: viewportState.value
4498
6559
  }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), mergeProps({
4499
6560
  key: 1,
4500
6561
  ref: unref(renderRef)
4501
6562
  }, unref(mergedProps)), {
4502
- default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: state.value })]),
6563
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default")]),
4503
6564
  _: 3
4504
6565
  }, 16));
4505
6566
  };
@@ -4507,57 +6568,20 @@ var SwitchThumb_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ de
4507
6568
  });
4508
6569
 
4509
6570
  //#endregion
4510
- //#region src/switch/thumb/SwitchThumb.vue
4511
- var SwitchThumb_default = SwitchThumb_vue_vue_type_script_setup_true_lang_default;
6571
+ //#region src/scroll-area/viewport/ScrollAreaViewport.vue
6572
+ var ScrollAreaViewport_default = ScrollAreaViewport_vue_vue_type_script_setup_true_lang_default;
4512
6573
 
4513
6574
  //#endregion
4514
- //#region src/switch/thumb/SwitchThumbDataAttributes.ts
4515
- let SwitchThumbDataAttributes = /* @__PURE__ */ function(SwitchThumbDataAttributes) {
4516
- /**
4517
- * Present when the switch is checked.
4518
- */
4519
- SwitchThumbDataAttributes["checked"] = "data-checked";
4520
- /**
4521
- * Present when the switch is not checked.
4522
- */
4523
- SwitchThumbDataAttributes["unchecked"] = "data-unchecked";
4524
- /**
4525
- * Present when the switch is disabled.
4526
- */
4527
- SwitchThumbDataAttributes["disabled"] = "data-disabled";
4528
- /**
4529
- * Present when the switch is readonly.
4530
- */
4531
- SwitchThumbDataAttributes["readonly"] = "data-readonly";
4532
- /**
4533
- * Present when the switch is required.
4534
- */
4535
- SwitchThumbDataAttributes["required"] = "data-required";
4536
- /**
4537
- * Present when the switch is in valid state (when wrapped in FieldRoot).
4538
- */
4539
- SwitchThumbDataAttributes["valid"] = "data-valid";
4540
- /**
4541
- * Present when the switch is in invalid state (when wrapped in FieldRoot).
4542
- */
4543
- SwitchThumbDataAttributes["invalid"] = "data-invalid";
4544
- /**
4545
- * Present when the switch has been touched (when wrapped in FieldRoot).
4546
- */
4547
- SwitchThumbDataAttributes["touched"] = "data-touched";
4548
- /**
4549
- * Present when the switch's value has changed (when wrapped in FieldRoot).
4550
- */
4551
- SwitchThumbDataAttributes["dirty"] = "data-dirty";
4552
- /**
4553
- * Present when the switch is active (when wrapped in FieldRoot).
4554
- */
4555
- SwitchThumbDataAttributes["filled"] = "data-filled";
4556
- /**
4557
- * Present when the switch is focused (when wrapped in FieldRoot).
4558
- */
4559
- SwitchThumbDataAttributes["focused"] = "data-focused";
4560
- return SwitchThumbDataAttributes;
6575
+ //#region src/scroll-area/viewport/ScrollAreaViewportDataAttributes.ts
6576
+ let ScrollAreaViewportDataAttributes = /* @__PURE__ */ function(ScrollAreaViewportDataAttributes) {
6577
+ ScrollAreaViewportDataAttributes["scrolling"] = "data-scrolling";
6578
+ ScrollAreaViewportDataAttributes["hasOverflowX"] = "data-has-overflow-x";
6579
+ ScrollAreaViewportDataAttributes["hasOverflowY"] = "data-has-overflow-y";
6580
+ ScrollAreaViewportDataAttributes["overflowXStart"] = "data-overflow-x-start";
6581
+ ScrollAreaViewportDataAttributes["overflowXEnd"] = "data-overflow-x-end";
6582
+ ScrollAreaViewportDataAttributes["overflowYStart"] = "data-overflow-y-start";
6583
+ ScrollAreaViewportDataAttributes["overflowYEnd"] = "data-overflow-y-end";
6584
+ return ScrollAreaViewportDataAttributes;
4561
6585
  }({});
4562
6586
 
4563
6587
  //#endregion
@@ -5709,5 +7733,5 @@ const name = "base-ui-vue";
5709
7733
  const version = "0.0.0";
5710
7734
 
5711
7735
  //#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 };
7736
+ 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, 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, meterRootContextKey, name, progressRootContextKey, progressStateAttributesMapping, switchRootContextKey, toggleGroupContextKey, useAccordionRootContext, useCollapsibleRootContext, useFieldsetRootContext, useMeterRootContext, useProgressRootContext, useRender, useSwitchRootContext, useToggleGroupContext, version };
5713
7737
  //# sourceMappingURL=index2.js.map