better chart range slider
This commit is contained in:
@@ -1,10 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="chart-range-slider">
|
<div class="chart-range-slider">
|
||||||
<div ref="trackRef" class="track" @pointerdown="handleTrackPointerDown">
|
<div ref="trackRef" class="track" @pointerdown="handleTrackPointerDown">
|
||||||
|
<div
|
||||||
|
class="selection-hit"
|
||||||
|
:style="selectionHitStyle"
|
||||||
|
@pointerdown.stop="handleSelectionPointerDown"
|
||||||
|
/>
|
||||||
<div
|
<div
|
||||||
class="selection"
|
class="selection"
|
||||||
:style="selectionStyle"
|
:style="selectionStyle"
|
||||||
@pointerdown.stop="handleSelectionPointerDown"
|
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
class="thumb start"
|
class="thumb start"
|
||||||
@@ -45,6 +49,7 @@ const emit = defineEmits<{
|
|||||||
change: [value: number[]];
|
change: [value: number[]];
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
const minTouchWidth = 44;
|
||||||
const trackRef = ref<HTMLElement>();
|
const trackRef = ref<HTMLElement>();
|
||||||
const draggingMode = ref<DragMode>();
|
const draggingMode = ref<DragMode>();
|
||||||
const dragStartX = ref(0);
|
const dragStartX = ref(0);
|
||||||
@@ -61,6 +66,20 @@ const selectionStyle = computed(() => ({
|
|||||||
left: `${startPercent.value}%`,
|
left: `${startPercent.value}%`,
|
||||||
width: `${Math.max(0, endPercent.value - startPercent.value)}%`
|
width: `${Math.max(0, endPercent.value - startPercent.value)}%`
|
||||||
}));
|
}));
|
||||||
|
const selectionHitStyle = computed(() => {
|
||||||
|
const rect = trackRef.value?.getBoundingClientRect();
|
||||||
|
const selectionWidth = Math.max(0, endPercent.value - startPercent.value);
|
||||||
|
if (!rect || rect.width < minTouchWidth) {
|
||||||
|
return selectionStyle.value;
|
||||||
|
}
|
||||||
|
const touchWidthPercent = minTouchWidth / rect.width * 100;
|
||||||
|
const width = Math.max(selectionWidth, touchWidthPercent);
|
||||||
|
const center = (startPercent.value + endPercent.value) / 2;
|
||||||
|
return {
|
||||||
|
left: `${clamp(center - width / 2, 0, 100 - width)}%`,
|
||||||
|
width: `${width}%`
|
||||||
|
};
|
||||||
|
});
|
||||||
const startThumbStyle = computed(() => ({
|
const startThumbStyle = computed(() => ({
|
||||||
left: `${startPercent.value}%`
|
left: `${startPercent.value}%`
|
||||||
}));
|
}));
|
||||||
@@ -199,9 +218,17 @@ function clamp(value: number, min: number, max: number): number {
|
|||||||
|
|
||||||
.selection {
|
.selection {
|
||||||
height: .5rem;
|
height: .5rem;
|
||||||
|
z-index: 1;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background: var(--td-brand-color);
|
background: var(--td-brand-color);
|
||||||
border-radius: 999rem;
|
border-radius: 999rem;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selection-hit {
|
||||||
|
height: 2.25rem;
|
||||||
|
z-index: 3;
|
||||||
|
position: absolute;
|
||||||
touch-action: none;
|
touch-action: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,6 +238,7 @@ function clamp(value: number, min: number, max: number): number {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
width: 1.25rem;
|
width: 1.25rem;
|
||||||
height: 1.25rem;
|
height: 1.25rem;
|
||||||
|
z-index: 2;
|
||||||
border: .125rem solid var(--td-brand-color);
|
border: .125rem solid var(--td-brand-color);
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
|
|||||||
Reference in New Issue
Block a user