UNPKG

vuetify

Version:

Vue Material Component Framework

173 lines (172 loc) 6.06 kB
import { normalizeClass as _normalizeClass, createElementVNode as _createElementVNode, normalizeStyle as _normalizeStyle, withDirectives as _withDirectives, vShow as _vShow, createVNode as _createVNode } from "vue"; // Styles import "./VSliderThumb.css"; // Components import { VSliderSymbol } from "./slider.js"; import { VScaleTransition } from "../transitions/index.js"; // Composables import { useTextColor } from "../../composables/color.js"; import { makeComponentProps } from "../../composables/component.js"; import { useElevation } from "../../composables/elevation.js"; import { useRtl } from "../../composables/locale.js"; // Directives import vRipple from "../../directives/ripple/index.js"; // Utilities import { computed, inject } from 'vue'; import { convertToUnit, genericComponent, keyValues, propsFactory, useRender } from "../../util/index.js"; // Types export const makeVSliderThumbProps = propsFactory({ focused: Boolean, max: { type: Number, required: true }, min: { type: Number, required: true }, modelValue: { type: Number, required: true }, position: { type: Number, required: true }, ripple: { type: [Boolean, Object], default: true }, name: String, ...makeComponentProps() }, 'VSliderThumb'); export const VSliderThumb = genericComponent()({ name: 'VSliderThumb', directives: { vRipple }, props: makeVSliderThumbProps(), emits: { 'update:modelValue': v => true }, setup(props, _ref) { let { slots, emit } = _ref; const slider = inject(VSliderSymbol); const { isRtl, rtlClasses } = useRtl(); if (!slider) throw new Error('[Vuetify] v-slider-thumb must be used inside v-slider or v-range-slider'); const { min, max, thumbColor, step, disabled, thumbSize, thumbLabel, direction, isReversed, vertical, readonly, elevation, mousePressed, decimals, indexFromEnd } = slider; const elevationProps = computed(() => !disabled.value ? elevation.value : undefined); const { elevationClasses } = useElevation(elevationProps); const { textColorClasses, textColorStyles } = useTextColor(thumbColor); const { pageup, pagedown, end, home, left, right, down, up } = keyValues; const relevantKeys = [pageup, pagedown, end, home, left, right, down, up]; const multipliers = computed(() => { if (step.value) return [1, 2, 3];else return [1, 5, 10]; }); function parseKeydown(e, value) { if (!relevantKeys.includes(e.key)) return; e.preventDefault(); const _step = step.value || 0.1; const steps = (max.value - min.value) / _step; if ([left, right, down, up].includes(e.key)) { const increase = vertical.value ? [isRtl.value ? left : right, isReversed.value ? down : up] : indexFromEnd.value !== isRtl.value ? [left, up] : [right, up]; const direction = increase.includes(e.key) ? 1 : -1; const multiplier = e.shiftKey ? 2 : e.ctrlKey ? 1 : 0; if (direction === -1 && value === max.value && !multiplier && !Number.isInteger(steps)) { value = value - steps % 1 * _step; } else { value = value + direction * _step * multipliers.value[multiplier]; } } else if (e.key === home) { value = min.value; } else if (e.key === end) { value = max.value; } else { const direction = e.key === pagedown ? 1 : -1; value = value - direction * _step * (steps > 100 ? steps / 10 : 10); } return Math.max(props.min, Math.min(props.max, value)); } function onKeydown(e) { const newValue = parseKeydown(e, props.modelValue); newValue != null && emit('update:modelValue', newValue); } useRender(() => { const positionPercentage = convertToUnit(indexFromEnd.value ? 100 - props.position : props.position, '%'); return _createElementVNode("div", { "class": _normalizeClass(['v-slider-thumb', { 'v-slider-thumb--focused': props.focused, 'v-slider-thumb--pressed': props.focused && mousePressed.value }, props.class, rtlClasses.value]), "style": _normalizeStyle([{ '--v-slider-thumb-position': positionPercentage, '--v-slider-thumb-size': convertToUnit(thumbSize.value) }, props.style]), "role": "slider", "tabindex": disabled.value ? -1 : 0, "aria-label": props.name, "aria-valuemin": min.value, "aria-valuemax": max.value, "aria-valuenow": props.modelValue, "aria-readonly": !!readonly.value, "aria-orientation": direction.value, "onKeydown": !readonly.value ? onKeydown : undefined }, [_createElementVNode("div", { "class": _normalizeClass(['v-slider-thumb__surface', textColorClasses.value, elevationClasses.value]), "style": { ...textColorStyles.value } }, null), _withDirectives(_createElementVNode("div", { "class": _normalizeClass(['v-slider-thumb__ripple', textColorClasses.value]), "style": _normalizeStyle(textColorStyles.value) }, null), [[vRipple, props.ripple, null, { circle: true, center: true }]]), _createVNode(VScaleTransition, { "origin": "bottom center" }, { default: () => [_withDirectives(_createElementVNode("div", { "class": "v-slider-thumb__label-container" }, [_createElementVNode("div", { "class": _normalizeClass(['v-slider-thumb__label', textColorClasses.value]) }, [_createElementVNode("div", null, [slots['thumb-label']?.({ modelValue: props.modelValue }) ?? props.modelValue.toFixed(step.value ? decimals.value : 1)])])]), [[_vShow, thumbLabel.value && props.focused || thumbLabel.value === 'always']])] })]); }); return {}; } }); //# sourceMappingURL=VSliderThumb.js.map