calendar

Preset time selection

Preset time selection

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

src/calendar/c-calendar-14.vue

<script setup lang="ts">
import { computed, ref } from "vue"
import { Button } from "@/components/ui/button"
import { Card, CardContent } from "@/components/ui/card"
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: false, time: "09:30" },
  { available: true, time: "10:00" },
  { available: true, time: "10:30" },
  { available: true, time: "11:00" },
  { available: true, time: "11:30" },
  { available: false, time: "12:00" },
  { available: true, time: "12:30" },
  { available: true, time: "13:00" },
  { available: true, time: "13:30" },
  { available: true, time: "14:00" },
  { available: false, time: "14:30" },
  { available: false, time: "15:00" },
  { available: true, time: "15:30" },
  { available: true, time: "16:00" },
  { available: true, time: "16:30" },
  { available: true, time: "17:00" },
  { available: true, time: "17:30" },
]

function isDisabled(d: Date): boolean {
  return d < today
}

function onSelect(d: Date | Date[] | { from?: Date; to?: Date } | undefined) {
  if (d instanceof Date) {
    date.value = d
    time.value = null
  }
}

const weekday = computed(() =>
  new Intl.DateTimeFormat("en-US", { weekday: "long", day: "numeric", timeZone: "UTC" }).format(
    new Date(Date.UTC(date.value.getFullYear(), date.value.getMonth(), date.value.getDate()))
  )
)
</script>

<template>
  <Card class="p-0">
    <CardContent class="p-0">
      <div class="flex max-sm:flex-col">
        <CCalendar mode="single" :model-value="date" :disabled-fn="isDisabled" @update:model-value="onSelect" />
        <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="space-y-3">
                <div class="flex h-5 shrink-0 items-center px-5">
                  <p class="text-sm font-medium">{{ weekday }}</p>
                </div>
                <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>
              </div>
            </ScrollArea>
          </div>
        </div>
      </div>
    </CardContent>
  </Card>
</template>

Установка

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

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

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