UNPKG

9.92 kBJavaScriptView Raw
1var __defProp = Object.defineProperty;
2var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3var __getOwnPropNames = Object.getOwnPropertyNames;
4var __hasOwnProp = Object.prototype.hasOwnProperty;
5var __export = (target, all) => {
6 for (var name2 in all)
7 __defProp(target, name2, { get: all[name2], enumerable: true });
8};
9var __copyProps = (to, from, except, desc) => {
10 if (from && typeof from === "object" || typeof from === "function") {
11 for (let key of __getOwnPropNames(from))
12 if (!__hasOwnProp.call(to, key) && key !== except)
13 __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14 }
15 return to;
16};
17var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18var stdin_exports = {};
19__export(stdin_exports, {
20 default: () => stdin_default,
21 sliderProps: () => sliderProps
22});
23module.exports = __toCommonJS(stdin_exports);
24var import_vue = require("vue");
25var import_utils = require("../utils");
26var import_use = require("@vant/use");
27var import_use_touch = require("../composables/use-touch");
28const [name, bem] = (0, import_utils.createNamespace)("slider");
29const sliderProps = {
30 min: (0, import_utils.makeNumericProp)(0),
31 max: (0, import_utils.makeNumericProp)(100),
32 step: (0, import_utils.makeNumericProp)(1),
33 range: Boolean,
34 reverse: Boolean,
35 disabled: Boolean,
36 readonly: Boolean,
37 vertical: Boolean,
38 barHeight: import_utils.numericProp,
39 buttonSize: import_utils.numericProp,
40 activeColor: String,
41 inactiveColor: String,
42 modelValue: {
43 type: [Number, Array],
44 default: 0
45 }
46};
47var stdin_default = (0, import_vue.defineComponent)({
48 name,
49 props: sliderProps,
50 emits: ["change", "dragEnd", "dragStart", "update:modelValue"],
51 setup(props, {
52 emit,
53 slots
54 }) {
55 let buttonIndex;
56 let current;
57 let startValue;
58 const root = (0, import_vue.ref)();
59 const slider = [(0, import_vue.ref)(), (0, import_vue.ref)()];
60 const dragStatus = (0, import_vue.ref)();
61 const touch = (0, import_use_touch.useTouch)();
62 const scope = (0, import_vue.computed)(() => Number(props.max) - Number(props.min));
63 const wrapperStyle = (0, import_vue.computed)(() => {
64 const crossAxis = props.vertical ? "width" : "height";
65 return {
66 background: props.inactiveColor,
67 [crossAxis]: (0, import_utils.addUnit)(props.barHeight)
68 };
69 });
70 const isRange = (val) => props.range && Array.isArray(val);
71 const calcMainAxis = () => {
72 const {
73 modelValue,
74 min
75 } = props;
76 if (isRange(modelValue)) {
77 return `${(modelValue[1] - modelValue[0]) * 100 / scope.value}%`;
78 }
79 return `${(modelValue - Number(min)) * 100 / scope.value}%`;
80 };
81 const calcOffset = () => {
82 const {
83 modelValue,
84 min
85 } = props;
86 if (isRange(modelValue)) {
87 return `${(modelValue[0] - Number(min)) * 100 / scope.value}%`;
88 }
89 return "0%";
90 };
91 const barStyle = (0, import_vue.computed)(() => {
92 const mainAxis = props.vertical ? "height" : "width";
93 const style = {
94 [mainAxis]: calcMainAxis(),
95 background: props.activeColor
96 };
97 if (dragStatus.value) {
98 style.transition = "none";
99 }
100 const getPositionKey = () => {
101 if (props.vertical) {
102 return props.reverse ? "bottom" : "top";
103 }
104 return props.reverse ? "right" : "left";
105 };
106 style[getPositionKey()] = calcOffset();
107 return style;
108 });
109 const format = (value) => {
110 const min = +props.min;
111 const max = +props.max;
112 const step = +props.step;
113 value = (0, import_utils.clamp)(value, min, max);
114 const diff = Math.round((value - min) / step) * step;
115 return (0, import_utils.addNumber)(min, diff);
116 };
117 const updateStartValue = () => {
118 const current2 = props.modelValue;
119 if (isRange(current2)) {
120 startValue = current2.map(format);
121 } else {
122 startValue = format(current2);
123 }
124 };
125 const handleRangeValue = (value) => {
126 var _a, _b;
127 const left = (_a = value[0]) != null ? _a : Number(props.min);
128 const right = (_b = value[1]) != null ? _b : Number(props.max);
129 return left > right ? [right, left] : [left, right];
130 };
131 const updateValue = (value, end) => {
132 if (isRange(value)) {
133 value = handleRangeValue(value).map(format);
134 } else {
135 value = format(value);
136 }
137 if (!(0, import_utils.isSameValue)(value, props.modelValue)) {
138 emit("update:modelValue", value);
139 }
140 if (end && !(0, import_utils.isSameValue)(value, startValue)) {
141 emit("change", value);
142 }
143 };
144 const onClick = (event) => {
145 event.stopPropagation();
146 if (props.disabled || props.readonly) {
147 return;
148 }
149 updateStartValue();
150 const {
151 min,
152 reverse,
153 vertical,
154 modelValue
155 } = props;
156 const rect = (0, import_use.useRect)(root);
157 const getDelta = () => {
158 if (vertical) {
159 if (reverse) {
160 return rect.bottom - event.clientY;
161 }
162 return event.clientY - rect.top;
163 }
164 if (reverse) {
165 return rect.right - event.clientX;
166 }
167 return event.clientX - rect.left;
168 };
169 const total = vertical ? rect.height : rect.width;
170 const value = Number(min) + getDelta() / total * scope.value;
171 if (isRange(modelValue)) {
172 const [left, right] = modelValue;
173 const middle = (left + right) / 2;
174 if (value <= middle) {
175 updateValue([value, right], true);
176 } else {
177 updateValue([left, value], true);
178 }
179 } else {
180 updateValue(value, true);
181 }
182 };
183 const onTouchStart = (event) => {
184 if (props.disabled || props.readonly) {
185 return;
186 }
187 touch.start(event);
188 current = props.modelValue;
189 updateStartValue();
190 dragStatus.value = "start";
191 };
192 const onTouchMove = (event) => {
193 if (props.disabled || props.readonly) {
194 return;
195 }
196 if (dragStatus.value === "start") {
197 emit("dragStart", event);
198 }
199 (0, import_utils.preventDefault)(event, true);
200 touch.move(event);
201 dragStatus.value = "dragging";
202 const rect = (0, import_use.useRect)(root);
203 const delta = props.vertical ? touch.deltaY.value : touch.deltaX.value;
204 const total = props.vertical ? rect.height : rect.width;
205 let diff = delta / total * scope.value;
206 if (props.reverse) {
207 diff = -diff;
208 }
209 if (isRange(startValue)) {
210 const index = props.reverse ? 1 - buttonIndex : buttonIndex;
211 current[index] = startValue[index] + diff;
212 } else {
213 current = startValue + diff;
214 }
215 updateValue(current);
216 };
217 const onTouchEnd = (event) => {
218 if (props.disabled || props.readonly) {
219 return;
220 }
221 if (dragStatus.value === "dragging") {
222 updateValue(current, true);
223 emit("dragEnd", event);
224 }
225 dragStatus.value = "";
226 };
227 const getButtonClassName = (index) => {
228 if (typeof index === "number") {
229 const position = ["left", "right"];
230 return bem(`button-wrapper`, position[index]);
231 }
232 return bem("button-wrapper", props.reverse ? "left" : "right");
233 };
234 const renderButtonContent = (value, index) => {
235 const dragging = dragStatus.value === "dragging";
236 if (typeof index === "number") {
237 const slot = slots[index === 0 ? "left-button" : "right-button"];
238 let dragIndex;
239 if (dragging && Array.isArray(current)) {
240 dragIndex = current[0] > current[1] ? buttonIndex ^ 1 : buttonIndex;
241 }
242 if (slot) {
243 return slot({
244 value,
245 dragging,
246 dragIndex
247 });
248 }
249 }
250 if (slots.button) {
251 return slots.button({
252 value,
253 dragging
254 });
255 }
256 return (0, import_vue.createVNode)("div", {
257 "class": bem("button"),
258 "style": (0, import_utils.getSizeStyle)(props.buttonSize)
259 }, null);
260 };
261 const renderButton = (index) => {
262 const current2 = typeof index === "number" ? props.modelValue[index] : props.modelValue;
263 return (0, import_vue.createVNode)("div", {
264 "ref": slider[index != null ? index : 0],
265 "role": "slider",
266 "class": getButtonClassName(index),
267 "tabindex": props.disabled ? void 0 : 0,
268 "aria-valuemin": props.min,
269 "aria-valuenow": current2,
270 "aria-valuemax": props.max,
271 "aria-disabled": props.disabled || void 0,
272 "aria-readonly": props.readonly || void 0,
273 "aria-orientation": props.vertical ? "vertical" : "horizontal",
274 "onTouchstartPassive": (event) => {
275 if (typeof index === "number") {
276 buttonIndex = index;
277 }
278 onTouchStart(event);
279 },
280 "onTouchend": onTouchEnd,
281 "onTouchcancel": onTouchEnd,
282 "onClick": import_utils.stopPropagation
283 }, [renderButtonContent(current2, index)]);
284 };
285 updateValue(props.modelValue);
286 (0, import_use.useCustomFieldValue)(() => props.modelValue);
287 slider.forEach((item) => {
288 (0, import_use.useEventListener)("touchmove", onTouchMove, {
289 target: item
290 });
291 });
292 return () => (0, import_vue.createVNode)("div", {
293 "ref": root,
294 "style": wrapperStyle.value,
295 "class": bem({
296 vertical: props.vertical,
297 disabled: props.disabled
298 }),
299 "onClick": onClick
300 }, [(0, import_vue.createVNode)("div", {
301 "class": bem("bar"),
302 "style": barStyle.value
303 }, [props.range ? [renderButton(0), renderButton(1)] : renderButton()])]);
304 }
305});