From cb974f95e06f476a64f0ab1f6a178350e779be5e Mon Sep 17 00:00:00 2001 From: Valentin Hutter Date: Thu, 18 Jan 2024 13:36:56 +0100 Subject: [PATCH 01/29] feat: Calendar component inherits the VCalendar slots (#285) --- apps/www/__registry__/index.ts | 14 ++++ .../src/content/docs/components/calendar.md | 37 +++++++++- .../content/docs/components/date-picker.md | 4 + .../default/example/RangePickerWithSlot.vue | 69 ++++++++++++++++++ .../registry/default/ui/calendar/Calendar.vue | 19 ++++- .../lib/registry/default/ui/calendar/index.ts | 21 ++++++ .../new-york/example/RangePickerWithSlot.vue | 73 +++++++++++++++++++ .../new-york/ui/calendar/Calendar.vue | 19 ++++- .../registry/new-york/ui/calendar/index.ts | 21 ++++++ .../registry/styles/default/calendar.json | 4 +- .../registry/styles/new-york/calendar.json | 4 +- 11 files changed, 276 insertions(+), 9 deletions(-) create mode 100644 apps/www/src/lib/registry/default/example/RangePickerWithSlot.vue create mode 100644 apps/www/src/lib/registry/new-york/example/RangePickerWithSlot.vue diff --git a/apps/www/__registry__/index.ts b/apps/www/__registry__/index.ts index 08289ff8..2c7ae3aa 100644 --- a/apps/www/__registry__/index.ts +++ b/apps/www/__registry__/index.ts @@ -506,6 +506,13 @@ export const Index = { component: () => import('../src/lib/registry/default/example/RadioGroupForm.vue').then(m => m.default), files: ['../src/lib/registry/default/example/RadioGroupForm.vue'], }, + RangePickerWithSlot: { + name: 'RangePickerWithSlot', + type: 'components:example', + registryDependencies: ['utils', 'button', 'calendar', 'popover'], + component: () => import('../src/lib/registry/default/example/RangePickerWithSlot.vue').then(m => m.default), + files: ['../src/lib/registry/default/example/RangePickerWithSlot.vue'], + }, ScrollAreaDemo: { name: 'ScrollAreaDemo', type: 'components:example', @@ -1390,6 +1397,13 @@ export const Index = { component: () => import('../src/lib/registry/new-york/example/RadioGroupForm.vue').then(m => m.default), files: ['../src/lib/registry/new-york/example/RadioGroupForm.vue'], }, + RangePickerWithSlot: { + name: 'RangePickerWithSlot', + type: 'components:example', + registryDependencies: ['utils', 'button', 'calendar', 'popover'], + component: () => import('../src/lib/registry/new-york/example/RangePickerWithSlot.vue').then(m => m.default), + files: ['../src/lib/registry/new-york/example/RangePickerWithSlot.vue'], + }, ScrollAreaDemo: { name: 'ScrollAreaDemo', type: 'components:example', diff --git a/apps/www/src/content/docs/components/calendar.md b/apps/www/src/content/docs/components/calendar.md index ccdc9971..ab0dff47 100644 --- a/apps/www/src/content/docs/components/calendar.md +++ b/apps/www/src/content/docs/components/calendar.md @@ -56,5 +56,40 @@ import { Calendar } from '@/components/ui/calendar' ``` -See the [VCalendar](https://vcalendar.io/getting-started/installation.html) documentation for more information. +The API is essentially the same, i.e. props and slots. See the [VCalendar](https://vcalendar.io/getting-started/installation.html) documentation for more information. +### Slots + +The slots available are [those currently supported](https://github.com/nathanreyes/v-calendar/blob/v3.1.2/src/components/Calendar/CalendarSlot.vue#L16-L28) by VCalendar, namely : + +- `day-content` +- `day-popover` +- `dp-footer` +- `footer` +- `header-title-wrapper` +- `header-title` +- `header-prev-button` +- `header-next-button` +- `nav` +- `nav-prev-button` +- `nav-next-button` +- `page` +- `time-header` + +Example using the `day-content` slot: + +```vue + + + +``` \ No newline at end of file diff --git a/apps/www/src/content/docs/components/date-picker.md b/apps/www/src/content/docs/components/date-picker.md index d2070ad2..3fbdc563 100644 --- a/apps/www/src/content/docs/components/date-picker.md +++ b/apps/www/src/content/docs/components/date-picker.md @@ -72,6 +72,10 @@ const date = ref() +### With Slot + + + ### Form diff --git a/apps/www/src/lib/registry/default/example/RangePickerWithSlot.vue b/apps/www/src/lib/registry/default/example/RangePickerWithSlot.vue new file mode 100644 index 00000000..be4ab976 --- /dev/null +++ b/apps/www/src/lib/registry/default/example/RangePickerWithSlot.vue @@ -0,0 +1,69 @@ + + + diff --git a/apps/www/src/lib/registry/default/ui/calendar/Calendar.vue b/apps/www/src/lib/registry/default/ui/calendar/Calendar.vue index 9415ce64..f3c11d83 100644 --- a/apps/www/src/lib/registry/default/ui/calendar/Calendar.vue +++ b/apps/www/src/lib/registry/default/ui/calendar/Calendar.vue @@ -3,7 +3,8 @@ import { useVModel } from '@vueuse/core' import type { Calendar } from 'v-calendar' import { DatePicker } from 'v-calendar' import { ChevronLeft, ChevronRight } from 'lucide-vue-next' -import { computed, nextTick, onMounted, ref } from 'vue' +import { computed, nextTick, onMounted, ref, useSlots } from 'vue' +import { isVCalendarSlot } from '.' import { buttonVariants } from '@/lib/registry/default/ui/button' import { cn } from '@/lib/utils' @@ -64,6 +65,16 @@ onMounted(async () => { if (modelValue.value instanceof Date && calendarRef.value) calendarRef.value.focusDate(modelValue.value) }) + +const $slots = useSlots() +const vCalendarSlots = computed(() => { + return Object.keys($slots) + .filter(name => isVCalendarSlot(name)) + .reduce((obj: Record, key: string) => { + obj[key] = $slots[key] + return obj + }, {}) +}) diff --git a/apps/www/src/lib/registry/default/ui/calendar/index.ts b/apps/www/src/lib/registry/default/ui/calendar/index.ts index 50f21114..d17d00f2 100644 --- a/apps/www/src/lib/registry/default/ui/calendar/index.ts +++ b/apps/www/src/lib/registry/default/ui/calendar/index.ts @@ -1 +1,22 @@ export { default as Calendar } from './Calendar.vue' +import type { CalendarSlotName } from 'v-calendar/dist/types/src/components/Calendar/CalendarSlot.vue.d.ts' + +export function isVCalendarSlot(slotName: string): slotName is CalendarSlotName { + const validSlots: CalendarSlotName[] = [ + 'day-content', + 'day-popover', + 'dp-footer', + 'footer', + 'header-title-wrapper', + 'header-title', + 'header-prev-button', + 'header-next-button', + 'nav', + 'nav-prev-button', + 'nav-next-button', + 'page', + 'time-header', + ] + + return validSlots.includes(slotName as CalendarSlotName) +} diff --git a/apps/www/src/lib/registry/new-york/example/RangePickerWithSlot.vue b/apps/www/src/lib/registry/new-york/example/RangePickerWithSlot.vue new file mode 100644 index 00000000..95dcd021 --- /dev/null +++ b/apps/www/src/lib/registry/new-york/example/RangePickerWithSlot.vue @@ -0,0 +1,73 @@ + + + diff --git a/apps/www/src/lib/registry/new-york/ui/calendar/Calendar.vue b/apps/www/src/lib/registry/new-york/ui/calendar/Calendar.vue index 182ad770..f5241ea2 100644 --- a/apps/www/src/lib/registry/new-york/ui/calendar/Calendar.vue +++ b/apps/www/src/lib/registry/new-york/ui/calendar/Calendar.vue @@ -3,7 +3,8 @@ import { useVModel } from '@vueuse/core' import type { Calendar } from 'v-calendar' import { DatePicker } from 'v-calendar' import { ChevronLeftIcon, ChevronRightIcon } from '@radix-icons/vue' -import { computed, nextTick, onMounted, ref } from 'vue' +import { computed, nextTick, onMounted, ref, useSlots } from 'vue' +import { isVCalendarSlot } from '.' import { buttonVariants } from '@/lib/registry/new-york/ui/button' import { cn } from '@/lib/utils' @@ -63,6 +64,16 @@ onMounted(async () => { if (modelValue.value instanceof Date && calendarRef.value) calendarRef.value.focusDate(modelValue.value) }) + +const $slots = useSlots() +const vCalendarSlots = computed(() => { + return Object.keys($slots) + .filter(name => isVCalendarSlot(name)) + .reduce((obj: Record, key: string) => { + obj[key] = $slots[key] + return obj + }, {}) +}) diff --git a/apps/www/src/lib/registry/new-york/ui/calendar/index.ts b/apps/www/src/lib/registry/new-york/ui/calendar/index.ts index 50f21114..d17d00f2 100644 --- a/apps/www/src/lib/registry/new-york/ui/calendar/index.ts +++ b/apps/www/src/lib/registry/new-york/ui/calendar/index.ts @@ -1 +1,22 @@ export { default as Calendar } from './Calendar.vue' +import type { CalendarSlotName } from 'v-calendar/dist/types/src/components/Calendar/CalendarSlot.vue.d.ts' + +export function isVCalendarSlot(slotName: string): slotName is CalendarSlotName { + const validSlots: CalendarSlotName[] = [ + 'day-content', + 'day-popover', + 'dp-footer', + 'footer', + 'header-title-wrapper', + 'header-title', + 'header-prev-button', + 'header-next-button', + 'nav', + 'nav-prev-button', + 'nav-next-button', + 'page', + 'time-header', + ] + + return validSlots.includes(slotName as CalendarSlotName) +} diff --git a/apps/www/src/public/registry/styles/default/calendar.json b/apps/www/src/public/registry/styles/default/calendar.json index e8f631e2..bae081a3 100644 --- a/apps/www/src/public/registry/styles/default/calendar.json +++ b/apps/www/src/public/registry/styles/default/calendar.json @@ -11,11 +11,11 @@ "files": [ { "name": "Calendar.vue", - "content": "\n\n\n\n\n" + "content": "\n\n\n\n\n" }, { "name": "index.ts", - "content": "export { default as Calendar } from './Calendar.vue'\n" + "content": "export { default as Calendar } from './Calendar.vue'\nimport type { CalendarSlotName } from 'v-calendar/dist/types/src/components/Calendar/CalendarSlot.vue.d.ts'\n\nexport function isVCalendarSlot(slotName: string): slotName is CalendarSlotName {\n const validSlots: CalendarSlotName[] = [\n 'day-content',\n 'day-popover',\n 'dp-footer',\n 'footer',\n 'header-title-wrapper',\n 'header-title',\n 'header-prev-button',\n 'header-next-button',\n 'nav',\n 'nav-prev-button',\n 'nav-next-button',\n 'page',\n 'time-header',\n ]\n\n return validSlots.includes(slotName as CalendarSlotName)\n}\n" } ], "type": "components:ui" diff --git a/apps/www/src/public/registry/styles/new-york/calendar.json b/apps/www/src/public/registry/styles/new-york/calendar.json index b83d724f..3adbb0b1 100644 --- a/apps/www/src/public/registry/styles/new-york/calendar.json +++ b/apps/www/src/public/registry/styles/new-york/calendar.json @@ -11,11 +11,11 @@ "files": [ { "name": "Calendar.vue", - "content": "\n\n\n\n\n" + "content": "\n\n\n\n\n" }, { "name": "index.ts", - "content": "export { default as Calendar } from './Calendar.vue'\n" + "content": "export { default as Calendar } from './Calendar.vue'\nimport type { CalendarSlotName } from 'v-calendar/dist/types/src/components/Calendar/CalendarSlot.vue.d.ts'\n\nexport function isVCalendarSlot(slotName: string): slotName is CalendarSlotName {\n const validSlots: CalendarSlotName[] = [\n 'day-content',\n 'day-popover',\n 'dp-footer',\n 'footer',\n 'header-title-wrapper',\n 'header-title',\n 'header-prev-button',\n 'header-next-button',\n 'nav',\n 'nav-prev-button',\n 'nav-next-button',\n 'page',\n 'time-header',\n ]\n\n return validSlots.includes(slotName as CalendarSlotName)\n}\n" } ], "type": "components:ui" From 5336fce443e08324f7ec892351f6da823e0a2f2b Mon Sep 17 00:00:00 2001 From: Rukshan Ranatunge Date: Thu, 18 Jan 2024 13:38:39 +0100 Subject: [PATCH 02/29] docs: add @types/node section in Vite installation(#289) Add install @types/node to follow the documentation in shadcn-ui. And import path without an error --- apps/www/src/content/docs/installation/vite.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/www/src/content/docs/installation/vite.md b/apps/www/src/content/docs/installation/vite.md index b1a512ef..1763b867 100644 --- a/apps/www/src/content/docs/installation/vite.md +++ b/apps/www/src/content/docs/installation/vite.md @@ -42,6 +42,11 @@ Add the code below to the compilerOptions of your tsconfig.json so your app can Add the code below to the vite.config.ts so your app can resolve paths without error +```bash +# (so you can import "path" without error) +npm i -D @types/node +``` + ```typescript import path from "path" import vue from "@vitejs/plugin-vue" From 50586487d5567950ae337c8394c65ef06ef821ce Mon Sep 17 00:00:00 2001 From: Sadegh Barati Date: Thu, 18 Jan 2024 16:45:38 +0330 Subject: [PATCH 03/29] docs: update vite installation (#250) --- .../www/src/content/docs/installation/vite.md | 60 +++++++++++++++++-- 1 file changed, 55 insertions(+), 5 deletions(-) diff --git a/apps/www/src/content/docs/installation/vite.md b/apps/www/src/content/docs/installation/vite.md index 1763b867..cbb706a2 100644 --- a/apps/www/src/content/docs/installation/vite.md +++ b/apps/www/src/content/docs/installation/vite.md @@ -19,13 +19,63 @@ npm create vite@latest my-vue-app -- --template vue-ts ### Add Tailwind and its configuration -Install `tailwindcss` and its peer dependencies, then generate your `tailwind.config.js` and `postcss.config.js` files: +Install `tailwindcss` and its peer dependencies, then generate your `tailwind.config.js` and configure `postcss` plugins -```bash -npm install -D tailwindcss postcss autoprefixer -npx tailwindcss init -p -``` + + + + + 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 + + ```bash + npm install -D tailwindcss autoprefixer + ``` + + #### `vite.config` + + ```typescript {5,6,10-14} + import path from "path" + import { defineConfig } from "vite" + import vue from "@vitejs/plugin-vue" + + import tailwind from "tailwindcss" + import autoprefixer from "autoprefixer" + + export default defineConfig({ + plugins: [vue()], + css: { + postcss: { + plugins: [tailwind(), autoprefixer()], + }, + }, + resolve: {...} + }) + ``` + + + + + + + ```bash + npm install -D tailwindcss autoprefixer postcss + ``` + + #### `postcss.config.js` + + ```js + module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, + } + ``` + + + + ### Edit tsconfig.json From f41642f5d8e258215627959b051fdcfb0842fe9a Mon Sep 17 00:00:00 2001 From: trolladam Date: Sat, 20 Jan 2024 12:42:36 +0100 Subject: [PATCH 04/29] fix: separator background color (#295) --- apps/www/src/lib/registry/default/ui/separator/Separator.vue | 2 +- apps/www/src/lib/registry/new-york/ui/separator/Separator.vue | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/www/src/lib/registry/default/ui/separator/Separator.vue b/apps/www/src/lib/registry/default/ui/separator/Separator.vue index 1e6b3f3f..2cc88b0c 100644 --- a/apps/www/src/lib/registry/default/ui/separator/Separator.vue +++ b/apps/www/src/lib/registry/default/ui/separator/Separator.vue @@ -8,7 +8,7 @@ const props = defineProps()