webcake-ui-kit 1.1.8 → 1.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webcake-ui-kit",
3
- "version": "1.1.8",
3
+ "version": "1.1.9",
4
4
  "description": "UI Kit for Vue 2 && 3 - Pure Options API",
5
5
  "main": "src/index.js",
6
6
  "module": "src/index.js",
@@ -6,6 +6,7 @@
6
6
  'ui-slider--disabled': disabled,
7
7
  'ui-slider--range': range
8
8
  }"
9
+ :style="rootStyle"
9
10
  >
10
11
  <div class="ui-slider__track" ref="track" @click="onTrackClick">
11
12
  <div class="ui-slider__fill" :style="fillStyle" />
@@ -87,7 +88,19 @@ export default {
87
88
  return ['horizontal', 'vertical'].indexOf(v) !== -1
88
89
  }
89
90
  },
90
- disabled: { type: Boolean, default: false }
91
+ disabled: { type: Boolean, default: false },
92
+ width: { type: [String, Number], default: null },
93
+ stepRanges: {
94
+ type: Array,
95
+ default: function () {
96
+ return []
97
+ },
98
+ validator: function (v) {
99
+ return v.every(function (seg) {
100
+ return typeof seg.step === 'number' && seg.step > 0
101
+ })
102
+ }
103
+ }
91
104
  },
92
105
 
93
106
  emits: ['change', 'input', 'update:modelValue'],
@@ -101,6 +114,10 @@ export default {
101
114
  localRangeMin: rangeInit[0],
102
115
  localRangeMax: rangeInit[1],
103
116
  dragging: null,
117
+ dragAccum: 0,
118
+ dragLastX: 0,
119
+ dragLastY: 0,
120
+ dragTrackRect: null,
104
121
  boundMouseMove: null,
105
122
  boundMouseUp: null,
106
123
  boundTouchMove: null,
@@ -131,10 +148,28 @@ export default {
131
148
  }
132
149
  },
