routie dev init since i didn't adhere to any proper guidance up until now
This commit is contained in:
+198
@@ -0,0 +1,198 @@
|
||||
import { normalizeClass as _normalizeClass, normalizeStyle as _normalizeStyle, createElementVNode as _createElementVNode, 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 { useBackgroundColor, 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, shallowRef, watch } 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,
|
||||
noKeyboard: Boolean,
|
||||
...makeComponentProps()
|
||||
}, 'VSliderThumb');
|
||||
export const VSliderThumb = genericComponent()({
|
||||
name: 'VSliderThumb',
|
||||
directives: {
|
||||
vRipple
|
||||
},
|
||||
props: makeVSliderThumbProps(),
|
||||
emits: {
|
||||
'update:modelValue': v => true
|
||||
},
|
||||
setup(props, {
|
||||
slots,
|
||||
emit
|
||||
}) {
|
||||
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,
|
||||
thumbLabelColor,
|
||||
step,
|
||||
disabled,
|
||||
thumbSize,
|
||||
thumbLabel,
|
||||
direction,
|
||||
isReversed,
|
||||
vertical,
|
||||
readonly,
|
||||
elevation,
|
||||
mousePressed,
|
||||
decimals,
|
||||
indexFromEnd
|
||||
} = slider;
|
||||
const isHovered = shallowRef(false);
|
||||
const isHidden = shallowRef(false);
|
||||
const elevationProps = computed(() => !disabled.value ? elevation.value : undefined);
|
||||
const {
|
||||
elevationClasses
|
||||
} = useElevation(elevationProps);
|
||||
const {
|
||||
textColorClasses,
|
||||
textColorStyles
|
||||
} = useTextColor(thumbColor);
|
||||
const {
|
||||
backgroundColorClasses,
|
||||
backgroundColorStyles
|
||||
} = useBackgroundColor(thumbLabelColor);
|
||||
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 (props.noKeyboard || disabled.value) return;
|
||||
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);
|
||||
if (newValue != null) {
|
||||
isHidden.value = false;
|
||||
emit('update:modelValue', newValue);
|
||||
}
|
||||
}
|
||||
watch(() => props.focused, val => {
|
||||
if (val) {
|
||||
isHidden.value = false;
|
||||
}
|
||||
});
|
||||
useRender(() => {
|
||||
const positionPercentage = convertToUnit(indexFromEnd.value ? 100 - props.position : props.position, '%');
|
||||
const thumbLabelVisible = thumbLabel.value === 'always' || thumbLabel.value === true && props.focused || thumbLabel.value === 'hover' && (isHovered.value || props.focused && !isHidden.value);
|
||||
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,
|
||||
"onMouseenter": () => {
|
||||
isHovered.value = true;
|
||||
},
|
||||
"onMouseleave": () => {
|
||||
isHovered.value = false;
|
||||
isHidden.value = true;
|
||||
}
|
||||
}, [_createElementVNode("div", {
|
||||
"class": _normalizeClass(['v-slider-thumb__surface', textColorClasses.value, elevationClasses.value]),
|
||||
"style": _normalizeStyle(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', backgroundColorClasses.value]),
|
||||
"style": _normalizeStyle(backgroundColorStyles.value)
|
||||
}, [_createElementVNode("div", null, [slots['thumb-label']?.({
|
||||
modelValue: props.modelValue
|
||||
}) ?? props.modelValue.toFixed(step.value ? decimals.value : 1)]), _createElementVNode("div", {
|
||||
"class": "v-slider-thumb__label-wedge"
|
||||
}, null)])]), [[_vShow, thumbLabelVisible]])]
|
||||
})]);
|
||||
});
|
||||
return {};
|
||||
}
|
||||
});
|
||||
//# sourceMappingURL=VSliderThumb.js.map
|
||||
Reference in New Issue
Block a user