|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452 |
- var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
-
- // Styles
- import '../../../src/stylus/components/_sliders.styl';
- // Components
- import { VScaleTransition } from '../transitions';
- // Extensions
- import VInput from '../VInput';
- // Directives
- import ClickOutside from '../../directives/click-outside';
- // Utilities
- import { addOnceEventListener, convertToUnit, createRange, keyCodes, deepEqual } from '../../util/helpers';
- import { consoleWarn } from '../../util/console';
- import Loadable from '../../mixins/loadable';
- /* @vue/component */
- export default VInput.extend({
- name: 'v-slider',
- directives: { ClickOutside: ClickOutside },
- mixins: [Loadable],
- props: {
- alwaysDirty: Boolean,
- inverseLabel: Boolean,
- label: String,
- min: {
- type: [Number, String],
- default: 0
- },
- max: {
- type: [Number, String],
- default: 100
- },
- step: {
- type: [Number, String],
- default: 1
- },
- ticks: {
- type: [Boolean, String],
- default: false,
- validator: function validator(v) {
- return typeof v === 'boolean' || v === 'always';
- }
- },
- tickLabels: {
- type: Array,
- default: function _default() {
- return [];
- }
- },
- tickSize: {
- type: [Number, String],
- default: 1
- },
- thumbColor: {
- type: String,
- default: null
- },
- thumbLabel: {
- type: [Boolean, String],
- default: null,
- validator: function validator(v) {
- return typeof v === 'boolean' || v === 'always';
- }
- },
- thumbSize: {
- type: [Number, String],
- default: 32
- },
- trackColor: {
- type: String,
- default: null
- },
- value: [Number, String]
- },
- data: function data(vm) {
- return {
- app: {},
- isActive: false,
- keyPressed: 0,
- lazyValue: typeof vm.value !== 'undefined' ? vm.value : Number(vm.min),
- oldValue: null
- };
- },
- computed: {
- classes: function classes() {
- return {
- 'v-input--slider': true,
- 'v-input--slider--ticks': this.showTicks,
- 'v-input--slider--inverse-label': this.inverseLabel,
- 'v-input--slider--ticks-labels': this.tickLabels.length > 0,
- 'v-input--slider--thumb-label': this.thumbLabel || this.$scopedSlots.thumbLabel
- };
- },
- showTicks: function showTicks() {
- return this.tickLabels.length > 0 || !this.disabled && this.stepNumeric && !!this.ticks;
- },
- showThumbLabel: function showThumbLabel() {
- return !this.disabled && (!!this.thumbLabel || this.thumbLabel === '' || this.$scopedSlots['thumb-label']);
- },
- computedColor: function computedColor() {
- if (this.disabled) return null;
- return this.validationState || this.color || 'primary';
- },
- computedTrackColor: function computedTrackColor() {
- return this.disabled ? null : this.trackColor || null;
- },
- computedThumbColor: function computedThumbColor() {
- if (this.disabled || !this.isDirty) return null;
- return this.validationState || this.thumbColor || this.color || 'primary';
- },
-
- internalValue: {
- get: function get() {
- return this.lazyValue;
- },
- set: function set(val) {
- var min = this.min,
- max = this.max;
- // Round value to ensure the
- // entire slider range can
- // be selected with step
-
- var value = this.roundValue(Math.min(Math.max(val, min), max));
- if (value === this.lazyValue) return;
- this.lazyValue = value;
- this.$emit('input', value);
- this.validate();
- }
- },
- stepNumeric: function stepNumeric() {
- return this.step > 0 ? parseFloat(this.step) : 0;
- },
- trackFillStyles: function trackFillStyles() {
- var left = this.$vuetify.rtl ? 'auto' : 0;
- var right = this.$vuetify.rtl ? 0 : 'auto';
- var width = this.inputWidth + '%';
- if (this.disabled) width = 'calc(' + this.inputWidth + '% - 8px)';
- return {
- transition: this.trackTransition,
- left: left,
- right: right,
- width: width
- };
- },
- trackPadding: function trackPadding() {
- return this.isActive || this.inputWidth > 0 || this.disabled ? 0 : 7;
- },
- trackStyles: function trackStyles() {
- var trackPadding = this.disabled ? 'calc(' + this.inputWidth + '% + 8px)' : this.trackPadding + 'px';
- var left = this.$vuetify.rtl ? 'auto' : trackPadding;
- var right = this.$vuetify.rtl ? trackPadding : 'auto';
- var width = this.disabled ? 'calc(' + (100 - this.inputWidth) + '% - 8px)' : '100%';
- return {
- transition: this.trackTransition,
- left: left,
- right: right,
- width: width
- };
- },
- tickStyles: function tickStyles() {
- var size = Number(this.tickSize);
- return {
- 'border-width': size + 'px',
- 'border-radius': size > 1 ? '50%' : null,
- transform: size > 1 ? 'translateX(-' + size + 'px) translateY(-' + (size - 1) + 'px)' : null
- };
- },
- trackTransition: function trackTransition() {
- return this.keyPressed >= 2 ? 'none' : '';
- },
- numTicks: function numTicks() {
- return Math.ceil((this.max - this.min) / this.stepNumeric);
- },
- inputWidth: function inputWidth() {
- return (this.roundValue(this.internalValue) - this.min) / (this.max - this.min) * 100;
- },
- isDirty: function isDirty() {
- return this.internalValue > this.min || this.alwaysDirty;
- }
- },
- watch: {
- min: function min(val) {
- val > this.internalValue && this.$emit('input', parseFloat(val));
- },
- max: function max(val) {
- val < this.internalValue && this.$emit('input', parseFloat(val));
- },
- value: function value(val) {
- this.internalValue = val;
- }
- },
- mounted: function mounted() {
- // Without a v-app, iOS does not work with body selectors
- this.app = document.querySelector('[data-app]') || consoleWarn('Missing v-app or a non-body wrapping element with the [data-app] attribute', this);
- },
-
- methods: {
- genDefaultSlot: function genDefaultSlot() {
- var children = [this.genLabel()];
- var slider = this.genSlider();
- this.inverseLabel ? children.unshift(slider) : children.push(slider);
- children.push(this.genProgress());
- return children;
- },
- genListeners: function genListeners() {
- return {
- blur: this.onBlur,
- click: this.onSliderClick,
- focus: this.onFocus,
- keydown: this.onKeyDown,
- keyup: this.onKeyUp
- };
- },
- genInput: function genInput() {
- return this.$createElement('input', {
- attrs: _extends({
- 'aria-label': this.label,
- name: this.name,
- role: 'slider',
- tabindex: this.disabled ? -1 : this.$attrs.tabindex,
- value: this.internalValue,
- readonly: true,
- 'aria-readonly': String(this.readonly),
- 'aria-valuemin': this.min,
- 'aria-valuemax': this.max,
- 'aria-valuenow': this.internalValue
- }, this.$attrs),
- on: this.genListeners(),
- ref: 'input'
- });
- },
- genSlider: function genSlider() {
- return this.$createElement('div', {
- staticClass: 'v-slider',
- 'class': {
- 'v-slider--is-active': this.isActive
- },
- directives: [{
- name: 'click-outside',
- value: this.onBlur
- }]
- }, this.genChildren());
- },
- genChildren: function genChildren() {
- return [this.genInput(), this.genTrackContainer(), this.genSteps(), this.genThumbContainer(this.internalValue, this.inputWidth, this.isFocused || this.isActive, this.onThumbMouseDown)];
- },
- genSteps: function genSteps() {
- var _this = this;
-
- if (!this.step || !this.showTicks) return null;
- var ticks = createRange(this.numTicks + 1).map(function (i) {
- var children = [];
- if (_this.tickLabels[i]) {
- children.push(_this.$createElement('span', _this.tickLabels[i]));
- }
- return _this.$createElement('span', {
- key: i,
- staticClass: 'v-slider__ticks',
- class: {
- 'v-slider__ticks--always-show': _this.ticks === 'always' || _this.tickLabels.length > 0
- },
- style: _extends({}, _this.tickStyles, {
- left: i * (100 / _this.numTicks) + '%'
- })
- }, children);
- });
- return this.$createElement('div', {
- staticClass: 'v-slider__ticks-container'
- }, ticks);
- },
- genThumb: function genThumb() {
- return this.$createElement('div', this.setBackgroundColor(this.computedThumbColor, {
- staticClass: 'v-slider__thumb'
- }));
- },
- genThumbContainer: function genThumbContainer(value, valueWidth, isActive, onDrag) {
- var children = [this.genThumb()];
- var thumbLabelContent = this.getLabel(value);
- this.showThumbLabel && children.push(this.genThumbLabel(thumbLabelContent));
- return this.$createElement('div', this.setTextColor(this.computedThumbColor, {
- staticClass: 'v-slider__thumb-container',
- 'class': {
- 'v-slider__thumb-container--is-active': isActive,
- 'v-slider__thumb-container--show-label': this.showThumbLabel
- },
- style: {
- transition: this.trackTransition,
- left: (this.$vuetify.rtl ? 100 - valueWidth : valueWidth) + '%'
- },
- on: {
- touchstart: onDrag,
- mousedown: onDrag
- }
- }), children);
- },
- genThumbLabel: function genThumbLabel(content) {
- var size = convertToUnit(this.thumbSize);
- return this.$createElement(VScaleTransition, {
- props: { origin: 'bottom center' }
- }, [this.$createElement('div', {
- staticClass: 'v-slider__thumb-label__container',
- directives: [{
- name: 'show',
- value: this.isFocused || this.isActive || this.thumbLabel === 'always'
- }]
- }, [this.$createElement('div', this.setBackgroundColor(this.computedThumbColor, {
- staticClass: 'v-slider__thumb-label',
- style: {
- height: size,
- width: size
- }
- }), [content])])]);
- },
- genTrackContainer: function genTrackContainer() {
- var children = [this.$createElement('div', this.setBackgroundColor(this.computedTrackColor, {
- staticClass: 'v-slider__track',
- style: this.trackStyles
- })), this.$createElement('div', this.setBackgroundColor(this.computedColor, {
- staticClass: 'v-slider__track-fill',
- style: this.trackFillStyles
- }))];
- return this.$createElement('div', {
- staticClass: 'v-slider__track__container',
- ref: 'track'
- }, children);
- },
- getLabel: function getLabel(value) {
- return this.$scopedSlots['thumb-label'] ? this.$scopedSlots['thumb-label']({ value: value }) : this.$createElement('span', value);
- },
- onBlur: function onBlur(e) {
- if (this.keyPressed === 2) return;
- this.isActive = false;
- this.isFocused = false;
- this.$emit('blur', e);
- },
- onFocus: function onFocus(e) {
- this.isFocused = true;
- this.$emit('focus', e);
- },
- onThumbMouseDown: function onThumbMouseDown(e) {
- this.oldValue = this.internalValue;
- this.keyPressed = 2;
- var options = { passive: true };
- this.isActive = true;
- this.isFocused = false;
- if ('touches' in e) {
- this.app.addEventListener('touchmove', this.onMouseMove, options);
- addOnceEventListener(this.app, 'touchend', this.onSliderMouseUp);
- } else {
- this.app.addEventListener('mousemove', this.onMouseMove, options);
- addOnceEventListener(this.app, 'mouseup', this.onSliderMouseUp);
- }
- this.$emit('start', this.internalValue);
- },
- onSliderMouseUp: function onSliderMouseUp() {
- this.keyPressed = 0;
- var options = { passive: true };
- this.isActive = false;
- this.isFocused = false;
- this.app.removeEventListener('touchmove', this.onMouseMove, options);
- this.app.removeEventListener('mousemove', this.onMouseMove, options);
- this.$emit('end', this.internalValue);
- if (!deepEqual(this.oldValue, this.internalValue)) {
- this.$emit('change', this.internalValue);
- }
- },
- onMouseMove: function onMouseMove(e) {
- var _parseMouseMove = this.parseMouseMove(e),
- value = _parseMouseMove.value,
- isInsideTrack = _parseMouseMove.isInsideTrack;
-
- if (isInsideTrack) {
- this.setInternalValue(value);
- }
- },
- onKeyDown: function onKeyDown(e) {
- if (this.disabled || this.readonly) return;
- var value = this.parseKeyDown(e);
- if (value == null) return;
- this.setInternalValue(value);
- this.$emit('change', value);
- },
- onKeyUp: function onKeyUp() {
- this.keyPressed = 0;
- },
- onSliderClick: function onSliderClick(e) {
- this.isFocused = true;
- this.onMouseMove(e);
- this.$emit('change', this.internalValue);
- },
- parseMouseMove: function parseMouseMove(e) {
- var _$refs$track$getBound = this.$refs.track.getBoundingClientRect(),
- offsetLeft = _$refs$track$getBound.left,
- trackWidth = _$refs$track$getBound.width;
-
- var clientX = 'touches' in e ? e.touches[0].clientX : e.clientX;
- // It is possible for left to be NaN, force to number
- var left = Math.min(Math.max((clientX - offsetLeft) / trackWidth, 0), 1) || 0;
- if (this.$vuetify.rtl) left = 1 - left;
- var isInsideTrack = clientX >= offsetLeft - 8 && clientX <= offsetLeft + trackWidth + 8;
- var value = parseFloat(this.min) + left * (this.max - this.min);
- return { value: value, isInsideTrack: isInsideTrack };
- },
- parseKeyDown: function parseKeyDown(e) {
- var value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.internalValue;
-
- if (this.disabled) return;
- var pageup = keyCodes.pageup,
- pagedown = keyCodes.pagedown,
- end = keyCodes.end,
- home = keyCodes.home,
- left = keyCodes.left,
- right = keyCodes.right,
- down = keyCodes.down,
- up = keyCodes.up;
-
- if (![pageup, pagedown, end, home, left, right, down, up].includes(e.keyCode)) return;
- e.preventDefault();
- var step = this.stepNumeric || 1;
- var steps = (this.max - this.min) / step;
- if ([left, right, down, up].includes(e.keyCode)) {
- this.keyPressed += 1;
- var increase = this.$vuetify.rtl ? [left, up] : [right, up];
- var direction = increase.includes(e.keyCode) ? 1 : -1;
- var multiplier = e.shiftKey ? 3 : e.ctrlKey ? 2 : 1;
- value = value + direction * step * multiplier;
- } else if (e.keyCode === home) {
- value = parseFloat(this.min);
- } else if (e.keyCode === end) {
- value = parseFloat(this.max);
- } else /* if (e.keyCode === keyCodes.pageup || e.keyCode === pagedown) */{
- // Page up/down
- var _direction = e.keyCode === pagedown ? 1 : -1;
- value = value - _direction * step * (steps > 100 ? steps / 10 : 10);
- }
- return value;
- },
- roundValue: function roundValue(value) {
- if (!this.stepNumeric) return value;
- // Format input value using the same number
- // of decimals places as in the step prop
- var trimmedStep = this.step.toString().trim();
- var decimals = trimmedStep.indexOf('.') > -1 ? trimmedStep.length - trimmedStep.indexOf('.') - 1 : 0;
- var offset = this.min % this.stepNumeric;
- var newValue = Math.round((value - offset) / this.stepNumeric) * this.stepNumeric + offset;
- return parseFloat(Math.max(Math.min(newValue, this.max), this.min).toFixed(decimals));
- },
- setInternalValue: function setInternalValue(value) {
- this.internalValue = value;
- }
- }
- });
- //# sourceMappingURL=VSlider.js.map
|