Calendar 日历

支持日期选择、范围选择和事件标记的日历组件。

组件特性

  • 📅 多种选择模式:支持单日选择、日期范围选择和范围时间选择。
  • 🏷️ 事件标记:支持在日期上显示事件标记。
  • 📆 双视图显示:支持 monthyear 视图模式。
  • 🛠️ 工具栏:支持带导航和今日按钮的自定义工具栏。
  • 🌍 国际化:支持 i18n 语言特定的日期格式化。
  • 🎨 主题定制:基于 BrConfigProvider 支持全局主题配置和 TailwindCSS 局部覆盖。

基础用法

展示基础的单选日历。注意:组件使用 @internationalized/date 来处理日期。

<script setup lang="ts">
import { ref } from 'vue'
import { today, getLocalTimeZone } from '@internationalized/date'
import { BrCalendar } from '@breezeui/vue'

const tz = getLocalTimeZone()
const date = ref(today(tz))
</script>

<template>
  <div class="flex flex-col gap-4 items-center">
    <BrCalendar v-model="date" />
    <p class="text-sm text-muted-foreground">
      Selected: {{ date?.toString() }}
    </p>
  </div>
</template>

日期范围选择

设置 mode="range" 即可开启日期范围选择。

<script setup lang="ts">
import { ref } from 'vue'
import { today, getLocalTimeZone } from '@internationalized/date'
import { BrCalendar } from '@breezeui/vue'

const tz = getLocalTimeZone()
const now = today(tz)

const range = ref({
  start: now,
  end: now.add({ days: 7 })
})
</script>

<template>
  <div class="flex flex-col gap-4 items-center">
    <BrCalendar 
      v-model="range" 
      mode="range" 
    />
    <div class="text-sm text-muted-foreground flex gap-4">
      <p>Start: {{ range?.start?.toString() }}</p>
      <p>End: {{ range?.end?.toString() }}</p>
    </div>
  </div>
</template>

事件标记

通过 events 属性可以为特定日期添加标记。支持 dot (圆点)、badge (徽标) 和 text (文本) 三种标记类型,并可自定义颜色。

<script setup lang="ts">
import { ref } from 'vue'
import { today, getLocalTimeZone } from '@internationalized/date'
import { BrCalendar } from '@breezeui/vue'

const tz = getLocalTimeZone()
const now = today(tz)

const value = ref(now)

const events = [
  // Dot Badge
  { 
    date: now, 
    type: 'dot', 
    color: 'hsl(var(--primary))', 
    label: 'Meeting' 
  },
  { 
    date: now.add({ days: 1 }), 
    type: 'dot', 
    color: 'hsl(var(--destructive))', 
    label: 'Urgent' 
  },
  // Badge
  { 
    date: now.add({ days: 3 }), 
    type: 'badge', 
    color: 'hsl(var(--warning))', 
    label: 'Wait' 
  },
  // Text Badge
  { 
    date: now.add({ days: 5 }), 
    type: 'text', 
    color: 'hsl(var(--success))', 
    label: 'Done' 
  }
]
</script>

<template>
  <div class="flex flex-col gap-4 items-center">
    <BrCalendar 
      v-model="value" 
      :events="events"
    />
  </div>
</template>

弹窗模式

结合 BrCalendarPopover 实现点击触发的日历弹窗。

<script setup lang="ts">
import { ref } from 'vue'
import { today, getLocalTimeZone } from '@internationalized/date'
import { BrCalendar, BrCalendarPopover, BrButton } from '@breezeui/vue'

const tz = getLocalTimeZone()
const date = ref(today(tz))
</script>

<template>
  <div class="flex items-center gap-4">
    <span class="text-sm font-medium">Select Date:</span>
    <BrCalendarPopover>
      <template #trigger>
        <BrButton variant="outline" class="w-[240px] justify-start text-left font-normal">
          {{ date ? date.toString() : 'Pick a date' }}
        </BrButton>
      </template>
      <BrCalendar v-model="date" display-mode="popover" />
    </BrCalendarPopover>
  </div>
</template>

API

BrCalendar Props

参数类型默认值说明
modelValueDateValue | DateValue[] | { start: DateValue, end: DateValue }-绑定的日期值
mode'single' | 'multiple' | 'range''single'选择模式
eventsEventMarker[][]日期事件标记
displayMode'inline' | 'popover''inline'展示模式
weekStartsOn0 | 1 | 2 | 3 | 4 | 5 | 60周起始日(0为周日)
showToolbarbooleantrue是否显示工具栏

EventMarker 类型

属性类型说明
datestring | Date | DateValue目标日期
type'dot' | 'badge' | 'text'标记类型
colorstring标记颜色(支持 CSS 变量)
labelstring悬浮提示文本