Merge branch 'dev' into fix/tanstack-table

This commit is contained in:
romanhrynevych 2024-08-31 10:19:23 +03:00
commit 83b9bc2027
21 changed files with 1134 additions and 654 deletions

View File

@ -1060,6 +1060,13 @@ export const Index = {
component: () => import("../src/lib/registry/default/example/TabsDemo.vue").then((m) => m.default), component: () => import("../src/lib/registry/default/example/TabsDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/TabsDemo.vue"], files: ["../src/lib/registry/default/example/TabsDemo.vue"],
}, },
"TabsVerticalDemo": {
name: "TabsVerticalDemo",
type: "components:example",
registryDependencies: ["button","card","input","label","tabs"],
component: () => import("../src/lib/registry/default/example/TabsVerticalDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/TabsVerticalDemo.vue"],
},
"TagsInputComboboxDemo": { "TagsInputComboboxDemo": {
name: "TagsInputComboboxDemo", name: "TagsInputComboboxDemo",
type: "components:example", type: "components:example",
@ -2552,6 +2559,13 @@ export const Index = {
component: () => import("../src/lib/registry/new-york/example/TabsDemo.vue").then((m) => m.default), component: () => import("../src/lib/registry/new-york/example/TabsDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/new-york/example/TabsDemo.vue"], files: ["../src/lib/registry/new-york/example/TabsDemo.vue"],
}, },
"TabsVerticalDemo": {
name: "TabsVerticalDemo",
type: "components:example",
registryDependencies: ["button","card","input","label","tabs"],
component: () => import("../src/lib/registry/new-york/example/TabsVerticalDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/new-york/example/TabsVerticalDemo.vue"],
},
"TagsInputComboboxDemo": { "TagsInputComboboxDemo": {
name: "TagsInputComboboxDemo", name: "TagsInputComboboxDemo",
type: "components:example", type: "components:example",

View File

@ -20,18 +20,18 @@
"@internationalized/date": "^3.5.5", "@internationalized/date": "^3.5.5",
"@radix-icons/vue": "^1.0.0", "@radix-icons/vue": "^1.0.0",
"@stackblitz/sdk": "^1.11.0", "@stackblitz/sdk": "^1.11.0",
"@tanstack/vue-table": "^8.20.4", "@tanstack/vue-table": "^8.20.5",
"@unovis/ts": "^1.4.4", "@unovis/ts": "^1.4.4",
"@unovis/vue": "^1.4.4", "@unovis/vue": "^1.4.4",
"@vee-validate/zod": "^4.13.2", "@vee-validate/zod": "^4.13.2",
"@vueuse/core": "^11.0.1", "@vueuse/core": "^11.0.3",
"class-variance-authority": "^0.7.0", "class-variance-authority": "^0.7.0",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"codesandbox": "^2.2.3", "codesandbox": "^2.2.3",
"date-fns": "^3.6.0", "date-fns": "^3.6.0",
"embla-carousel-autoplay": "^8.2.0", "embla-carousel-autoplay": "^8.2.0",
"embla-carousel-vue": "^8.2.0", "embla-carousel-vue": "^8.2.0",
"lucide-vue-next": "^0.428.0", "lucide-vue-next": "^0.436.0",
"magic-string": "^0.30.11", "magic-string": "^0.30.11",
"radix-vue": "catalog:", "radix-vue": "catalog:",
"tailwindcss-animate": "^1.0.7", "tailwindcss-animate": "^1.0.7",
@ -39,12 +39,12 @@
"vaul-vue": "^0.2.0", "vaul-vue": "^0.2.0",
"vee-validate": "4.13.2", "vee-validate": "4.13.2",
"vue": "^3.4.38", "vue": "^3.4.38",
"vue-sonner": "^1.1.4", "vue-sonner": "^1.1.5",
"vue-wrap-balancer": "^1.1.3", "vue-wrap-balancer": "^1.1.3",
"zod": "catalog:" "zod": "catalog:"
}, },
"devDependencies": { "devDependencies": {
"@babel/traverse": "^7.25.3", "@babel/traverse": "^7.25.6",
"@iconify-json/gravity-ui": "^1.1.3", "@iconify-json/gravity-ui": "^1.1.3",
"@iconify-json/lucide": "^1.1.198", "@iconify-json/lucide": "^1.1.198",
"@iconify-json/ph": "^1.1.13", "@iconify-json/ph": "^1.1.13",
@ -54,10 +54,10 @@
"@iconify-json/tabler": "^1.1.116", "@iconify-json/tabler": "^1.1.116",
"@iconify/vue": "^4.1.2", "@iconify/vue": "^4.1.2",
"@oxc-parser/wasm": "catalog:", "@oxc-parser/wasm": "catalog:",
"@shikijs/transformers": "^1.14.1", "@shikijs/transformers": "^1.15.1",
"@types/lodash-es": "^4.17.12", "@types/lodash-es": "^4.17.12",
"@types/node": "^20.16.1", "@types/node": "^20.16.2",
"@vitejs/plugin-vue": "^5.1.2", "@vitejs/plugin-vue": "^5.1.3",
"@vitejs/plugin-vue-jsx": "^4.0.1", "@vitejs/plugin-vue-jsx": "^4.0.1",
"@vue/compiler-core": "^3.4.38", "@vue/compiler-core": "^3.4.38",
"@vue/compiler-dom": "^3.4.38", "@vue/compiler-dom": "^3.4.38",
@ -68,14 +68,14 @@
"markdown-it": "^14.1.0", "markdown-it": "^14.1.0",
"pathe": "^1.1.2", "pathe": "^1.1.2",
"rimraf": "^6.0.1", "rimraf": "^6.0.1",
"shiki": "^1.14.1", "shiki": "^1.15.1",
"tailwind-merge": "^2.5.2", "tailwind-merge": "^2.5.2",
"tailwindcss": "^3.4.10", "tailwindcss": "^3.4.10",
"tsx": "^4.17.0", "tsx": "^4.19.0",
"typescript": "^5.5.3", "typescript": "^5.5.4",
"unplugin-icons": "^0.19.2", "unplugin-icons": "^0.19.2",
"vitepress": "^1.3.3", "vitepress": "^1.3.4",
"vue-component-meta": "^2.0.29", "vue-component-meta": "^2.1.2",
"vue-tsc": "^2.0.29" "vue-tsc": "^2.1.2"
} }
} }

