feat: update

This commit is contained in:
Sadegh Barati 2024-04-01 13:26:54 +03:30
parent 0fc37dc782
commit a79a7ed5cd
7 changed files with 267 additions and 490 deletions

View File

@ -16,6 +16,7 @@
},
"dependencies": {
"@formkit/auto-animate": "^0.8.1",
"@internationalized/date": "^3.5.2",
"@radix-icons/vue": "^1.0.0",
"@stackblitz/sdk": "^1.9.0",
"@tanstack/vue-table": "^8.14.0",
@ -30,10 +31,9 @@
"embla-carousel": "^8.0.0",
"embla-carousel-autoplay": "^8.0.0",
"embla-carousel-vue": "^8.0.0",
"flat-internationalized-date": "^1.2.3",
"lucide-vue-next": "^0.359.0",
"magic-string": "^0.30.8",
"radix-vue": "^1.5.3",
"radix-vue": "^1.6.1",
"tailwindcss-animate": "^1.0.7",
"v-calendar": "^3.1.2",
"vaul-vue": "^0.1.0",
@ -68,8 +68,8 @@
"tsx": "^4.7.1",
"typescript": "^5.4.2",
"unplugin-icons": "^0.18.5",
"vite": "^5.2.2",
"vitepress": "^1.0.0-rc.45",
"vite": "^5.2.7",
"vitepress": "^1.0.1",
"vue-tsc": "^2.0.7"
}
}

View File

