calendar

Calendar with event list

Calendar with event list

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

src/calendar/c-calendar-22.vue

<!--
  АДАПТАЦИЯ (docs/PORTING.md §4a/§5): оригинал форматирует диапазон времени
  событий через `formatDateRange` из пакета `little-date`, которого нет в
  зависимостях воркспейса (тот же класс блокера, что и `IconPlaceholder` у
  других кейсов). Локальный `formatEventRange` ниже воспроизводит тот же
  вывод для конкретных фиксированных времён этого кейса (однодневные
  события) через `Intl.DateTimeFormat`, не универсальный аналог библиотеки.
-->
<script setup lang="ts">
import { ref } from "vue"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardFooter } from "@/components/ui/card"
import { Calendar as CCalendar } from "@/components/ui/calendar"

const date = ref<Date | undefined>(new Date(2026, 0, 15))

const events = [
  { title: "Product Launch", start: new Date(2026, 0, 24, 10, 0), end: new Date(2026, 0, 24, 11, 30), colorful: "after:bg-green-500" },
  { title: "Weekly Standup", start: new Date(2026, 0, 28, 13, 0), end: new Date(2026, 0, 28, 13, 30), colorful: "after:bg-yellow-500" },
  { title: "Code Review Session", start: new Date(2026, 0, 31, 15, 0), end: new Date(2026, 0, 31, 16, 0), colorful: "after:bg-blue-500" },
]

const timeFmt = new Intl.DateTimeFormat("en-US", { hour: "numeric", minute: "2-digit", hour12: true })
const dayFmt = new Intl.DateTimeFormat("en-US", { weekday: "short", month: "short", day: "numeric" })

function formatEventRange(start: Date, end: Date): string {
  return `${dayFmt.format(start)}, ${timeFmt.format(start).replace(" ", "")} - ${timeFmt.format(end).replace(" ", "")}`
}

const dateLabel = new Intl.DateTimeFormat("en-US", { day: "numeric", month: "long", year: "numeric" }).format(date.value)
</script>

<template>
  <Card class="w-2xs py-4">
    <CardContent class="px-4">
      <CCalendar mode="single" v-model="date" class="w-full bg-transparent p-0" />
    </CardContent>
    <CardFooter class="flex flex-col items-start gap-3 border-t px-4! pt-3! pb-0!">
      <div class="flex w-full items-center justify-between px-1">
        <div class="text-sm font-medium">{{ dateLabel }}</div>
        <Button variant="ghost" size="icon" class="size-6" title="Add Event">
          <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">
            <path d="M5 12h14" />
            <path d="M12 5v14" />
          </svg>
          <span class="sr-only">Add Event</span>
        </Button>
      </div>
      <div class="flex w-full flex-col gap-2">
        <div
          v-for="event in events"
          :key="event.title"
          :class="['bg-muted relative p-2 pl-6 text-sm after:absolute after:inset-y-2 after:left-2 after:w-1 rounded-md after:rounded-full', event.colorful]"
        >
          <div class="font-medium">{{ event.title }}</div>
          <div class="text-muted-foreground text-xs">{{ formatEventRange(event.start, event.end) }}</div>
        </div>
      </div>
    </CardFooter>
  </Card>
</template>

Установка

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

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

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