diff --git a/docs/components/slider.md b/docs/components/slider.md index b101c721a..b4f8739b3 100644 --- a/docs/components/slider.md +++ b/docs/components/slider.md @@ -9,6 +9,7 @@ const valueTwo = ref(0) + diff --git a/lib/components/base/Slider.vue b/lib/components/base/Slider.vue index 4341c7b2f..53182d440 100644 --- a/lib/components/base/Slider.vue +++ b/lib/components/base/Slider.vue @@ -2,6 +2,15 @@
+
+
+
{{ min }} {{ unit }} @@ -64,6 +73,14 @@ const props = defineProps({ type: Boolean, default: true, }, + snapPoints: { + type: Array, + default: () => [], + }, + snapRange: { + type: Number, + default: 100, + }, disabled: { type: Boolean, default: false, @@ -88,9 +105,24 @@ const inputValueValid = (newValue) => { } else { currentValue.value = (parsedValue - (props.forceStep ? parsedValue % props.step : 0)).toString() } + emit('update:modelValue', parseInt(currentValue.value)) } +const onInputWithSnap = (value) => { + let parsedValue = parseInt(value) + + for (let snapPoint of props.snapPoints) { + const distance = Math.abs(snapPoint - parsedValue) + + if (distance < props.snapRange) { + parsedValue = snapPoint + } + } + + inputValueValid(parsedValue) +} + const onInput = (value) => { inputValueValid(value) } @@ -111,11 +143,15 @@ const onInput = (value) => { .slider-component, .slide-container { width: 100%; + + position: relative; } .slider-component .slide-container .slider { -webkit-appearance: none; appearance: none; + position: relative; + border-radius: var(--radius-sm); height: 0.25rem; background: linear-gradient( @@ -144,6 +180,7 @@ const onInput = (value) => { } .slider-component .slide-container .slider::-moz-range-thumb { + border: none; width: 0.75rem; height: 0.75rem; background: var(--color-brand); @@ -164,6 +201,29 @@ const onInput = (value) => { transition: 0.2s; } +.slider-component .slide-container .snap-points { + position: absolute; + width: calc(100% - 0.75rem); + left: calc(0.75rem / 2); + top: calc(1rem / 2); + + .snap-point { + position: absolute; + + width: 0.25rem; + height: 0.75rem; + border-radius: var(--radius-sm); + + background-color: var(--color-base); + + transform: translateX(calc(-0.25rem / 2)); + + &.green { + background-color: var(--color-brand); + } + } +} + .slider-input { width: 6rem; margin-left: 0.75rem;