mirror of
https://github.com/primefaces/primevue.git
synced 2025-05-09 00:42:36 +00:00
Fixed #3802 - Improve folder structure for nuxt configurations
This commit is contained in:
parent
851950270b
commit
f5fe822afb
563 changed files with 1703 additions and 1095 deletions
125
components/lib/slider/Slider.d.ts
vendored
Executable file
125
components/lib/slider/Slider.d.ts
vendored
Executable file
|
@ -0,0 +1,125 @@
|
|||
/**
|
||||
*
|
||||
* Slider is a component to provide input with a drag handle.
|
||||
*
|
||||
* [Live Demo](https://www.primevue.org/slider/)
|
||||
*
|
||||
* @module slider
|
||||
*
|
||||
*/
|
||||
import { ClassComponent, GlobalComponentConstructor } from '../ts-helpers';
|
||||
|
||||
/**
|
||||
* Custom slide end event.
|
||||
* @see {@link SliderEmits.slideend}
|
||||
*/
|
||||
export interface SliderSlideEndEvent {
|
||||
/**
|
||||
* Original event
|
||||
*/
|
||||
originalEvent: Event;
|
||||
/**
|
||||
* New value.
|
||||
*/
|
||||
value: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines valid properties in Slider component.
|
||||
*/
|
||||
export interface SliderProps {
|
||||
/**
|
||||
* Value of the component.
|
||||
*/
|
||||
modelValue?: number | number[] | undefined;
|
||||
/**
|
||||
* Mininum boundary value.
|
||||
* @defaultValue 0
|
||||
*/
|
||||
min?: number | undefined;
|
||||
/**
|
||||
* Maximum boundary value.
|
||||
* @defaultValue 100
|
||||
*/
|
||||
max?: number | undefined;
|
||||
/**
|
||||
* Orientation of the slider.
|
||||
* @defaultValue horizontal
|
||||
*/
|
||||
orientation?: 'horizontal' | 'vertical' | undefined;
|
||||
/**
|
||||
* Step factor to increment/decrement the value.
|
||||
* @defaultValue 1
|
||||
*/
|
||||
step?: number | undefined;
|
||||
/**
|
||||
* When speficed, allows two boundary values to be picked.
|
||||
* @defaultValue false
|
||||
*/
|
||||
range?: boolean | undefined;
|
||||
/**
|
||||
* When present, it specifies that the component should be disabled.
|
||||
* @defaultValue false
|
||||
*/
|
||||
disabled?: boolean | undefined;
|
||||
/**
|
||||
* Index of the element in tabbing order.
|
||||
*/
|
||||
tabindex?: number | undefined;
|
||||
/**
|
||||
* Establishes relationships between the component and label(s) where its value should be one or more element IDs.
|
||||
*/
|
||||
'aria-labelledby'?: string | undefined;
|
||||
/**
|
||||
* Used to define a string that labels the element.
|
||||
*/
|
||||
'aria-label'?: string | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines valid slots in Slider component.
|
||||
*/
|
||||
export interface SliderSlots {}
|
||||
|
||||
/**
|
||||
* Defines valid emits in Slider component.
|
||||
*/
|
||||
export interface SliderEmits {
|
||||
/**
|
||||
* Emitted when the value changes.
|
||||
* @param {number | number[]} value - New value.
|
||||
*/
|
||||
'update:modelValue'(value: number | number[]): void;
|
||||
/**
|
||||
* Callback to invoke on value change.
|
||||
* @param {number} value - New value
|
||||
*/
|
||||
change(value: number): void;
|
||||
/**
|
||||
* Callback to invoke when slide ends.
|
||||
* @param {SliderSlideEndEvent} event - Custom slide end event.
|
||||
*/
|
||||
slideend(event: SliderSlideEndEvent): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* **PrimeVue - Slider**
|
||||
*
|
||||
* _Slider is a component to provide input with a drag handle._
|
||||
*
|
||||
* [Live Demo](https://www.primevue.org/slider/)
|
||||
* --- ---
|
||||
* 
|
||||
*
|
||||
* @group Component
|
||||
*
|
||||
*/
|
||||
declare class Slider extends ClassComponent<SliderProps, SliderSlots, SliderEmits> {}
|
||||
|
||||
declare module '@vue/runtime-core' {
|
||||
interface GlobalComponents {
|
||||
Slider: GlobalComponentConstructor<Slider>;
|
||||
}
|
||||
}
|
||||
|
||||
export default Slider;
|
49
components/lib/slider/Slider.spec.js
Normal file
49
components/lib/slider/Slider.spec.js
Normal file
|
@ -0,0 +1,49 @@
|
|||
import { mount } from '@vue/test-utils';
|
||||
import Slider from './Slider.vue';
|
||||
|
||||
describe('Slider.vue', () => {
|
||||
let wrapper;
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = mount(Slider, {
|
||||
props: {
|
||||
modelValue: null
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should exist', () => {
|
||||
expect(wrapper.find('.p-slider.p-component').exists()).toBe(true);
|
||||
expect(wrapper.find('.p-slider').classes()).toContain('p-slider-horizontal');
|
||||
});
|
||||
|
||||
it('should drag start and end', async () => {
|
||||
await wrapper.vm.onDragStart({ preventDefault: () => {}, currentTarget: { focus: () => {} } });
|
||||
|
||||
expect(wrapper.find('.p-slider').classes()).toContain('p-slider-sliding');
|
||||
|
||||
await wrapper.vm.onDragEnd();
|
||||
|
||||
expect(wrapper.find('.p-slider').classes()).not.toContain('p-slider-sliding');
|
||||
});
|
||||
|
||||
it('should set value', async () => {
|
||||
wrapper.element.setAttribute('width', '14rem');
|
||||
|
||||
await wrapper.vm.updateDomData();
|
||||
|
||||
await wrapper.vm.setValue({ pageX: 60 }); // TODO:
|
||||
|
||||
expect(wrapper.emitted()['update:modelValue'][0][0]).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('should set value on vertical mode', async () => {
|
||||
await wrapper.setProps({ orientation: 'vertical', modelValue: 0 });
|
||||
|
||||
await wrapper.vm.updateDomData();
|
||||
|
||||
await wrapper.vm.setValue({ pageY: 111 }); // TODO:
|
||||
|
||||
expect(wrapper.emitted()['update:modelValue'][0][0]).toBe(0);
|
||||
});
|
||||
});
|
411
components/lib/slider/Slider.vue
Executable file
411
components/lib/slider/Slider.vue
Executable file
|
@ -0,0 +1,411 @@
|
|||
<template>
|
||||
<div :class="containerClass" @click="onBarClick">
|
||||
<span class="p-slider-range" :style="rangeStyle"></span>
|
||||
<span
|
||||
v-if="!range"
|
||||
class="p-slider-handle"
|
||||
:style="handleStyle"
|
||||
@touchstart="onDragStart($event)"
|
||||
@touchmove="onDrag($event)"
|
||||
@touchend="onDragEnd($event)"
|
||||
@mousedown="onMouseDown($event)"
|
||||
@keydown="onKeyDown($event)"
|
||||
:tabindex="tabindex"
|
||||
role="slider"
|
||||
:aria-valuemin="min"
|
||||
:aria-valuenow="modelValue"
|
||||
:aria-valuemax="max"
|
||||
:aria-labelledby="ariaLabelledby"
|
||||
:aria-label="ariaLabel"
|
||||
:aria-orientation="orientation"
|
||||
></span>
|
||||
<span
|
||||
v-if="range"
|
||||
class="p-slider-handle"
|
||||
:style="rangeStartHandleStyle"
|
||||
@touchstart="onDragStart($event, 0)"
|
||||
@touchmove="onDrag($event)"
|
||||
@touchend="onDragEnd($event)"
|
||||
@mousedown="onMouseDown($event, 0)"
|
||||
@keydown="onKeyDown($event, 0)"
|
||||
:tabindex="tabindex"
|
||||
role="slider"
|
||||
:aria-valuemin="min"
|
||||
:aria-valuenow="modelValue ? modelValue[0] : null"
|
||||
:aria-valuemax="max"
|
||||
:aria-labelledby="ariaLabelledby"
|
||||
:aria-label="ariaLabel"
|
||||
:aria-orientation="orientation"
|
||||
></span>
|
||||
<span
|
||||
v-if="range"
|
||||
class="p-slider-handle"
|
||||
:style="rangeEndHandleStyle"
|
||||
@touchstart="onDragStart($event, 1)"
|
||||
@touchmove="onDrag($event)"
|
||||
@touchend="onDragEnd($event)"
|
||||
@mousedown="onMouseDown($event, 1)"
|
||||
@keydown="onKeyDown($event, 1)"
|
||||
:tabindex="tabindex"
|
||||
role="slider"
|
||||
:aria-valuemin="min"
|
||||
:aria-valuenow="modelValue ? modelValue[1] : null"
|
||||
:aria-valuemax="max"
|
||||
:aria-labelledby="ariaLabelledby"
|
||||
:aria-label="ariaLabel"
|
||||
:aria-orientation="orientation"
|
||||
></span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { DomHandler } from 'primevue/utils';
|
||||
|
||||
export default {
|
||||
name: 'Slider',
|
||||
emits: ['update:modelValue', 'change', 'slideend'],
|
||||
props: {
|
||||
modelValue: [Number, Array],
|
||||
min: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
max: {
|
||||
type: Number,
|
||||
default: 100
|
||||
},
|
||||
orientation: {
|
||||
type: String,
|
||||
default: 'horizontal'
|
||||
},
|
||||
step: {
|
||||
type: Number,
|
||||
default: null
|
||||
},
|
||||
range: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
tabindex: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
'aria-labelledby': {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
'aria-label': {
|
||||
type: String,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
dragging: false,
|
||||
handleIndex: null,
|
||||
initX: null,
|
||||
initY: null,
|
||||
barWidth: null,
|
||||
barHeight: null,
|
||||
dragListener: null,
|
||||
dragEndListener: null,
|
||||
beforeUnmount() {
|
||||
this.unbindDragListeners();
|
||||
},
|
||||
methods: {
|
||||
updateDomData() {
|
||||
let rect = this.$el.getBoundingClientRect();
|
||||
|
||||
this.initX = rect.left + DomHandler.getWindowScrollLeft();
|
||||
this.initY = rect.top + DomHandler.getWindowScrollTop();
|
||||
this.barWidth = this.$el.offsetWidth;
|
||||
this.barHeight = this.$el.offsetHeight;
|
||||
},
|
||||
setValue(event) {
|
||||
let handleValue;
|
||||
let pageX = event.touches ? event.touches[0].pageX : event.pageX;
|
||||
let pageY = event.touches ? event.touches[0].pageY : event.pageY;
|
||||
|
||||
if (this.orientation === 'horizontal') handleValue = ((pageX - this.initX) * 100) / this.barWidth;
|
||||
else handleValue = ((this.initY + this.barHeight - pageY) * 100) / this.barHeight;
|
||||
let newValue = (this.max - this.min) * (handleValue / 100) + this.min;
|
||||
|
||||
if (this.step) {
|
||||
const oldValue = this.range ? this.modelValue[this.handleIndex] : this.modelValue;
|
||||
const diff = newValue - oldValue;
|
||||
|
||||
if (diff < 0) newValue = oldValue + Math.ceil(newValue / this.step - oldValue / this.step) * this.step;
|
||||
else if (diff > 0) newValue = oldValue + Math.floor(newValue / this.step - oldValue / this.step) * this.step;
|
||||
} else {
|
||||
newValue = Math.floor(newValue);
|
||||
}
|
||||
|
||||
this.updateModel(event, newValue);
|
||||
},
|
||||
updateModel(event, value) {
|
||||
let newValue = parseFloat(value.toFixed(10));
|
||||
let modelValue;
|
||||
|
||||
if (this.range) {
|
||||
modelValue = this.modelValue ? [...this.modelValue] : [];
|
||||
|
||||
if (this.handleIndex == 0) {
|
||||
if (newValue < this.min) newValue = this.min;
|
||||
else if (newValue >= this.max) newValue = this.max;
|
||||
|
||||
modelValue[0] = newValue;
|
||||
} else {
|
||||
if (newValue > this.max) newValue = this.max;
|
||||
else if (newValue <= this.min) newValue = this.min;
|
||||
|
||||
modelValue[1] = newValue;
|
||||
}
|
||||
} else {
|
||||
if (newValue < this.min) newValue = this.min;
|
||||
else if (newValue > this.max) newValue = this.max;
|
||||
|
||||
modelValue = newValue;
|
||||
}
|
||||
|
||||
this.$emit('update:modelValue', modelValue);
|
||||
this.$emit('change', modelValue);
|
||||
},
|
||||
onDragStart(event, index) {
|
||||
if (this.disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
DomHandler.addClass(this.$el, 'p-slider-sliding');
|
||||
this.dragging = true;
|
||||
this.updateDomData();
|
||||
|
||||
if (this.range && this.modelValue[0] === this.max) {
|
||||
this.handleIndex = 0;
|
||||
} else {
|
||||
this.handleIndex = index;
|
||||
}
|
||||
|
||||
event.currentTarget.focus();
|
||||
event.preventDefault();
|
||||
},
|
||||
onDrag(event) {
|
||||
if (this.dragging) {
|
||||
this.setValue(event);
|
||||
event.preventDefault();
|
||||
}
|
||||
},
|
||||
onDragEnd(event) {
|
||||
if (this.dragging) {
|
||||
this.dragging = false;
|
||||
DomHandler.removeClass(this.$el, 'p-slider-sliding');
|
||||
this.$emit('slideend', { originalEvent: event, value: this.modelValue });
|
||||
}
|
||||
},
|
||||
onBarClick(event) {
|
||||
if (this.disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!DomHandler.hasClass(event.target, 'p-slider-handle')) {
|
||||
this.updateDomData();
|
||||
this.setValue(event);
|
||||
}
|
||||
},
|
||||
onMouseDown(event, index) {
|
||||
this.bindDragListeners();
|
||||
this.onDragStart(event, index);
|
||||
},
|
||||
onKeyDown(event, index) {
|
||||
this.handleIndex = index;
|
||||
|
||||
switch (event.code) {
|
||||
case 'ArrowDown':
|
||||
case 'ArrowLeft':
|
||||
this.decrementValue(event, index);
|
||||
event.preventDefault();
|
||||
break;
|
||||
|
||||
case 'ArrowUp':
|
||||
case 'ArrowRight':
|
||||
this.incrementValue(event, index);
|
||||
event.preventDefault();
|
||||
break;
|
||||
|
||||
case 'PageDown':
|
||||
this.decrementValue(event, index, true);
|
||||
event.preventDefault();
|
||||
break;
|
||||
|
||||
case 'PageUp':
|
||||
this.incrementValue(event, index, true);
|
||||
event.preventDefault();
|
||||
break;
|
||||
|
||||
case 'Home':
|
||||
this.updateModel(event, this.min);
|
||||
event.preventDefault();
|
||||
break;
|
||||
|
||||
case 'End':
|
||||
this.updateModel(event, this.max);
|
||||
event.preventDefault();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
decrementValue(event, index, pageKey = false) {
|
||||
let newValue;
|
||||
|
||||
if (this.range) {
|
||||
if (this.step) newValue = this.modelValue[index] - this.step;
|
||||
else newValue = this.modelValue[index] - 1;
|
||||
} else {
|
||||
if (this.step) newValue = this.modelValue - this.step;
|
||||
else if (!this.step && pageKey) newValue = this.modelValue - 10;
|
||||
else newValue = this.modelValue - 1;
|
||||
}
|
||||
|
||||
this.updateModel(event, newValue);
|
||||
event.preventDefault();
|
||||
},
|
||||
incrementValue(event, index, pageKey = false) {
|
||||
let newValue;
|
||||
|
||||
if (this.range) {
|
||||
if (this.step) newValue = this.modelValue[index] + this.step;
|
||||
else newValue = this.modelValue[index] + 1;
|
||||
} else {
|
||||
if (this.step) newValue = this.modelValue + this.step;
|
||||
else if (!this.step && pageKey) newValue = this.modelValue + 10;
|
||||
else newValue = this.modelValue + 1;
|
||||
}
|
||||
|
||||
this.updateModel(event, newValue);
|
||||
event.preventDefault();
|
||||
},
|
||||
bindDragListeners() {
|
||||
if (!this.dragListener) {
|
||||
this.dragListener = this.onDrag.bind(this);
|
||||
document.addEventListener('mousemove', this.dragListener);
|
||||
}
|
||||
|
||||
if (!this.dragEndListener) {
|
||||
this.dragEndListener = this.onDragEnd.bind(this);
|
||||
document.addEventListener('mouseup', this.dragEndListener);
|
||||
}
|
||||
},
|
||||
unbindDragListeners() {
|
||||
if (this.dragListener) {
|
||||
document.removeEventListener('mousemove', this.dragListener);
|
||||
this.dragListener = null;
|
||||
}
|
||||
|
||||
if (this.dragEndListener) {
|
||||
document.removeEventListener('mouseup', this.dragEndListener);
|
||||
this.dragEndListener = null;
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
containerClass() {
|
||||
return [
|
||||
'p-slider p-component',
|
||||
{
|
||||
'p-disabled': this.disabled,
|
||||
'p-slider-horizontal': this.orientation === 'horizontal',
|
||||
'p-slider-vertical': this.orientation === 'vertical'
|
||||
}
|
||||
];
|
||||
},
|
||||
horizontal() {
|
||||
return this.orientation === 'horizontal';
|
||||
},
|
||||
vertical() {
|
||||
return this.orientation === 'vertical';
|
||||
},
|
||||
rangeStyle() {
|
||||
if (this.range) {
|
||||
const rangeSliderWidth = this.rangeEndPosition > this.rangeStartPosition ? this.rangeEndPosition - this.rangeStartPosition : this.rangeStartPosition - this.rangeEndPosition;
|
||||
const rangeSliderPosition = this.rangeEndPosition > this.rangeStartPosition ? this.rangeStartPosition : this.rangeEndPosition;
|
||||
|
||||
if (this.horizontal) return { left: rangeSliderPosition + '%', width: rangeSliderWidth + '%' };
|
||||
else return { bottom: rangeSliderPosition + '%', height: rangeSliderWidth + '%' };
|
||||
} else {
|
||||
if (this.horizontal) return { width: this.handlePosition + '%' };
|
||||
else return { height: this.handlePosition + '%' };
|
||||
}
|
||||
},
|
||||
handleStyle() {
|
||||
if (this.horizontal) return { left: this.handlePosition + '%' };
|
||||
else return { bottom: this.handlePosition + '%' };
|
||||
},
|
||||
handlePosition() {
|
||||
if (this.modelValue < this.min) return 0;
|
||||
else if (this.modelValue > this.max) return 100;
|
||||
else return ((this.modelValue - this.min) * 100) / (this.max - this.min);
|
||||
},
|
||||
rangeStartPosition() {
|
||||
if (this.modelValue && this.modelValue[0]) return ((this.modelValue[0] < this.min ? 0 : this.modelValue[0] - this.min) * 100) / (this.max - this.min);
|
||||
else return 0;
|
||||
},
|
||||
rangeEndPosition() {
|
||||
if (this.modelValue && this.modelValue.length === 2) return ((this.modelValue[1] > this.max ? 100 : this.modelValue[1] - this.min) * 100) / (this.max - this.min);
|
||||
else return 100;
|
||||
},
|
||||
rangeStartHandleStyle() {
|
||||
if (this.horizontal) return { left: this.rangeStartPosition + '%' };
|
||||
else return { bottom: this.rangeStartPosition + '%' };
|
||||
},
|
||||
rangeEndHandleStyle() {
|
||||
if (this.horizontal) return { left: this.rangeEndPosition + '%' };
|
||||
else return { bottom: this.rangeEndPosition + '%' };
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.p-slider {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.p-slider .p-slider-handle {
|
||||
position: absolute;
|
||||
cursor: grab;
|
||||
touch-action: none;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.p-slider-range {
|
||||
position: absolute;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.p-slider-horizontal .p-slider-range {
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.p-slider-horizontal .p-slider-handle {
|
||||
top: 50%;
|
||||
}
|
||||
|
||||
.p-slider-vertical {
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.p-slider-vertical .p-slider-handle {
|
||||
left: 50%;
|
||||
}
|
||||
|
||||
.p-slider-vertical .p-slider-range {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
9
components/lib/slider/package.json
Normal file
9
components/lib/slider/package.json
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"main": "./slider.cjs.js",
|
||||
"module": "./slider.esm.js",
|
||||
"unpkg": "./slider.min.js",
|
||||
"types": "./Slider.d.ts",
|
||||
"browser": {
|
||||
"./sfc": "./Slider.vue"
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue