Skip to content

Commit

Permalink
Add range slider & use it for the price slider
Browse files Browse the repository at this point in the history
  • Loading branch information
Jade-GG committed Jan 23, 2025
1 parent 977a9f0 commit 24685c2
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 30 deletions.
85 changes: 85 additions & 0 deletions resources/js/components/Elements/RangeSlider.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<script>
export default {
props: {
range: {
type: Object,
default: () => ({min: 0, max: 100})
},
current: {
type: Object,
default: () => ({min: undefined, max: undefined})
},
},
render() {
return this.$scopedSlots.default(this)
},
data() {
return {
minValue: null,
maxValue: null,
}
},
watch: {
minValue() {
if(this.minValue >= this.maxValue) {
this.minValue = this.maxValue - 1
}
},
maxValue() {
if(this.maxValue <= this.minValue) {
this.maxValue = this.minValue + 1
}
},
range() {
if(this.range.min == this.range.max && this.range.min == 0) {
return
}
if(this.minValue === null && this.maxValue === null) {
this.updateFromProps()
}
},
current() {
this.updateFromProps()
},
},
mounted() {
this.updateFromProps()
},
methods: {
updateFromProps() {
this.minValue = this.current.min ?? this.range.min
this.maxValue = this.current.max ?? this.range.max
},
percentage(amount) {
return (amount - this.range.min) / (this.range.max - this.range.min) * 100
},
updateRefinement() {
this.$emit('change', {
min: this.minValue,
max: this.maxValue
})
},
},
computed: {
minThumb() {
return Math.max(this.percentage(this.minValue), 0)
},
maxThumb() {
return Math.max(100 - this.percentage(this.maxValue), 0)
},
},
}
</script>
8 changes: 7 additions & 1 deletion resources/js/components/Listing/Listing.vue
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,15 @@ export default {
},
searchkit: function () {
let url = new URL(config.es_url)
let searchkit = new Searchkit({
connection: {
host: config.es_url,
host: url.origin,
auth: {
username: url.username,
password: url.password,
}
},
search_settings: {
// Are we using this? In the autocomplete maybe?
Expand Down
1 change: 1 addition & 0 deletions resources/js/vue-components.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,4 @@ Vue.component('listing', () => import('./components/Listing/Listing.vue'))
Vue.component('checkout-success', () => import('./components/Checkout/CheckoutSuccess.vue'))
Vue.component('popup', () => import('./components/Popup.vue'))
Vue.component('selected-filters-values', () => import('./components/Listing/Filters/SelectedFiltersValues.vue'))
Vue.component('range-slider', () => import('./components/Elements/RangeSlider.vue'))
36 changes: 36 additions & 0 deletions resources/views/components/input/range-slider.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<range-slider v-slot="rangeInputScope" {{ $attributes }}>
<div class="flex relative h-16 mx-5">
<input
type="range"
v-bind:disabled="!canRefine"
v-bind:min="rangeInputScope.range.min"
v-bind:max="rangeInputScope.range.max"
v-model="rangeInputScope.minValue"
v-on:change="rangeInputScope.updateRefinement"
class="absolute pointer-events-none appearance-none z-20 h-5 w-full opacity-0 cursor-pointer [&::-moz-range-thumb]:pointer-events-auto [&::-webkit-slider-thumb]:pointer-events-auto"
>

<input
type="range"
v-bind:disabled="!canRefine"
v-bind:min="rangeInputScope.range.min"
v-bind:max="rangeInputScope.range.max"
v-model="rangeInputScope.maxValue"
v-on:change="rangeInputScope.updateRefinement"
class="absolute pointer-events-none appearance-none z-20 h-5 w-full opacity-0 cursor-pointer [&::-moz-range-thumb]:pointer-events-auto [&::-webkit-slider-thumb]:pointer-events-auto"
>

<div class="relative z-10 h-1 w-full mt-2 mx-2">
<div class="absolute z-10 inset-0 rounded-md bg-border"></div>
<div class="absolute z-20 inset-y-0 rounded-md bg-primary" v-bind:style="'right:'+rangeInputScope.maxThumb+'%; left:'+rangeInputScope.minThumb+'%'"></div>
<div class="absolute z-30 size-5 top-0 left-0 bg-white border rounded-full -mt-2 -translate-x-1/2" v-bind:style="'left: '+rangeInputScope.minThumb+'%'"></div>
<div class="absolute z-30 size-5 top-0 right-0 bg-white border rounded-full -mt-2 translate-x-1/2" v-bind:style="'right: '+rangeInputScope.maxThumb+'%'"></div>
<div class="absolute z-30 top-4 left-0 bg-white border px-2 py-0.5 rounded-full -translate-x-1/2" v-bind:style="'left: '+rangeInputScope.minThumb+'%'">
@{{ rangeInputScope.minValue }}
</div>
<div class="absolute z-30 top-4 right-0 bg-white border px-2 py-0.5 rounded-full translate-x-1/2" v-bind:style="'right: '+rangeInputScope.maxThumb+'%'">
@{{ rangeInputScope.maxValue }}
</div>
</div>
</div>
</range-input>
34 changes: 5 additions & 29 deletions resources/views/listing/partials/filter/price.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,11 @@
>
<template v-slot="{ currentRefinement, range, canRefine, refine, sendEvent }">
<x-rapidez::filter.heading>
{{-- TODO: This should become a slider --}}
<div class="flex">
<input
class="w-1/2"
type="number"
:min="range.min"
:max="range.max"
:placeholder="range.min"
:disabled="!canRefine"
:value="currentRefinement.min"
v-on:input="refine({
min: $event.currentTarget.value,
max: currentRefinement.max,
})"
/>
<input
class="w-1/2"
type="number"
:min="range.min"
:max="range.max"
:placeholder="range.max"
:disabled="!canRefine"
:value="currentRefinement.max"
v-on:input="refine({
min: currentRefinement.min,
max: $event.currentTarget.value,
})"
/>
</div>
<x-rapidez::input.range-slider
v-bind:range="range"
v-bind:current="currentRefinement"
v-on:change="refine"
/>
</x-rapidez::filter.heading>
</template>
</ais-range-input>

0 comments on commit 24685c2

Please sign in to comment.