78 lines
2.0 KiB
Vue
78 lines
2.0 KiB
Vue
<template>
|
||
<div class="relative inline-flex h-10 items-center overflow-hidden rounded-md border border-primary-500 bg-white" :class="widthClass">
|
||
<input
|
||
ref="nativeInput"
|
||
:value="pickerValue"
|
||
:type="pickerType"
|
||
class="pointer-events-none absolute inset-0 h-full w-full opacity-0"
|
||
tabindex="-1"
|
||
aria-hidden="true"
|
||
@input="onPickerInput"
|
||
@change="onPickerInput"
|
||
/>
|
||
<button
|
||
type="button"
|
||
class="h-10 px-3 text-lg font-semibold text-primary-500 hover:bg-tertiary-500 active:bg-tertiary-500 active:scale-[0.96]"
|
||
:aria-label="prevAriaLabel"
|
||
@click="emit('prev')"
|
||
>
|
||
‹
|
||
</button>
|
||
<button
|
||
type="button"
|
||
class="h-10 flex-1 border-x border-primary-500 px-4 text-sm font-semibold text-primary-500 text-center hover:bg-tertiary-500 active:bg-tertiary-500"
|
||
@click="openPicker"
|
||
>
|
||
{{ label }}
|
||
</button>
|
||
<button
|
||
type="button"
|
||
class="h-10 px-3 text-lg font-semibold text-primary-500 hover:bg-tertiary-500 active:bg-tertiary-500 active:scale-[0.96]"
|
||
:aria-label="nextAriaLabel"
|
||
@click="emit('next')"
|
||
>
|
||
›
|
||
</button>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
const props = withDefaults(defineProps<{
|
||
label: string
|
||
pickerType: 'date' | 'week' | 'month'
|
||
pickerValue: string
|
||
widthClass?: string
|
||
prevAriaLabel?: string
|
||
nextAriaLabel?: string
|
||
}>(), {
|
||
widthClass: 'w-[320px]',
|
||
prevAriaLabel: 'Précédent',
|
||
nextAriaLabel: 'Suivant'
|
||
})
|
||
|
||
const emit = defineEmits<{
|
||
(e: 'prev'): void
|
||
(e: 'next'): void
|
||
(e: 'pick', value: string): void
|
||
}>()
|
||
|
||
const nativeInput = ref<HTMLInputElement | null>(null)
|
||
|
||
const openPicker = () => {
|
||
const input = nativeInput.value
|
||
if (!input) return
|
||
if (typeof input.showPicker === 'function') {
|
||
input.showPicker()
|
||
return
|
||
}
|
||
input.focus()
|
||
input.click()
|
||
}
|
||
|
||
const onPickerInput = (event: Event) => {
|
||
const value = (event.target as HTMLInputElement).value
|
||
if (!value) return
|
||
emit('pick', value)
|
||
}
|
||
</script>
|