Changed filter slider layout
This commit is contained in:
@@ -1,8 +1,9 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useMap } from '@/stores/map';
|
import { useMap } from '@/stores/map';
|
||||||
import { PhCheck } from '@phosphor-icons/vue';
|
import { PhCheck, PhMinus, PhPlus } from '@phosphor-icons/vue';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import { CheckboxIndicator, CheckboxRoot } from 'reka-ui'
|
import { CheckboxIndicator, CheckboxRoot, NumberFieldDecrement, NumberFieldIncrement, NumberFieldInput, NumberFieldRoot, SliderRange, SliderRoot, SliderThumb, SliderTrack } from 'reka-ui'
|
||||||
|
import { ref, watch } from 'vue';
|
||||||
|
|
||||||
const { filterCovered, filterUncovered, filterKorrigo } = storeToRefs(useMap())
|
const { filterCovered, filterUncovered, filterKorrigo } = storeToRefs(useMap())
|
||||||
|
|
||||||
@@ -11,12 +12,37 @@ defineProps<{
|
|||||||
nbCovered?: number
|
nbCovered?: number
|
||||||
nbKorrigo?: number
|
nbKorrigo?: number
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
const MIN = 0
|
||||||
|
const MAX = 100
|
||||||
|
|
||||||
|
const minSpots = ref(MIN)
|
||||||
|
const maxSpots = ref(MAX)
|
||||||
|
const spotsRange = ref([minSpots.value, maxSpots.value])
|
||||||
|
|
||||||
|
watch(spotsRange, ([newMin, newMax]) => {
|
||||||
|
if (newMin === undefined || newMax === undefined) return
|
||||||
|
|
||||||
|
minSpots.value = newMin
|
||||||
|
maxSpots.value = newMax
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(minSpots, (val) => {
|
||||||
|
if (val !== spotsRange.value[0])
|
||||||
|
spotsRange.value = [Math.min(val, spotsRange.value[1]!), spotsRange.value[1]!]
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(maxSpots, (val) => {
|
||||||
|
if (val !== spotsRange.value[1])
|
||||||
|
spotsRange.value = [spotsRange.value[0]!, Math.max(val, spotsRange.value[0]!)]
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<aside class="absolute top-5 left-5 z-10 p-2 bg-slate-50 text-slate-950 text-xs rounded-xs">
|
<aside class="max-w-xs absolute top-5 left-5 z-10 p-2 bg-slate-50 text-slate-950 text-xs rounded-xs">
|
||||||
<form>
|
<form>
|
||||||
<div class="grid gap-1.5">
|
<div class="grid grid-cols-2 gap-1.5">
|
||||||
|
<div class="col-span-2">
|
||||||
<label class="flex flex-row gap-1.5 items-center text-sm cursor-pointer">
|
<label class="flex flex-row gap-1.5 items-center text-sm cursor-pointer">
|
||||||
<CheckboxRoot v-model="filterUncovered"
|
<CheckboxRoot v-model="filterUncovered"
|
||||||
class="hover:bg-stone-100 flex size-4 appearance-none items-center justify-center rounded-xs bg-foreground shadow-sm border focus-within:ring-1 cursor-pointer">
|
class="hover:bg-stone-100 flex size-4 appearance-none items-center justify-center rounded-xs bg-foreground shadow-sm border focus-within:ring-1 cursor-pointer">
|
||||||
@@ -24,16 +50,14 @@ defineProps<{
|
|||||||
<PhCheck :size="10" weight="bold" />
|
<PhCheck :size="10" weight="bold" />
|
||||||
</CheckboxIndicator>
|
</CheckboxIndicator>
|
||||||
</CheckboxRoot>
|
</CheckboxRoot>
|
||||||
|
|
||||||
<span class="select-none">
|
<span class="select-none">
|
||||||
Non-abrités
|
Non-abrités
|
||||||
|
<small v-if="nbUncovered">({{ nbUncovered }})</small>
|
||||||
<small v-if="nbUncovered">
|
|
||||||
({{ nbUncovered }})
|
|
||||||
</small>
|
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-span-2">
|
||||||
<label class="flex flex-row gap-1.5 items-center text-sm cursor-pointer">
|
<label class="flex flex-row gap-1.5 items-center text-sm cursor-pointer">
|
||||||
<CheckboxRoot v-model="filterCovered"
|
<CheckboxRoot v-model="filterCovered"
|
||||||
class="hover:bg-stone-100 flex size-4 appearance-none items-center justify-center rounded-xs bg-foreground shadow-sm border focus-within:ring-1 cursor-pointer">
|
class="hover:bg-stone-100 flex size-4 appearance-none items-center justify-center rounded-xs bg-foreground shadow-sm border focus-within:ring-1 cursor-pointer">
|
||||||
@@ -41,16 +65,14 @@ defineProps<{
|
|||||||
<PhCheck :size="10" weight="bold" />
|
<PhCheck :size="10" weight="bold" />
|
||||||
</CheckboxIndicator>
|
</CheckboxIndicator>
|
||||||
</CheckboxRoot>
|
</CheckboxRoot>
|
||||||
|
|
||||||
<span class="select-none">
|
<span class="select-none">
|
||||||
Abrités
|
Abrités
|
||||||
|
<small v-if="nbCovered">({{ nbCovered }})</small>
|
||||||
<small v-if="nbCovered">
|
|
||||||
({{ nbCovered }})
|
|
||||||
</small>
|
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-span-2">
|
||||||
<label class="flex flex-row gap-1.5 items-center text-sm cursor-pointer">
|
<label class="flex flex-row gap-1.5 items-center text-sm cursor-pointer">
|
||||||
<CheckboxRoot v-model="filterKorrigo"
|
<CheckboxRoot v-model="filterKorrigo"
|
||||||
class="hover:bg-stone-100 flex size-4 appearance-none items-center justify-center rounded-xs bg-foreground shadow-sm border focus-within:ring-1 cursor-pointer">
|
class="hover:bg-stone-100 flex size-4 appearance-none items-center justify-center rounded-xs bg-foreground shadow-sm border focus-within:ring-1 cursor-pointer">
|
||||||
@@ -58,16 +80,70 @@ defineProps<{
|
|||||||
<PhCheck :size="10" weight="bold" />
|
<PhCheck :size="10" weight="bold" />
|
||||||
</CheckboxIndicator>
|
</CheckboxIndicator>
|
||||||
</CheckboxRoot>
|
</CheckboxRoot>
|
||||||
|
|
||||||
<span class="select-none">
|
<span class="select-none">
|
||||||
Abonnement Korrigo
|
Abonnement Korrigo
|
||||||
|
<small v-if="nbKorrigo">({{ nbKorrigo }})</small>
|
||||||
<small v-if="nbKorrigo">
|
|
||||||
({{ nbKorrigo }})
|
|
||||||
</small>
|
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-1 col-span-2">
|
||||||
|
<label class="flex justify-between">
|
||||||
|
<span>Nombre de places</span>
|
||||||
|
|
||||||
|
<span class="text-muted-foreground">
|
||||||
|
{{ spotsRange[0] }}
|
||||||
|
–
|
||||||
|
{{ spotsRange[1] }}<template v-if="spotsRange[1] === 100">+</template>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div class="mt-1">
|
||||||
|
<SliderRoot v-model="spotsRange" class="relative flex items-center select-none touch-none w-full py-2"
|
||||||
|
:min="MIN" :max="MAX" :step="5">
|
||||||
|
<SliderTrack class="bg-muted/10 relative grow rounded-full h-1.5">
|
||||||
|
<SliderRange class="absolute bg-primary rounded-full h-full" />
|
||||||
|
</SliderTrack>
|
||||||
|
<SliderThumb
|
||||||
|
class="cursor-pointer size-4 bg-white rounded-full hover:bg-primary shadow-sm focus:outline-none focus:ring-2" />
|
||||||
|
<SliderThumb
|
||||||
|
class="cursor-pointer size-4 bg-white rounded-full hover:bg-primary shadow-sm focus:outline-none focus:ring-2" />
|
||||||
|
</SliderRoot>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- <div>
|
||||||
|
<NumberFieldRoot :min="MIN" :max="maxSpots" :step="5" v-model="minSpots" class="max-w-full">
|
||||||
|
<label>Min.</label>
|
||||||
|
<div
|
||||||
|
class="mt-1 flex items-center justify-center overflow-hidden border bg-white hover:bg-stone-50 rounded-lg shadow-sm h-8 focus-within:ring-2">
|
||||||
|
<NumberFieldDecrement class="p-2 pr-1 disabled:opacity-20 shrink-0">
|
||||||
|
<PhMinus :size="10" />
|
||||||
|
</NumberFieldDecrement>
|
||||||
|
<NumberFieldInput class="w-0 min-w-0 flex-1 bg-transparent text-center focus:outline-0 p-1" />
|
||||||
|
<NumberFieldIncrement class="p-2 pl-1 disabled:opacity-20 shrink-0">
|
||||||
|
<PhPlus :size="10" />
|
||||||
|
</NumberFieldIncrement>
|
||||||
|
</div>
|
||||||
|
</NumberFieldRoot>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<NumberFieldRoot :min="minSpots" :max="MAX" :step="5" v-model="maxSpots" class="max-w-full">
|
||||||
|
<label>Max.</label>
|
||||||
|
<div
|
||||||
|
class="mt-1 flex items-center justify-center overflow-hidden border bg-white hover:bg-stone-50 rounded-lg shadow-sm h-8 focus-within:ring-2">
|
||||||
|
<NumberFieldDecrement class="p-2 pr-1 disabled:opacity-20 shrink-0">
|
||||||
|
<PhMinus :size="10" />
|
||||||
|
</NumberFieldDecrement>
|
||||||
|
<NumberFieldInput class="w-0 min-w-0 flex-1 bg-transparent text-center focus:outline-0 p-1" />
|
||||||
|
<NumberFieldIncrement class="p-2 pl-1 disabled:opacity-20 shrink-0">
|
||||||
|
<PhPlus :size="10" />
|
||||||
|
</NumberFieldIncrement>
|
||||||
|
</div>
|
||||||
|
</NumberFieldRoot>
|
||||||
|
</div> -->
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</aside>
|
</aside>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ const { filterUncovered, filterCovered, filterKorrigo } = storeToRefs(useMap())
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Transition enter-from-class="opacity-0 translate-y-2"
|
<Transition enter-from-class="opacity-0 translate-y-2"
|
||||||
enter-active-class="transition-all duration-500 ease-out delay-300" enter-to-class="opacity-100 translate-y-0">
|
enter-active-class="transition-all duration-300 ease-out delay-500" enter-to-class="opacity-100 translate-y-0">
|
||||||
<BikeFilters v-if="state.status === 'success'" :nb-uncovered="nonCoveredParkingsSpots"
|
<BikeFilters v-if="state.status === 'success'" :nb-uncovered="nonCoveredParkingsSpots"
|
||||||
:nb-covered="coveredParkingsSpots" :nb-korrigo="premiumParkingsSpots" />
|
:nb-covered="coveredParkingsSpots" :nb-korrigo="premiumParkingsSpots" />
|
||||||
</Transition>
|
</Transition>
|
||||||
|
|||||||
Reference in New Issue
Block a user