feat: update
This commit is contained in:
parent
0fc37dc782
commit
a79a7ed5cd
|
|
@ -16,6 +16,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@formkit/auto-animate": "^0.8.1",
|
"@formkit/auto-animate": "^0.8.1",
|
||||||
|
"@internationalized/date": "^3.5.2",
|
||||||
"@radix-icons/vue": "^1.0.0",
|
"@radix-icons/vue": "^1.0.0",
|
||||||
"@stackblitz/sdk": "^1.9.0",
|
"@stackblitz/sdk": "^1.9.0",
|
||||||
"@tanstack/vue-table": "^8.14.0",
|
"@tanstack/vue-table": "^8.14.0",
|
||||||
|
|
@ -30,10 +31,9 @@
|
||||||
"embla-carousel": "^8.0.0",
|
"embla-carousel": "^8.0.0",
|
||||||
"embla-carousel-autoplay": "^8.0.0",
|
"embla-carousel-autoplay": "^8.0.0",
|
||||||
"embla-carousel-vue": "^8.0.0",
|
"embla-carousel-vue": "^8.0.0",
|
||||||
"flat-internationalized-date": "^1.2.3",
|
|
||||||
"lucide-vue-next": "^0.359.0",
|
"lucide-vue-next": "^0.359.0",
|
||||||
"magic-string": "^0.30.8",
|
"magic-string": "^0.30.8",
|
||||||
"radix-vue": "^1.5.3",
|
"radix-vue": "^1.6.1",
|
||||||
"tailwindcss-animate": "^1.0.7",
|
"tailwindcss-animate": "^1.0.7",
|
||||||
"v-calendar": "^3.1.2",
|
"v-calendar": "^3.1.2",
|
||||||
"vaul-vue": "^0.1.0",
|
"vaul-vue": "^0.1.0",
|
||||||
|
|
@ -68,8 +68,8 @@
|
||||||
"tsx": "^4.7.1",
|
"tsx": "^4.7.1",
|
||||||
"typescript": "^5.4.2",
|
"typescript": "^5.4.2",
|
||||||
"unplugin-icons": "^0.18.5",
|
"unplugin-icons": "^0.18.5",
|
||||||
"vite": "^5.2.2",
|
"vite": "^5.2.7",
|
||||||
"vitepress": "^1.0.0-rc.45",
|
"vitepress": "^1.0.1",
|
||||||
"vue-tsc": "^2.0.7"
|
"vue-tsc": "^2.0.7"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ primitive: https://www.radix-vue.com/components/calendar.html
|
||||||
|
|
||||||
## About
|
## About
|
||||||
|
|
||||||
The `<Calendar />` component is built on top of the [RadixVue Calendar](https://www.radix-vue.com/components/calendar.html) component, which uses the [flat-internationalized-date](https://github.com/epr3/flat-internationalized-date) package to handle dates.
|
The `<Calendar />` component is built on top of the [RadixVue Calendar](https://www.radix-vue.com/components/calendar.html) component, which uses the [@internationalized/date](https://react-spectrum.adobe.com/internationalized/date/index.html) package to handle dates.
|
||||||
|
|
||||||
If you're looking for a range calendar, check out the [Range Calendar](#asdasd) component.
|
If you're looking for a range calendar, check out the [Range Calendar](#asdasd) component.
|
||||||
|
|
||||||
|
|
@ -27,6 +27,10 @@ You can use the `<Calendar />` component to build a date picker. See the [Date P
|
||||||
|
|
||||||
### Form
|
### Form
|
||||||
|
|
||||||
<ComponentPreview name="CalendarWithSelect" />
|
|
||||||
|
|
||||||
<ComponentPreview name="CalendarForm" />
|
<ComponentPreview name="CalendarForm" />
|
||||||
|
|
||||||
|
## Advanced Customization
|
||||||
|
|
||||||
|
### Month & Year Selects
|
||||||
|
|
||||||
|
<ComponentPreview name="CalendarWithSelect" />
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue'
|
import { type Ref, ref } from 'vue'
|
||||||
import { getLocalTimeZone, today } from 'flat-internationalized-date'
|
import { type DateValue, getLocalTimeZone, today } from '@internationalized/date'
|
||||||
import { Calendar } from '@/lib/registry/default/ui/calendar'
|
import { Calendar } from '@/lib/registry/default/ui/calendar'
|
||||||
|
|
||||||
const value = ref(today(getLocalTimeZone()))
|
const value = ref(today(getLocalTimeZone())) as Ref<DateValue>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { h, ref } from 'vue'
|
import { computed, h, ref } from 'vue'
|
||||||
import { DateFormatter, type DateValue, createCalendarDate, getLocalTimeZone, parseDate, today } from 'flat-internationalized-date'
|
import { CalendarDate, DateFormatter, getLocalTimeZone, parseDate, today } from '@internationalized/date'
|
||||||
import { useDateFormatter } from 'radix-vue'
|
import { toDate } from 'radix-vue'
|
||||||
import { Calendar as CalendarIcon } from 'lucide-vue-next'
|
import { Calendar as CalendarIcon } from 'lucide-vue-next'
|
||||||
import { useForm } from 'vee-validate'
|
import { useForm } from 'vee-validate'
|
||||||
import { toTypedSchema } from '@vee-validate/zod'
|
import { toTypedSchema } from '@vee-validate/zod'
|
||||||
|
|
@ -20,8 +20,9 @@ import { Popover, PopoverContent, PopoverTrigger } from '@/lib/registry/default/
|
||||||
import { toast } from '@/lib/registry/default/ui/toast'
|
import { toast } from '@/lib/registry/default/ui/toast'
|
||||||
import { cn } from '@/lib/utils'
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
const df = useDateFormatter('en')
|
const df = new DateFormatter('en-US', {
|
||||||
const dateValue = ref<DateValue | undefined>()
|
dateStyle: 'long',
|
||||||
|
})
|
||||||
|
|
||||||
const formSchema = toTypedSchema(z.object({
|
const formSchema = toTypedSchema(z.object({
|
||||||
dob: z
|
dob: z
|
||||||
|
|
@ -31,9 +32,16 @@ const formSchema = toTypedSchema(z.object({
|
||||||
|
|
||||||
const placeholder = ref()
|
const placeholder = ref()
|
||||||
|
|
||||||
const { handleSubmit } = useForm({
|
const { handleSubmit, setValues, values } = useForm({
|
||||||
validationSchema: formSchema,
|
validationSchema: formSchema,
|
||||||
|
initialValues: {
|
||||||
|
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const value = computed({
|
||||||
|
get: () => values.dob ? parseDate(values.dob) : undefined,
|
||||||
|
set: val => val,
|
||||||
})
|
})
|
||||||
|
|
||||||
const onSubmit = handleSubmit((values) => {
|
const onSubmit = handleSubmit((values) => {
|
||||||
|
|
@ -46,7 +54,7 @@ const onSubmit = handleSubmit((values) => {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<form class="space-y-8" @submit="onSubmit">
|
<form class="space-y-8" @submit="onSubmit">
|
||||||
<FormField v-slot="{ value }" name="dob">
|
<FormField name="dob">
|
||||||
<FormItem class="flex flex-col">
|
<FormItem class="flex flex-col">
|
||||||
<FormLabel>Date of birth</FormLabel>
|
<FormLabel>Date of birth</FormLabel>
|
||||||
<Popover>
|
<Popover>
|
||||||
|
|
@ -58,7 +66,7 @@ const onSubmit = handleSubmit((values) => {
|
||||||
!value && 'text-muted-foreground',
|
!value && 'text-muted-foreground',
|
||||||
)"
|
)"
|
||||||
>
|
>
|
||||||
<span>{{ value ? JSON.stringify(value) : "Pick a date" }} {{ JSON.stringify(value) }}</span>
|
<span>{{ value ? df.format(toDate(value)) : "Pick a date" }}</span>
|
||||||
<CalendarIcon class="ms-auto h-4 w-4 opacity-50" />
|
<CalendarIcon class="ms-auto h-4 w-4 opacity-50" />
|
||||||
</Button>
|
</Button>
|
||||||
<input hidden>
|
<input hidden>
|
||||||
|
|
@ -67,17 +75,23 @@ const onSubmit = handleSubmit((values) => {
|
||||||
<PopoverContent class="p-0">
|
<PopoverContent class="p-0">
|
||||||
<Calendar
|
<Calendar
|
||||||
v-model:placeholder="placeholder"
|
v-model:placeholder="placeholder"
|
||||||
v-model="dateValue"
|
v-model="value"
|
||||||
calendar-label="Date of birth"
|
calendar-label="Date of birth"
|
||||||
initial-focus
|
initial-focus
|
||||||
:min-value="createCalendarDate({
|
:min-value="new CalendarDate(1900, 1, 1)"
|
||||||
day: 1,
|
|
||||||
month: 2,
|
|
||||||
year: 2024,
|
|
||||||
})"
|
|
||||||
:max-value="today(getLocalTimeZone())"
|
:max-value="today(getLocalTimeZone())"
|
||||||
@update:model-value="(v) => {
|
@update:model-value="(v) => {
|
||||||
console.log(v)
|
if (v) {
|
||||||
|
setValues({
|
||||||
|
dob: v.toString(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setValues({
|
||||||
|
dob: '',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
}"
|
}"
|
||||||
/>
|
/>
|
||||||
</PopoverContent>
|
</PopoverContent>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { type HTMLAttributes, computed, onMounted, ref, toRef } from 'vue'
|
import { type HTMLAttributes, type Ref, computed, onMounted, ref, toRaw, toRef } from 'vue'
|
||||||
import { CalendarRoot, type CalendarRootEmits, type CalendarRootProps, useForwardPropsEmits } from 'radix-vue'
|
import { CalendarRoot, type CalendarRootEmits, type CalendarRootProps, toDate, useForwardPropsEmits } from 'radix-vue'
|
||||||
import { CALENDAR, DateFormatter, getLocalTimeZone, temporalToString, toCalendar, toDate, today } from 'flat-internationalized-date'
|
import { type DateValue, GregorianCalendar, getLocalTimeZone, toCalendar, today } from '@internationalized/date'
|
||||||
import { CalendarCell, CalendarCellTrigger, CalendarGrid, CalendarGridBody, CalendarGridHead, CalendarGridRow, CalendarHeadCell, CalendarHeader, CalendarHeading } from '@/lib/registry/default/ui/calendar'
|
import { CalendarCell, CalendarCellTrigger, CalendarGrid, CalendarGridBody, CalendarGridHead, CalendarGridRow, CalendarHeadCell, CalendarHeader, CalendarHeading } from '@/lib/registry/default/ui/calendar'
|
||||||
import {
|
import {
|
||||||
Select,
|
Select,
|
||||||
|
|
@ -17,7 +17,7 @@ import { cn } from '@/lib/utils'
|
||||||
const props = withDefaults(defineProps<CalendarRootProps & { class?: HTMLAttributes['class'] }>(), {
|
const props = withDefaults(defineProps<CalendarRootProps & { class?: HTMLAttributes['class'] }>(), {
|
||||||
modelValue: undefined,
|
modelValue: undefined,
|
||||||
placeholder() {
|
placeholder() {
|
||||||
return toCalendar(today(getLocalTimeZone()), CALENDAR.GREGORIAN)
|
return today(getLocalTimeZone())
|
||||||
},
|
},
|
||||||
weekdayFormat: 'short',
|
weekdayFormat: 'short',
|
||||||
})
|
})
|
||||||
|
|
@ -28,7 +28,7 @@ const delegatedProps = computed(() => {
|
||||||
|
|
||||||
return delegated
|
return delegated
|
||||||
})
|
})
|
||||||
const placeholder = toRef(props.placeholder)
|
const placeholder = toRef(props.placeholder) as Ref<DateValue>
|
||||||
|
|
||||||
const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -36,7 +36,7 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||||
<template>
|
<template>
|
||||||
<CalendarRoot
|
<CalendarRoot
|
||||||
|
|
||||||
v-slot="{ getMonths, getYears, formatter, date }"
|
v-slot="{ getMonths, getYears, formatter, grid, weekDays }"
|
||||||
v-model:placeholder="placeholder"
|
v-model:placeholder="placeholder"
|
||||||
v-bind="forwarded"
|
v-bind="forwarded"
|
||||||
:class="cn('rounded-md border p-3', props.class)"
|
:class="cn('rounded-md border p-3', props.class)"
|
||||||
|
|
@ -45,7 +45,18 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||||
<CalendarHeader>
|
<CalendarHeader>
|
||||||
<CalendarHeading class="flex w-full items-center justify-between gap-2">
|
<CalendarHeading class="flex w-full items-center justify-between gap-2">
|
||||||
<Select
|
<Select
|
||||||
:default-value="props.placeholder.month.toString()"
|
:default-value="placeholder.month.toString()"
|
||||||
|
@update:model-value="(v) => {
|
||||||
|
|
||||||
|
console.log(v)
|
||||||
|
// if (!v || !placeholder) return;
|
||||||
|
// if (Number(v) === placeholder?.month) return;
|
||||||
|
|
||||||
|
toRaw(placeholder).set({
|
||||||
|
month: 6,
|
||||||
|
})
|
||||||
|
console.log(toRaw(placeholder))
|
||||||
|
}"
|
||||||
>
|
>
|
||||||
<SelectTrigger aria-label="Select month" class="w-[60%]">
|
<SelectTrigger aria-label="Select month" class="w-[60%]">
|
||||||
<SelectValue placeholder="Select month" />
|
<SelectValue placeholder="Select month" />
|
||||||
|
|
@ -53,10 +64,9 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||||
<SelectContent class="max-h-[200px]">
|
<SelectContent class="max-h-[200px]">
|
||||||
<SelectItem
|
<SelectItem
|
||||||
v-for="month in getMonths"
|
v-for="month in getMonths"
|
||||||
:key="temporalToString(month)" :value="month.month.toString()"
|
:key="month.toString()" :value="month.month.toString()"
|
||||||
@click="placeholder = month"
|
|
||||||
>
|
>
|
||||||
{{ formatter.custom(month, { month: 'long' }) }}
|
{{ formatter.custom(toDate(month), { month: 'long' }) }}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
|
|
@ -70,8 +80,7 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||||
<SelectContent class="max-h-[200px]">
|
<SelectContent class="max-h-[200px]">
|
||||||
<SelectItem
|
<SelectItem
|
||||||
v-for="yearValue in getYears({ startIndex: -10, endIndex: 10 })"
|
v-for="yearValue in getYears({ startIndex: -10, endIndex: 10 })"
|
||||||
:key="temporalToString(yearValue)" :value="yearValue.year.toString()"
|
:key="yearValue.toString()" :value="yearValue.year.toString()"
|
||||||
@click="placeholder = yearValue"
|
|
||||||
>
|
>
|
||||||
{{ yearValue.year }}
|
{{ yearValue.year }}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
|
|
@ -79,5 +88,33 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||||
</Select>
|
</Select>
|
||||||
</CalendarHeading>
|
</CalendarHeading>
|
||||||
</CalendarHeader>
|
</CalendarHeader>
|
||||||
|
|
||||||
|
<div class="flex flex-col space-y-4 pt-4 sm:flex-row sm:gap-x-4 sm:gap-y-0">
|
||||||
|
<CalendarGrid v-for="month in grid" :key="month.value.toString()">
|
||||||
|
<CalendarGridHead>
|
||||||
|
<CalendarGridRow class="mb-1 grid w-full grid-cols-7">
|
||||||
|
<CalendarHeadCell
|
||||||
|
v-for="day in weekDays" :key="day"
|
||||||
|
>
|
||||||
|
{{ day }}
|
||||||
|
</CalendarHeadCell>
|
||||||
|
</CalendarGridRow>
|
||||||
|
</CalendarGridHead>
|
||||||
|
<CalendarGridBody class="grid">
|
||||||
|
<CalendarGridRow v-for="(weekDates, index) in month.rows" :key="`weekDate-${index}`" class="grid grid-cols-7">
|
||||||
|
<CalendarCell
|
||||||
|
v-for="weekDate in weekDates"
|
||||||
|
:key="weekDate.toString()"
|
||||||
|
:date="weekDate"
|
||||||
|
>
|
||||||
|
<CalendarCellTrigger
|
||||||
|
:day="weekDate"
|
||||||
|
:month="month.value"
|
||||||
|
/>
|
||||||
|
</CalendarCell>
|
||||||
|
</CalendarGridRow>
|
||||||
|
</CalendarGridBody>
|
||||||
|
</CalendarGrid>
|
||||||
|
</div>
|
||||||
</CalendarRoot>
|
</CalendarRoot>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { h, ref } from 'vue'
|
import { h, ref } from 'vue'
|
||||||
import { DateFormatter, getLocalTimeZone, toDate, today } from 'flat-internationalized-date'
|
import { DateFormatter, getLocalTimeZone, today } from '@internationalized/date'
|
||||||
import { useForm } from 'vee-validate'
|
import { useForm } from 'vee-validate'
|
||||||
import { toTypedSchema } from '@vee-validate/zod'
|
import { toTypedSchema } from '@vee-validate/zod'
|
||||||
import { z } from 'zod'
|
import { z } from 'zod'
|
||||||
|
|
|
||||||
626
pnpm-lock.yaml
626
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user