VSliderThumb.mjs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. import { vShow as _vShow, withDirectives as _withDirectives, resolveDirective as _resolveDirective, createVNode as _createVNode } from "vue";
  2. // Styles
  3. import "./VSliderThumb.css";
  4. // Components
  5. import { VSliderSymbol } from "./slider.mjs";
  6. import { VScaleTransition } from "../transitions/index.mjs"; // Composables
  7. import { useTextColor } from "../../composables/color.mjs";
  8. import { makeComponentProps } from "../../composables/component.mjs";
  9. import { useElevation } from "../../composables/elevation.mjs";
  10. import { useRtl } from "../../composables/locale.mjs"; // Directives
  11. import Ripple from "../../directives/ripple/index.mjs"; // Utilities
  12. import { computed, inject } from 'vue';
  13. import { convertToUnit, genericComponent, keyValues, propsFactory, useRender } from "../../util/index.mjs"; // Types
  14. export const makeVSliderThumbProps = propsFactory({
  15. focused: Boolean,
  16. max: {
  17. type: Number,
  18. required: true
  19. },
  20. min: {
  21. type: Number,
  22. required: true
  23. },
  24. modelValue: {
  25. type: Number,
  26. required: true
  27. },
  28. position: {
  29. type: Number,
  30. required: true
  31. },
  32. ripple: {
  33. type: [Boolean, Object],
  34. default: true
  35. },
  36. name: String,
  37. ...makeComponentProps()
  38. }, 'VSliderThumb');
  39. export const VSliderThumb = genericComponent()({
  40. name: 'VSliderThumb',
  41. directives: {
  42. Ripple
  43. },
  44. props: makeVSliderThumbProps(),
  45. emits: {
  46. 'update:modelValue': v => true
  47. },
  48. setup(props, _ref) {
  49. let {
  50. slots,
  51. emit
  52. } = _ref;
  53. const slider = inject(VSliderSymbol);
  54. const {
  55. isRtl,
  56. rtlClasses
  57. } = useRtl();
  58. if (!slider) throw new Error('[Vuetify] v-slider-thumb must be used inside v-slider or v-range-slider');
  59. const {
  60. thumbColor,
  61. step,
  62. disabled,
  63. thumbSize,
  64. thumbLabel,
  65. direction,
  66. isReversed,
  67. vertical,
  68. readonly,
  69. elevation,
  70. mousePressed,
  71. decimals,
  72. indexFromEnd
  73. } = slider;
  74. const elevationProps = computed(() => !disabled.value ? elevation.value : undefined);
  75. const {
  76. elevationClasses
  77. } = useElevation(elevationProps);
  78. const {
  79. textColorClasses,
  80. textColorStyles
  81. } = useTextColor(thumbColor);
  82. const {
  83. pageup,
  84. pagedown,
  85. end,
  86. home,
  87. left,
  88. right,
  89. down,
  90. up
  91. } = keyValues;
  92. const relevantKeys = [pageup, pagedown, end, home, left, right, down, up];
  93. const multipliers = computed(() => {
  94. if (step.value) return [1, 2, 3];else return [1, 5, 10];
  95. });
  96. function parseKeydown(e, value) {
  97. if (!relevantKeys.includes(e.key)) return;
  98. e.preventDefault();
  99. const _step = step.value || 0.1;
  100. const steps = (props.max - props.min) / _step;
  101. if ([left, right, down, up].includes(e.key)) {
  102. const increase = vertical.value ? [isRtl.value ? left : right, isReversed.value ? down : up] : indexFromEnd.value !== isRtl.value ? [left, up] : [right, up];
  103. const direction = increase.includes(e.key) ? 1 : -1;
  104. const multiplier = e.shiftKey ? 2 : e.ctrlKey ? 1 : 0;
  105. value = value + direction * _step * multipliers.value[multiplier];
  106. } else if (e.key === home) {
  107. value = props.min;
  108. } else if (e.key === end) {
  109. value = props.max;
  110. } else {
  111. const direction = e.key === pagedown ? 1 : -1;
  112. value = value - direction * _step * (steps > 100 ? steps / 10 : 10);
  113. }
  114. return Math.max(props.min, Math.min(props.max, value));
  115. }
  116. function onKeydown(e) {
  117. const newValue = parseKeydown(e, props.modelValue);
  118. newValue != null && emit('update:modelValue', newValue);
  119. }
  120. useRender(() => {
  121. const positionPercentage = convertToUnit(indexFromEnd.value ? 100 - props.position : props.position, '%');
  122. return _createVNode("div", {
  123. "class": ['v-slider-thumb', {
  124. 'v-slider-thumb--focused': props.focused,
  125. 'v-slider-thumb--pressed': props.focused && mousePressed.value
  126. }, props.class, rtlClasses.value],
  127. "style": [{
  128. '--v-slider-thumb-position': positionPercentage,
  129. '--v-slider-thumb-size': convertToUnit(thumbSize.value)
  130. }, props.style],
  131. "role": "slider",
  132. "tabindex": disabled.value ? -1 : 0,
  133. "aria-label": props.name,
  134. "aria-valuemin": props.min,
  135. "aria-valuemax": props.max,
  136. "aria-valuenow": props.modelValue,
  137. "aria-readonly": !!readonly.value,
  138. "aria-orientation": direction.value,
  139. "onKeydown": !readonly.value ? onKeydown : undefined
  140. }, [_createVNode("div", {
  141. "class": ['v-slider-thumb__surface', textColorClasses.value, elevationClasses.value],
  142. "style": {
  143. ...textColorStyles.value
  144. }
  145. }, null), _withDirectives(_createVNode("div", {
  146. "class": ['v-slider-thumb__ripple', textColorClasses.value],
  147. "style": textColorStyles.value
  148. }, null), [[_resolveDirective("ripple"), props.ripple, null, {
  149. circle: true,
  150. center: true
  151. }]]), _createVNode(VScaleTransition, {
  152. "origin": "bottom center"
  153. }, {
  154. default: () => [_withDirectives(_createVNode("div", {
  155. "class": "v-slider-thumb__label-container"
  156. }, [_createVNode("div", {
  157. "class": ['v-slider-thumb__label']
  158. }, [_createVNode("div", null, [slots['thumb-label']?.({
  159. modelValue: props.modelValue
  160. }) ?? props.modelValue.toFixed(step.value ? decimals.value : 1)])])]), [[_vShow, thumbLabel.value && props.focused || thumbLabel.value === 'always']])]
  161. })]);
  162. });
  163. return {};
  164. }
  165. });
  166. //# sourceMappingURL=VSliderThumb.mjs.map