mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-14 20:19:34 +01:00
feat(Calendar): implement component (#2618)
Co-authored-by: Benjamin Canac <canacb1@gmail.com>
This commit is contained in:
@@ -93,6 +93,8 @@ const options = computed(() => {
|
||||
chip: key.toLowerCase().endsWith('color') ? { color: variant } : undefined
|
||||
}))
|
||||
|
||||
// TODO: process "undefined | Date | DateRange", https://github.com/nuxt/ui/issues/2651
|
||||
|
||||
return {
|
||||
name: key,
|
||||
label: key,
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
<script setup lang="ts">
|
||||
import { CalendarDate, DateFormatter, getLocalTimeZone } from '@internationalized/date'
|
||||
|
||||
const df = new DateFormatter('en-US', {
|
||||
dateStyle: 'medium'
|
||||
})
|
||||
|
||||
const modelValue = shallowRef(new CalendarDate(2022, 1, 10))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UPopover>
|
||||
<UButton color="neutral" variant="subtle" icon="i-lucide-calendar">
|
||||
{{ df.format(modelValue.toDate(getLocalTimeZone())) }}
|
||||
</UButton>
|
||||
|
||||
<template #content>
|
||||
<UCalendar v-model="modelValue" class="p-2" />
|
||||
</template>
|
||||
</UPopover>
|
||||
</template>
|
||||
@@ -0,0 +1,35 @@
|
||||
<script setup lang="ts">
|
||||
import { CalendarDate, DateFormatter, getLocalTimeZone } from '@internationalized/date'
|
||||
|
||||
const df = new DateFormatter('en-US', {
|
||||
dateStyle: 'medium'
|
||||
})
|
||||
|
||||
const modelValue = shallowRef({
|
||||
start: new CalendarDate(2022, 1, 20),
|
||||
end: new CalendarDate(2022, 2, 10)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UPopover>
|
||||
<UButton color="neutral" variant="subtle" icon="i-lucide-calendar">
|
||||
<template v-if="modelValue.start">
|
||||
<template v-if="modelValue.end">
|
||||
{{ df.format(modelValue.start.toDate(getLocalTimeZone())) }} - {{ df.format(modelValue.end.toDate(getLocalTimeZone())) }}
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
{{ df.format(modelValue.start.toDate(getLocalTimeZone())) }}
|
||||
</template>
|
||||
</template>
|
||||
<template v-else>
|
||||
Pick a date
|
||||
</template>
|
||||
</UButton>
|
||||
|
||||
<template #content>
|
||||
<UCalendar v-model="modelValue" class="p-2" :number-of-months="2" range />
|
||||
</template>
|
||||
</UPopover>
|
||||
</template>
|
||||
@@ -0,0 +1,17 @@
|
||||
<script setup lang="ts">
|
||||
import { CalendarDate } from '@internationalized/date'
|
||||
import type { Matcher } from 'radix-vue/date'
|
||||
|
||||
const modelValue = shallowRef({
|
||||
start: new CalendarDate(2022, 1, 1),
|
||||
end: new CalendarDate(2022, 1, 9)
|
||||
})
|
||||
|
||||
const isDateDisabled: Matcher = (date) => {
|
||||
return date.day >= 10 && date.day <= 16
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UCalendar v-model="modelValue" :is-date-disabled="isDateDisabled" range />
|
||||
</template>
|
||||
@@ -0,0 +1,30 @@
|
||||
<script setup lang="ts">
|
||||
import { CalendarDate } from '@internationalized/date'
|
||||
|
||||
const modelValue = shallowRef(new CalendarDate(2022, 1, 10))
|
||||
|
||||
function getColorByDate(date: Date) {
|
||||
const isWeekend = date.getDay() % 6 == 0
|
||||
const isDayMeeting = date.getDay() % 3 == 0
|
||||
|
||||
if (isWeekend) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
if (isDayMeeting) {
|
||||
return 'error'
|
||||
}
|
||||
|
||||
return 'success'
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UCalendar v-model="modelValue">
|
||||
<template #day="{ day }">
|
||||
<UChip :show="!!getColorByDate(day.toDate('UTC'))" :color="getColorByDate(day.toDate('UTC'))" size="2xs">
|
||||
{{ day.day }}
|
||||
</UChip>
|
||||
</template>
|
||||
</UCalendar>
|
||||
</template>
|
||||
@@ -0,0 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import { CalendarDate } from '@internationalized/date'
|
||||
|
||||
const modelValue = shallowRef(new CalendarDate(2023, 9, 10))
|
||||
const minDate = new CalendarDate(2023, 9, 1)
|
||||
const maxDate = new CalendarDate(2023, 9, 30)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UCalendar v-model="modelValue" :min-value="minDate" :max-value="maxDate" />
|
||||
</template>
|
||||
@@ -0,0 +1,17 @@
|
||||
<script setup lang="ts">
|
||||
import { CalendarDate } from '@internationalized/date'
|
||||
import type { Matcher } from 'radix-vue/date'
|
||||
|
||||
const modelValue = shallowRef({
|
||||
start: new CalendarDate(2022, 1, 1),
|
||||
end: new CalendarDate(2022, 1, 9)
|
||||
})
|
||||
|
||||
const isDateUnavailable: Matcher = (date) => {
|
||||
return date.day >= 10 && date.day <= 16
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UCalendar v-model="modelValue" :is-date-unavailable="isDateUnavailable" range />
|
||||
</template>
|
||||
210
docs/content/3.components/calendar.md
Normal file
210
docs/content/3.components/calendar.md
Normal file
@@ -0,0 +1,210 @@
|
||||
---
|
||||
title: Calendar
|
||||
description: A calendar component for selecting single dates, multiple dates or date ranges.
|
||||
links:
|
||||
- label: Calendar
|
||||
icon: i-custom-radix-vue
|
||||
to: https://www.radix-vue.com/components/calendar.html
|
||||
- label: GitHub
|
||||
icon: i-simple-icons-github
|
||||
to: https://github.com/nuxt/ui/tree/v3/src/runtime/components/Calendar.vue
|
||||
navigation.badge: New
|
||||
---
|
||||
|
||||
::note
|
||||
This component relies on the [@internationalized/date](https://react-spectrum.adobe.com/internationalized/date/index.html) package which provides objects and functions for representing and manipulating dates and times in a locale-aware manner.
|
||||
::
|
||||
|
||||
## Usage
|
||||
|
||||
Use the `v-model` directive to control the selected date.
|
||||
|
||||
::component-code
|
||||
---
|
||||
---
|
||||
::
|
||||
|
||||
<!-- TODO: Add example with default value -->
|
||||
|
||||
### Multiple
|
||||
|
||||
Use the `multiple` prop to allow multiple selections.
|
||||
|
||||
::component-code
|
||||
---
|
||||
ignore:
|
||||
- multiple
|
||||
props:
|
||||
multiple: true
|
||||
---
|
||||
::
|
||||
|
||||
### Range
|
||||
|
||||
Use the `range` prop to select a range of dates.
|
||||
|
||||
::component-code
|
||||
---
|
||||
ignore:
|
||||
- range
|
||||
props:
|
||||
range: true
|
||||
---
|
||||
::
|
||||
|
||||
### Color
|
||||
|
||||
Use the `color` prop to change the color of the calendar.
|
||||
|
||||
::component-code
|
||||
---
|
||||
props:
|
||||
color: neutral
|
||||
---
|
||||
::
|
||||
|
||||
### Size
|
||||
|
||||
Use the `size` prop to change the size of the calendar.
|
||||
|
||||
::component-code
|
||||
---
|
||||
props:
|
||||
size: xl
|
||||
---
|
||||
::
|
||||
|
||||
### Disabled
|
||||
|
||||
Use the `disabled` prop to disable the calendar.
|
||||
|
||||
::component-code
|
||||
---
|
||||
props:
|
||||
disabled: true
|
||||
---
|
||||
::
|
||||
|
||||
### Number Of Months
|
||||
|
||||
Use the `numberOfMonths` prop to change the number of months in the calendar.
|
||||
|
||||
::component-code
|
||||
---
|
||||
props:
|
||||
numberOfMonths: 3
|
||||
---
|
||||
::
|
||||
|
||||
### Month Controls
|
||||
|
||||
Use the `month-controls` prop to show the month controls. Defaults to `true`.
|
||||
|
||||
::component-code
|
||||
---
|
||||
props:
|
||||
monthControls: false
|
||||
---
|
||||
::
|
||||
|
||||
### Year Controls
|
||||
|
||||
Use the `year-controls` prop to show the year controls. Defaults to `true`.
|
||||
|
||||
::component-code
|
||||
---
|
||||
props:
|
||||
yearControls: false
|
||||
---
|
||||
::
|
||||
|
||||
### Fixed Weeks
|
||||
|
||||
Use the `fixed-weeks` prop to display the calendar with fixed weeks.
|
||||
|
||||
::component-code
|
||||
---
|
||||
props:
|
||||
fixedWeeks: false
|
||||
---
|
||||
::
|
||||
|
||||
## Examples
|
||||
|
||||
### With chip events
|
||||
|
||||
Use the [Chip](/components/chip) component to add events to specific days.
|
||||
|
||||
::component-example
|
||||
---
|
||||
name: 'calendar-events-example'
|
||||
---
|
||||
::
|
||||
|
||||
### With disabled dates
|
||||
|
||||
Use the `is-date-disabled` prop with a function to mark specific dates as disabled.
|
||||
|
||||
::component-example
|
||||
---
|
||||
name: 'calendar-disabled-dates-example'
|
||||
---
|
||||
::
|
||||
|
||||
### With unavailable dates
|
||||
|
||||
Use the `is-date-unavailable` prop with a function to mark specific dates as unavailable.
|
||||
|
||||
::component-example
|
||||
---
|
||||
name: 'calendar-unavailable-dates-example'
|
||||
---
|
||||
::
|
||||
|
||||
### With min/max dates
|
||||
|
||||
Use the `min-value` and `max-value` props to limit the dates.
|
||||
|
||||
::component-example
|
||||
---
|
||||
name: 'calendar-min-max-dates-example'
|
||||
---
|
||||
::
|
||||
|
||||
### As a DatePicker
|
||||
|
||||
Use a [Button](/components/button) and a [Popover](/components/popover) component to create a date picker.
|
||||
|
||||
::component-example
|
||||
---
|
||||
name: 'calendar-date-picker-example'
|
||||
---
|
||||
::
|
||||
|
||||
### As a DateRangePicker
|
||||
|
||||
Use a [Button](/components/button) and a [Popover](/components/popover) component to create a date range picker.
|
||||
|
||||
::component-example
|
||||
---
|
||||
name: 'calendar-date-range-picker-example'
|
||||
---
|
||||
::
|
||||
|
||||
## API
|
||||
|
||||
### Props
|
||||
|
||||
:component-props
|
||||
|
||||
### Slots
|
||||
|
||||
:component-slots
|
||||
|
||||
### Emits
|
||||
|
||||
:component-emits
|
||||
|
||||
## Theme
|
||||
|
||||
:component-theme
|
||||
@@ -771,7 +771,7 @@ name: 'input-menu-filter-fields-example'
|
||||
---
|
||||
::
|
||||
|
||||
### As a country picker
|
||||
### As a CountryPicker
|
||||
|
||||
This example demonstrates using the InputMenu as a country picker with lazy loading - countries are only fetched when the menu is opened.
|
||||
|
||||
|
||||
@@ -11,6 +11,10 @@ links:
|
||||
navigation.badge: New
|
||||
---
|
||||
|
||||
::note
|
||||
This component relies on the [@internationalized/number](https://react-spectrum.adobe.com/internationalized/number/index.html) package which provides utilities for formatting and parsing numbers across locales and numbering systems.
|
||||
::
|
||||
|
||||
## Usage
|
||||
|
||||
Use the `v-model` directive to control the value of the InputNumber.
|
||||
|
||||
@@ -806,7 +806,7 @@ name: 'select-menu-filter-fields-example'
|
||||
---
|
||||
::
|
||||
|
||||
### As a country picker
|
||||
### As a CountryPicker
|
||||
|
||||
This example demonstrates using the SelectMenu as a country picker with lazy loading - countries are only fetched when the menu is opened.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user