calendar

Range calendar with presets

Range calendar with presets

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

src/calendar/c-calendar-16.vue

<script setup lang="ts">
import { ref } from "vue"
import { Button } from "@/components/ui/button"
import { Card, CardContent } from "@/components/ui/card"
import { Calendar as CCalendar } from "@/components/ui/calendar"
import { CalendarDateRange as CCalendarRange } from "@/components/ui/calendar"

const today = new Date(2026, 0, 15)
function addDays(d: Date, n: number): Date {
  return new Date(d.getFullYear(), d.getMonth(), d.getDate() + n)
}
function startOfMonth(d: Date): Date {
  return new Date(d.getFullYear(), d.getMonth(), 1)
}
function endOfMonth(d: Date): Date {
  return new Date(d.getFullYear(), d.getMonth() + 1, 0)
}
function startOfYear(d: Date): Date {
  return new Date(d.getFullYear(), 0, 1)
}
function endOfYear(d: Date): Date {
  return new Date(d.getFullYear(), 11, 31)
}
function subMonths(d: Date, n: number): Date {
  return new Date(d.getFullYear(), d.getMonth() - n, d.getDate())
}
function subYears(d: Date, n: number): Date {
  return new Date(d.getFullYear() - n, d.getMonth(), d.getDate())
}

const yesterday: CCalendarRange = { from: addDays(today, -1), to: addDays(today, -1) }
const last7Days: CCalendarRange = { from: addDays(today, -6), to: today }
const last30Days: CCalendarRange = { from: addDays(today, -29), to: today }
const monthToDate: CCalendarRange = { from: startOfMonth(today), to: today }
const lastMonth: CCalendarRange = { from: startOfMonth(subMonths(today, 1)), to: endOfMonth(subMonths(today, 1)) }
const yearToDate: CCalendarRange = { from: startOfYear(today), to: today }
const lastYear: CCalendarRange = { from: startOfYear(subYears(today, 1)), to: endOfYear(subYears(today, 1)) }

const month = ref<Date>(today)
const date = ref<CCalendarRange | undefined>(last7Days)

function pick(range: CCalendarRange) {
  date.value = range
  month.value = range.to ?? today
}
</script>

<template>
  <Card class="p-0">
    <CardContent class="p-0">
      <div class="flex max-sm:flex-col">
        <div class="relative py-4 max-sm:order-1 max-sm:border-t sm:w-32">
          <div class="h-full sm:border-e">
            <div class="flex flex-col px-2">
              <Button class="w-full justify-start" size="sm" variant="ghost" @click="pick({ from: today, to: today })">Today</Button>
              <Button class="w-full justify-start" size="sm" variant="ghost" @click="pick(yesterday)">Yesterday</Button>
              <Button class="w-full justify-start" size="sm" variant="ghost" @click="pick(last7Days)">Last 7 days</Button>
              <Button class="w-full justify-start" size="sm" variant="ghost" @click="pick(last30Days)">Last 30 days</Button>
              <Button class="w-full justify-start" size="sm" variant="ghost" @click="pick(monthToDate)">Month to date</Button>
              <Button class="w-full justify-start" size="sm" variant="ghost" @click="pick(lastMonth)">Last month</Button>
              <Button class="w-full justify-start" size="sm" variant="ghost" @click="pick(yearToDate)">Year to date</Button>
              <Button class="w-full justify-start" size="sm" variant="ghost" @click="pick(lastYear)">Last year</Button>
            </div>
          </div>
        </div>
        <CCalendar
          mode="range"
          v-model="date"
          :month="month"
          @update:month="month = $event"
          :disabled-fn="(d: Date) => d > today"
        />
      </div>
    </CardContent>
  </Card>
</template>

Установка

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

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

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