View File

@ -39,3 +39,9 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
</Tabs> </Tabs>
</template> </template>
``` ```
## Examples
### Vertical
<ComponentPreview name="TabsVerticalDemo" />

View File

@ -7,7 +7,7 @@ description: Adding dark mode to your nuxt app.
<Steps> <Steps>
### Install Dependencies <!-- ### Install Dependencies
```bash ```bash
npm install -D @nuxtjs/color-mode npm install -D @nuxtjs/color-mode
@ -25,19 +25,21 @@ export default defineNuxtConfig({
classSuffix: '' classSuffix: ''
} }
}) })
``` ``` -->
Optional, to include icons for theme button.
```bash
npm install -D @iconify/vue @iconify-json/radix-icons
```
### Add a mode toggle ### Add a mode toggle
Place a mode toggle on your site to toggle between light and dark mode. Place a mode toggle on your site to toggle between light and dark mode.
The `@nuxtjs/color-mode` module is automatically installed and configured during the installation of the `shadcn-nuxt` module, so you literally have nothing to do.
We're using [`useColorMode`](https://color-mode.nuxtjs.org/#usage) from [`Nuxt Color Mode`](https://color-mode.nuxtjs.org/). We're using [`useColorMode`](https://color-mode.nuxtjs.org/#usage) from [`Nuxt Color Mode`](https://color-mode.nuxtjs.org/).
Optional, to include icons for theme button.
```bash
npm install -D @iconify/vue @iconify-json/radix-icons
```
```vue ```vue
<script setup lang="ts"> <script setup lang="ts">
import { Icon } from '@iconify/vue' import { Icon } from '@iconify/vue'

View File

@ -4,7 +4,7 @@ import { Card, CardContent } from '@/lib/registry/default/ui/card'
</script> </script>
<template> <template>
<Carousel class="relative w-full max-w-xs"> <Carousel v-slot="{ canScrollNext }" class="relative w-full max-w-xs">
<CarouselContent> <CarouselContent>
<CarouselItem v-for="(_, index) in 5" :key="index"> <CarouselItem v-for="(_, index) in 5" :key="index">
<div class="p-1"> <div class="p-1">
@ -17,6 +17,6 @@ import { Card, CardContent } from '@/lib/registry/default/ui/card'
</CarouselItem> </CarouselItem>
</CarouselContent> </CarouselContent>
<CarouselPrevious /> <CarouselPrevious />
<CarouselNext /> <CarouselNext v-if="canScrollNext" />
</Carousel> </Carousel>
</template> </template>

View File

@ -0,0 +1,78 @@
<script setup lang="ts">
import { Button } from '@/lib/registry/default/ui/button'
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from '@/lib/registry/default/ui/card'
import { Input } from '@/lib/registry/default/ui/input'
import { Label } from '@/lib/registry/default/ui/label'
import {
Tabs,
TabsContent,
TabsList,
TabsTrigger,
} from '@/lib/registry/default/ui/tabs'
</script>
<template>
<Tabs default-value="account" class="w-[400px]" orientation="vertical">
<TabsList class="grid w-full grid-cols-1">
<TabsTrigger value="account">
Accounts
</TabsTrigger>
<TabsTrigger value="password">
Password
</TabsTrigger>
</TabsList>
<TabsContent value="account">
<Card>
<CardHeader>
<CardTitle>Account</CardTitle>
<CardDescription>
Make changes to your account here. Click save when you're done.
</CardDescription>
</CardHeader>
<CardContent class="space-y-2">
<div class="space-y-1">
<Label for="name">Name</Label>
<Input id="name" default-value="Pedro Duarte" />
</div>
<div class="space-y-1">
<Label for="username">Username</Label>
<Input id="username" default-value="@peduarte" />
</div>
</CardContent>
<CardFooter>
<Button>Save changes</Button>
</CardFooter>
</Card>
</TabsContent>
<TabsContent value="password">
<Card>
<CardHeader>
<CardTitle>Password</CardTitle>
<CardDescription>
Change your password here. After saving, you'll be logged out.
</CardDescription>
</CardHeader>
<CardContent class="space-y-2">
<div class="space-y-1">
<Label for="current">Current password</Label>
<Input id="current" type="password" />
</div>
<div class="space-y-1">
<Label for="new">New password</Label>
<Input id="new" type="password" />
</div>
</CardContent>
<CardFooter>
<Button>Save password</Button>
</CardFooter>
</Card>
</TabsContent>
</Tabs>
</template>

View File

@ -9,9 +9,17 @@ const props = withDefaults(defineProps<CarouselProps & WithClassAsProps>(), {
const emits = defineEmits<CarouselEmits>() const emits = defineEmits<CarouselEmits>()
const carouselArgs = useProvideCarousel(props, emits) const { canScrollNext, canScrollPrev, carouselApi, carouselRef, orientation, scrollNext, scrollPrev } = useProvideCarousel(props, emits)
defineExpose(carouselArgs) defineExpose({
canScrollNext,
canScrollPrev,
carouselApi,
carouselRef,
orientation,
scrollNext,
scrollPrev,
})
function onKeyDown(event: KeyboardEvent) { function onKeyDown(event: KeyboardEvent) {
const prevKey = props.orientation === 'vertical' ? 'ArrowUp' : 'ArrowLeft' const prevKey = props.orientation === 'vertical' ? 'ArrowUp' : 'ArrowLeft'
@ -19,14 +27,14 @@ function onKeyDown(event: KeyboardEvent) {
if (event.key === prevKey) { if (event.key === prevKey) {
event.preventDefault() event.preventDefault()
carouselArgs.scrollPrev() scrollPrev()
return return
} }
if (event.key === nextKey) { if (event.key === nextKey) {
event.preventDefault() event.preventDefault()
carouselArgs.scrollNext() scrollNext()
} }
} }
</script> </script>
@ -39,6 +47,6 @@ function onKeyDown(event: KeyboardEvent) {
tabindex="0" tabindex="0"
@keydown="onKeyDown" @keydown="onKeyDown"
> >
<slot v-bind="carouselArgs" /> <slot :can-scroll-next :can-scroll-prev :carousel-api :carousel-ref :orientation :scroll-next :scroll-prev />
</div> </div>
</template> </template>

View File

@ -16,7 +16,7 @@ const delegatedProps = computed(() => {
<TabsList <TabsList
v-bind="delegatedProps" v-bind="delegatedProps"
:class="cn( :class="cn(
'inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground', 'inline-flex items-center justify-center rounded-md bg-muted p-1 text-muted-foreground',
props.class, props.class,
)" )"
> >

View File

@ -22,6 +22,8 @@ const forwardedProps = useForwardProps(delegatedProps)
props.class, props.class,
)" )"
> >
<slot /> <span class="truncate">
<slot />
</span>
</TabsTrigger> </TabsTrigger>
</template> </template>

View File

@ -0,0 +1,78 @@
<script setup lang="ts">
import { Button } from '@/lib/registry/new-york/ui/button'
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from '@/lib/registry/new-york/ui/card'
import { Input } from '@/lib/registry/new-york/ui/input'
import { Label } from '@/lib/registry/new-york/ui/label'
import {
Tabs,
TabsContent,
TabsList,
TabsTrigger,
} from '@/lib/registry/new-york/ui/tabs'
</script>
<template>
<Tabs default-value="account" class="w-[400px]" orientation="vertical">
<TabsList class="grid w-full grid-cols-1">
<TabsTrigger value="account">
Account
</TabsTrigger>
<TabsTrigger value="password">
Password
</TabsTrigger>
</TabsList>
<TabsContent value="account">
<Card>
<CardHeader>
<CardTitle>Account</CardTitle>
<CardDescription>
Make changes to your account here. Click save when you're done.
</CardDescription>
</CardHeader>
<CardContent class="space-y-2">
<div class="space-y-1">
<Label for="name">Name</Label>
<Input id="name" default-value="Pedro Duarte" />
</div>
<div class="space-y-1">
<Label for="username">Username</Label>
<Input id="username" default-value="@peduarte" />
</div>
</CardContent>
<CardFooter>
<Button>Save changes</Button>
</CardFooter>
</Card>
</TabsContent>
<TabsContent value="password">
<Card>
<CardHeader>
<CardTitle>Password</CardTitle>
<CardDescription>
Change your password here. After saving, you'll be logged out.
</CardDescription>
</CardHeader>
<CardContent class="space-y-2">
<div class="space-y-1">
<Label for="current">Current password</Label>
<Input id="current" type="password" />
</div>
<div class="space-y-1">
<Label for="new">New password</Label>
<Input id="new" type="password" />
</div>
</CardContent>
<CardFooter>
<Button>Save password</Button>
</CardFooter>
</Card>
</TabsContent>
</Tabs>
</template>

View File

@ -9,9 +9,17 @@ const props = withDefaults(defineProps<CarouselProps & WithClassAsProps>(), {
const emits = defineEmits<CarouselEmits>() const emits = defineEmits<CarouselEmits>()
const carouselArgs = useProvideCarousel(props, emits) const { canScrollNext, canScrollPrev, carouselApi, carouselRef, orientation, scrollNext, scrollPrev } = useProvideCarousel(props, emits)
defineExpose(carouselArgs) defineExpose({
canScrollNext,
canScrollPrev,
carouselApi,
carouselRef,
orientation,
scrollNext,
scrollPrev,
})
function onKeyDown(event: KeyboardEvent) { function onKeyDown(event: KeyboardEvent) {
const prevKey = props.orientation === 'vertical' ? 'ArrowUp' : 'ArrowLeft' const prevKey = props.orientation === 'vertical' ? 'ArrowUp' : 'ArrowLeft'
@ -19,14 +27,14 @@ function onKeyDown(event: KeyboardEvent) {
if (event.key === prevKey) { if (event.key === prevKey) {
event.preventDefault() event.preventDefault()
carouselArgs.scrollPrev() scrollPrev()
return return
} }
if (event.key === nextKey) { if (event.key === nextKey) {
event.preventDefault() event.preventDefault()
carouselArgs.scrollNext() scrollNext()
} }
} }
</script> </script>
@ -39,6 +47,6 @@ function onKeyDown(event: KeyboardEvent) {
tabindex="0" tabindex="0"
@keydown="onKeyDown" @keydown="onKeyDown"
> >
<slot v-bind="carouselArgs" /> <slot :can-scroll-next :can-scroll-prev :carousel-api :carousel-ref :orientation :scroll-next :scroll-prev />
</div> </div>
</template> </template>

View File

@ -16,7 +16,7 @@ const delegatedProps = computed(() => {
<TabsList <TabsList
v-bind="delegatedProps" v-bind="delegatedProps"
:class="cn( :class="cn(
'inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground', 'inline-flex items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground',
props.class, props.class,
)" )"
> >

View File

@ -22,6 +22,8 @@ const forwardedProps = useForwardProps(delegatedProps)
props.class, props.class,
)" )"
> >
<slot /> <span class="truncate">
<slot />
</span>
</TabsTrigger> </TabsTrigger>
</template> </template>

View File

@ -11,7 +11,7 @@
"files": [ "files": [
{ {
"name": "Carousel.vue", "name": "Carousel.vue",
"content": "<script setup lang=\"ts\">\nimport { useProvideCarousel } from './useCarousel'\nimport type { CarouselEmits, CarouselProps, WithClassAsProps } from './interface'\nimport { cn } from '@/lib/utils'\n\nconst props = withDefaults(defineProps<CarouselProps & WithClassAsProps>(), {\n orientation: 'horizontal',\n})\n\nconst emits = defineEmits<CarouselEmits>()\n\nconst carouselArgs = useProvideCarousel(props, emits)\n\ndefineExpose(carouselArgs)\n\nfunction onKeyDown(event: KeyboardEvent) {\n const prevKey = props.orientation === 'vertical' ? 'ArrowUp' : 'ArrowLeft'\n const nextKey = props.orientation === 'vertical' ? 'ArrowDown' : 'ArrowRight'\n\n if (event.key === prevKey) {\n event.preventDefault()\n carouselArgs.scrollPrev()\n\n return\n }\n\n if (event.key === nextKey) {\n event.preventDefault()\n carouselArgs.scrollNext()\n }\n}\n</script>\n\n<template>\n <div\n :class=\"cn('relative', props.class)\"\n role=\"region\"\n aria-roledescription=\"carousel\"\n tabindex=\"0\"\n @keydown=\"onKeyDown\"\n >\n <slot v-bind=\"carouselArgs\" />\n </div>\n</template>\n" "content": "<script setup lang=\"ts\">\nimport { useProvideCarousel } from './useCarousel'\nimport type { CarouselEmits, CarouselProps, WithClassAsProps } from './interface'\nimport { cn } from '@/lib/utils'\n\nconst props = withDefaults(defineProps<CarouselProps & WithClassAsProps>(), {\n orientation: 'horizontal',\n})\n\nconst emits = defineEmits<CarouselEmits>()\n\nconst { canScrollNext, canScrollPrev, carouselApi, carouselRef, orientation, scrollNext, scrollPrev } = useProvideCarousel(props, emits)\n\ndefineExpose({\n canScrollNext,\n canScrollPrev,\n carouselApi,\n carouselRef,\n orientation,\n scrollNext,\n scrollPrev,\n})\n\nfunction onKeyDown(event: KeyboardEvent) {\n const prevKey = props.orientation === 'vertical' ? 'ArrowUp' : 'ArrowLeft'\n const nextKey = props.orientation === 'vertical' ? 'ArrowDown' : 'ArrowRight'\n\n if (event.key === prevKey) {\n event.preventDefault()\n scrollPrev()\n\n return\n }\n\n if (event.key === nextKey) {\n event.preventDefault()\n scrollNext()\n }\n}\n</script>\n\n<template>\n <div\n :class=\"cn('relative', props.class)\"\n role=\"region\"\n aria-roledescription=\"carousel\"\n tabindex=\"0\"\n @keydown=\"onKeyDown\"\n >\n <slot :can-scroll-next :can-scroll-prev :carousel-api :carousel-ref :orientation :scroll-next :scroll-prev />\n </div>\n</template>\n"
}, },
{ {
"name": "CarouselContent.vue", "name": "CarouselContent.vue",

View File

@ -15,11 +15,11 @@
}, },
{ {
"name": "TabsList.vue", "name": "TabsList.vue",
"content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed } from 'vue'\nimport { TabsList, type TabsListProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<TabsListProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <TabsList\n v-bind=\"delegatedProps\"\n :class=\"cn(\n 'inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground',\n props.class,\n )\"\n >\n <slot />\n </TabsList>\n</template>\n" "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed } from 'vue'\nimport { TabsList, type TabsListProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<TabsListProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <TabsList\n v-bind=\"delegatedProps\"\n :class=\"cn(\n 'inline-flex items-center justify-center rounded-md bg-muted p-1 text-muted-foreground',\n props.class,\n )\"\n >\n <slot />\n </TabsList>\n</template>\n"
}, },
{ {
"name": "TabsTrigger.vue", "name": "TabsTrigger.vue",
"content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed } from 'vue'\nimport { TabsTrigger, type TabsTriggerProps, useForwardProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<TabsTriggerProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <TabsTrigger\n v-bind=\"forwardedProps\"\n :class=\"cn(\n 'inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm',\n props.class,\n )\"\n >\n <slot />\n </TabsTrigger>\n</template>\n" "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed } from 'vue'\nimport { TabsTrigger, type TabsTriggerProps, useForwardProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<TabsTriggerProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <TabsTrigger\n v-bind=\"forwardedProps\"\n :class=\"cn(\n 'inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm',\n props.class,\n )\"\n >\n <span class=\"truncate\">\n <slot />\n </span>\n </TabsTrigger>\n</template>\n"
}, },
{ {
"name": "index.ts", "name": "index.ts",

View File

@ -11,7 +11,7 @@
"files": [ "files": [
{ {
"name": "Carousel.vue", "name": "Carousel.vue",
"content": "<script setup lang=\"ts\">\nimport { useProvideCarousel } from './useCarousel'\nimport type { CarouselEmits, CarouselProps, WithClassAsProps } from './interface'\nimport { cn } from '@/lib/utils'\n\nconst props = withDefaults(defineProps<CarouselProps & WithClassAsProps>(), {\n orientation: 'horizontal',\n})\n\nconst emits = defineEmits<CarouselEmits>()\n\nconst carouselArgs = useProvideCarousel(props, emits)\n\ndefineExpose(carouselArgs)\n\nfunction onKeyDown(event: KeyboardEvent) {\n const prevKey = props.orientation === 'vertical' ? 'ArrowUp' : 'ArrowLeft'\n const nextKey = props.orientation === 'vertical' ? 'ArrowDown' : 'ArrowRight'\n\n if (event.key === prevKey) {\n event.preventDefault()\n carouselArgs.scrollPrev()\n\n return\n }\n\n if (event.key === nextKey) {\n event.preventDefault()\n carouselArgs.scrollNext()\n }\n}\n</script>\n\n<template>\n <div\n :class=\"cn('relative', props.class)\"\n role=\"region\"\n aria-roledescription=\"carousel\"\n tabindex=\"0\"\n @keydown=\"onKeyDown\"\n >\n <slot v-bind=\"carouselArgs\" />\n </div>\n</template>\n" "content": "<script setup lang=\"ts\">\nimport { useProvideCarousel } from './useCarousel'\nimport type { CarouselEmits, CarouselProps, WithClassAsProps } from './interface'\nimport { cn } from '@/lib/utils'\n\nconst props = withDefaults(defineProps<CarouselProps & WithClassAsProps>(), {\n orientation: 'horizontal',\n})\n\nconst emits = defineEmits<CarouselEmits>()\n\nconst { canScrollNext, canScrollPrev, carouselApi, carouselRef, orientation, scrollNext, scrollPrev } = useProvideCarousel(props, emits)\n\ndefineExpose({\n canScrollNext,\n canScrollPrev,\n carouselApi,\n carouselRef,\n orientation,\n scrollNext,\n scrollPrev,\n})\n\nfunction onKeyDown(event: KeyboardEvent) {\n const prevKey = props.orientation === 'vertical' ? 'ArrowUp' : 'ArrowLeft'\n const nextKey = props.orientation === 'vertical' ? 'ArrowDown' : 'ArrowRight'\n\n if (event.key === prevKey) {\n event.preventDefault()\n scrollPrev()\n\n return\n }\n\n if (event.key === nextKey) {\n event.preventDefault()\n scrollNext()\n }\n}\n</script>\n\n<template>\n <div\n :class=\"cn('relative', props.class)\"\n role=\"region\"\n aria-roledescription=\"carousel\"\n tabindex=\"0\"\n @keydown=\"onKeyDown\"\n >\n <slot :can-scroll-next :can-scroll-prev :carousel-api :carousel-ref :orientation :scroll-next :scroll-prev />\n </div>\n</template>\n"
}, },
{ {
"name": "CarouselContent.vue", "name": "CarouselContent.vue",

View File

@ -15,11 +15,11 @@
}, },
{ {
"name": "TabsList.vue", "name": "TabsList.vue",
"content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed } from 'vue'\nimport { TabsList, type TabsListProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<TabsListProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <TabsList\n v-bind=\"delegatedProps\"\n :class=\"cn(\n 'inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground',\n props.class,\n )\"\n >\n <slot />\n </TabsList>\n</template>\n" "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed } from 'vue'\nimport { TabsList, type TabsListProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<TabsListProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <TabsList\n v-bind=\"delegatedProps\"\n :class=\"cn(\n 'inline-flex items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground',\n props.class,\n )\"\n >\n <slot />\n </TabsList>\n</template>\n"
}, },
{ {
"name": "TabsTrigger.vue", "name": "TabsTrigger.vue",
"content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed } from 'vue'\nimport { TabsTrigger, type TabsTriggerProps, useForwardProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<TabsTriggerProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <TabsTrigger\n v-bind=\"forwardedProps\"\n :class=\"cn(\n 'inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow',\n props.class,\n )\"\n >\n <slot />\n </TabsTrigger>\n</template>\n" "content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed } from 'vue'\nimport { TabsTrigger, type TabsTriggerProps, useForwardProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<TabsTriggerProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <TabsTrigger\n v-bind=\"forwardedProps\"\n :class=\"cn(\n 'inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow',\n props.class,\n )\"\n >\n <span class=\"truncate\">\n <slot />\n </span>\n </TabsTrigger>\n</template>\n"
}, },
{ {
"name": "index.ts", "name": "index.ts",

View File

@ -3,7 +3,7 @@
"type": "module", "type": "module",
"version": "0.10.5", "version": "0.10.5",
"private": true, "private": true,
"packageManager": "pnpm@9.7.1", "packageManager": "pnpm@9.9.0",
"license": "MIT", "license": "MIT",
"repository": "radix-vue/shadcn-vue", "repository": "radix-vue/shadcn-vue",
"workspaces": [ "workspaces": [
@ -31,16 +31,16 @@
"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.26.0", "@antfu/eslint-config": "^3.0.0",
"@commitlint/cli": "^19.4.0", "@commitlint/cli": "^19.4.1",
"@commitlint/config-conventional": "^19.2.2", "@commitlint/config-conventional": "^19.4.1",
"@vitest/ui": "^2.0.5", "@vitest/ui": "^2.0.5",
"bumpp": "^9.5.1", "bumpp": "^9.5.2",
"eslint": "^9.9.0", "eslint": "^9.9.1",
"lint-staged": "^15.2.9", "lint-staged": "^15.2.9",
"simple-git-hooks": "^2.11.1", "simple-git-hooks": "^2.11.1",
"taze": "^0.16.6", "taze": "^0.16.7",
"typescript": "^5.5.3", "typescript": "^5.5.4",
"vitest": "^2.0.5" "vitest": "^2.0.5"
}, },
"commitlint": { "commitlint": {

View File

@ -1,7 +1,7 @@
import { readFileSync, readdirSync } from 'node:fs' import { readFileSync, readdirSync } from 'node:fs'
import { join } from 'node:path' import { join } from 'node:path'
import { parseSync } from '@oxc-parser/wasm' import { parseSync } from '@oxc-parser/wasm'
import { addComponent, addTemplate, createResolver, defineNuxtModule, findPath, useLogger } from '@nuxt/kit' import { addComponent, addTemplate, createResolver, defineNuxtModule, findPath, installModule, useLogger } from '@nuxt/kit'
import { UTILS } from '../../cli/src/utils/templates' import { UTILS } from '../../cli/src/utils/templates'
// TODO: add test to make sure all registry is being parse correctly // TODO: add test to make sure all registry is being parse correctly
@ -59,6 +59,14 @@ export default defineNuxtModule<ModuleOptions>({
}) })
}) })
// Installs the `@nuxtjs/color-mode` module.
await installModule('@nuxtjs/color-mode', {
colorMode: {
classSuffix: '',
},
})
// Manually scan `componentsDir` for components and register them for auto imports // Manually scan `componentsDir` for components and register them for auto imports
try { try {
readdirSync(resolve(COMPONENT_DIR_PATH)) readdirSync(resolve(COMPONENT_DIR_PATH))
@ -73,7 +81,7 @@ export default defineNuxtModule<ModuleOptions>({
const exportedKeys: string[] = ast.program.body const exportedKeys: string[] = ast.program.body
.filter(node => node.type === 'ExportNamedDeclaration') .filter(node => node.type === 'ExportNamedDeclaration')
// @ts-expect-error parse return any // @ts-expect-error parse return any
.flatMap(node => node.specifiers.map(specifier => specifier.exported.name)) .flatMap(node => node.specifiers.map(specifier => specifier.exported.name))
.filter((key: string) => /^[A-Z]/.test(key)) .filter((key: string) => /^[A-Z]/.test(key))

File diff suppressed because it is too large Load Diff

View File

@ -2,6 +2,6 @@ packages:
- apps/* - apps/*
- packages/* - packages/*
catalog: catalog:
'@oxc-parser/wasm': ^0.24.2 '@oxc-parser/wasm': ^0.25.0
radix-vue: ^1.9.4 radix-vue: ^1.9.5
zod: ^3.23.8 zod: ^3.23.8