{"version":3,"file":"SliderRoot.cjs","sources":["../../src/Slider/SliderRoot.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { ComputedRef, Ref } from 'vue'\nimport type { PrimitiveProps } from '@/Primitive'\nimport type { DataOrientation, Direction, FormFieldProps } from '../shared/types'\nimport { clamp, createContext, useDirection, useFormControl, useForwardExpose } from '@/shared'\nimport { useCollection } from '@/Collection'\n\ntype ThumbAlignment = 'contain' | 'overflow'\n\nexport interface SliderRootProps extends PrimitiveProps, FormFieldProps {\n  /** The value of the slider when initially rendered. Use when you do not need to control the state of the slider. */\n  defaultValue?: number[]\n  /** The controlled value of the slider. Can be bind as `v-model`. */\n  modelValue?: number[] | null\n  /** When `true`, prevents the user from interacting with the slider. */\n  disabled?: boolean\n  /** The orientation of the slider. */\n  orientation?: DataOrientation\n  /** The reading direction of the combobox when applicable. <br> If omitted, inherits globally from `ConfigProvider` or assumes LTR (left-to-right) reading mode. */\n  dir?: Direction\n  /** Whether the slider is visually inverted. */\n  inverted?: boolean\n  /** The minimum value for the range. */\n  min?: number\n  /** The maximum value for the range. */\n  max?: number\n  /** The stepping interval. */\n  step?: number\n  /** The minimum permitted steps between multiple thumbs. */\n  minStepsBetweenThumbs?: number\n  /**\n   * The alignment of the slider thumb.\n   * - `contain`: thumbs will be contained within the bounds of the track.\n   * - `overflow`: thumbs will not be bound by the track. No extra offset will be added.\n   * @defaultValue 'contain'\n   */\n  thumbAlignment?: ThumbAlignment\n}\n\nexport type SliderRootEmits = {\n  /**\n   * Event handler called when the slider value changes\n   */\n  'update:modelValue': [payload: number[] | undefined]\n  /**\n   * Event handler called when the value changes at the end of an interaction.\n   *\n   * Useful when you only need to capture a final value e.g. to update a backend service.\n   */\n  'valueCommit': [payload: number[]]\n}\n\nexport interface SliderRootContext {\n  orientation: Ref<DataOrientation>\n  disabled: Ref<boolean>\n  min: Ref<number>\n  max: Ref<number>\n  modelValue?: Readonly<Ref<number[] | null | undefined>>\n  currentModelValue: ComputedRef<number[]>\n  valueIndexToChangeRef: Ref<number>\n  thumbElements: Ref<HTMLElement[]>\n  thumbAlignment: Ref<ThumbAlignment>\n}\n\nexport const [injectSliderRootContext, provideSliderRootContext]\n  = createContext<SliderRootContext>('SliderRoot')\n</script>\n\n<script setup lang=\"ts\">\nimport SliderHorizontal from './SliderHorizontal.vue'\nimport SliderVertical from './SliderVertical.vue'\nimport { computed, ref, toRaw, toRefs } from 'vue'\nimport { useVModel } from '@vueuse/core'\nimport { ARROW_KEYS, PAGE_KEYS, getClosestValueIndex, getDecimalCount, getNextSortedValues, hasMinStepsBetweenValues, roundValue } from './utils'\nimport { VisuallyHiddenInput } from '@/VisuallyHidden'\n\ndefineOptions({\n  inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<SliderRootProps>(), {\n  min: 0,\n  max: 100,\n  step: 1,\n  orientation: 'horizontal',\n  disabled: false,\n  minStepsBetweenThumbs: 0,\n  defaultValue: () => [0],\n  inverted: false,\n  thumbAlignment: 'contain',\n  as: 'span',\n})\nconst emits = defineEmits<SliderRootEmits>()\n\ndefineSlots<{\n  default: (props: {\n    /** Current slider values */\n    modelValue: typeof modelValue.value\n  }) => any\n}>()\n\nconst { min, max, step, minStepsBetweenThumbs, orientation, disabled, thumbAlignment, dir: propDir } = toRefs(props)\nconst dir = useDirection(propDir)\nconst { forwardRef, currentElement } = useForwardExpose()\nconst isFormControl = useFormControl(currentElement)\n\nconst { CollectionSlot } = useCollection({ isProvider: true })\n\nconst modelValue = useVModel(props, 'modelValue', emits, {\n  defaultValue: props.defaultValue,\n  passive: (props.modelValue === undefined) as false,\n}) as Ref<number[] | null>\n\nconst currentModelValue = computed(() => Array.isArray(modelValue.value) ? [...modelValue.value] : [])\n\nconst valueIndexToChangeRef = ref(0)\nconst valuesBeforeSlideStartRef = ref(currentModelValue.value)\n\nfunction handleSlideStart(value: number) {\n  const closestIndex = getClosestValueIndex(currentModelValue.value, value)\n  updateValues(value, closestIndex)\n}\n\nfunction handleSlideMove(value: number) {\n  updateValues(value, valueIndexToChangeRef.value)\n}\n\nfunction handleSlideEnd() {\n  const prevValue = valuesBeforeSlideStartRef.value[valueIndexToChangeRef.value]\n  const nextValue = currentModelValue.value[valueIndexToChangeRef.value]\n  const hasChanged = nextValue !== prevValue\n  if (hasChanged)\n    emits('valueCommit', toRaw(currentModelValue.value))\n}\n\nfunction updateValues(value: number, atIndex: number, { commit } = { commit: false }) {\n  const decimalCount = getDecimalCount(step.value)\n  const snapToStep = roundValue(Math.round((value - min.value) / step.value) * step.value + min.value, decimalCount)\n  const nextValue = clamp(snapToStep, min.value, max.value)\n\n  const nextValues = getNextSortedValues(currentModelValue.value, nextValue, atIndex)\n\n  if (hasMinStepsBetweenValues(nextValues, minStepsBetweenThumbs.value * step.value)) {\n    valueIndexToChangeRef.value = nextValues.indexOf(nextValue)\n    const hasChanged = String(nextValues) !== String(modelValue.value)\n    if (hasChanged && commit)\n      emits('valueCommit', nextValues)\n\n    if (hasChanged) {\n      thumbElements.value[valueIndexToChangeRef.value]?.focus()\n      modelValue.value = nextValues\n    }\n  }\n}\n\nconst thumbElements = ref<HTMLElement[]>([])\nprovideSliderRootContext({\n  modelValue,\n  currentModelValue,\n  valueIndexToChangeRef,\n  thumbElements,\n  orientation,\n  min,\n  max,\n  disabled,\n  thumbAlignment,\n})\n</script>\n\n<template>\n  <CollectionSlot>\n    <component\n      :is=\"orientation === 'horizontal' ? SliderHorizontal : SliderVertical\"\n      v-bind=\"$attrs\"\n      :ref=\"forwardRef\"\n      :as-child=\"asChild\"\n      :as=\"as\"\n      :min=\"min\"\n      :max=\"max\"\n      :dir=\"dir\"\n      :inverted=\"inverted\"\n      :aria-disabled=\"disabled\"\n      :data-disabled=\"disabled ? '' : undefined\"\n      @pointerdown=\"() => {\n        if (!disabled) valuesBeforeSlideStartRef = currentModelValue\n      }\"\n      @slide-start=\"!disabled && handleSlideStart($event)\"\n      @slide-move=\"!disabled && handleSlideMove($event)\"\n      @slide-end=\"!disabled && handleSlideEnd()\"\n      @home-key-down=\"!disabled && updateValues(min, 0, { commit: true })\"\n      @end-key-down=\"!disabled && updateValues(max, currentModelValue.length - 1, { commit: true })\"\n      @step-key-down=\"(event, direction) => {\n        if (!disabled) {\n          const isPageKey = PAGE_KEYS.includes(event.key);\n          const isSkipKey = isPageKey || (event.shiftKey && ARROW_KEYS.includes(event.key));\n          const multiplier = isSkipKey ? 10 : 1;\n          const atIndex = valueIndexToChangeRef;\n          const value = currentModelValue[atIndex];\n          const stepInDirection = step * multiplier * direction;\n          updateValues(value + stepInDirection, atIndex, { commit: true });\n        }\n      }\"\n    >\n      <slot :model-value=\"modelValue\" />\n\n      <VisuallyHiddenInput\n        v-if=\"isFormControl && name\"\n        type=\"number\"\n        :value=\"modelValue\"\n        :name=\"name\"\n        :required=\"required\"\n        :disabled=\"disabled\"\n        :step=\"step\"\n      />\n    </component>\n  </CollectionSlot>\n</template>\n"],"names":["createContext","toRefs","useDirection","useForwardExpose","useFormControl","useCollection","useVModel","computed","ref","getClosestValueIndex","toRaw","getDecimalCount","roundValue","clamp","getNextSortedValues","hasMinStepsBetweenValues"],"mappings":"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"}