范围日历
AlphaS | M | T | W | T | F | S |
---|---|---|---|---|---|---|
29 | 30 | 1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | 1 | 2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 |
<script setup lang="ts">
import { Icon } from '@iconify/vue'
import type { DateValue } from '@internationalized/date'
import { RangeCalendarCell, RangeCalendarCellTrigger, RangeCalendarGrid, RangeCalendarGridBody, RangeCalendarGridHead, RangeCalendarGridRow, RangeCalendarHeadCell, RangeCalendarHeader, RangeCalendarHeading, RangeCalendarNext, RangeCalendarPrev, RangeCalendarRoot } from 'radix-vue'
function isDateUnavailable(date: DateValue) {
return date.day === 17 || date.day === 18
}
</script>
<template>
<RangeCalendarRoot
v-slot="{ weekDays, grid }"
:is-date-unavailable="isDateUnavailable"
class="rounded-xl bg-white p-4 shadow-xl"
fixed-weeks
>
<RangeCalendarHeader class="flex items-center justify-between">
<RangeCalendarPrev
class="inline-flex items-center cursor-pointer text-black justify-center rounded-[9px] bg-transparent w-8 h-8 hover:bg-black hover:text-white active:scale-98 active:transition-all focus:shadow-[0_0_0_2px] focus:shadow-black"
>
<Icon
icon="radix-icons:chevron-left"
class="w-6 h-6"
/>
</RangeCalendarPrev>
<RangeCalendarHeading class="text-[15px] text-black font-medium" />
<RangeCalendarNext
class="inline-flex items-center cursor-pointer justify-center text-black rounded-[9px] bg-transparent w-8 h-8 hover:bg-black hover:text-white active:scale-98 active:transition-all focus:shadow-[0_0_0_2px] focus:shadow-black"
>
<Icon
icon="radix-icons:chevron-right"
class="w-6 h-6"
/>
</RangeCalendarNext>
</RangeCalendarHeader>
<div
class="flex flex-col space-y-4 pt-4 sm:flex-row sm:space-x-4 sm:space-y-0"
>
<RangeCalendarGrid
v-for="month in grid"
:key="month.value.toString()"
class="w-full border-collapse select-none space-y-1"
>
<RangeCalendarGridHead>
<RangeCalendarGridRow class="mb-1 grid w-full grid-cols-7">
<RangeCalendarHeadCell
v-for="day in weekDays"
:key="day"
class="rounded-md text-xs text-green8"
>
{{ day }}
</RangeCalendarHeadCell>
</RangeCalendarGridRow>
</RangeCalendarGridHead>
<RangeCalendarGridBody class="grid">
<RangeCalendarGridRow
v-for="(weekDates, index) in month.rows"
:key="`weekDate-${index}`"
class="grid grid-cols-7"
>
<RangeCalendarCell
v-for="weekDate in weekDates"
:key="weekDate.toString()"
:date="weekDate"
>
<RangeCalendarCellTrigger
:day="weekDate"
:month="month.value"
class="relative flex items-center justify-center rounded-full whitespace-nowrap text-sm font-normal text-black w-8 h-8 outline-none focus:shadow-[0_0_0_2px] focus:shadow-black data-[disabled]:text-black/30 data-[selected]:!bg-green10 data-[selected]:text-white hover:bg-green5 data-[highlighted]:bg-green5 data-[unavailable]:pointer-events-none data-[unavailable]:text-black/30 data-[unavailable]:line-through before:absolute before:top-[5px] before:hidden before:rounded-full before:w-1 before:h-1 before:bg-white data-[today]:before:block data-[today]:before:bg-green9 "
/>
</RangeCalendarCell>
</RangeCalendarGridRow>
</RangeCalendarGridBody>
</RangeCalendarGrid>
</div>
</RangeCalendarRoot>
</template>
致谢
此组件的构建灵感来自于 melt-ui 中的实现。
功能
- 完整的键盘导航
- 可以是受控或不受控的
- 焦点完全管理
- 本地化支持
- 高度可组合
前言
该组件依赖于 @internationalized/date 包,该包解决了在 JavaScript 中处理日期和时间时遇到的许多问题。
我们强烈建议您通读该包的文档,以全面了解其工作原理,并且您需要将其安装到您的项目中才能使用与日期相关的组件。
安装
安装日期包。
$ npm add @internationalized/date
从您的命令行安装该组件。
$ npm add radix-vue
解剖
导入所有部分并将它们组合在一起。
<script setup>
import {
RangeCalendarCell,
RangeCalendarCellTrigger,
RangeCalendarGrid,
RangeCalendarGridBody,
RangeCalendarGridHead,
RangeCalendarGridRow,
RangeCalendarHeadCell,
RangeCalendarHeader,
RangeCalendarHeading,
RangeCalendarNext,
RangeCalendarPrev,
RangeCalendarRoot
} from 'radix-vue'
</script>
<template>
<RangeCalendarRoot>
<RangeCalendarHeader>
<RangeCalendarPrev />
<RangeCalendarHeading />
<RangeCalendarNext />
</RangeCalendarHeader>
<RangeCalendarGrid>
<RangeCalendarGridHead>
<RangeCalendarGridRow>
<RangeCalendarHeadCell />
</RangeCalendarGridRow>
</RangeCalendarGridHead>
<RangeCalendarGridBody>
<RangeCalendarGridRow>
<RangeCalendarCell>
<RangeCalendarCellTrigger />
</RangeCalendarCell>
</RangeCalendarGridRow>
</RangeCalendarGridBody>
</RangeCalendarGrid>
</RangeCalendarRoot>
</template>
API 参考
根
包含日历的所有部分
道具 | 默认 | 类型 |
---|---|---|
as | 'div' | AsTag | 组件 此组件应渲染成的元素或组件。可以通过 |
asChild | 布尔值 将默认渲染的元素更改为作为子元素传递的元素,合并其属性和行为。 阅读我们的 组合 指南以了解更多详细信息。 | |
calendarLabel | 字符串 日历的可访问标签 | |
defaultPlaceholder | DateValue 默认占位符日期 | |
defaultValue | { start: undefined, end: undefined } | DateRange 日历的默认值 |
dir | 'ltr' | 'rtl' 日历适用的阅读方向。 | |
disabled | false | 布尔值 日历是否禁用 |
fixedWeeks | false | 布尔值 是否始终在日历中显示 6 周 |
initialFocus | false | 布尔值 如果为真,日历将根据日历安装时可见的内容,聚焦选定的日期、当天或本月的第一天 |
isDateDisabled | Matcher 一个返回日期是否禁用的函数 | |
isDateUnavailable | Matcher 一个返回日期是否不可用的函数 | |
locale | 'en' | 字符串 用于格式化日期的区域设置 |
maxValue | DateValue 可以选择的最大日期 | |
minValue | DateValue 可以选择的最早日期 | |
modelValue | DateRange 日历的受控选中状态。可以绑定为 | |
nextPage | ((placeholder: DateValue) => DateValue) 一个返回日历下一页的函数。它接收组件内部的当前占位符作为参数。 | |
numberOfMonths | 1 | 数字 要一次显示的月份数 |
pagedNavigation | false | 布尔值 此属性会导致上一个和下一个按钮按一次显示的月份数进行导航,而不是一个月 |
placeholder | DateValue 占位符日期,用于确定未选择日期时显示哪个月。当用户浏览日历时,它会更新,可用于以编程方式控制日历视图 | |
preventDeselect | false | 布尔值 是否阻止用户在不先选择另一个日期的情况下取消选择日期 |
prevPage | ((placeholder: DateValue) => DateValue) 一个返回日历上一页的函数。它接收组件内部的当前占位符作为参数。 | |
readonly | false | 布尔值 日历是否只读 |
weekdayFormat | 'narrow' | 'narrow' | 'short' | 'long' 通过 weekdays 插槽道具提供的星期几字符串使用的格式 |
weekStartsOn | 0 | 0 | 1 | 2 | 3 | 4 | 5 | 6 日历开始的星期几 |
发射 | 有效载荷 |
---|---|
update:modelValue | [date: DateRange] 每当模型值发生变化时调用的事件处理程序 |
update:placeholder | [date: DateValue] 每当占位符值发生变化时调用的事件处理程序 |
update:startValue | [date: DateValue] 每当开始值发生变化时调用的事件处理程序 |
插槽(默认) | 有效载荷 |
---|---|
date | DateValue 占位符的当前日期 |
grid | Grid<DateValue>[] 日期网格 |
weekDays | 字符串[] 一周中的日子 |
weekStartsOn | 0 | 1 | 2 | 3 | 4 | 5 | 6 一周的开始 |
locale | 字符串 日历区域设置 |
fixedWeeks | 布尔值 是否始终在日历中显示 6 周 |
数据属性 | 价值 |
---|---|
[data-readonly] | 只读时出现 |
[data-disabled] | 禁用时出现 |
[data-invalid] | 无效时出现 |
标题
包含导航按钮和标题段。
道具 | 默认 | 类型 |
---|---|---|
as | 'div' | AsTag | 组件 此组件应渲染成的元素或组件。可以通过 |
asChild | 布尔值 将默认渲染的元素更改为作为子元素传递的元素,合并其属性和行为。 阅读我们的 组合 指南以了解更多详细信息。 |
上一个按钮
日历导航按钮。它根据当前日历视图,将日历向前导航一个月/一年/十年。
数据属性 | 价值 |
---|---|
[data-disabled] | 禁用时出现 |
道具 | 默认 | 类型 |
---|---|---|
as | 'button' | AsTag | 组件 此组件应渲染成的元素或组件。可以通过 |
asChild | 布尔值 将默认渲染的元素更改为作为子元素传递的元素,合并其属性和行为。 阅读我们的 组合 指南以了解更多详细信息。 | |
prevPage | ((placeholder: DateValue) => DateValue) 用于上一个页面的函数。覆盖了在 | |
step | 'month' | 'year' 要前进的日历单位 |
下一个按钮
日历导航按钮。它根据当前日历视图,将日历向后导航一个月/一年/十年。
道具 | 默认 | 类型 |
---|---|---|
as | 'button' | AsTag | 组件 此组件应渲染成的元素或组件。可以通过 |
asChild | 布尔值 将默认渲染的元素更改为作为子元素传递的元素,合并其属性和行为。 阅读我们的 组合 指南以了解更多详细信息。 | |
nextPage | ((placeholder: DateValue) => DateValue) 用于下一页的函数。覆盖了在 | |
step | 'month' | 'year' 要前进的日历单位 |
数据属性 | 价值 |
---|---|
[data-disabled] | 禁用时出现 |
标题
用于显示当前月份和年份的标题。
道具 | 默认 | 类型 |
---|---|---|
as | 'div' | AsTag | 组件 此组件应渲染成的元素或组件。可以通过 |
asChild | 布尔值 将默认渲染的元素更改为作为子元素传递的元素,合并其属性和行为。 阅读我们的 组合 指南以了解更多详细信息。 |
插槽(默认) | 有效载荷 |
---|---|
headingValue | 字符串 当前月份和年份 |
数据属性 | 价值 |
---|---|
[data-disabled] | 禁用时出现 |
网格
用于包装日历网格的容器。
道具 | 默认 | 类型 |
---|---|---|
as | 'table' | AsTag | 组件 此组件应渲染成的元素或组件。可以通过 |
asChild | 布尔值 将默认渲染的元素更改为作为子元素传递的元素,合并其属性和行为。 阅读我们的 组合 指南以了解更多详细信息。 |
数据属性 | 价值 |
---|---|
[data-readonly] | 只读时出现 |
[data-disabled] | 禁用时出现 |
网格头
用于包装网格头的容器。
道具 | 默认 | 类型 |
---|---|---|
as | 'thead' | AsTag | 组件 此组件应渲染成的元素或组件。可以通过 |
asChild | 布尔值 将默认渲染的元素更改为作为子元素传递的元素,合并其属性和行为。 阅读我们的 组合 指南以了解更多详细信息。 |
网格主体
用于包装网格主体的容器。
道具 | 默认 | 类型 |
---|---|---|
as | 'tbody' | AsTag | 组件 此组件应渲染成的元素或组件。可以通过 |
asChild | 布尔值 将默认渲染的元素更改为作为子元素传递的元素,合并其属性和行为。 阅读我们的 组合 指南以了解更多详细信息。 |
网格行
用于包装网格行的容器。
道具 | 默认 | 类型 |
---|---|---|
as | 'tr' | AsTag | 组件 此组件应渲染成的元素或组件。可以通过 |
asChild | 布尔值 将默认渲染的元素更改为作为子元素传递的元素,合并其属性和行为。 阅读我们的 组合 指南以了解更多详细信息。 |
头部单元格
用于包装头部单元格的容器。用于显示星期几。
道具 | 默认 | 类型 |
---|---|---|
as | 'th' | AsTag | 组件 此组件应渲染成的元素或组件。可以通过 |
asChild | 布尔值 将默认渲染的元素更改为作为子元素传递的元素,合并其属性和行为。 阅读我们的 组合 指南以了解更多详细信息。 |
单元格
用于包装日历单元格的容器。
道具 | 默认 | 类型 |
---|---|---|
as | 'td' | AsTag | 组件 此组件应渲染成的元素或组件。可以通过 |
asChild | 布尔值 将默认渲染的元素更改为作为子元素传递的元素,合并其属性和行为。 阅读我们的 组合 指南以了解更多详细信息。 | |
date* | DateValue |
数据属性 | 价值 |
---|---|
[data-disabled] | 禁用时出现 |
单元格触发器
用于显示单元格日期的可交互容器。点击它可以选择日期。
道具 | 默认 | 类型 |
---|---|---|
as | 'div' | AsTag | 组件 此组件应渲染成的元素或组件。可以通过 |
asChild | 布尔值 将默认渲染的元素更改为作为子元素传递的元素,合并其属性和行为。 阅读我们的 组合 指南以了解更多详细信息。 | |
day* | DateValue | |
month* | DateValue |
插槽(默认) | 有效载荷 |
---|---|
dayValue | 字符串 当前日期 |
数据属性 | 价值 |
---|---|
[data-selected] | 选中时出现 |
[data-value] | 日期的 ISO 字符串值。 |
[data-disabled] | 禁用时出现 |
[data-unavailable] | 不可用时出现 |
[data-today] | 当天时出现 |
[data-outside-view] | 日期不在其显示的当前月份中时出现。 |
[data-outside-visible-view] | 日期不在日历上可见的月份中时出现。 |
[data-selection-start] | 日期是选择的开始时出现。 |
[data-selection-end] | 日期是选择的结束时出现。 |
[data-highlighted] | 用户在选择范围时突出显示日期时出现。 |
[data-highlighted-start] | 日期是用户突出显示的范围的开始时出现。 |
[data-highlighted-end] | 日期是用户突出显示的范围的结束时出现。 |
[data-focused] | 聚焦时出现 |
无障碍
键盘交互
按键 | 描述 |
---|---|
Tab | 当焦点移动到日历时,聚焦第一个导航按钮。 |
空格 |
当焦点在 `CalendarNext` 或 `CalendarPrev` 上时,它会导航日历。否则,它会选择日期。
|
回车 |
当焦点在 `CalendarNext` 或 `CalendarPrev` 上时,它会导航日历。否则,它会选择日期。
|
左箭头右箭头上箭头下箭头 | 当焦点在 `CalendarCellTrigger` 上时,它会导航日期,必要时会更改月份/年份/十年。 |