Merge remote-tracking branch 'origin/dev' into charting
This commit is contained in:
commit
e298048cea
|
|
@ -437,6 +437,13 @@ export const Index = {
|
||||||
component: () => import("../src/lib/registry/default/example/DatePickerForm.vue").then((m) => m.default),
|
component: () => import("../src/lib/registry/default/example/DatePickerForm.vue").then((m) => m.default),
|
||||||
files: ["../src/lib/registry/default/example/DatePickerForm.vue"],
|
files: ["../src/lib/registry/default/example/DatePickerForm.vue"],
|
||||||
},
|
},
|
||||||
|
"DatePickerWithIndependentMonths": {
|
||||||
|
name: "DatePickerWithIndependentMonths",
|
||||||
|
type: "components:example",
|
||||||
|
registryDependencies: ["range-calendar","button","popover","utils"],
|
||||||
|
component: () => import("../src/lib/registry/default/example/DatePickerWithIndependentMonths.vue").then((m) => m.default),
|
||||||
|
files: ["../src/lib/registry/default/example/DatePickerWithIndependentMonths.vue"],
|
||||||
|
},
|
||||||
"DatePickerWithPresets": {
|
"DatePickerWithPresets": {
|
||||||
name: "DatePickerWithPresets",
|
name: "DatePickerWithPresets",
|
||||||
type: "components:example",
|
type: "components:example",
|
||||||
|
|
@ -1698,6 +1705,13 @@ export const Index = {
|
||||||
component: () => import("../src/lib/registry/new-york/example/DatePickerForm.vue").then((m) => m.default),
|
component: () => import("../src/lib/registry/new-york/example/DatePickerForm.vue").then((m) => m.default),
|
||||||
files: ["../src/lib/registry/new-york/example/DatePickerForm.vue"],
|
files: ["../src/lib/registry/new-york/example/DatePickerForm.vue"],
|
||||||
},
|
},
|
||||||
|
"DatePickerWithIndependentMonths": {
|
||||||
|
name: "DatePickerWithIndependentMonths",
|
||||||
|
type: "components:example",
|
||||||
|
registryDependencies: ["range-calendar","button","popover","utils"],
|
||||||
|
component: () => import("../src/lib/registry/new-york/example/DatePickerWithIndependentMonths.vue").then((m) => m.default),
|
||||||
|
files: ["../src/lib/registry/new-york/example/DatePickerWithIndependentMonths.vue"],
|
||||||
|
},
|
||||||
"DatePickerWithPresets": {
|
"DatePickerWithPresets": {
|
||||||
name: "DatePickerWithPresets",
|
name: "DatePickerWithPresets",
|
||||||
type: "components:example",
|
type: "components:example",
|
||||||
|
|
|
||||||
|
|
@ -19,29 +19,29 @@
|
||||||
"@internationalized/date": "^3.5.2",
|
"@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.15.3",
|
"@tanstack/vue-table": "^8.16.0",
|
||||||
"@unovis/ts": "^1.4.0",
|
"@unovis/ts": "^1.4.0",
|
||||||
"@unovis/vue": "^1.4.0",
|
"@unovis/vue": "^1.4.0",
|
||||||
"@vee-validate/zod": "^4.12.6",
|
"@vee-validate/zod": "^4.12.6",
|
||||||
"@vueuse/core": "^10.9.0",
|
"@vueuse/core": "^10.9.0",
|
||||||
"class-variance-authority": "^0.7.0",
|
"class-variance-authority": "^0.7.0",
|
||||||
"clsx": "^2.1.0",
|
"clsx": "^2.1.1",
|
||||||
"codesandbox": "^2.2.3",
|
"codesandbox": "^2.2.3",
|
||||||
"date-fns": "^3.6.0",
|
"date-fns": "^3.6.0",
|
||||||
"embla-carousel": "^8.0.2",
|
"embla-carousel": "^8.0.2",
|
||||||
"embla-carousel-autoplay": "^8.0.2",
|
"embla-carousel-autoplay": "^8.0.2",
|
||||||
"embla-carousel-vue": "^8.0.2",
|
"embla-carousel-vue": "^8.0.2",
|
||||||
"lucide-vue-next": "^0.359.0",
|
"lucide-vue-next": "^0.359.0",
|
||||||
"magic-string": "^0.30.9",
|
"magic-string": "^0.30.10",
|
||||||
"radix-vue": "^1.7.0",
|
"radix-vue": "^1.7.2",
|
||||||
"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",
|
||||||
"vee-validate": "4.12.5",
|
"vee-validate": "4.12.5",
|
||||||
"vue": "^3.4.21",
|
"vue": "^3.4.24",
|
||||||
"vue-sonner": "^1.1.2",
|
"vue-sonner": "^1.1.2",
|
||||||
"vue-wrap-balancer": "^1.1.3",
|
"vue-wrap-balancer": "^1.1.3",
|
||||||
"zod": "^3.22.4"
|
"zod": "^3.23.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@iconify-json/lucide": "^1.1.180",
|
"@iconify-json/lucide": "^1.1.180",
|
||||||
|
|
@ -50,27 +50,27 @@
|
||||||
"@iconify-json/ri": "^1.1.18",
|
"@iconify-json/ri": "^1.1.18",
|
||||||
"@iconify-json/simple-icons": "^1.1.94",
|
"@iconify-json/simple-icons": "^1.1.94",
|
||||||
"@iconify-json/tabler": "^1.1.106",
|
"@iconify-json/tabler": "^1.1.106",
|
||||||
"@iconify/vue": "^4.1.1",
|
"@iconify/vue": "^4.1.2",
|
||||||
"@oxc-parser/wasm": "^0.1.0",
|
"@oxc-parser/wasm": "^0.1.0",
|
||||||
"@shikijs/transformers": "^1.3.0",
|
"@shikijs/transformers": "^1.3.0",
|
||||||
"@types/lodash.template": "^4.5.3",
|
"@types/lodash.template": "^4.5.3",
|
||||||
"@types/node": "^20.12.7",
|
"@types/node": "^20.12.7",
|
||||||
"@vitejs/plugin-vue": "^5.0.4",
|
"@vitejs/plugin-vue": "^5.0.4",
|
||||||
"@vitejs/plugin-vue-jsx": "^3.1.0",
|
"@vitejs/plugin-vue-jsx": "^3.1.0",
|
||||||
"@vue/compiler-core": "^3.4.21",
|
"@vue/compiler-core": "^3.4.24",
|
||||||
"@vue/compiler-dom": "^3.4.21",
|
"@vue/compiler-dom": "^3.4.24",
|
||||||
"@vue/tsconfig": "^0.5.1",
|
"@vue/tsconfig": "^0.5.1",
|
||||||
"autoprefixer": "^10.4.19",
|
"autoprefixer": "^10.4.19",
|
||||||
"lodash.template": "^4.5.0",
|
"lodash.template": "^4.5.0",
|
||||||
"pathe": "^1.1.2",
|
"pathe": "^1.1.2",
|
||||||
"rimraf": "^5.0.5",
|
"rimraf": "^5.0.5",
|
||||||
"shiki": "^1.3.0",
|
"shiki": "^1.3.0",
|
||||||
"tailwind-merge": "^2.2.2",
|
"tailwind-merge": "^2.3.0",
|
||||||
"tailwindcss": "^3.4.3",
|
"tailwindcss": "^3.4.3",
|
||||||
"tsx": "^4.7.2",
|
"tsx": "^4.7.2",
|
||||||
"typescript": "^5.4.2",
|
"typescript": "^5.4.5",
|
||||||
"unplugin-icons": "^0.18.5",
|
"unplugin-icons": "^0.18.5",
|
||||||
"vitepress": "^1.1.0",
|
"vitepress": "^1.1.3",
|
||||||
"vue-tsc": "^2.0.12"
|
"vue-tsc": "^2.0.14"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,10 @@ See installations instructions for the [Popover](/docs/components/popover), [Cal
|
||||||
|
|
||||||
<ComponentPreview name="DatePickerWithRange" />
|
<ComponentPreview name="DatePickerWithRange" />
|
||||||
|
|
||||||
|
### Date Range Picker with Independent Months
|
||||||
|
|
||||||
|
<ComponentPreview name="DatePickerWithIndependentMonths" />
|
||||||
|
|
||||||
### With Presets
|
### With Presets
|
||||||
|
|
||||||
<ComponentPreview name="DatePickerWithPresets" />
|
<ComponentPreview name="DatePickerWithPresets" />
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ primitive: https://www.radix-vue.com/components/range-calendar.html
|
||||||
|
|
||||||
## About
|
## About
|
||||||
|
|
||||||
The `<RangeCalendar />` component is built on top of the [RadixVue Range Calendar](https://www.bits-ui.com/docs/components/range-calendar) component, which uses the [@internationalized/date](https://react-spectrum.adobe.com/internationalized/date/index.html) package to handle dates.
|
The `<RangeCalendar />` component is built on top of the [RadixVue Range Calendar](https://www.radix-vue.com/components/date-range-picker.html) component, which uses the [@internationalized/date](https://react-spectrum.adobe.com/internationalized/date/index.html) package to handle dates.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ npm install -D typescript
|
||||||
### Install TailwindCSS module
|
### Install TailwindCSS module
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install -D @nuxtjs/tailwindcss
|
npx nuxi@latest module add @nuxtjs/tailwindcss
|
||||||
```
|
```
|
||||||
|
|
||||||
### Add `Nuxt` module
|
### Add `Nuxt` module
|
||||||
|
|
@ -36,7 +36,7 @@ npm install -D @nuxtjs/tailwindcss
|
||||||
Install the package below.
|
Install the package below.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install -D shadcn-nuxt
|
npx nuxi@latest module add shadcn-nuxt
|
||||||
```
|
```
|
||||||
|
|
||||||
</TabMarkdown>
|
</TabMarkdown>
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,12 @@ description: Install and configure Vite.
|
||||||
|
|
||||||
Start by creating a new Vue project using `vite`:
|
Start by creating a new Vue project using `vite`:
|
||||||
|
|
||||||
|
<Callout>
|
||||||
|
|
||||||
|
If you're using the JS template, `jsconfig.json` must exist for the CLI to run without errors.
|
||||||
|
|
||||||
|
</Callout>
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# npm 6.x
|
# npm 6.x
|
||||||
npm create vite@latest my-vue-app --template vue-ts
|
npm create vite@latest my-vue-app --template vue-ts
|
||||||
|
|
@ -24,12 +30,18 @@ Install `tailwindcss` and its peer dependencies, then generate your `tailwind.co
|
||||||
<TabsMarkdown>
|
<TabsMarkdown>
|
||||||
<TabMarkdown title="vite.config">
|
<TabMarkdown title="vite.config">
|
||||||
|
|
||||||
Vite already has [`postcss`](https://github.com/vitejs/vite/blob/main/packages/vite/package.json#L78) dependency so you don't have to install it again in your package.json
|
Vite already has [`postcss`](https://github.com/vitejs/vite/blob/main/packages/vite/package.json#89) dependency so you don't have to install it again in your package.json
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install -D tailwindcss autoprefixer
|
npm install -D tailwindcss autoprefixer
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<Callout>
|
||||||
|
|
||||||
|
If you're utilizing `postcss.config.js`, these changes will be inconsequential.
|
||||||
|
|
||||||
|
</Callout>
|
||||||
|
|
||||||
#### `vite.config`
|
#### `vite.config`
|
||||||
|
|
||||||
```typescript {5,6,9-13}
|
```typescript {5,6,9-13}
|
||||||
|
|
@ -77,9 +89,9 @@ Install `tailwindcss` and its peer dependencies, then generate your `tailwind.co
|
||||||
</TabMarkdown>
|
</TabMarkdown>
|
||||||
</TabsMarkdown>
|
</TabsMarkdown>
|
||||||
|
|
||||||
### Edit tsconfig.json
|
### Edit tsconfig/jsconfig.json
|
||||||
|
|
||||||
Add the code below to the compilerOptions of your tsconfig.json so your app can resolve paths without error
|
Add the code below to the compilerOptions of your `tsconfig.json` or `jsconfig.json` so your app can resolve paths without error
|
||||||
|
|
||||||
```json {4-7}
|
```json {4-7}
|
||||||
{
|
{
|
||||||
|
|
@ -126,6 +138,10 @@ export default defineConfig({
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Delete default Vite styles
|
||||||
|
|
||||||
|
Delete the default Vite stylesheet `./src/style.css`
|
||||||
|
|
||||||
### Run the CLI
|
### Run the CLI
|
||||||
|
|
||||||
Run the `shadcn-vue` init command to setup your project:
|
Run the `shadcn-vue` init command to setup your project:
|
||||||
|
|
@ -150,6 +166,19 @@ Configure the import alias for components: › @/components
|
||||||
Configure the import alias for utils: › @/lib/utils
|
Configure the import alias for utils: › @/lib/utils
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Update main.ts
|
||||||
|
|
||||||
|
Remove import for style.css and add tailwind style import `import './assets/index.css'`
|
||||||
|
|
||||||
|
```diff typescript {2,4}
|
||||||
|
import { createApp } from 'vue'
|
||||||
|
- import './style.css'
|
||||||
|
import App from './App.vue'
|
||||||
|
+ import './assets/index.css'
|
||||||
|
|
||||||
|
createApp(App).mount('#app')
|
||||||
|
```
|
||||||
|
|
||||||
### That's it
|
### That's it
|
||||||
|
|
||||||
You can now start adding components to your project.
|
You can now start adding components to your project.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,286 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { type Ref, ref, watch } from 'vue'
|
||||||
|
|
||||||
|
import {
|
||||||
|
Calendar as CalendarIcon,
|
||||||
|
ChevronLeft,
|
||||||
|
ChevronRight,
|
||||||
|
} from 'lucide-vue-next'
|
||||||
|
import {
|
||||||
|
CalendarDate,
|
||||||
|
type DateValue,
|
||||||
|
isEqualMonth,
|
||||||
|
} from '@internationalized/date'
|
||||||
|
|
||||||
|
import { type DateRange, RangeCalendarRoot, useDateFormatter } from 'radix-vue'
|
||||||
|
import { type Grid, createMonth, toDate } from 'radix-vue/date'
|
||||||
|
import {
|
||||||
|
RangeCalendarCell,
|
||||||
|
RangeCalendarCellTrigger,
|
||||||
|
RangeCalendarGrid,
|
||||||
|
RangeCalendarGridBody,
|
||||||
|
RangeCalendarGridHead,
|
||||||
|
RangeCalendarGridRow,
|
||||||
|
RangeCalendarHeadCell,
|
||||||
|
} from '@/lib/registry/default/ui/range-calendar'
|
||||||
|
import { Button, buttonVariants } from '@/lib/registry/default/ui/button'
|
||||||
|
import {
|
||||||
|
Popover,
|
||||||
|
PopoverContent,
|
||||||
|
PopoverTrigger,
|
||||||
|
} from '@/lib/registry/default/ui/popover'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
|
const value = ref({
|
||||||
|
start: new CalendarDate(2022, 1, 20),
|
||||||
|
end: new CalendarDate(2022, 1, 20).add({ days: 20 }),
|
||||||
|
}) as Ref<DateRange>
|
||||||
|
|
||||||
|
const locale = ref('en-US')
|
||||||
|
const formatter = useDateFormatter(locale.value)
|
||||||
|
|
||||||
|
const placeholder = ref(value.value.start) as Ref<DateValue>
|
||||||
|
const secondMonthPlaceholder = ref(value.value.end) as Ref<DateValue>
|
||||||
|
|
||||||
|
const firstMonth = ref(
|
||||||
|
createMonth({
|
||||||
|
dateObj: placeholder.value,
|
||||||
|
locale: locale.value,
|
||||||
|
fixedWeeks: true,
|
||||||
|
weekStartsOn: 0,
|
||||||
|
}),
|
||||||
|
) as Ref<Grid<DateValue>>
|
||||||
|
const secondMonth = ref(
|
||||||
|
createMonth({
|
||||||
|
dateObj: secondMonthPlaceholder.value,
|
||||||
|
locale: locale.value,
|
||||||
|
fixedWeeks: true,
|
||||||
|
weekStartsOn: 0,
|
||||||
|
}),
|
||||||
|
) as Ref<Grid<DateValue>>
|
||||||
|
|
||||||
|
function updateMonth(reference: 'first' | 'second', months: number) {
|
||||||
|
if (reference === 'first') {
|
||||||
|
placeholder.value = placeholder.value.add({ months })
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
secondMonthPlaceholder.value = secondMonthPlaceholder.value.add({
|
||||||
|
months,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(placeholder, (_placeholder) => {
|
||||||
|
firstMonth.value = createMonth({
|
||||||
|
dateObj: _placeholder,
|
||||||
|
weekStartsOn: 0,
|
||||||
|
fixedWeeks: false,
|
||||||
|
locale: locale.value,
|
||||||
|
})
|
||||||
|
if (isEqualMonth(secondMonthPlaceholder.value, _placeholder)) {
|
||||||
|
secondMonthPlaceholder.value = secondMonthPlaceholder.value.add({
|
||||||
|
months: 1,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(secondMonthPlaceholder, (_secondMonthPlaceholder) => {
|
||||||
|
secondMonth.value = createMonth({
|
||||||
|
dateObj: _secondMonthPlaceholder,
|
||||||
|
weekStartsOn: 0,
|
||||||
|
fixedWeeks: false,
|
||||||
|
locale: locale.value,
|
||||||
|
})
|
||||||
|
if (isEqualMonth(_secondMonthPlaceholder, placeholder.value))
|
||||||
|
placeholder.value = placeholder.value.subtract({ months: 1 })
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Popover>
|
||||||
|
<PopoverTrigger as-child>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
:class="
|
||||||
|
cn(
|
||||||
|
'w-[280px] justify-start text-left font-normal',
|
||||||
|
!value && 'text-muted-foreground',
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<CalendarIcon class="mr-2 h-4 w-4" />
|
||||||
|
<template v-if="value.start">
|
||||||
|
<template v-if="value.end">
|
||||||
|
{{
|
||||||
|
formatter.custom(toDate(value.start), {
|
||||||
|
dateStyle: "medium",
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
-
|
||||||
|
{{
|
||||||
|
formatter.custom(toDate(value.end), {
|
||||||
|
dateStyle: "medium",
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-else>
|
||||||
|
{{
|
||||||
|
formatter.custom(toDate(value.start), {
|
||||||
|
dateStyle: "medium",
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
Pick a date
|
||||||
|
</template>
|
||||||
|
</Button>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent class="w-auto p-0">
|
||||||
|
<RangeCalendarRoot v-slot="{ weekDays }" v-model="value" v-model:placeholder="placeholder" class="p-3">
|
||||||
|
<div
|
||||||
|
class="flex flex-col gap-y-4 mt-4 sm:flex-row sm:gap-x-4 sm:gap-y-0"
|
||||||
|
>
|
||||||
|
<div class="flex flex-col gap-4">
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<button
|
||||||
|
:class="
|
||||||
|
cn(
|
||||||
|
buttonVariants({ variant: 'outline' }),
|
||||||
|
'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@click="updateMonth('first', -1)"
|
||||||
|
>
|
||||||
|
<ChevronLeft class="h-4 w-4" />
|
||||||
|
</button>
|
||||||
|
<div
|
||||||
|
:class="cn('text-sm font-medium')"
|
||||||
|
>
|
||||||
|
{{
|
||||||
|
formatter.fullMonthAndYear(
|
||||||
|
toDate(firstMonth.value),
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
:class="
|
||||||
|
cn(
|
||||||
|
buttonVariants({ variant: 'outline' }),
|
||||||
|
'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@click="updateMonth('first', 1)"
|
||||||
|
>
|
||||||
|
<ChevronRight class="h-4 w-4" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<RangeCalendarGrid>
|
||||||
|
<RangeCalendarGridHead>
|
||||||
|
<RangeCalendarGridRow>
|
||||||
|
<RangeCalendarHeadCell
|
||||||
|
v-for="day in weekDays"
|
||||||
|
:key="day"
|
||||||
|
class="w-full"
|
||||||
|
>
|
||||||
|
{{ day }}
|
||||||
|
</RangeCalendarHeadCell>
|
||||||
|
</RangeCalendarGridRow>
|
||||||
|
</RangeCalendarGridHead>
|
||||||
|
<RangeCalendarGridBody>
|
||||||
|
<RangeCalendarGridRow
|
||||||
|
v-for="(
|
||||||
|
weekDates, index
|
||||||
|
) in firstMonth.rows"
|
||||||
|
:key="`weekDate-${index}`"
|
||||||
|
class="mt-2 w-full"
|
||||||
|
>
|
||||||
|
<RangeCalendarCell
|
||||||
|
v-for="weekDate in weekDates"
|
||||||
|
:key="weekDate.toString()"
|
||||||
|
:date="weekDate"
|
||||||
|
>
|
||||||
|
<RangeCalendarCellTrigger
|
||||||
|
:day="weekDate"
|
||||||
|
:month="firstMonth.value"
|
||||||
|
/>
|
||||||
|
</RangeCalendarCell>
|
||||||
|
</RangeCalendarGridRow>
|
||||||
|
</RangeCalendarGridBody>
|
||||||
|
</RangeCalendarGrid>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col gap-4">
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<button
|
||||||
|
:class="
|
||||||
|
cn(
|
||||||
|
buttonVariants({ variant: 'outline' }),
|
||||||
|
'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@click="updateMonth('second', -1)"
|
||||||
|
>
|
||||||
|
<ChevronLeft class="h-4 w-4" />
|
||||||
|
</button>
|
||||||
|
<div
|
||||||
|
:class="cn('text-sm font-medium')"
|
||||||
|
>
|
||||||
|
{{
|
||||||
|
formatter.fullMonthAndYear(
|
||||||
|
toDate(secondMonth.value),
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
:class="
|
||||||
|
cn(
|
||||||
|
buttonVariants({ variant: 'outline' }),
|
||||||
|
'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@click="updateMonth('second', 1)"
|
||||||
|
>
|
||||||
|
<ChevronRight class="h-4 w-4" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<RangeCalendarGrid>
|
||||||
|
<RangeCalendarGridHead>
|
||||||
|
<RangeCalendarGridRow>
|
||||||
|
<RangeCalendarHeadCell
|
||||||
|
v-for="day in weekDays"
|
||||||
|
:key="day"
|
||||||
|
class="w-full"
|
||||||
|
>
|
||||||
|
{{ day }}
|
||||||
|
</RangeCalendarHeadCell>
|
||||||
|
</RangeCalendarGridRow>
|
||||||
|
</RangeCalendarGridHead>
|
||||||
|
<RangeCalendarGridBody>
|
||||||
|
<RangeCalendarGridRow
|
||||||
|
v-for="(
|
||||||
|
weekDates, index
|
||||||
|
) in secondMonth.rows"
|
||||||
|
:key="`weekDate-${index}`"
|
||||||
|
class="mt-2 w-full"
|
||||||
|
>
|
||||||
|
<RangeCalendarCell
|
||||||
|
v-for="weekDate in weekDates"
|
||||||
|
:key="weekDate.toString()"
|
||||||
|
:date="weekDate"
|
||||||
|
>
|
||||||
|
<RangeCalendarCellTrigger
|
||||||
|
:day="weekDate"
|
||||||
|
:month="secondMonth.value"
|
||||||
|
/>
|
||||||
|
</RangeCalendarCell>
|
||||||
|
</RangeCalendarGridRow>
|
||||||
|
</RangeCalendarGridBody>
|
||||||
|
</RangeCalendarGrid>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</RangeCalendarRoot>
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
|
</template>
|
||||||
|
|
@ -49,7 +49,7 @@ const value = ref({
|
||||||
</Button>
|
</Button>
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
<PopoverContent class="w-auto p-0">
|
<PopoverContent class="w-auto p-0">
|
||||||
<RangeCalendar v-model="value" initial-focus :number-of-months="2" :placeholder="value?.start" @update:start-value="(startDate) => value.start = startDate" />
|
<RangeCalendar v-model="value" initial-focus :number-of-months="2" @update:start-value="(startDate) => value.start = startDate" />
|
||||||
</PopoverContent>
|
</PopoverContent>
|
||||||
</Popover>
|
</Popover>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,282 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { type Ref, ref, watch } from 'vue'
|
||||||
|
|
||||||
|
import {
|
||||||
|
Calendar as CalendarIcon,
|
||||||
|
ChevronLeft,
|
||||||
|
ChevronRight,
|
||||||
|
} from 'lucide-vue-next'
|
||||||
|
import {
|
||||||
|
CalendarDate,
|
||||||
|
type DateValue,
|
||||||
|
isEqualMonth,
|
||||||
|
} from '@internationalized/date'
|
||||||
|
|
||||||
|
import { type DateRange, RangeCalendarRoot, useDateFormatter } from 'radix-vue'
|
||||||
|
import { type Grid, createMonth, toDate } from 'radix-vue/date'
|
||||||
|
import {
|
||||||
|
RangeCalendarCell,
|
||||||
|
RangeCalendarCellTrigger,
|
||||||
|
RangeCalendarGrid,
|
||||||
|
RangeCalendarGridBody,
|
||||||
|
RangeCalendarGridHead,
|
||||||
|
RangeCalendarGridRow,
|
||||||
|
RangeCalendarHeadCell,
|
||||||
|
} from '@/lib/registry/new-york/ui/range-calendar'
|
||||||
|
import { Button, buttonVariants } from '@/lib/registry/new-york/ui/button'
|
||||||
|
import {
|
||||||
|
Popover,
|
||||||
|
PopoverContent,
|
||||||
|
PopoverTrigger,
|
||||||
|
} from '@/lib/registry/new-york/ui/popover'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
|
const value = ref({
|
||||||
|
start: new CalendarDate(2022, 1, 20),
|
||||||
|
end: new CalendarDate(2022, 1, 20).add({ days: 20 }),
|
||||||
|
}) as Ref<DateRange>
|
||||||
|
|
||||||
|
const locale = ref('en-US')
|
||||||
|
const formatter = useDateFormatter(locale.value)
|
||||||
|
|
||||||
|
const placeholder = ref(value.value.start) as Ref<DateValue>
|
||||||
|
const secondMonthPlaceholder = ref(value.value.end) as Ref<DateValue>
|
||||||
|
|
||||||
|
const firstMonth = ref(
|
||||||
|
createMonth({
|
||||||
|
dateObj: placeholder.value,
|
||||||
|
locale: locale.value,
|
||||||
|
fixedWeeks: true,
|
||||||
|
weekStartsOn: 0,
|
||||||
|
}),
|
||||||
|
) as Ref<Grid<DateValue>>
|
||||||
|
const secondMonth = ref(
|
||||||
|
createMonth({
|
||||||
|
dateObj: secondMonthPlaceholder.value,
|
||||||
|
locale: locale.value,
|
||||||
|
fixedWeeks: true,
|
||||||
|
weekStartsOn: 0,
|
||||||
|
}),
|
||||||
|
) as Ref<Grid<DateValue>>
|
||||||
|
|
||||||
|
function updateMonth(reference: 'first' | 'second', months: number) {
|
||||||
|
if (reference === 'first') {
|
||||||
|
placeholder.value = placeholder.value.add({ months })
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
secondMonthPlaceholder.value = secondMonthPlaceholder.value.add({
|
||||||
|
months,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(placeholder, (_placeholder) => {
|
||||||
|
firstMonth.value = createMonth({
|
||||||
|
dateObj: _placeholder,
|
||||||
|
weekStartsOn: 0,
|
||||||
|
fixedWeeks: false,
|
||||||
|
locale: locale.value,
|
||||||
|
})
|
||||||
|
if (isEqualMonth(secondMonthPlaceholder.value, _placeholder)) {
|
||||||
|
secondMonthPlaceholder.value = secondMonthPlaceholder.value.add({
|
||||||
|
months: 1,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(secondMonthPlaceholder, (_secondMonthPlaceholder) => {
|
||||||
|
secondMonth.value = createMonth({
|
||||||
|
dateObj: _secondMonthPlaceholder,
|
||||||
|
weekStartsOn: 0,
|
||||||
|
fixedWeeks: false,
|
||||||
|
locale: locale.value,
|
||||||
|
})
|
||||||
|
if (isEqualMonth(_secondMonthPlaceholder, placeholder.value))
|
||||||
|
placeholder.value = placeholder.value.subtract({ months: 1 })
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Popover>
|
||||||
|
<PopoverTrigger as-child>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
:class="
|
||||||
|
cn(
|
||||||
|
'w-[280px] justify-start text-left font-normal',
|
||||||
|
!value && 'text-muted-foreground',
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<CalendarIcon class="mr-2 h-4 w-4" />
|
||||||
|
<template v-if="value.start">
|
||||||
|
<template v-if="value.end">
|
||||||
|
{{
|
||||||
|
formatter.custom(toDate(value.start), {
|
||||||
|
dateStyle: "medium",
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
-
|
||||||
|
{{
|
||||||
|
formatter.custom(toDate(value.end), {
|
||||||
|
dateStyle: "medium",
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-else>
|
||||||
|
{{
|
||||||
|
formatter.custom(toDate(value.start), {
|
||||||
|
dateStyle: "medium",
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
Pick a date
|
||||||
|
</template>
|
||||||
|
</Button>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent class="w-auto p-0">
|
||||||
|
<RangeCalendarRoot v-slot="{ weekDays }" v-model="value" v-model:placeholder="placeholder" class="p-3">
|
||||||
|
<div
|
||||||
|
class="flex flex-col gap-y-4 mt-4 sm:flex-row sm:gap-x-4 sm:gap-y-0"
|
||||||
|
>
|
||||||
|
<div class="flex flex-col gap-4">
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<button
|
||||||
|
:class="
|
||||||
|
cn(
|
||||||
|
buttonVariants({ variant: 'outline' }),
|
||||||
|
'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@click="updateMonth('first', -1)"
|
||||||
|
>
|
||||||
|
<ChevronLeft class="h-4 w-4" />
|
||||||
|
</button>
|
||||||
|
<div :class="cn('text-sm font-medium')">
|
||||||
|
{{
|
||||||
|
formatter.fullMonthAndYear(
|
||||||
|
toDate(firstMonth.value),
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
:class="
|
||||||
|
cn(
|
||||||
|
buttonVariants({ variant: 'outline' }),
|
||||||
|
'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@click="updateMonth('first', 1)"
|
||||||
|
>
|
||||||
|
<ChevronRight class="h-4 w-4" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<RangeCalendarGrid>
|
||||||
|
<RangeCalendarGridHead>
|
||||||
|
<RangeCalendarGridRow>
|
||||||
|
<RangeCalendarHeadCell
|
||||||
|
v-for="day in weekDays"
|
||||||
|
:key="day"
|
||||||
|
class="w-full"
|
||||||
|
>
|
||||||
|
{{ day }}
|
||||||
|
</RangeCalendarHeadCell>
|
||||||
|
</RangeCalendarGridRow>
|
||||||
|
</RangeCalendarGridHead>
|
||||||
|
<RangeCalendarGridBody>
|
||||||
|
<RangeCalendarGridRow
|
||||||
|
v-for="(
|
||||||
|
weekDates, index
|
||||||
|
) in firstMonth.rows"
|
||||||
|
:key="`weekDate-${index}`"
|
||||||
|
class="mt-2 w-full"
|
||||||
|
>
|
||||||
|
<RangeCalendarCell
|
||||||
|
v-for="weekDate in weekDates"
|
||||||
|
:key="weekDate.toString()"
|
||||||
|
:date="weekDate"
|
||||||
|
>
|
||||||
|
<RangeCalendarCellTrigger
|
||||||
|
:day="weekDate"
|
||||||
|
:month="firstMonth.value"
|
||||||
|
/>
|
||||||
|
</RangeCalendarCell>
|
||||||
|
</RangeCalendarGridRow>
|
||||||
|
</RangeCalendarGridBody>
|
||||||
|
</RangeCalendarGrid>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col gap-4">
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<button
|
||||||
|
:class="
|
||||||
|
cn(
|
||||||
|
buttonVariants({ variant: 'outline' }),
|
||||||
|
'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@click="updateMonth('second', -1)"
|
||||||
|
>
|
||||||
|
<ChevronLeft class="h-4 w-4" />
|
||||||
|
</button>
|
||||||
|
<div :class="cn('text-sm font-medium')">
|
||||||
|
{{
|
||||||
|
formatter.fullMonthAndYear(
|
||||||
|
toDate(secondMonth.value),
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
:class="
|
||||||
|
cn(
|
||||||
|
buttonVariants({ variant: 'outline' }),
|
||||||
|
'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@click="updateMonth('second', 1)"
|
||||||
|
>
|
||||||
|
<ChevronRight class="h-4 w-4" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<RangeCalendarGrid>
|
||||||
|
<RangeCalendarGridHead>
|
||||||
|
<RangeCalendarGridRow>
|
||||||
|
<RangeCalendarHeadCell
|
||||||
|
v-for="day in weekDays"
|
||||||
|
:key="day"
|
||||||
|
class="w-full"
|
||||||
|
>
|
||||||
|
{{ day }}
|
||||||
|
</RangeCalendarHeadCell>
|
||||||
|
</RangeCalendarGridRow>
|
||||||
|
</RangeCalendarGridHead>
|
||||||
|
<RangeCalendarGridBody>
|
||||||
|
<RangeCalendarGridRow
|
||||||
|
v-for="(
|
||||||
|
weekDates, index
|
||||||
|
) in secondMonth.rows"
|
||||||
|
:key="`weekDate-${index}`"
|
||||||
|
class="mt-2 w-full"
|
||||||
|
>
|
||||||
|
<RangeCalendarCell
|
||||||
|
v-for="weekDate in weekDates"
|
||||||
|
:key="weekDate.toString()"
|
||||||
|
:date="weekDate"
|
||||||
|
>
|
||||||
|
<RangeCalendarCellTrigger
|
||||||
|
:day="weekDate"
|
||||||
|
:month="secondMonth.value"
|
||||||
|
/>
|
||||||
|
</RangeCalendarCell>
|
||||||
|
</RangeCalendarGridRow>
|
||||||
|
</RangeCalendarGridBody>
|
||||||
|
</RangeCalendarGrid>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</RangeCalendarRoot>
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
|
</template>
|
||||||
|
|
@ -49,7 +49,7 @@ const value = ref({
|
||||||
</Button>
|
</Button>
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
<PopoverContent class="w-auto p-0">
|
<PopoverContent class="w-auto p-0">
|
||||||
<RangeCalendar v-model="value" initial-focus :number-of-months="2" :placeholder="value?.start" @update:start-value="(startDate) => value.start = startDate" />
|
<RangeCalendar v-model="value" initial-focus :number-of-months="2" @update:start-value="(startDate) => value.start = startDate" />
|
||||||
</PopoverContent>
|
</PopoverContent>
|
||||||
</Popover>
|
</Popover>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
14
package.json
14
package.json
|
|
@ -3,7 +3,7 @@
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "0.10.3",
|
"version": "0.10.3",
|
||||||
"private": true,
|
"private": true,
|
||||||
"packageManager": "pnpm@8.15.6",
|
"packageManager": "pnpm@9.0.5",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"repository": "radix-vue/shadcn-vue",
|
"repository": "radix-vue/shadcn-vue",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
|
|
@ -27,15 +27,15 @@
|
||||||
"taze:minor": "taze minor -fwri --ignore-paths ./packages/cli/test/** --exclude /@iconify/"
|
"taze:minor": "taze minor -fwri --ignore-paths ./packages/cli/test/** --exclude /@iconify/"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@antfu/eslint-config": "^2.13.3",
|
"@antfu/eslint-config": "^2.15.0",
|
||||||
"@commitlint/cli": "^19.2.1",
|
"@commitlint/cli": "^19.3.0",
|
||||||
"@commitlint/config-conventional": "^19.1.0",
|
"@commitlint/config-conventional": "^19.2.2",
|
||||||
"bumpp": "^9.4.0",
|
"bumpp": "^9.4.0",
|
||||||
"eslint": "^9.0.0",
|
"eslint": "^9.1.1",
|
||||||
"lint-staged": "^15.2.2",
|
"lint-staged": "^15.2.2",
|
||||||
"simple-git-hooks": "^2.11.1",
|
"simple-git-hooks": "^2.11.1",
|
||||||
"taze": "^0.13.3",
|
"taze": "^0.13.6",
|
||||||
"typescript": "^5.4.2",
|
"typescript": "^5.4.5",
|
||||||
"vitest": "^0.34.6"
|
"vitest": "^0.34.6"
|
||||||
},
|
},
|
||||||
"commitlint": {
|
"commitlint": {
|
||||||
|
|
|
||||||
|
|
@ -56,28 +56,28 @@
|
||||||
"fs-extra": "^11.2.0",
|
"fs-extra": "^11.2.0",
|
||||||
"https-proxy-agent": "^7.0.4",
|
"https-proxy-agent": "^7.0.4",
|
||||||
"lodash.template": "^4.5.0",
|
"lodash.template": "^4.5.0",
|
||||||
"magic-string": "^0.30.9",
|
"magic-string": "^0.30.10",
|
||||||
"nypm": "^0.3.8",
|
"nypm": "^0.3.8",
|
||||||
"ofetch": "^1.3.4",
|
"ofetch": "^1.3.4",
|
||||||
"ora": "^8.0.1",
|
"ora": "^8.0.1",
|
||||||
"pathe": "^1.1.2",
|
"pathe": "^1.1.2",
|
||||||
"prompts": "^2.4.2",
|
"prompts": "^2.4.2",
|
||||||
"radix-vue": "^1.7.0",
|
"radix-vue": "^1.7.2",
|
||||||
"ts-morph": "^22.0.0",
|
"ts-morph": "^22.0.0",
|
||||||
"tsconfig-paths": "^4.2.0",
|
"tsconfig-paths": "^4.2.0",
|
||||||
"zod": "^3.22.4"
|
"zod": "^3.23.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/babel__core": "^7.20.5",
|
"@types/babel__core": "^7.20.5",
|
||||||
"@types/diff": "^5.0.9",
|
"@types/diff": "^5.2.0",
|
||||||
"@types/fs-extra": "^11.0.4",
|
"@types/fs-extra": "^11.0.4",
|
||||||
"@types/lodash.template": "^4.5.3",
|
"@types/lodash.template": "^4.5.3",
|
||||||
"@types/node": "^20.11.30",
|
"@types/node": "^20.11.30",
|
||||||
"@types/prompts": "^2.4.9",
|
"@types/prompts": "^2.4.9",
|
||||||
"@vitest/ui": "^0.34.4",
|
"@vitest/ui": "^0.34.4",
|
||||||
"tsup": "^8.0.2",
|
"tsup": "^8.0.2",
|
||||||
"type-fest": "^4.15.0",
|
"type-fest": "^4.16.0",
|
||||||
"typescript": "^5.4.2",
|
"typescript": "^5.4.5",
|
||||||
"vite-tsconfig-paths": "^4.3.2"
|
"vite-tsconfig-paths": "^4.3.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
19768
pnpm-lock.yaml
19768
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user