calendar

Calendar with date and appointment picker

Calendar with date and appointment picker

Загрузка превью…

src/calendar/c-calendar-27.vue

<!--
  Кейс проверяет ЗАКРЫТОЕ состояние триггера (см. PORTING.md §5).
-->
<script setup lang="ts">
import { ref } from "vue"
import { Button } from "@/components/ui/button"
import { Card, CardContent } from "@/components/ui/card"
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"
import { ScrollArea } from "@/components/ui/scroll-area"
import { Calendar as CCalendar } from "@/components/ui/calendar"

const today = new Date(2026, 0, 15)
const date = ref<Date>(today)
const time = ref<string | null>(null)
const timeSlots = [
  { available: false, time: "09:00" },
  { available: true, time: "10:00" },
  { available: true, time: "10:30" },
]
</script>

<template>
  <Popover>
    <PopoverTrigger as-child>
      <Button class="group/pick-date w-60 justify-between" variant="outline">
        <span class="truncate text-muted-foreground">Pick a date</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" class="text-muted-foreground/80 group-hover:text-foreground shrink-0 transition-colors">
          <path d="M8 2v4" />
          <path d="M16 2v4" />
          <rect width="18" height="18" x="3" y="4" rx="2" />
          <path d="M3 10h18" />
        </svg>
      </Button>
    </PopoverTrigger>
    <PopoverContent align="start" class="w-auto p-0">
      <Card class="p-0">
        <CardContent class="p-0">
          <div class="flex max-sm:flex-col">
            <CCalendar mode="single" v-model="date" :disabled-fn="(d: Date) => d < today" />
            <div class="relative w-full max-sm:h-48 sm:w-40">
              <div class="absolute inset-0 py-4 max-sm:border-t">
                <ScrollArea class="h-full sm:border-s">
                  <div class="grid gap-1.5 px-5 max-sm:grid-cols-2">
                    <Button
                      v-for="slot in timeSlots"
                      :key="slot.time"
                      class="w-full"
                      :disabled="!slot.available"
                      :variant="time === slot.time ? 'default' : 'outline'"
                      size="sm"
                      @click="time = slot.time"
                    >
                      {{ slot.time }}
                    </Button>
                  </div>
                </ScrollArea>
              </div>
            </div>
          </div>
        </CardContent>
      </Card>
    </PopoverContent>
  </Popover>
</template>

Установка

npx shadcn-vue@latest add https://revueui.rootapi.dev/r/c-calendar-27.json

Зависимости реестра

Источник: порт из ReUI (Keenthemes, MIT)