@ -9,7 +9,7 @@ primitive: https://www.radix-vue.com/components/calendar.html
## 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.
@ -27,6 +27,10 @@ You can use the `<Calendar />` component to build a date picker. See the [Date P
### Form
<ComponentPreview name="CalendarWithSelect" />
<ComponentPreview name="CalendarForm" />
## Advanced Customization
### Month & Year Selects
<ComponentPreview name="CalendarWithSelect" />

View File

@ -1,9 +1,9 @@
<script setup lang="ts">
import { ref } from 'vue'
import { getLocalTimeZone, today } from 'flat-internationalized-date'
import { type Ref, ref } from 'vue'
import { type DateValue, getLocalTimeZone, today } from '@internationalized/date'
import { Calendar } from '@/lib/registry/default/ui/calendar'
const value = ref(today(getLocalTimeZone()))
const value = ref(today(getLocalTimeZone())) as Ref<DateValue>
</script>
<template>

View File

@ -1,7 +1,7 @@
<script setup lang="ts">
import { h, ref } from 'vue'
import { DateFormatter, type DateValue, createCalendarDate, getLocalTimeZone, parseDate, today } from 'flat-internationalized-date'
import { useDateFormatter } from 'radix-vue'
import { computed, h, ref } from 'vue'
import { CalendarDate, DateFormatter, getLocalTimeZone, parseDate, today } from '@internationalized/date'
import { toDate } from 'radix-vue'
import { Calendar as CalendarIcon } from 'lucide-vue-next'
import { useForm } from 'vee-validate'
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 { cn } from '@/lib/utils'
const df = useDateFormatter('en')
const dateValue = ref<DateValue | undefined>()
const df = new DateFormatter('en-US', {
dateStyle: 'long',
})
const formSchema = toTypedSchema(z.object({
dob: z
@ -31,9 +32,16 @@ const formSchema = toTypedSchema(z.object({
const placeholder = ref()
const { handleSubmit } = useForm({
const { handleSubmit, setValues, values } = useForm({
validationSchema: formSchema,
initialValues: {
},
})
const value = computed({
get: () => values.dob ? parseDate(values.dob) : undefined,
set: val => val,
})
const onSubmit = handleSubmit((values) => {
@ -46,7 +54,7 @@ const onSubmit = handleSubmit((values) => {
<template>
<form class="space-y-8" @submit="onSubmit">
<FormField v-slot="{ value }" name="dob">
<FormField name="dob">
<FormItem class="flex flex-col">
<FormLabel>Date of birth</FormLabel>
<Popover>
@ -58,7 +66,7 @@ const onSubmit = handleSubmit((values) => {
!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" />
</Button>
<input hidden>
@ -67,17 +75,23 @@ const onSubmit = handleSubmit((values) => {
<PopoverContent class="p-0">
<Calendar
v-model:placeholder="placeholder"
v-model="dateValue"
v-model="value"
calendar-label="Date of birth"
initial-focus
:min-value="createCalendarDate({
day: 1,
month: 2,
year: 2024,
})"
:min-value="new CalendarDate(1900, 1, 1)"
:max-value="today(getLocalTimeZone())"
@update:model-value="(v) => {
console.log(v)
if (v) {
setValues({
dob: v.toString(),
})
}
else {
setValues({
dob: '',
})
}
}"
/>
</PopoverContent>

View File

@ -1,7 +1,7 @@
<script setup lang="ts">
import { type HTMLAttributes, computed, onMounted, ref, toRef } from 'vue'
import { CalendarRoot, type CalendarRootEmits, type CalendarRootProps, useForwardPropsEmits } from 'radix-vue'
import { CALENDAR, DateFormatter, getLocalTimeZone, temporalToString, toCalendar, toDate, today } from 'flat-internationalized-date'
import { type HTMLAttributes, type Ref, computed, onMounted, ref, toRaw, toRef } from 'vue'
import { CalendarRoot, type CalendarRootEmits, type CalendarRootProps, toDate, useForwardPropsEmits } from 'radix-vue'
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 {
Select,
@ -17,7 +17,7 @@ import { cn } from '@/lib/utils'
const props = withDefaults(defineProps<CalendarRootProps & { class?: HTMLAttributes['class'] }>(), {
modelValue: undefined,
placeholder() {
return toCalendar(today(getLocalTimeZone()), CALENDAR.GREGORIAN)
return today(getLocalTimeZone())
},
weekdayFormat: 'short',
})
@ -28,7 +28,7 @@ const delegatedProps = computed(() => {
return delegated
})
const placeholder = toRef(props.placeholder)
const placeholder = toRef(props.placeholder) as Ref<DateValue>
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script>
@ -36,7 +36,7 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
<template>
<CalendarRoot
v-slot="{ getMonths, getYears, formatter, date }"
v-slot="{ getMonths, getYears, formatter, grid, weekDays }"
v-model:placeholder="placeholder"
v-bind="forwarded"
:class="cn('rounded-md border p-3', props.class)"
@ -45,7 +45,18 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
<CalendarHeader>
<CalendarHeading class="flex w-full items-center justify-between gap-2">
<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%]">
<SelectValue placeholder="Select month" />
@ -53,10 +64,9 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
<SelectContent class="max-h-[200px]">
<SelectItem
v-for="month in getMonths"
:key="temporalToString(month)" :value="month.month.toString()"
@click="placeholder = month"
:key="month.toString()" :value="month.month.toString()"
>
{{ formatter.custom(month, { month: 'long' }) }}
{{ formatter.custom(toDate(month), { month: 'long' }) }}
</SelectItem>
</SelectContent>
</Select>
@ -70,8 +80,7 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
<SelectContent class="max-h-[200px]">
<SelectItem
v-for="yearValue in getYears({ startIndex: -10, endIndex: 10 })"
:key="temporalToString(yearValue)" :value="yearValue.year.toString()"
@click="placeholder = yearValue"
:key="yearValue.toString()" :value="yearValue.year.toString()"
>
{{ yearValue.year }}
</SelectItem>
@ -79,5 +88,33 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
</Select>
</CalendarHeading>
</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>
</template>

View File

@ -1,6 +1,6 @@
<script setup lang="ts">
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 { toTypedSchema } from '@vee-validate/zod'
import { z } from 'zod'

File diff suppressed because it is too large Load Diff