date-selector
Date selector with dropdown menu
Date selector with dropdown menu
Загрузка превью…
src/date-selector/c-date-selector-4.vue
<!--
IconPlaceholder (иконки "calendar" в триггере диалога, "chevron-down" в
триггере переключателя языка) заменена инлайновым `<svg>`. Оба плавающих
слоя (Dialog, DropdownMenu) закрыты по умолчанию — их содержимое (включая
`DateSelector`) не монтируется, известное расхождение сетки календаря
сюда не попадает.
-->
<script setup lang="ts">
import { computed, ref, watch } from "vue"
import { DateSelector, DEFAULT_DATE_SELECTOR_I18N } from "@/components/reui/date-selector"
import { Button } from "@/components/ui/button"
import { Dialog, DialogClose, DialogContent, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"
import { DateSelectorValue } from "@/components/reui/date-selector"
const languageMetadata = {
en: { label: "English", flag: "🇺🇸", dateFormat: "MM/dd/yyyy", weekStartsOn: 0 as const, ui: { label: "Due date", hint: "Try: 2025, Q4, 05/10/2025", placeholder: "Select a date" } },
es: { label: "Español", flag: "🇪🇸", dateFormat: "dd/MM/yyyy", weekStartsOn: 1 as const, ui: { label: "Fecha de vencimiento", hint: "Prueba: 2025, T4, 05/10/2025", placeholder: "Seleccionar una fecha" } },
fr: { label: "Français", flag: "🇫🇷", dateFormat: "dd/MM/yyyy", weekStartsOn: 1 as const, ui: { label: "Date d'échéance", hint: "Essayez: 2025, T4, 05/10/2025", placeholder: "Sélectionner une date" } },
de: { label: "Deutsch", flag: "🇩🇪", dateFormat: "dd.MM.yyyy", weekStartsOn: 1 as const, ui: { label: "Fälligkeitsdatum", hint: "Versuchen Sie: 2025, Q4, 05.10.2025", placeholder: "Datum auswählen" } },
}
const languageOptions = Object.entries(languageMetadata).map(([value, meta]) => ({
value,
label: meta.label,
flag: meta.flag,
}))
const value = ref<DateSelectorValue | undefined>(undefined)
const open = ref(false)
const internalValue = ref<DateSelectorValue | undefined>(value.value)
const currentLanguage = ref<keyof typeof languageMetadata>("fr")
const currentMeta = computed(() => languageMetadata[currentLanguage.value] ?? languageMetadata.en)
const currentI18n = DEFAULT_DATE_SELECTOR_I18N
watch(open, (isOpen) => {
if (isOpen) {
internalValue.value = value.value
}
})
const displayText = computed(() => currentMeta.value.ui.placeholder)
</script>
<template>
<div class="flex h-full w-full grow flex-col items-stretch gap-4">
<div class="flex w-full justify-end">
<DropdownMenu>
<DropdownMenuTrigger as-child>
<Button variant="outline" size="sm" class="flex items-center gap-2">
<span>{{ currentMeta.flag }}</span>
<span>{{ currentMeta.label }}</span>
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
><path d="m6 9 6 6 6-6" /></svg>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="start">
<DropdownMenuItem
v-for="lang in languageOptions"
:key="lang.value"
class="flex items-center gap-2"
@click="currentLanguage = lang.value as keyof typeof languageMetadata"
>
<span>{{ lang.flag }}</span>
<span>{{ lang.label }}</span>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
<div class="flex grow items-center justify-center">
<Dialog v-model:open="open">
<DialogTrigger as-child>
<Button variant="outline" class="w-56 justify-start">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
><path d="M8 2v4" /><path d="M16 2v4" /><rect width="18" height="18" x="3" y="4" rx="2" /><path d="M3 10h18" /></svg>
{{ displayText }}
</Button>
</DialogTrigger>
<DialogContent class="sm:max-w-lg" :show-close-button="false">
<DialogHeader>
<DialogTitle>{{ currentMeta.ui.label }}</DialogTitle>
</DialogHeader>
<DateSelector
:value="internalValue"
@change="internalValue = $event"
:show-input="true"
:i18n="currentI18n"
:day-date-format="currentMeta.dateFormat"
:week-starts-on="currentMeta.weekStartsOn"
/>
<DialogFooter>
<DialogClose as-child>
<Button variant="outline">{{ currentI18n.cancel }}</Button>
</DialogClose>
<Button>{{ currentI18n.apply }}</Button>
</DialogFooter>
</DialogContent>
</Dialog>
</div>
</div>
</template>
Установка
npx shadcn-vue@latest add https://revueui.rootapi.dev/r/c-date-selector-4.jsonЗависимости реестра
Источник: порт из ReUI (Keenthemes, MIT)