133
150
  computed: {
151
+ rootStyle: function () {
152
+ if (this.width === null) return {}
153
+ return { width: typeof this.width === 'number' ? this.width + 'px' : this.width }
154
+ },
155
+ totalSteps: function () {
156
+ if (!this.stepRanges || this.stepRanges.length === 0) {
157
+ return (this.max - this.min) / this.step
158
+ }
159
+ var total = 0
160
+ var from = this.min
161
+ for (var i = 0; i < this.stepRanges.length; i++) {
162
+ var seg = this.stepRanges[i]
163
+ var to = seg.to !== undefined ? seg.to : this.max
164
+ total += (to - from) / seg.step
165
+ from = to
166
+ }
167
+ return total
168
+ },
134
169
  fillStyle: function () {
135
- var minPct = (this.localRangeMin - this.min) / (this.max - this.min)
136
- var maxPct = (this.localRangeMax - this.min) / (this.max - this.min)
137
- var valPct = (this.localValue - this.min) / (this.max - this.min)
170
+ var minPct = this.valueToRatio(this.localRangeMin)
171
+ var maxPct = this.valueToRatio(this.localRangeMax)
172
+ var valPct = this.valueToRatio(this.localValue)
138
173
  if (this.orientation === 'vertical') {
139
174
  if (this.range) {
140
175
  return { bottom: minPct * 100 + '%', height: (maxPct - minPct) * 100 + '%' }
@@ -164,14 +199,67 @@ export default {
164
199
  document.removeEventListener('touchend', this.boundTouchEnd)
165
200
  },
166
201
  thumbStyle: function (val) {
167
- var p = (val - this.min) / (this.max - this.min)
202
+ var p = this.valueToRatio(val)
168
203
  if (this.orientation === 'vertical') {
169
204
  return { bottom: p * 100 + '%' }
170
205
  }
171
206
  return { left: p * 100 + '%' }
172
207
  },
208
+ valueToRatio: function (val) {
209
+ if (!this.stepRanges || this.stepRanges.length === 0) {
210
+ return (val - this.min) / (this.max - this.min)
211
+ }
212
+ var stepIndex = 0
213
+ var from = this.min
214
+ for (var i = 0; i < this.stepRanges.length; i++) {
215
+ var seg = this.stepRanges[i]
216
+ var to = seg.to !== undefined ? seg.to : this.max
217
+ if (val <= to || i === this.stepRanges.length - 1) {
218
+ stepIndex += (val - from) / seg.step
219
+ break
220
+ }
221
+ stepIndex += (to - from) / seg.step
222
+ from = to
223
+ }
224
+ return stepIndex / this.totalSteps
225
+ },
226
+ ratioToValue: function (ratio) {
227
+ if (!this.stepRanges || this.stepRanges.length === 0) {
228
+ return this.snap(this.min + ratio * (this.max - this.min))
229
+ }
230
+ var targetStep = ratio * this.totalSteps
231
+ var accSteps = 0
232
+ var from = this.min
233
+ for (var i = 0; i < this.stepRanges.length; i++) {
234
+ var seg = this.stepRanges[i]
235
+ var to = seg.to !== undefined ? seg.to : this.max
236
+ var segSteps = (to - from) / seg.step
237
+ if (targetStep <= accSteps + segSteps || i === this.stepRanges.length - 1) {
238
+ return this.snap(from + (targetStep - accSteps) * seg.step)
239
+ }
240
+ accSteps += segSteps
241
+ from = to
242
+ }
243
+ return this.max
244
+ },
245
+ getSegmentAt: function (val) {
246
+ if (!this.stepRanges || this.stepRanges.length === 0) {
247
+ return { from: this.min, to: this.max, step: this.step }
248
+ }
249
+ var from = this.min
250
+ for (var i = 0; i < this.stepRanges.length; i++) {
251
+ var seg = this.stepRanges[i]
252
+ var to = seg.to !== undefined ? seg.to : this.max
253
+ if (val <= to || i === this.stepRanges.length - 1) {
254
+ return { from: from, to: to, step: seg.step }
255
+ }
256
+ from = to
257
+ }
258
+ return { from: this.min, to: this.max, step: this.step }
259
+ },
173
260
  snap: function (val) {
174
- var stepped = Math.round((val - this.min) / this.step) * this.step + this.min
261
+ var seg = this.getSegmentAt(val)
262
+ var stepped = Math.round((val - seg.from) / seg.step) * seg.step + seg.from
175
263
  return Math.max(this.min, Math.min(this.max, parseFloat(stepped.toFixed(10))))
176
264
  },
177
265
  valueFromPointer: function (clientX, clientY) {
@@ -183,32 +271,72 @@ export default {
183
271
  ratio = (clientX - rect.left) / rect.width
184
272
  }
185
273
  ratio = Math.max(0, Math.min(1, ratio))
186
- return this.snap(this.min + ratio * (this.max - this.min))
274
+ return this.ratioToValue(ratio)
187
275
  },
188
- startDrag: function (which) {
276
+ valueAtStepOffset: function (baseVal, stepDelta) {
277
+ var baseStep = Math.round(this.valueToRatio(baseVal) * this.totalSteps)
278
+ var targetStep = Math.max(0, Math.min(this.totalSteps, baseStep + stepDelta))
279
+ return this.ratioToValue(targetStep / this.totalSteps)
280
+ },
281
+ startDrag: function (which, event) {
189
282
  if (this.disabled) return
190
283
  this.dragging = which
284
+ this.dragLastX = event.clientX
285
+ this.dragLastY = event.clientY
286
+ this.dragAccum = 0
287
+ this.dragTrackRect = this.$refs.track.getBoundingClientRect()
191
288
  document.addEventListener('mousemove', this.boundMouseMove)
192
289
  document.addEventListener('mouseup', this.boundMouseUp)
193
290
  },
194
- startDragTouch: function (which) {
291
+ startDragTouch: function (which, event) {
195
292
  if (this.disabled) return
196
293
  this.dragging = which
294
+ var t = event.touches[0]
295
+ this.dragLastX = t.clientX
296
+ this.dragLastY = t.clientY
297
+ this.dragAccum = 0
298
+ this.dragTrackRect = this.$refs.track.getBoundingClientRect()
197
299
  document.addEventListener('touchmove', this.boundTouchMove, { passive: false })
198
300
  document.addEventListener('touchend', this.boundTouchEnd)
199
301
  },
200
302
  onMouseMove: function (event) {
201
303
  if (!this.dragging) return
202
- this.applyValue(this.dragging, this.valueFromPointer(event.clientX, event.clientY))
304
+ this.processDragDelta(this.dragging, event.clientX - this.dragLastX, event.clientY - this.dragLastY)
305
+ this.dragLastX = event.clientX
306
+ this.dragLastY = event.clientY
203
307
  },
204
308
  onTouchMove: function (event) {
205
309
  if (!this.dragging) return
206
310
  event.preventDefault()
207
311
  var t = event.touches[0]
208
- this.applyValue(this.dragging, this.valueFromPointer(t.clientX, t.clientY))
312
+ this.processDragDelta(this.dragging, t.clientX - this.dragLastX, t.clientY - this.dragLastY)
313
+ this.dragLastX = t.clientX
314
+ this.dragLastY = t.clientY
315
+ },
316
+ processDragDelta: function (which, deltaX, deltaY) {
317
+ var pixelsPerStep =
318
+ this.orientation === 'vertical'
319
+ ? this.dragTrackRect.height / this.totalSteps
320
+ : this.dragTrackRect.width / this.totalSteps
321
+ this.dragAccum += (this.orientation === 'vertical' ? -deltaY : deltaX) / pixelsPerStep
322
+
323
+ var steps =
324
+ this.dragAccum >= 1 ? Math.floor(this.dragAccum) : this.dragAccum <= -1 ? Math.ceil(this.dragAccum) : 0
325
+ if (steps === 0) return
326
+ this.dragAccum -= steps
327
+
328
+ var currentVal = which === 'single' ? this.localValue : which === 'min' ? this.localRangeMin : this.localRangeMax
329
+ var newVal = this.valueAtStepOffset(currentVal, steps)
330
+ if (newVal === currentVal) {
331
+ this.dragAccum = 0
332
+ return
333
+ }
334
+ this.applyValue(which, newVal)
209
335
  },
210
336
  stopDrag: function () {
211
337
  this.dragging = null
338
+ this.dragAccum = 0
339
+ this.dragTrackRect = null
212
340
  document.removeEventListener('mousemove', this.boundMouseMove)
213
341
  document.removeEventListener('mouseup', this.boundMouseUp)
214
342
  document.removeEventListener('touchmove', this.boundTouchMove)
@@ -224,9 +352,9 @@ export default {
224
352
  return
225
353
  }
226
354
  if (which === 'min') {
227
- this.localRangeMin = this.snap(Math.min(val, this.localRangeMax - this.step))
355
+ this.localRangeMin = this.snap(Math.min(val, this.localRangeMax - this.getSegmentAt(val).step))
228
356
  } else {
229
- this.localRangeMax = this.snap(Math.max(val, this.localRangeMin + this.step))
357
+ this.localRangeMax = this.snap(Math.max(val, this.localRangeMin + this.getSegmentAt(val).step))
230
358
  }
231
359
  arr = [this.localRangeMin, this.localRangeMax]
232
360
  this.$emit('input', arr)
@@ -253,26 +381,29 @@ export default {
253
381
  var isEnd = key === 'End'
254
382
  if (!isIncrease && !isDecrease && !isHome && !isEnd) return
255
383
  event.preventDefault()
256
- var current, newVal
384
+ var current, newVal, stepSize
257
385
  if (which === 'single') {
258
386
  current = this.localValue
259
- newVal = isHome ? this.min : isEnd ? this.max : current + (isIncrease ? this.step : -this.step)
387
+ stepSize = this.getSegmentAt(current).step
388
+ newVal = isHome ? this.min : isEnd ? this.max : current + (isIncrease ? stepSize : -stepSize)
260
389
  this.applyValue('single', this.snap(newVal))
261
390
  } else if (which === 'min') {
262
391
  current = this.localRangeMin
392
+ stepSize = this.getSegmentAt(current).step
263
393
  newVal = isHome
264
394
  ? this.min
265
395
  : isEnd
266
- ? this.localRangeMax - this.step
267
- : current + (isIncrease ? this.step : -this.step)
396
+ ? this.localRangeMax - stepSize
397
+ : current + (isIncrease ? stepSize : -stepSize)
268
398
  this.applyValue('min', this.snap(newVal))
269
399
  } else if (which === 'max') {
270
400
  current = this.localRangeMax
401
+ stepSize = this.getSegmentAt(current).step
271
402
  newVal = isHome
272
- ? this.localRangeMin + this.step
403
+ ? this.localRangeMin + stepSize
273
404
  : isEnd
274
405
  ? this.max
275
- : current + (isIncrease ? this.step : -this.step)
406
+ : current + (isIncrease ? stepSize : -stepSize)
276
407
  this.applyValue('max', this.snap(newVal))
277
408
  }
278
409
  }
@@ -2,7 +2,6 @@
2
2
  display: flex;
3
3
  align-items: center;
4
4
  width: 100%;
5
- min-width: 120px;
6
5
  padding: var(--spacing-xs) 0;
7
6
  user-select: none;
8
7
  -webkit-user-select: none;