internals

Use slider Input

Composable use-slider-input() — VueUse-порт одноимённого хука ReUI.

Загрузка превью…

src/composables/use-slider-input.ts

/**
 * Порт `useSliderInput` (registry-reui/bases/radix/hooks/use-slider-input.ts, MIT).
 *
 * Не завязан на React-специфичные хуки общего назначения (`useState`/
 * `useCallback`) — переносится на `ref`/обычные функции (в Vue отдельный
 * `useCallback`-аналог не нужен, см. docs/PORTING.md, раздел 2).
 * Сигнатура возврата сохранена буквально: `sliderValues`/`inputValues`
 * (здесь — реактивные `Ref`), `setSliderValues`/`setInputValues` (здесь —
 * тонкие функции-сеттеры поверх тех же `Ref`, 1:1 с `setState`-сеттерами
 * оригинала), `handleSliderChange`/`handleInputChange`/`validateAndUpdateValue`.
 */
import { ref } from "vue"

export interface UseSliderInputOptions {
  minValue: number
  maxValue: number
  initialValue: [number, number]
}

export function useSliderInput({ minValue, maxValue, initialValue }: UseSliderInputOptions) {
  const sliderValues = ref<[number, number]>([...initialValue])
  const inputValues = ref<[number, number]>([...initialValue])

  function setSliderValues(values: [number, number]) {
    sliderValues.value = values
  }

  function setInputValues(values: [number, number]) {
    inputValues.value = values
  }

  // Handle slider changes and sync with input values
  function handleSliderChange(values: [number, number]) {
    sliderValues.value = values
    inputValues.value = values
  }

  // Handle input changes for min or max
  function handleInputChange(e: Event, index: 0 | 1) {
    const target = e.target as HTMLInputElement
    const newValue = Number.parseFloat(target.value)
    if (!Number.isNaN(newValue)) {
      const updatedInputs = [...inputValues.value] as [number, number]
      updatedInputs[index] = newValue
      inputValues.value = updatedInputs
    }
  }

  // Validate and update slider values when input loses focus or user presses Enter
  function validateAndUpdateValue(value: number, index: 0 | 1) {
    const updatedSlider = [...sliderValues.value] as [number, number]

    if (index === 0) {
      // Min value
      updatedSlider[0] = Math.max(minValue, Math.min(value, sliderValues.value[1]))
    } else {
      // Max value
      updatedSlider[1] = Math.min(maxValue, Math.max(value, sliderValues.value[0]))
    }

    sliderValues.value = updatedSlider
    inputValues.value = updatedSlider
  }

  return {
    setSliderValues,
    setInputValues,
    sliderValues,
    inputValues,
    handleSliderChange,
    handleInputChange,
    validateAndUpdateValue,
  }
}

Установка

npx shadcn-vue@latest add https://revueui.rootapi.dev/r/use-slider-input.json

Источник: порт из ReUI (Keenthemes, MIT)