refactor: use class as prop to prevent class duplication with cn function (#241)

This commit is contained in:
Sadegh Barati 2024-02-02 19:08:06 +03:30 committed by GitHub
parent 8875261576
commit a829212d42
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
402 changed files with 3480 additions and 2058 deletions

View File

@ -3,9 +3,9 @@ import { defineConfig } from 'vitepress'
import Icons from 'unplugin-icons/vite' import Icons from 'unplugin-icons/vite'
import tailwind from 'tailwindcss' import tailwind from 'tailwindcss'
import autoprefixer from 'autoprefixer' import autoprefixer from 'autoprefixer'
import { createCssVariablesTheme } from 'shikiji' import { createCssVariablesTheme } from 'shiki'
// import { transformerMetaWordHighlight } from 'shikiji-transformers' // import { transformerMetaWordHighlight, transformerNotationWordHighlight } from '@shikijs/transformers'
import { siteConfig } from './theme/config/site' import { siteConfig } from './theme/config/site'
import ComponentPreviewPlugin from './theme/plugins/previewer' import ComponentPreviewPlugin from './theme/plugins/previewer'
@ -61,6 +61,7 @@ export default defineConfig({
theme: cssVariables, theme: cssVariables,
codeTransformers: [ codeTransformers: [
// transformerMetaWordHighlight(), // transformerMetaWordHighlight(),
// transformerNotationWordHighlight(),
], ],
config(md) { config(md) {
md.use(ComponentPreviewPlugin) md.use(ComponentPreviewPlugin)
@ -86,8 +87,5 @@ export default defineConfig({
'@': path.resolve(__dirname, '../src'), '@': path.resolve(__dirname, '../src'),
}, },
}, },
ssr: {
noExternal: ['vue-sonner'],
},
}, },
}) })

View File

@ -46,9 +46,9 @@ const sourceLink = 'https://github.com/radix-vue/shadcn-vue/tree/dev/'
> >
{{ doc.title }} {{ doc.title }}
<Badge v-if="doc.label" class="ml-2" :variant="'secondary'"> <span v-if="doc.label" class="ml-2 rounded-md bg-[#adfa1d] px-1.5 py-0.5 text-xs leading-none text-[#000000] no-underline group-hover:no-underline">
{{ doc.label }} {{ doc.label }}
</Badge> </span>
</a> </a>
</div> </div>
</div> </div>

View File

@ -288,7 +288,9 @@ watch(() => $route.path, (n) => {
</DialogContent> </DialogContent>
</Dialog> </Dialog>
<DefaultToaster /> <DefaultToaster />
<NewYorkSonner :theme="isDark ? 'dark' : 'light'" /> <ClientOnly>
<NewYorkSonner :theme="isDark ? 'dark' : 'light'" />
</ClientOnly>
<NewYorkToaster /> <NewYorkToaster />
</div> </div>
</template> </template>

View File

@ -11,3 +11,10 @@
--shiki-token-punctuation: #ffffff; --shiki-token-punctuation: #ffffff;
--shiki-token-link: #EE0000; --shiki-token-link: #EE0000;
} }
.shiki .highlighted-word {
border-radius: calc(var(--radius) - 2px);
border-color: rgba(63,63,70,.7);
background-color: rgba(63,63,70,.5);
padding: 0.25rem;
}

View File

@ -19,25 +19,25 @@
"@morev/vue-transitions": "^2.3.6", "@morev/vue-transitions": "^2.3.6",
"@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.11.7", "@tanstack/vue-table": "^8.11.8",
"@unovis/ts": "^1.3.1", "@unovis/ts": "^1.3.3",
"@unovis/vue": "^1.3.1", "@unovis/vue": "^1.3.3",
"@vee-validate/zod": "^4.12.4", "@vee-validate/zod": "^4.12.5",
"@vueuse/core": "^10.7.2", "@vueuse/core": "^10.7.2",
"class-variance-authority": "^0.7.0", "class-variance-authority": "^0.7.0",
"clsx": "^2.1.0", "clsx": "^2.1.0",
"codesandbox": "^2.2.3", "codesandbox": "^2.2.3",
"date-fns": "^2.30.0", "date-fns": "^2.30.0",
"embla-carousel": "8.0.0-rc19", "embla-carousel": "^8.0.0-rc22",
"embla-carousel-autoplay": "8.0.0-rc19", "embla-carousel-autoplay": "^8.0.0-rc22",
"embla-carousel-vue": "8.0.0-rc19", "embla-carousel-vue": "^8.0.0-rc22",
"lucide-vue-next": "^0.276.0", "lucide-vue-next": "^0.276.0",
"radix-vue": "^1.3.2", "radix-vue": "^1.4.0",
"tailwindcss-animate": "^1.0.7", "tailwindcss-animate": "^1.0.7",
"v-calendar": "^3.1.2", "v-calendar": "^3.1.2",
"vee-validate": "4.12.4", "vee-validate": "4.12.5",
"vue": "^3.4.15", "vue": "^3.4.15",
"vue-sonner": "^1.0.2", "vue-sonner": "^1.0.3",
"vue-wrap-balancer": "^1.1.3", "vue-wrap-balancer": "^1.1.3",
"zod": "^3.22.4" "zod": "^3.22.4"
}, },
@ -46,26 +46,26 @@
"@iconify-json/tabler": "^1.1.89", "@iconify-json/tabler": "^1.1.89",
"@iconify/json": "^2.2.108", "@iconify/json": "^2.2.108",
"@iconify/vue": "^4.1.1", "@iconify/vue": "^4.1.1",
"@shikijs/transformers": "^1.0.0-beta.3",
"@types/lodash.template": "^4.5.2", "@types/lodash.template": "^4.5.2",
"@types/node": "^20.8.10", "@types/node": "^20.8.10",
"@vitejs/plugin-vue": "^5.0.3", "@vitejs/plugin-vue": "^5.0.3",
"@vitejs/plugin-vue-jsx": "^3.1.0", "@vitejs/plugin-vue-jsx": "^3.1.0",
"@vue/compiler-core": "^3.4.14", "@vue/compiler-core": "^3.4.15",
"@vue/compiler-dom": "^3.4.14", "@vue/compiler-dom": "^3.4.15",
"@vue/tsconfig": "^0.5.1", "@vue/tsconfig": "^0.5.1",
"autoprefixer": "^10.4.16", "autoprefixer": "^10.4.17",
"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",
"shikiji": "^0.10.0-beta.9", "shiki": "^1.0.0-beta.3",
"shikiji-transformers": "^0.10.0-beta.9", "tailwind-merge": "^2.2.1",
"tailwind-merge": "^2.2.0",
"tailwindcss": "^3.4.1", "tailwindcss": "^3.4.1",
"tsx": "^4.7.0", "tsx": "^4.7.0",
"typescript": "^5.3.3", "typescript": "^5.3.3",
"unplugin-icons": "^0.17.1", "unplugin-icons": "^0.18.3",
"vite": "^5.0.12", "vite": "^5.0.12",
"vitepress": "^1.0.0-rc.39", "vitepress": "^1.0.0-rc.41",
"vue-tsc": "^1.8.27" "vue-tsc": "^1.8.27"
} }
} }

View File

@ -25,7 +25,7 @@ We'll start with the basic `<Table />` component and build a complex data table
## Table of Contents ## Table of Contents
This guide will show you how to use [TanStack Table](https://tanstack.com/table/v8) and the <Table /> component to build your own custom data table. We'll cover the following topics: This guide will show you how to use [TanStack Table](https://tanstack.com/table/v8) and the `<Table />` component to build your own custom data table. We'll cover the following topics:
- [Basic Table](#basic-table) - [Basic Table](#basic-table)
- [Row Actions](#row-actions) - [Row Actions](#row-actions)
@ -109,31 +109,23 @@ Let's start by building a basic table.
First, we'll define our columns in the `columns.ts` file. First, we'll define our columns in the `columns.ts` file.
```ts:line-numbers title="components/payments/columns.ts" {1,12-27} ```ts:line-numbers {1,12-27}
import type { ColumnDef } from '@tanstack/vue-table' import { h } from 'vue'
// This type is used to define the shape of our data.
// You can use a Zod schema here if you want.
export interface Payment {
id: string
amount: number
status: 'pending' | 'processing' | 'success' | 'failed'
email: string
}
export const columns: ColumnDef<Payment>[] = [ export const columns: ColumnDef<Payment>[] = [
{
accessorKey: 'status',
header: 'Status',
},
{
accessorKey: 'email',
header: 'Email',
},
{ {
accessorKey: 'amount', accessorKey: 'amount',
header: 'Amount', header: () => h('div', { class: 'text-right' }, 'Amount'),
}, cell: ({ row }) => {
const amount = Number.parseFloat(row.getValue('amount'))
const formatted = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
}).format(amount)
return h('div', { class: 'text-right font-medium' }, formatted)
},
}
] ]
``` ```
@ -149,7 +141,7 @@ formatted, sorted and filtered.
Next, we'll create a `<DataTable />` component to render our table. Next, we'll create a `<DataTable />` component to render our table.
```ts:line-numbers ```vue:line-numbers
<script setup lang="ts" generic="TData, TValue"> <script setup lang="ts" generic="TData, TValue">
import type { ColumnDef } from '@tanstack/vue-table' import type { ColumnDef } from '@tanstack/vue-table'
import { import {
@ -225,7 +217,7 @@ const table = useVueTable({
Finally, we'll render our table in our index component. Finally, we'll render our table in our index component.
```ts:line-numbers {28} ```vue:line-numbers {28}
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted } from 'vue' import { ref, onMounted } from 'vue'
import { columns } from "./components/columns" import { columns } from "./components/columns"
@ -302,7 +294,7 @@ Let's add row actions to our table. We'll use a `<Dropdown />` component for thi
### Add the following into your `DataTableDropDown.vue` component: ### Add the following into your `DataTableDropDown.vue` component:
```ts:line-numbers ```vue:line-numbers
// DataTableDropDown.vue // DataTableDropDown.vue
<script setup lang="ts"> <script setup lang="ts">
import { MoreHorizontal } from 'lucide-vue-next' import { MoreHorizontal } from 'lucide-vue-next'
@ -402,8 +394,7 @@ This will automatically paginate your rows into pages of 10. See the [pagination
We can add pagination controls to our table using the `<Button />` component and the `table.previousPage()`, `table.nextPage()` API methods. We can add pagination controls to our table using the `<Button />` component and the `table.previousPage()`, `table.nextPage()` API methods.
```ts:line-numbers {3,15,21-39} ```vue:line-numbers {3,15,21-39}
// components/payments/DataTable.vue
<script lang="ts" generic="TData, TValue"> <script lang="ts" generic="TData, TValue">
import { Button } from "@/components/ui/button" import { Button } from "@/components/ui/button"
@ -482,7 +473,7 @@ The `valueUpdater` function updates a Vue `ref` object's value. It handles both
### Update `<DataTable>` ### Update `<DataTable>`
```ts:line-numbers {4,7,16,34,41-44} ```vue:line-numbers {4,7,16,34,41-44}
<script setup lang="ts" generic="TData, TValue"> <script setup lang="ts" generic="TData, TValue">
import type { import type {
ColumnDef, ColumnDef,
@ -579,7 +570,7 @@ Let's add a search input to filter emails in our table.
### Update `<DataTable>` ### Update `<DataTable>`
```ts:line-numbers {4,11,19,39,48-49,52,60-64} ```vue:line-numbers {4,11,19,39,48-49,52,60-64}
<script setup lang="ts" generic="TData, TValue"> <script setup lang="ts" generic="TData, TValue">
import type { import type {
ColumnDef, ColumnDef,
@ -664,7 +655,7 @@ Adding column visibility is fairly simple using `@tanstack/vue-table` visibility
### Update `<DataTable>` ### Update `<DataTable>`
```ts:line-numbers {6,9-14,48,59,63,75-91} ```vue:line-numbers {6,9-14,48,59,63,75-91}
<script setup lang="ts" generic="TData, TValue"> <script setup lang="ts" generic="TData, TValue">
import type { import type {
ColumnDef, ColumnDef,
@ -829,7 +820,7 @@ export const columns: ColumnDef<Payment>[] = [
### Update `<DataTable>` ### Update `<DataTable>`
```ts:line-numbers {10,22,27} ```vue:line-numbers {10,22,27}
<script setup lang="ts" generic="TData, TValue"> <script setup lang="ts" generic="TData, TValue">
const props = defineProps<{ const props = defineProps<{
columns: ColumnDef<TData, TValue>[] columns: ColumnDef<TData, TValue>[]
@ -895,7 +886,7 @@ Here are some components you can use to build your data tables. This is from the
Make any column header sortable and hideable. Make any column header sortable and hideable.
```ts:line-numbers ```vue:line-numbers
<script setup lang="ts"> <script setup lang="ts">
import type { Column } from '@tanstack/vue-table' import type { Column } from '@tanstack/vue-table'
import { type Task } from '../data/schema' import { type Task } from '../data/schema'
@ -988,7 +979,7 @@ export const columns = [
Add pagination controls to your table including page size and selection count. Add pagination controls to your table including page size and selection count.
```ts:line-numbers ```vue:line-numbers
<script setup lang="ts"> <script setup lang="ts">
import { type Table } from '@tanstack/vue-table' import { type Table } from '@tanstack/vue-table'
import { type Task } from '../data/schema' import { type Task } from '../data/schema'
@ -1093,8 +1084,7 @@ defineProps<DataTablePaginationProps>()
A component to toggle column visibility. A component to toggle column visibility.
```ts:line-numbers ```vue:line-numbers
<script setup lang="ts"> <script setup lang="ts">
import type { Table } from '@tanstack/vue-table' import type { Table } from '@tanstack/vue-table'
import { computed } from 'vue' import { computed } from 'vue'

View File

@ -47,7 +47,7 @@ import {
### Link Component ### Link Component
When using the Nuxt.js <NuxtLink /> component, you can use `navigationMenuTriggerStyle()` to apply the correct styles to the trigger. When using the Nuxt.js `<NuxtLink />` component, you can use `navigationMenuTriggerStyle()` to apply the correct styles to the trigger.
```ts ```ts
import { navigationMenuTriggerStyle } from '@/components/ui/navigation-menu' import { navigationMenuTriggerStyle } from '@/components/ui/navigation-menu'

View File

@ -40,7 +40,7 @@ const date = ref({
</span> </span>
</Button> </Button>
</PopoverTrigger> </PopoverTrigger>
<PopoverContent class="w-auto p-0" :align="'end'" :avoid-collisions="true"> <PopoverContent class="w-auto p-0" :align="'end'">
<Calendar <Calendar
v-model.range="date" v-model.range="date"
:columns="2" :columns="2"

View File

@ -95,7 +95,7 @@ async function onSubmit(values: any) {
</FormField> </FormField>
<FormField v-slot="{ componentField, value }" name="dob"> <FormField v-slot="{ componentField, value }" name="dob">
<FormItem> <FormItem class="flex flex-col">
<FormLabel>Date of birth</FormLabel> <FormLabel>Date of birth</FormLabel>
<Popover> <Popover>
<PopoverTrigger as-child> <PopoverTrigger as-child>
@ -123,7 +123,7 @@ async function onSubmit(values: any) {
</FormField> </FormField>
<FormField v-slot="{ value }" name="language"> <FormField v-slot="{ value }" name="language">
<FormItem> <FormItem class="flex flex-col">
<FormLabel>Language</FormLabel> <FormLabel>Language</FormLabel>
<Popover v-model:open="open"> <Popover v-model:open="open">

View File

@ -1,5 +1,12 @@
<script setup lang='ts'> <script setup lang='ts'>
import { Card, CardContent, CardHeader, CardTitle } from '@/lib/registry/default/ui/card' import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from '@/lib/registry/default/ui/card'
import { import {
Select, Select,
SelectContent, SelectContent,

View File

@ -14,7 +14,7 @@ import {
useVueTable, useVueTable,
} from '@tanstack/vue-table' } from '@tanstack/vue-table'
import { h, ref } from 'vue' import { h, ref } from 'vue'
import { CaretSortIcon, ChevronDownIcon } from '@radix-icons/vue' import { ChevronDown, ChevronsUpDown } from 'lucide-vue-next'
import DropdownAction from '../DataTableDemoColumn.vue' import DropdownAction from '../DataTableDemoColumn.vue'
import { Button } from '@/lib/registry/default/ui/button' import { Button } from '@/lib/registry/default/ui/button'
@ -104,7 +104,7 @@ const columns: ColumnDef<Payment>[] = [
return h(Button, { return h(Button, {
variant: 'ghost', variant: 'ghost',
onClick: () => column.toggleSorting(column.getIsSorted() === 'asc'), onClick: () => column.toggleSorting(column.getIsSorted() === 'asc'),
}, ['Email', h(CaretSortIcon, { class: 'ml-2 h-4 w-4' })]) }, ['Email', h(ChevronsUpDown, { class: 'ml-2 h-4 w-4' })])
}, },
cell: ({ row }) => h('div', { class: 'lowercase' }, row.getValue('email')), cell: ({ row }) => h('div', { class: 'lowercase' }, row.getValue('email')),
}, },
@ -179,7 +179,7 @@ const table = useVueTable({
<DropdownMenu> <DropdownMenu>
<DropdownMenuTrigger as-child> <DropdownMenuTrigger as-child>
<Button variant="outline" class="ml-auto"> <Button variant="outline" class="ml-auto">
Columns <ChevronDownIcon class="ml-2 h-4 w-4" /> Columns <ChevronDown class="ml-2 h-4 w-4" />
</Button> </Button>
</DropdownMenuTrigger> </DropdownMenuTrigger>
<DropdownMenuContent align="end"> <DropdownMenuContent align="end">

View File

@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue' import { ref } from 'vue'
import { CaretSortIcon, CheckIcon } from '@radix-icons/vue' import { Check, ChevronsUpDown } from 'lucide-vue-next'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
import { Button } from '@/lib/registry/default/ui/button' import { Button } from '@/lib/registry/default/ui/button'
@ -44,7 +44,7 @@ const value = ref<string>('')
{{ value {{ value
? frameworks.find((framework) => framework.value === value)?.label ? frameworks.find((framework) => framework.value === value)?.label
: "Select framework..." }} : "Select framework..." }}
<CaretSortIcon class="ml-2 h-4 w-4 shrink-0 opacity-50" /> <ChevronsUpDown class="ml-2 h-4 w-4 shrink-0 opacity-50" />
</Button> </Button>
</PopoverTrigger> </PopoverTrigger>
<PopoverContent class="w-[200px] p-0"> <PopoverContent class="w-[200px] p-0">
@ -65,7 +65,7 @@ const value = ref<string>('')
}" }"
> >
{{ framework.label }} {{ framework.label }}
<CheckIcon <Check
:class="cn( :class="cn(
'ml-auto h-4 w-4', 'ml-auto h-4 w-4',
value === framework.value ? 'opacity-100' : 'opacity-0', value === framework.value ? 'opacity-100' : 'opacity-0',

View File

@ -40,7 +40,7 @@ const date = ref({
</span> </span>
</Button> </Button>
</PopoverTrigger> </PopoverTrigger>
<PopoverContent class="w-auto p-0" align="start" :avoid-collisions="true"> <PopoverContent class="w-auto p-0" align="start">
<Calendar <Calendar
v-model.range="date" v-model.range="date"
:columns="2" :columns="2"

View File

@ -40,7 +40,7 @@ const date = ref({
</span> </span>
</Button> </Button>
</PopoverTrigger> </PopoverTrigger>
<PopoverContent class="w-auto p-0" align="start" :avoid-collisions="true"> <PopoverContent class="w-auto p-0" align="start">
<Calendar <Calendar
v-model.range="date" v-model.range="date"
mode="date" mode="date"

View File

@ -3,15 +3,17 @@ import {
AccordionRoot, AccordionRoot,
type AccordionRootEmits, type AccordionRootEmits,
type AccordionRootProps, type AccordionRootProps,
useEmitAsProps, useForwardPropsEmits,
} from 'radix-vue' } from 'radix-vue'
const props = defineProps<AccordionRootProps>() const props = defineProps<AccordionRootProps>()
const emits = defineEmits<AccordionRootEmits>() const emits = defineEmits<AccordionRootEmits>()
const forwarded = useForwardPropsEmits(props, emits)
</script> </script>
<template> <template>
<AccordionRoot v-bind="{ ...props, ...useEmitAsProps(emits) }"> <AccordionRoot v-bind="forwarded">
<slot /> <slot />
</AccordionRoot> </AccordionRoot>
</template> </template>

View File

@ -1,21 +1,23 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { AccordionContent, type AccordionContentProps } from 'radix-vue' import { AccordionContent, type AccordionContentProps } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<AccordionContentProps & { class?: string }>() const props = defineProps<AccordionContentProps & { class?: HTMLAttributes['class'] }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
</script> </script>
<template> <template>
<AccordionContent <AccordionContent
v-bind="props" v-bind="delegatedProps"
:class=" class="overflow-hidden text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down"
cn(
'overflow-hidden text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down',
props.class,
)
"
> >
<div class="pb-4 pt-0"> <div :class="cn('pb-4 pt-0', props.class)">
<slot /> <slot />
</div> </div>
</AccordionContent> </AccordionContent>

View File

@ -1,14 +1,23 @@
<script setup lang="ts"> <script setup lang="ts">
import { AccordionItem, type AccordionItemProps } from 'radix-vue' import { type HTMLAttributes, computed } from 'vue'
import { AccordionItem, type AccordionItemProps, useForwardProps } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<AccordionItemProps & { class?: string }>() const props = defineProps<AccordionItemProps & { class?: HTMLAttributes['class'] }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwardedProps = useForwardProps(delegatedProps)
</script> </script>
<template> <template>
<AccordionItem <AccordionItem
v-bind="props" v-bind="forwardedProps"
:class="cn('border-b', props.class ?? '')" :class="cn('border-b', props.class)"
> >
<slot /> <slot />
</AccordionItem> </AccordionItem>

View File

@ -1,4 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
AccordionHeader, AccordionHeader,
AccordionTrigger, AccordionTrigger,
@ -7,13 +8,19 @@ import {
import { ChevronDown } from 'lucide-vue-next' import { ChevronDown } from 'lucide-vue-next'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<AccordionTriggerProps & { class?: string }>() const props = defineProps<AccordionTriggerProps & { class?: HTMLAttributes['class'] }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
</script> </script>
<template> <template>
<AccordionHeader class="flex" as="div"> <AccordionHeader class="flex">
<AccordionTrigger <AccordionTrigger
v-bind="props" v-bind="delegatedProps"
:class=" :class="
cn( cn(
'flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180', 'flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180',
@ -22,9 +29,11 @@ const props = defineProps<AccordionTriggerProps & { class?: string }>()
" "
> >
<slot /> <slot />
<ChevronDown <slot name="icon">
class="h-4 w-4 shrink-0 transition-transform duration-200" <ChevronDown
/> class="h-4 w-4 shrink-0 transition-transform duration-200"
/>
</slot>
</AccordionTrigger> </AccordionTrigger>
</AccordionHeader> </AccordionHeader>
</template> </template>

View File

@ -1,13 +1,20 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { AlertDialogAction, type AlertDialogActionProps } from 'radix-vue' import { AlertDialogAction, type AlertDialogActionProps } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
import { buttonVariants } from '@/lib/registry/default/ui/button' import { buttonVariants } from '@/lib/registry/default/ui/button'
const props = defineProps<AlertDialogActionProps>() const props = defineProps<AlertDialogActionProps & { class?: HTMLAttributes['class'] }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
</script> </script>
<template> <template>
<AlertDialogAction v-bind="props" :class="cn(buttonVariants(), $attrs.class ?? '')"> <AlertDialogAction v-bind="delegatedProps" :class="cn(buttonVariants(), props.class)">
<slot /> <slot />
</AlertDialogAction> </AlertDialogAction>
</template> </template>

View File

@ -1,13 +1,20 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { AlertDialogCancel, type AlertDialogCancelProps } from 'radix-vue' import { AlertDialogCancel, type AlertDialogCancelProps } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
import { buttonVariants } from '@/lib/registry/default/ui/button' import { buttonVariants } from '@/lib/registry/default/ui/button'
const props = defineProps<AlertDialogCancelProps>() const props = defineProps<AlertDialogCancelProps & { class?: HTMLAttributes['class'] }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
</script> </script>
<template> <template>
<AlertDialogCancel v-bind="props" :class="cn(buttonVariants({ variant: 'outline' }), 'mt-2 sm:mt-0', $attrs.class ?? '')"> <AlertDialogCancel v-bind="delegatedProps" :class="cn(buttonVariants({ variant: 'outline' }), 'mt-2 sm:mt-0', props.class)">
<slot /> <slot />
</AlertDialogCancel> </AlertDialogCancel>
</template> </template>

View File

@ -1,30 +1,37 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
AlertDialogContent, AlertDialogContent,
type AlertDialogContentEmits, type AlertDialogContentEmits,
type AlertDialogContentProps, type AlertDialogContentProps,
AlertDialogOverlay, AlertDialogOverlay,
AlertDialogPortal, AlertDialogPortal,
useEmitAsProps, useForwardPropsEmits,
} from 'radix-vue' } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<AlertDialogContentProps & { class?: string }>() const props = defineProps<AlertDialogContentProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<AlertDialogContentEmits>() const emits = defineEmits<AlertDialogContentEmits>()
const emitsAsProps = useEmitAsProps(emits) const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script> </script>
<template> <template>
<AlertDialogPortal> <AlertDialogPortal>
<AlertDialogOverlay <AlertDialogOverlay
class="fixed inset-0 z-50 bg-background/80 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0" class="fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0"
/> />
<AlertDialogContent <AlertDialogContent
v-bind="{ ...props, ...emitsAsProps }" v-bind="forwarded"
:class=" :class="
cn( cn(
'fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border border-border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg md:w-full', 'fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg',
props.class, props.class,
) )
" "

View File

@ -1,17 +1,24 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
AlertDialogDescription, AlertDialogDescription,
type AlertDialogDescriptionProps, type AlertDialogDescriptionProps,
} from 'radix-vue' } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<AlertDialogDescriptionProps & { class?: string }>() const props = defineProps<AlertDialogDescriptionProps & { class?: HTMLAttributes['class'] }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
</script> </script>
<template> <template>
<AlertDialogDescription <AlertDialogDescription
:class="cn('text-muted-foreground text-sm', props.class)" v-bind="delegatedProps"
:as-child="props.asChild" :class="cn('text-sm text-muted-foreground', props.class)"
> >
<slot /> <slot />
</AlertDialogDescription> </AlertDialogDescription>

View File

@ -1,19 +1,17 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps({ const props = defineProps<{
class: { class?: HTMLAttributes['class']
type: String, }>()
default: '',
},
})
</script> </script>
<template> <template>
<div <div
:class=" :class="
cn( cn(
'flex flex-col space-y-2 sm:space-y-0 mt-3.5 sm:flex-row sm:justify-end sm:space-x-2', 'flex flex-col-reverse sm:flex-row sm:justify-end sm:gap-x-2',
props.class, props.class,
) )
" "

View File

@ -1,17 +1,15 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps({ const props = defineProps<{
class: { class?: HTMLAttributes['class']
type: String, }>()
default: '',
},
})
</script> </script>
<template> <template>
<div <div
:class="cn('flex flex-col space-y-2 text-center sm:text-left', props.class)" :class="cn('flex flex-col gap-y-2 text-center sm:text-left', props.class)"
> >
<slot /> <slot />
</div> </div>

View File

@ -1,14 +1,21 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { AlertDialogTitle, type AlertDialogTitleProps } from 'radix-vue' import { AlertDialogTitle, type AlertDialogTitleProps } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<AlertDialogTitleProps & { class?: string }>() const props = defineProps<AlertDialogTitleProps & { class?: HTMLAttributes['class'] }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
</script> </script>
<template> <template>
<AlertDialogTitle <AlertDialogTitle
:as-child="props.asChild" v-bind="delegatedProps"
:class="cn('text-lg text-foreground font-semibold', props.class)" :class="cn('text-lg font-semibold', props.class)"
> >
<slot /> <slot />
</AlertDialogTitle> </AlertDialogTitle>

View File

@ -1,17 +1,16 @@
<script setup lang="ts"> <script setup lang="ts">
import { alertVariants } from '.' import type { HTMLAttributes } from 'vue'
import { type AlertVariants, alertVariants } from '.'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
interface Props { const props = defineProps<{
variant?: NonNullable<Parameters<typeof alertVariants>[0]>['variant'] class?: HTMLAttributes['class']
class?: string variant?: AlertVariants['variant']
} }>()
const props = defineProps<Props>()
</script> </script>
<template> <template>
<div :class="cn(alertVariants({ variant }), props.class ?? '')"> <div :class="cn(alertVariants({ variant }), props.class)" role="alert">
<slot /> <slot />
</div> </div>
</template> </template>

View File

@ -1,9 +1,10 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps({ const props = defineProps<{
class: String, class?: HTMLAttributes['class']
}) }>()
</script> </script>
<template> <template>

View File

@ -1,9 +1,14 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<{
class?: HTMLAttributes['class']
}>()
</script> </script>
<template> <template>
<h5 :class="cn('mb-1 font-medium leading-none tracking-tight', $attrs.class ?? '')"> <h5 :class="cn('mb-1 font-medium leading-none tracking-tight', props.class)">
<slot /> <slot />
</h5> </h5>
</template> </template>

View File

@ -1,4 +1,4 @@
import { cva } from 'class-variance-authority' import { type VariantProps, cva } from 'class-variance-authority'
export { default as Alert } from './Alert.vue' export { default as Alert } from './Alert.vue'
export { default as AlertTitle } from './AlertTitle.vue' export { default as AlertTitle } from './AlertTitle.vue'
@ -19,3 +19,5 @@ export const alertVariants = cva(
}, },
}, },
) )
export type AlertVariants = VariantProps<typeof alertVariants>

View File

@ -1,15 +1,14 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { AvatarRoot } from 'radix-vue' import { AvatarRoot } from 'radix-vue'
import { avatarVariant } from '.' import { type AvatarVariants, avatarVariant } from '.'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
interface Props { const props = withDefaults(defineProps<{
size?: NonNullable<Parameters<typeof avatarVariant>[0]>['size'] class?: HTMLAttributes['class']
shape?: NonNullable<Parameters<typeof avatarVariant>[0]>['shape'] size?: AvatarVariants['size']
class?: string shape?: AvatarVariants['shape']
} }>(), {
const props = withDefaults(defineProps<Props>(), {
size: 'sm', size: 'sm',
shape: 'circle', shape: 'circle',
}) })

View File

@ -1,4 +1,4 @@
import { cva } from 'class-variance-authority' import { type VariantProps, cva } from 'class-variance-authority'
export { default as Avatar } from './Avatar.vue' export { default as Avatar } from './Avatar.vue'
export { default as AvatarImage } from './AvatarImage.vue' export { default as AvatarImage } from './AvatarImage.vue'
@ -20,3 +20,5 @@ export const avatarVariant = cva(
}, },
}, },
) )
export type AvatarVariants = VariantProps<typeof avatarVariant>

View File

@ -1,18 +1,16 @@
<script setup lang="ts"> <script setup lang="ts">
import type { VariantProps } from 'class-variance-authority' import type { HTMLAttributes } from 'vue'
import { badgeVariants } from '.' import { type BadgeVariants, badgeVariants } from '.'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
interface BadgeVariantProps extends VariantProps<typeof badgeVariants> {} const props = defineProps<{
variant?: BadgeVariants['variant']
interface Props { class?: HTMLAttributes['class']
variant?: BadgeVariantProps['variant'] }>()
}
defineProps<Props>()
</script> </script>
<template> <template>
<div :class="cn(badgeVariants({ variant }), $attrs.class ?? '')"> <div :class="cn(badgeVariants({ variant }), props.class)">
<slot /> <slot />
</div> </div>
</template> </template>

View File

@ -1,4 +1,4 @@
import { cva } from 'class-variance-authority' import { type VariantProps, cva } from 'class-variance-authority'
export { default as Badge } from './Badge.vue' export { default as Badge } from './Badge.vue'
@ -21,3 +21,5 @@ export const badgeVariants = cva(
}, },
}, },
) )
export type BadgeVariants = VariantProps<typeof badgeVariants>

View File

@ -1,20 +1,17 @@
<script setup lang="ts"> <script setup lang="ts">
import type { VariantProps } from 'class-variance-authority' import type { HTMLAttributes } from 'vue'
import { Primitive, type PrimitiveProps } from 'radix-vue' import { Primitive, type PrimitiveProps } from 'radix-vue'
import { buttonVariants } from '.' import { type ButtonVariants, buttonVariants } from '.'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
interface ButtonVariantProps extends VariantProps<typeof buttonVariants> {}
interface Props extends PrimitiveProps { interface Props extends PrimitiveProps {
variant?: ButtonVariantProps['variant'] variant?: ButtonVariants['variant']
size?: ButtonVariantProps['size'] size?: ButtonVariants['size']
as?: string as?: string
class?: HTMLAttributes['class']
} }
withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
variant: 'default',
size: 'default',
as: 'button', as: 'button',
}) })
</script> </script>
@ -23,7 +20,7 @@ withDefaults(defineProps<Props>(), {
<Primitive <Primitive
:as="as" :as="as"
:as-child="asChild" :as-child="asChild"
:class="cn(buttonVariants({ variant, size }), $attrs.class ?? '')" :class="cn(buttonVariants({ variant, size }), props.class)"
> >
<slot /> <slot />
</Primitive> </Primitive>

View File

@ -1,9 +1,9 @@
import { cva } from 'class-variance-authority' import { type VariantProps, cva } from 'class-variance-authority'
export { default as Button } from './Button.vue' export { default as Button } from './Button.vue'
export const buttonVariants = cva( export const buttonVariants = cva(
'inline-flex items-center justify-center rounded-md whitespace-nowrap text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50', 'inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
{ {
variants: { variants: {
variant: { variant: {
@ -30,3 +30,5 @@ export const buttonVariants = cva(
}, },
}, },
) )
export type ButtonVariants = VariantProps<typeof buttonVariants>

View File

@ -29,8 +29,7 @@ interface SimpleDateParts {
defineOptions({ defineOptions({
inheritAttrs: false, inheritAttrs: false,
}) })
const props = withDefaults(defineProps< {
const props = withDefaults(defineProps<{
modelValue?: string | number | Date | DatePickerModel modelValue?: string | number | Date | DatePickerModel
modelModifiers?: object modelModifiers?: object
columns?: number columns?: number
@ -90,8 +89,8 @@ const vCalendarSlots = computed(() => {
<DatePicker <DatePicker
ref="datePicker" ref="datePicker"
v-model="modelValue"
v-bind="$attrs" v-bind="$attrs"
v-model="modelValue"
:model-modifiers="modelModifiers" :model-modifiers="modelModifiers"
class="calendar" class="calendar"
trim-weeks trim-weeks
@ -152,7 +151,7 @@ const vCalendarSlots = computed(() => {
@apply rounded-md; @apply rounded-md;
} }
.calendar .vc-day-content { .calendar .vc-day-content {
@apply text-center text-sm p-0 relative focus-within:relative focus-within:z-20 inline-flex items-center justify-center ring-offset-background hover:transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 hover:bg-accent hover:text-accent-foreground h-9 w-9 font-normal aria-selected:opacity-100 select-none; @apply text-center text-sm p-0 relative focus-within:relative focus-within:z-20 inline-flex items-center justify-center ring-offset-background hover:transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 hover:bg-accent hover:text-accent-foreground h-9 w-9 font-normal aria-selected:opacity-100 select-none;
} }
.calendar .vc-day-content:not(.vc-highlight-content-light) { .calendar .vc-day-content:not(.vc-highlight-content-light) {
@apply rounded-md; @apply rounded-md;
@ -178,6 +177,7 @@ const vCalendarSlots = computed(() => {
--vc-slide-duration: 0.15s; --vc-slide-duration: 0.15s;
--vc-slide-timing: ease; --vc-slide-timing: ease;
} }
.calendar .vc-fade-enter-active, .calendar .vc-fade-enter-active,
.calendar .vc-fade-leave-active, .calendar .vc-fade-leave-active,
.calendar .vc-slide-left-enter-active, .calendar .vc-slide-left-enter-active,
@ -204,6 +204,7 @@ const vCalendarSlots = computed(() => {
backface-visibility: hidden; backface-visibility: hidden;
pointer-events: none; pointer-events: none;
} }
.calendar .vc-none-leave-active, .calendar .vc-none-leave-active,
.calendar .vc-fade-leave-active, .calendar .vc-fade-leave-active,
.calendar .vc-slide-left-leave-active, .calendar .vc-slide-left-leave-active,
@ -213,6 +214,7 @@ const vCalendarSlots = computed(() => {
position: absolute !important; position: absolute !important;
width: 100%; width: 100%;
} }
.calendar .vc-none-enter-from, .calendar .vc-none-enter-from,
.calendar .vc-none-leave-to, .calendar .vc-none-leave-to,
.calendar .vc-fade-enter-from, .calendar .vc-fade-enter-from,
@ -229,6 +231,7 @@ const vCalendarSlots = computed(() => {
.calendar .vc-slide-fade-leave-to { .calendar .vc-slide-fade-leave-to {
opacity: 0; opacity: 0;
} }
.calendar .vc-slide-left-enter-from, .calendar .vc-slide-left-enter-from,
.calendar .vc-slide-right-leave-to, .calendar .vc-slide-right-leave-to,
.calendar .vc-slide-fade-enter-from.direction-left, .calendar .vc-slide-fade-enter-from.direction-left,
@ -236,6 +239,7 @@ const vCalendarSlots = computed(() => {
-webkit-transform: translateX(var(--vc-slide-translate)); -webkit-transform: translateX(var(--vc-slide-translate));
transform: translateX(var(--vc-slide-translate)); transform: translateX(var(--vc-slide-translate));
} }
.calendar .vc-slide-right-enter-from, .calendar .vc-slide-right-enter-from,
.calendar .vc-slide-left-leave-to, .calendar .vc-slide-left-leave-to,
.calendar .vc-slide-fade-enter-from.direction-right, .calendar .vc-slide-fade-enter-from.direction-right,
@ -243,6 +247,7 @@ const vCalendarSlots = computed(() => {
-webkit-transform: translateX(calc(-1 * var(--vc-slide-translate))); -webkit-transform: translateX(calc(-1 * var(--vc-slide-translate)));
transform: translateX(calc(-1 * var(--vc-slide-translate))); transform: translateX(calc(-1 * var(--vc-slide-translate)));
} }
.calendar .vc-slide-up-enter-from, .calendar .vc-slide-up-enter-from,
.calendar .vc-slide-down-leave-to, .calendar .vc-slide-down-leave-to,
.calendar .vc-slide-fade-enter-from.direction-top, .calendar .vc-slide-fade-enter-from.direction-top,
@ -250,6 +255,7 @@ const vCalendarSlots = computed(() => {
-webkit-transform: translateY(var(--vc-slide-translate)); -webkit-transform: translateY(var(--vc-slide-translate));
transform: translateY(var(--vc-slide-translate)); transform: translateY(var(--vc-slide-translate));
} }
.calendar .vc-slide-down-enter-from, .calendar .vc-slide-down-enter-from,
.calendar .vc-slide-up-leave-to, .calendar .vc-slide-up-leave-to,
.calendar .vc-slide-fade-enter-from.direction-bottom, .calendar .vc-slide-fade-enter-from.direction-bottom,

View File

@ -1,12 +1,10 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps({ const props = defineProps<{
class: { class?: HTMLAttributes['class']
type: String, }>()
default: '',
},
})
</script> </script>
<template> <template>

View File

@ -1,12 +1,10 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps({ const props = defineProps<{
class: { class?: HTMLAttributes['class']
type: String, }>()
default: '',
},
})
</script> </script>
<template> <template>

View File

@ -1,12 +1,10 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps({ const props = defineProps<{
class: { class?: HTMLAttributes['class']
type: String, }>()
default: '',
},
})
</script> </script>
<template> <template>

View File

@ -1,16 +1,14 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps({ const props = defineProps<{
class: { class?: HTMLAttributes['class']
type: String, }>()
default: '',
},
})
</script> </script>
<template> <template>
<div :class="cn('p-6 pt-0', props.class)"> <div :class="cn('flex items-center p-6 pt-0', props.class)">
<slot /> <slot />
</div> </div>
</template> </template>

View File

@ -1,16 +1,14 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps({ const props = defineProps<{
class: { class?: HTMLAttributes['class']
type: String, }>()
default: '',
},
})
</script> </script>
<template> <template>
<div :class="cn('flex flex-col space-y-1.5 p-6', props.class)"> <div :class="cn('flex flex-col gap-y-1.5 p-6', props.class)">
<slot /> <slot />
</div> </div>
</template> </template>

View File

@ -1,18 +1,16 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps({ const props = defineProps<{
class: { class?: HTMLAttributes['class']
type: String, }>()
default: '',
},
})
</script> </script>
<template> <template>
<h3 <h3
:class=" :class="
cn('text-2xl font-semibold leading-none tracking-tighter', props.class) cn('text-2xl font-semibold leading-none tracking-tight', props.class)
" "
> >
<slot /> <slot />

View File

@ -1,5 +1,4 @@
<script setup lang="ts"> <script setup lang="ts">
import emblaCarouselVue from 'embla-carousel-vue'
import { useProvideCarousel } from './useCarousel' import { useProvideCarousel } from './useCarousel'
import type { CarouselEmits, CarouselProps, WithClassAsProps } from './interface' import type { CarouselEmits, CarouselProps, WithClassAsProps } from './interface'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'

View File

@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import type { WithClassAsProps } from './interface'
import { useCarousel } from './useCarousel' import { useCarousel } from './useCarousel'
import type { WithClassAsProps } from './interface'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
defineOptions({ defineOptions({

View File

@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import type { WithClassAsProps } from './interface'
import { useCarousel } from './useCarousel' import { useCarousel } from './useCarousel'
import type { WithClassAsProps } from './interface'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<WithClassAsProps>() const props = defineProps<WithClassAsProps>()

View File

@ -1,13 +1,20 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import type { CheckboxRootEmits, CheckboxRootProps } from 'radix-vue' import type { CheckboxRootEmits, CheckboxRootProps } from 'radix-vue'
import { CheckboxIndicator, CheckboxRoot, useForwardPropsEmits } from 'radix-vue' import { CheckboxIndicator, CheckboxRoot, useForwardPropsEmits } from 'radix-vue'
import { Check } from 'lucide-vue-next' import { Check } from 'lucide-vue-next'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<CheckboxRootProps>() const props = defineProps<CheckboxRootProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<CheckboxRootEmits>() const emits = defineEmits<CheckboxRootEmits>()
const forwarded = useForwardPropsEmits(props, emits) const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script> </script>
<template> <template>
@ -15,10 +22,12 @@ const forwarded = useForwardPropsEmits(props, emits)
v-bind="forwarded" v-bind="forwarded"
:class=" :class="
cn('peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground', cn('peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground',
$attrs.class ?? '')" props.class)"
> >
<CheckboxIndicator class="flex h-full w-full items-center justify-center text-current"> <CheckboxIndicator class="flex h-full w-full items-center justify-center text-current">
<Check class="h-4 w-4" /> <slot>
<Check class="h-4 w-4" />
</slot>
</CheckboxIndicator> </CheckboxIndicator>
</CheckboxRoot> </CheckboxRoot>
</template> </template>

View File

@ -1,13 +1,15 @@
<script setup lang="ts"> <script setup lang="ts">
import { CollapsibleRoot, useEmitAsProps } from 'radix-vue' import { CollapsibleRoot, useForwardPropsEmits } from 'radix-vue'
import type { CollapsibleRootEmits, CollapsibleRootProps } from 'radix-vue' import type { CollapsibleRootEmits, CollapsibleRootProps } from 'radix-vue'
const props = defineProps<CollapsibleRootProps>() const props = defineProps<CollapsibleRootProps>()
const emits = defineEmits<CollapsibleRootEmits>() const emits = defineEmits<CollapsibleRootEmits>()
const forwarded = useForwardPropsEmits(props, emits)
</script> </script>
<template> <template>
<CollapsibleRoot v-slot="{ open }" v-bind="{ ...props, ...useEmitAsProps(emits) }"> <CollapsibleRoot v-slot="{ open }" v-bind="forwarded">
<slot :open="open" /> <slot :open="open" />
</CollapsibleRoot> </CollapsibleRoot>
</template> </template>

View File

@ -1,20 +1,29 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import type { ComboboxRootEmits, ComboboxRootProps } from 'radix-vue' import type { ComboboxRootEmits, ComboboxRootProps } from 'radix-vue'
import { ComboboxRoot, useForwardPropsEmits } from 'radix-vue' import { ComboboxRoot, useForwardPropsEmits } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<ComboboxRootProps>() const props = withDefaults(defineProps<ComboboxRootProps & { class?: HTMLAttributes['class'] }>(), {
open: true,
modelValue: '',
})
const emits = defineEmits<ComboboxRootEmits>() const emits = defineEmits<ComboboxRootEmits>()
const forwarded = useForwardPropsEmits(props, emits) const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script> </script>
<template> <template>
<ComboboxRoot <ComboboxRoot
v-bind="forwarded" v-bind="forwarded"
:open="true" :class="cn('flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground', props.class)"
:model-value="''"
:class="cn('flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground', $attrs.class ?? '')"
> >
<slot /> <slot />
</ComboboxRoot> </ComboboxRoot>

View File

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { useEmitAsProps } from 'radix-vue' import { useForwardPropsEmits } from 'radix-vue'
import type { DialogRootEmits, DialogRootProps } from 'radix-vue' import type { DialogRootEmits, DialogRootProps } from 'radix-vue'
import Command from './Command.vue' import Command from './Command.vue'
import { Dialog, DialogContent } from '@/lib/registry/default/ui/dialog' import { Dialog, DialogContent } from '@/lib/registry/default/ui/dialog'
@ -7,12 +7,12 @@ import { Dialog, DialogContent } from '@/lib/registry/default/ui/dialog'
const props = defineProps<DialogRootProps>() const props = defineProps<DialogRootProps>()
const emits = defineEmits<DialogRootEmits>() const emits = defineEmits<DialogRootEmits>()
const emitsAsProps = useEmitAsProps(emits) const forwarded = useForwardPropsEmits(props, emits)
</script> </script>
<template> <template>
<Dialog v-bind="{ ...props, ...emitsAsProps }"> <Dialog v-bind="forwarded">
<DialogContent class="p-0 overflow-hidden shadow-lg"> <DialogContent class="overflow-hidden p-0 shadow-lg">
<Command class="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5"> <Command class="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
<slot /> <slot />
</Command> </Command>

View File

@ -1,13 +1,20 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import type { ComboboxEmptyProps } from 'radix-vue' import type { ComboboxEmptyProps } from 'radix-vue'
import { ComboboxEmpty } from 'radix-vue' import { ComboboxEmpty } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<ComboboxEmptyProps>() const props = defineProps<ComboboxEmptyProps & { class?: HTMLAttributes['class'] }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
</script> </script>
<template> <template>
<ComboboxEmpty v-bind="props" :class="cn('py-6 text-center text-sm', $attrs.class ?? '')"> <ComboboxEmpty v-bind="delegatedProps" :class="cn('py-6 text-center text-sm', props.class)">
<slot /> <slot />
</ComboboxEmpty> </ComboboxEmpty>
</template> </template>

View File

@ -1,17 +1,25 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import type { ComboboxGroupProps } from 'radix-vue' import type { ComboboxGroupProps } from 'radix-vue'
import { ComboboxGroup, ComboboxLabel } from 'radix-vue' import { ComboboxGroup, ComboboxLabel } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<ComboboxGroupProps & { const props = defineProps<ComboboxGroupProps & {
class?: HTMLAttributes['class']
heading?: string heading?: string
}>() }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
</script> </script>
<template> <template>
<ComboboxGroup <ComboboxGroup
v-bind="props" v-bind="delegatedProps"
:class="cn('overflow-hidden p-1 text-foreground', $attrs.class ?? '')" :class="cn('overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground', props.class)"
> >
<ComboboxLabel v-if="heading" class="px-2 py-1.5 text-xs font-medium text-muted-foreground"> <ComboboxLabel v-if="heading" class="px-2 py-1.5 text-xs font-medium text-muted-foreground">
{{ heading }} {{ heading }}

View File

@ -1,24 +1,33 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { Search } from 'lucide-vue-next' import { Search } from 'lucide-vue-next'
import { ComboboxInput, type ComboboxInputProps } from 'radix-vue' import { ComboboxInput, type ComboboxInputProps, useForwardProps } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<ComboboxInputProps>() defineOptions({
</script>
<script lang="ts">
export default {
inheritAttrs: false, inheritAttrs: false,
} })
const props = defineProps<ComboboxInputProps & {
class?: HTMLAttributes['class']
}>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwardedProps = useForwardProps(delegatedProps)
</script> </script>
<template> <template>
<div class="flex items-center border-b px-3" cmdk-input-wrapper> <div class="flex items-center border-b px-3" cmdk-input-wrapper>
<Search class="mr-2 h-4 w-4 shrink-0 opacity-50" /> <Search class="mr-2 h-4 w-4 shrink-0 opacity-50" />
<ComboboxInput <ComboboxInput
v-bind="{ ...props, ...$attrs }" v-bind="{ ...forwardedProps, ...$attrs }"
auto-focus auto-focus
:class="cn('flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50', $attrs.class ?? '')" :class="cn('flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50', props.class)"
/> />
</div> </div>
</template> </template>

View File

@ -1,18 +1,25 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import type { ComboboxItemEmits, ComboboxItemProps } from 'radix-vue' import type { ComboboxItemEmits, ComboboxItemProps } from 'radix-vue'
import { ComboboxItem, useEmitAsProps } from 'radix-vue' import { ComboboxItem, useForwardPropsEmits } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<ComboboxItemProps>() const props = defineProps<ComboboxItemProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<ComboboxItemEmits>() const emits = defineEmits<ComboboxItemEmits>()
const emitsAsProps = useEmitAsProps(emits) const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script> </script>
<template> <template>
<ComboboxItem <ComboboxItem
v-bind="{ ...props, ...emitsAsProps }" v-bind="forwarded"
:class="cn('relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50', $attrs.class ?? '')" :class="cn('relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none aria-selected:bg-accent aria-selected:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50', props.class)"
@select.prevent @select.prevent
> >
<slot /> <slot />

View File

@ -1,16 +1,23 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import type { ComboboxContentEmits, ComboboxContentProps } from 'radix-vue' import type { ComboboxContentEmits, ComboboxContentProps } from 'radix-vue'
import { ComboboxContent, useForwardPropsEmits } from 'radix-vue' import { ComboboxContent, useForwardPropsEmits } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<ComboboxContentProps>() const props = defineProps<ComboboxContentProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<ComboboxContentEmits>() const emits = defineEmits<ComboboxContentEmits>()
const forwarded = useForwardPropsEmits(props, emits) const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script> </script>
<template> <template>
<ComboboxContent v-bind="forwarded" :class="cn('max-h-[300px] overflow-y-auto overflow-x-hidden', $attrs.class ?? '')"> <ComboboxContent v-bind="forwarded" :class="cn('max-h-[300px] overflow-y-auto overflow-x-hidden', props.class)">
<div role="presentation"> <div role="presentation">
<slot /> <slot />
</div> </div>

View File

@ -1,15 +1,22 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import type { ComboboxSeparatorProps } from 'radix-vue' import type { ComboboxSeparatorProps } from 'radix-vue'
import { ComboboxSeparator } from 'radix-vue' import { ComboboxSeparator } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<ComboboxSeparatorProps>() const props = defineProps<ComboboxSeparatorProps & { class?: HTMLAttributes['class'] }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
</script> </script>
<template> <template>
<ComboboxSeparator <ComboboxSeparator
v-bind="props" v-bind="delegatedProps"
:class="cn('-mx-1 h-px bg-border', $attrs.class ?? '')" :class="cn('-mx-1 h-px bg-border', props.class)"
> >
<slot /> <slot />
</ComboboxSeparator> </ComboboxSeparator>

View File

@ -1,9 +1,14 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<{
class?: HTMLAttributes['class']
}>()
</script> </script>
<template> <template>
<span :class="cn('ml-auto text-xs tracking-widest text-muted-foreground', $attrs.class ?? '')"> <span :class="cn('ml-auto text-xs tracking-widest text-muted-foreground', props.class)">
<slot /> <slot />
</span> </span>
</template> </template>

View File

@ -1,33 +1,38 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
ContextMenuCheckboxItem, ContextMenuCheckboxItem,
type ContextMenuCheckboxItemEmits, type ContextMenuCheckboxItemEmits,
type ContextMenuCheckboxItemProps, type ContextMenuCheckboxItemProps,
ContextMenuItemIndicator, ContextMenuItemIndicator,
useEmitAsProps, useForwardPropsEmits,
} from 'radix-vue' } from 'radix-vue'
import { Check } from 'lucide-vue-next' import { Check } from 'lucide-vue-next'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<ContextMenuCheckboxItemProps & { class?: string }>() const props = defineProps<ContextMenuCheckboxItemProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<ContextMenuCheckboxItemEmits>() const emits = defineEmits<ContextMenuCheckboxItemEmits>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script> </script>
<template> <template>
<ContextMenuCheckboxItem <ContextMenuCheckboxItem
v-bind="{ ...props, ...useEmitAsProps(emits) }" v-bind="forwarded"
:class="[ :class="cn(
cn( 'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50', props.class,
props.class, )"
),
]"
> >
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center"> <span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<ContextMenuItemIndicator <ContextMenuItemIndicator>
class="absolute left-1.5 inline-flex w-4 h-4 items-center justify-center" <Check class="h-4 w-4" />
>
<Check class="h-4 h-w" />
</ContextMenuItemIndicator> </ContextMenuItemIndicator>
</span> </span>
<slot /> <slot />

View File

@ -1,4 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
ContextMenuContent, ContextMenuContent,
type ContextMenuContentEmits, type ContextMenuContentEmits,
@ -8,23 +9,26 @@ import {
} from 'radix-vue' } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<ContextMenuContentProps & { class?: string }>() const props = defineProps<ContextMenuContentProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<ContextMenuContentEmits>() const emits = defineEmits<ContextMenuContentEmits>()
const forwarded = useForwardPropsEmits(props, emits) const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script> </script>
<template> <template>
<ContextMenuPortal> <ContextMenuPortal>
<ContextMenuContent <ContextMenuContent
:align-offset="props.alignOffset"
:class="[
cn(
'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md animate-in fade-in-80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
props.class,
),
]"
v-bind="forwarded" v-bind="forwarded"
:class="cn(
'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md animate-in fade-in-80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
props.class,
)"
> >
<slot /> <slot />
</ContextMenuContent> </ContextMenuContent>

View File

@ -1,26 +1,33 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
ContextMenuItem, ContextMenuItem,
type ContextMenuItemEmits, type ContextMenuItemEmits,
type ContextMenuItemProps, type ContextMenuItemProps,
useEmitAsProps, useForwardPropsEmits,
} from 'radix-vue' } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<ContextMenuItemProps & { class?: string; inset?: boolean }>() const props = defineProps<ContextMenuItemProps & { class?: HTMLAttributes['class']; inset?: boolean }>()
const emits = defineEmits<ContextMenuItemEmits>() const emits = defineEmits<ContextMenuItemEmits>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script> </script>
<template> <template>
<ContextMenuItem <ContextMenuItem
v-bind="{ ...props, ...useEmitAsProps(emits) }" v-bind="forwarded"
:class="[ :class="cn(
cn( 'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50', inset && 'pl-8',
inset && 'pl-8', props.class,
props.class, )"
),
]"
> >
<slot /> <slot />
</ContextMenuItem> </ContextMenuItem>

View File

@ -1,16 +1,23 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { ContextMenuLabel, type ContextMenuLabelProps } from 'radix-vue' import { ContextMenuLabel, type ContextMenuLabelProps } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<ContextMenuLabelProps & { class?: string; inset?: boolean }>() const props = defineProps<ContextMenuLabelProps & { class?: HTMLAttributes['class']; inset?: boolean }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
</script> </script>
<template> <template>
<ContextMenuLabel <ContextMenuLabel
v-bind="props" v-bind="delegatedProps"
:class=" :class="
cn('px-2 py-1.5 text-sm font-semibold text-foreground', cn('px-2 py-1.5 text-sm font-semibold text-foreground',
inset && 'pl-8', props.class ?? '', inset && 'pl-8', props.class,
)" )"
> >
<slot /> <slot />

View File

@ -1,4 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
ContextMenuItemIndicator, ContextMenuItemIndicator,
ContextMenuRadioItem, ContextMenuRadioItem,
@ -9,21 +10,25 @@ import {
import { Circle } from 'lucide-vue-next' import { Circle } from 'lucide-vue-next'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<ContextMenuRadioItemProps & { class?: string }>() const props = defineProps<ContextMenuRadioItemProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<ContextMenuRadioItemEmits>() const emits = defineEmits<ContextMenuRadioItemEmits>()
const forwarded = useForwardPropsEmits(props, emits) const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script> </script>
<template> <template>
<ContextMenuRadioItem <ContextMenuRadioItem
v-bind="forwarded" v-bind="forwarded"
:class="[ :class="cn(
cn( 'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50', props.class,
props.class, )"
),
]"
> >
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center"> <span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<ContextMenuItemIndicator> <ContextMenuItemIndicator>

View File

@ -1,13 +1,20 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
ContextMenuSeparator, ContextMenuSeparator,
type ContextMenuSeparatorProps, type ContextMenuSeparatorProps,
} from 'radix-vue' } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<ContextMenuSeparatorProps>() const props = defineProps<ContextMenuSeparatorProps & { class?: HTMLAttributes['class'] }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
</script> </script>
<template> <template>
<ContextMenuSeparator v-bind="props" :class="cn('-mx-1 my-1 h-px bg-border', $attrs.class ?? '')" /> <ContextMenuSeparator v-bind="delegatedProps" :class="cn('-mx-1 my-1 h-px bg-border', props.class)" />
</template> </template>

View File

@ -1,9 +1,14 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<{
class?: HTMLAttributes['class']
}>()
</script> </script>
<template> <template>
<span :class="cn('ml-auto text-xs tracking-widest text-muted-foreground', $attrs.class ?? '')"> <span :class="cn('ml-auto text-xs tracking-widest text-muted-foreground', props.class)">
<slot /> <slot />
</span> </span>
</template> </template>

View File

@ -1,4 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
ContextMenuSubContent, ContextMenuSubContent,
type DropdownMenuSubContentEmits, type DropdownMenuSubContentEmits,
@ -7,10 +8,16 @@ import {
} from 'radix-vue' } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<DropdownMenuSubContentProps & { class?: string }>() const props = defineProps<DropdownMenuSubContentProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<DropdownMenuSubContentEmits>() const emits = defineEmits<DropdownMenuSubContentEmits>()
const forwarded = useForwardPropsEmits(props, emits) const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script> </script>
<template> <template>

View File

@ -1,24 +1,32 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
ContextMenuSubTrigger, ContextMenuSubTrigger,
type ContextMenuSubTriggerProps, type ContextMenuSubTriggerProps,
useForwardProps,
} from 'radix-vue' } from 'radix-vue'
import { ChevronRight } from 'lucide-vue-next' import { ChevronRight } from 'lucide-vue-next'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<ContextMenuSubTriggerProps & { class?: string; inset?: boolean }>() const props = defineProps<ContextMenuSubTriggerProps & { class?: HTMLAttributes['class']; inset?: boolean }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwardedProps = useForwardProps(delegatedProps)
</script> </script>
<template> <template>
<ContextMenuSubTrigger <ContextMenuSubTrigger
v-bind="props" v-bind="forwardedProps"
:class="[ :class="cn(
cn( 'flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground',
'flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground', inset && 'pl-8',
inset && 'pl-8', props.class,
props.class, )"
),
]"
> >
<slot /> <slot />
<ChevronRight class="ml-auto h-4 w-4" /> <ChevronRight class="ml-auto h-4 w-4" />

View File

@ -1,11 +1,13 @@
<script setup lang="ts"> <script setup lang="ts">
import { ContextMenuTrigger, type ContextMenuTriggerProps } from 'radix-vue' import { ContextMenuTrigger, type ContextMenuTriggerProps, useForwardProps } from 'radix-vue'
const props = defineProps<ContextMenuTriggerProps>() const props = defineProps<ContextMenuTriggerProps>()
const forwardedProps = useForwardProps(props)
</script> </script>
<template> <template>
<ContextMenuTrigger v-bind="props"> <ContextMenuTrigger v-bind="forwardedProps">
<slot /> <slot />
</ContextMenuTrigger> </ContextMenuTrigger>
</template> </template>

View File

@ -1,4 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
DialogClose, DialogClose,
DialogContent, DialogContent,
@ -6,35 +7,40 @@ import {
type DialogContentProps, type DialogContentProps,
DialogOverlay, DialogOverlay,
DialogPortal, DialogPortal,
useEmitAsProps, useForwardPropsEmits,
} from 'radix-vue' } from 'radix-vue'
import { X } from 'lucide-vue-next' import { X } from 'lucide-vue-next'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<DialogContentProps & { class?: string }>() const props = defineProps<DialogContentProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<DialogContentEmits>() const emits = defineEmits<DialogContentEmits>()
const emitsAsProps = useEmitAsProps(emits) const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script> </script>
<template> <template>
<DialogPortal> <DialogPortal>
<DialogOverlay <DialogOverlay
class="fixed inset-0 z-50 bg-background/80 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0" class="fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0"
/> />
<DialogContent <DialogContent
v-bind="forwarded"
:class=" :class="
cn( cn(
'fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border border-border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg md:w-full', 'fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg',
props.class, props.class,
) )"
"
v-bind="{ ...props, ...emitsAsProps }"
> >
<slot /> <slot />
<DialogClose <DialogClose
class="absolute top-3 right-3 p-0.5 transition-colors rounded-md hover:bg-secondary" class="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground"
> >
<X class="w-4 h-4" /> <X class="w-4 h-4" />
<span class="sr-only">Close</span> <span class="sr-only">Close</span>

View File

@ -1,14 +1,23 @@
<script setup lang="ts"> <script setup lang="ts">
import { DialogDescription, type DialogDescriptionProps } from 'radix-vue' import { type HTMLAttributes, computed } from 'vue'
import { DialogDescription, type DialogDescriptionProps, useForwardProps } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<DialogDescriptionProps & { class?: string }>() const props = defineProps<DialogDescriptionProps & { class?: HTMLAttributes['class'] }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwardedProps = useForwardProps(delegatedProps)
</script> </script>
<template> <template>
<DialogDescription <DialogDescription
v-bind="props" v-bind="forwardedProps"
:class="cn('text-muted-foreground text-sm', props.class)" :class="cn('text-sm text-muted-foreground', props.class)"
> >
<slot /> <slot />
</DialogDescription> </DialogDescription>

View File

@ -1,18 +1,15 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
interface DialogFooterProps { const props = defineProps<{ class?: HTMLAttributes['class'] }>()
class?: string
}
const props = defineProps<DialogFooterProps>()
</script> </script>
<template> <template>
<div <div
:class=" :class="
cn( cn(
'flex flex-col space-y-2 sm:space-y-0 mt-1.5 sm:flex-row sm:justify-end sm:space-x-2', 'flex flex-col-reverse sm:flex-row sm:justify-end sm:gap-x-2',
props.class, props.class,
) )
" "

View File

@ -1,16 +1,15 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
interface DialogHeaderProps { const props = defineProps<{
class?: string class?: HTMLAttributes['class']
} }>()
const props = defineProps<DialogHeaderProps>()
</script> </script>
<template> <template>
<div <div
:class="cn('flex flex-col space-y-2 text-center sm:text-left', props.class)" :class="cn('flex flex-col gap-y-1.5 text-center sm:text-left', props.class)"
> >
<slot /> <slot />
</div> </div>

View File

@ -1,16 +1,25 @@
<script setup lang="ts"> <script setup lang="ts">
import { DialogTitle, type DialogTitleProps } from 'radix-vue' import { type HTMLAttributes, computed } from 'vue'
import { DialogTitle, type DialogTitleProps, useForwardProps } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<DialogTitleProps & { class?: string }>() const props = defineProps<DialogTitleProps & { class?: HTMLAttributes['class'] }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwardedProps = useForwardProps(delegatedProps)
</script> </script>
<template> <template>
<DialogTitle <DialogTitle
v-bind="props" v-bind="forwardedProps"
:class=" :class="
cn( cn(
'text-lg text-foreground font-semibold leading-none tracking-tight', 'text-lg font-semibold leading-none tracking-tight',
props.class, props.class,
) )
" "

View File

@ -1,21 +1,30 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
DropdownMenuCheckboxItem, DropdownMenuCheckboxItem,
type DropdownMenuCheckboxItemEmits, type DropdownMenuCheckboxItemEmits,
type DropdownMenuCheckboxItemProps, type DropdownMenuCheckboxItemProps,
DropdownMenuItemIndicator, DropdownMenuItemIndicator,
useEmitAsProps, useForwardPropsEmits,
} from 'radix-vue' } from 'radix-vue'
import { Check } from 'lucide-vue-next' import { Check } from 'lucide-vue-next'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<DropdownMenuCheckboxItemProps & { class?: string }>() const props = defineProps<DropdownMenuCheckboxItemProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<DropdownMenuCheckboxItemEmits>() const emits = defineEmits<DropdownMenuCheckboxItemEmits>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script> </script>
<template> <template>
<DropdownMenuCheckboxItem <DropdownMenuCheckboxItem
v-bind="{ ...props, ...useEmitAsProps(emits) }" v-bind="forwarded"
:class=" cn( :class=" cn(
'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50', 'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
props.class, props.class,

View File

@ -1,4 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
DropdownMenuContent, DropdownMenuContent,
type DropdownMenuContentEmits, type DropdownMenuContentEmits,
@ -9,26 +10,27 @@ import {
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = withDefaults( const props = withDefaults(
defineProps<DropdownMenuContentProps & { class?: string }>(), defineProps<DropdownMenuContentProps & { class?: HTMLAttributes['class'] }>(),
{ {
sideOffset: 4, sideOffset: 4,
}, },
) )
const emits = defineEmits<DropdownMenuContentEmits>() const emits = defineEmits<DropdownMenuContentEmits>()
const forwarded = useForwardPropsEmits(props, emits) const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script> </script>
<template> <template>
<DropdownMenuPortal> <DropdownMenuPortal>
<DropdownMenuContent <DropdownMenuContent
:class="[
cn(
'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
props.class,
),
]"
v-bind="forwarded" v-bind="forwarded"
:class="cn('z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2', props.class)"
> >
<slot /> <slot />
</DropdownMenuContent> </DropdownMenuContent>

View File

@ -1,20 +1,27 @@
<script setup lang="ts"> <script setup lang="ts">
import { DropdownMenuItem, type DropdownMenuItemProps } from 'radix-vue' import { type HTMLAttributes, computed } from 'vue'
import { DropdownMenuItem, type DropdownMenuItemProps, useForwardProps } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<DropdownMenuItemProps & { inset?: boolean; class?: string }>() const props = defineProps<DropdownMenuItemProps & { class?: HTMLAttributes['class']; inset?: boolean }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwardedProps = useForwardProps(delegatedProps)
</script> </script>
<template> <template>
<DropdownMenuItem <DropdownMenuItem
v-bind="props" v-bind="forwardedProps"
:class="[ :class="cn(
cn( 'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50', inset && 'pl-8',
inset && 'pl-8', props.class,
props.class, )"
),
]"
> >
<slot /> <slot />
</DropdownMenuItem> </DropdownMenuItem>

View File

@ -1,19 +1,23 @@
<script setup lang="ts"> <script setup lang="ts">
import { DropdownMenuLabel, type DropdownMenuLabelProps } from 'radix-vue' import { type HTMLAttributes, computed } from 'vue'
import { DropdownMenuLabel, type DropdownMenuLabelProps, useForwardProps } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<DropdownMenuLabelProps & { const props = defineProps<DropdownMenuLabelProps & { class?: HTMLAttributes['class']; inset?: boolean }>()
inset?: boolean
class?: string const delegatedProps = computed(() => {
}>() const { class: _, ...delegated } = props
return delegated
})
const forwardedProps = useForwardProps(delegatedProps)
</script> </script>
<template> <template>
<DropdownMenuLabel <DropdownMenuLabel
v-bind="props" v-bind="forwardedProps"
:class=" :class="cn('px-2 py-1.5 text-sm font-semibold', inset && 'pl-8', props.class)"
cn('px-2 py-1.5 text-sm font-semibold',
inset && 'pl-8', props.class)"
> >
<slot /> <slot />
</DropdownMenuLabel> </DropdownMenuLabel>

View File

@ -3,18 +3,17 @@ import {
DropdownMenuRadioGroup, DropdownMenuRadioGroup,
type DropdownMenuRadioGroupEmits, type DropdownMenuRadioGroupEmits,
type DropdownMenuRadioGroupProps, type DropdownMenuRadioGroupProps,
useForwardPropsEmits,
} from 'radix-vue' } from 'radix-vue'
const props = defineProps<DropdownMenuRadioGroupProps>() const props = defineProps<DropdownMenuRadioGroupProps>()
const emits = defineEmits<DropdownMenuRadioGroupEmits>() const emits = defineEmits<DropdownMenuRadioGroupEmits>()
const forwarded = useForwardPropsEmits(props, emits)
</script> </script>
<template> <template>
<DropdownMenuRadioGroup <DropdownMenuRadioGroup v-bind="forwarded">
v-bind="props"
@update:model-value="emits('update:modelValue', $event)"
>
<slot /> <slot />
</DropdownMenuRadioGroup> </DropdownMenuRadioGroup>
</template> </template>

View File

@ -1,29 +1,37 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
DropdownMenuItemIndicator, DropdownMenuItemIndicator,
DropdownMenuRadioItem, DropdownMenuRadioItem,
type DropdownMenuRadioItemEmits, type DropdownMenuRadioItemEmits,
type DropdownMenuRadioItemProps, type DropdownMenuRadioItemProps,
useEmitAsProps, useForwardPropsEmits,
} from 'radix-vue' } from 'radix-vue'
import { Circle } from 'lucide-vue-next' import { Circle } from 'lucide-vue-next'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<DropdownMenuRadioItemProps & { class?: string }>() const props = defineProps<DropdownMenuRadioItemProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<DropdownMenuRadioItemEmits>() const emits = defineEmits<DropdownMenuRadioItemEmits>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script> </script>
<template> <template>
<DropdownMenuRadioItem <DropdownMenuRadioItem
v-bind="{ ...props, ...useEmitAsProps(emits) }" v-bind="forwarded"
:class="cn( :class="cn(
'flex relative items-center rounded-md transition-colors data-[disabled]:opacity-50 data-[disabled]:pointer-events-none data-[highlighted]:bg-outline-hover pl-7 py-1.5 text-sm outline-none select-none cursor-default', 'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
props.class, props.class,
)" )"
> >
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center"> <span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<DropdownMenuItemIndicator> <DropdownMenuItemIndicator>
<Circle class="h-2 w-2 fill-current" /> <Circle class="h-2 w-2 fill-current" />
</DropdownMenuItemIndicator> </DropdownMenuItemIndicator>

View File

@ -1,12 +1,22 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
DropdownMenuSeparator, DropdownMenuSeparator,
type DropdownMenuSeparatorProps, type DropdownMenuSeparatorProps,
} from 'radix-vue' } from 'radix-vue'
import { cn } from '@/lib/utils'
const props = defineProps<DropdownMenuSeparatorProps>() const props = defineProps<DropdownMenuSeparatorProps & {
class?: HTMLAttributes['class']
}>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
</script> </script>
<template> <template>
<DropdownMenuSeparator v-bind="props" class="-mx-1 my-1 h-px bg-muted" /> <DropdownMenuSeparator v-bind="delegatedProps" :class="cn('-mx-1 my-1 h-px bg-muted', props.class)" />
</template> </template>

View File

@ -1,9 +1,14 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<{
class?: HTMLAttributes['class']
}>()
</script> </script>
<template> <template>
<span :class="cn('ml-auto text-xs tracking-widest opacity-60', $attrs.class ?? '')"> <span :class="cn('ml-auto text-xs tracking-widest opacity-60', props.class)">
<slot /> <slot />
</span> </span>
</template> </template>

View File

@ -1,4 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
DropdownMenuSubContent, DropdownMenuSubContent,
type DropdownMenuSubContentEmits, type DropdownMenuSubContentEmits,
@ -7,16 +8,22 @@ import {
} from 'radix-vue' } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<DropdownMenuSubContentProps>() const props = defineProps<DropdownMenuSubContentProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<DropdownMenuSubContentEmits>() const emits = defineEmits<DropdownMenuSubContentEmits>()
const forwarded = useForwardPropsEmits(props, emits) const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script> </script>
<template> <template>
<DropdownMenuSubContent <DropdownMenuSubContent
v-bind="forwarded" v-bind="forwarded"
:class="cn('z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2', $attrs.class ?? '')" :class="cn('z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2', props.class)"
> >
<slot /> <slot />
</DropdownMenuSubContent> </DropdownMenuSubContent>

View File

@ -1,23 +1,31 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
DropdownMenuSubTrigger, DropdownMenuSubTrigger,
type DropdownMenuSubTriggerProps, type DropdownMenuSubTriggerProps,
useForwardProps,
} from 'radix-vue' } from 'radix-vue'
import { ChevronRight } from 'lucide-vue-next' import { ChevronRight } from 'lucide-vue-next'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<DropdownMenuSubTriggerProps & { class?: string }>() const props = defineProps<DropdownMenuSubTriggerProps & { class?: HTMLAttributes['class'] }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwardedProps = useForwardProps(delegatedProps)
</script> </script>
<template> <template>
<DropdownMenuSubTrigger <DropdownMenuSubTrigger
v-bind="props" v-bind="forwardedProps"
:class="[ :class="cn(
cn( 'flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent',
'flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent', props.class,
props.class, )"
),
]"
> >
<slot /> <slot />
<ChevronRight class="ml-auto h-4 w-4" /> <ChevronRight class="ml-auto h-4 w-4" />

View File

@ -1,11 +1,13 @@
<script setup lang="ts"> <script setup lang="ts">
import { DropdownMenuTrigger, type DropdownMenuTriggerProps } from 'radix-vue' import { DropdownMenuTrigger, type DropdownMenuTriggerProps, useForwardProps } from 'radix-vue'
const props = defineProps<DropdownMenuTriggerProps>() const props = defineProps<DropdownMenuTriggerProps>()
const forwardedProps = useForwardProps(props)
</script> </script>
<template> <template>
<DropdownMenuTrigger class="outline-none" v-bind="props"> <DropdownMenuTrigger class="outline-none" v-bind="forwardedProps">
<slot /> <slot />
</DropdownMenuTrigger> </DropdownMenuTrigger>
</template> </template>

View File

@ -1,21 +1,19 @@
<script lang="ts" setup> <script lang="ts" setup>
import { useAttrs } from 'vue' import type { HTMLAttributes } from 'vue'
import { useFormField } from './useFormField' import { useFormField } from './useFormField'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
defineOptions({ const props = defineProps<{
inheritAttrs: false, class?: HTMLAttributes['class']
}) }>()
const { formDescriptionId } = useFormField() const { formDescriptionId } = useFormField()
const { class: className, ...rest } = useAttrs()
</script> </script>
<template> <template>
<p <p
:id="formDescriptionId" :id="formDescriptionId"
:class="cn('text-sm text-muted-foreground', className ?? '')" :class="cn('text-sm text-muted-foreground', props.class)"
v-bind="rest"
> >
<slot /> <slot />
</p> </p>

View File

@ -1,27 +1,25 @@
<script lang="ts"> <script lang="ts">
import { type InjectionKey } from 'vue' import type { HTMLAttributes, InjectionKey } from 'vue'
export const FORM_ITEM_INJECTION_KEY export const FORM_ITEM_INJECTION_KEY
= Symbol() as InjectionKey<string> = Symbol() as InjectionKey<string>
</script> </script>
<script lang="ts" setup> <script lang="ts" setup>
import { provide, useAttrs } from 'vue' import { provide } from 'vue'
import { useId } from 'radix-vue' import { useId } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
defineOptions({ const props = defineProps<{
inheritAttrs: false, class?: HTMLAttributes['class']
}) }>()
const id = useId() const id = useId()
provide(FORM_ITEM_INJECTION_KEY, id) provide(FORM_ITEM_INJECTION_KEY, id)
const { class: className, ...rest } = useAttrs()
</script> </script>
<template> <template>
<div :class="cn('space-y-2', className ?? '')" v-bind="rest"> <div :class="cn('space-y-2', props.class)">
<slot /> <slot />
</div> </div>
</template> </template>

View File

@ -1,27 +1,22 @@
<script lang="ts" setup> <script lang="ts" setup>
import { useAttrs } from 'vue' import type { HTMLAttributes } from 'vue'
import { Label, type LabelProps } from 'radix-vue' import type { LabelProps } from 'radix-vue'
import { useFormField } from './useFormField' import { useFormField } from './useFormField'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
import { Label } from '@/lib/registry/default/ui/label'
defineOptions({ const props = defineProps<LabelProps & { class?: HTMLAttributes['class'] }>()
inheritAttrs: false,
})
const props = defineProps<LabelProps>()
const { error, formItemId } = useFormField() const { error, formItemId } = useFormField()
const { class: className, ...rest } = useAttrs()
</script> </script>
<template> <template>
<Label <Label
:class="cn( :class="cn(
'block text-sm tracking-tight font-medium text-foreground text-left',
error && 'text-destructive', error && 'text-destructive',
className ?? '', props.class,
)" )"
:for="formItemId" :for="formItemId"
v-bind="rest"
> >
<slot /> <slot />
</Label> </Label>

View File

@ -2,11 +2,12 @@
import { HoverCardRoot, type HoverCardRootProps, useForwardProps } from 'radix-vue' import { HoverCardRoot, type HoverCardRootProps, useForwardProps } from 'radix-vue'
const props = defineProps<HoverCardRootProps>() const props = defineProps<HoverCardRootProps>()
const forwarded = useForwardProps(props)
const forwardedProps = useForwardProps(props)
</script> </script>
<template> <template>
<HoverCardRoot v-bind="forwarded"> <HoverCardRoot v-bind="forwardedProps">
<slot /> <slot />
</HoverCardRoot> </HoverCardRoot>
</template> </template>

View File

@ -1,4 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
HoverCardContent, HoverCardContent,
type HoverCardContentProps, type HoverCardContentProps,
@ -8,22 +9,28 @@ import {
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = withDefaults( const props = withDefaults(
defineProps<HoverCardContentProps & { class?: string }>(), defineProps<HoverCardContentProps & { class?: HTMLAttributes['class'] }>(),
{ {
sideOffset: 4, sideOffset: 4,
}, },
) )
const forwarded = useForwardProps(props) const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwardedProps = useForwardProps(delegatedProps)
</script> </script>
<template> <template>
<HoverCardPortal> <HoverCardPortal>
<HoverCardContent <HoverCardContent
v-bind="forwarded" v-bind="forwardedProps"
:class=" :class="
cn( cn(
'z-50 w-64 rounded-md bg-background border border-border p-4 text-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2', 'z-50 w-64 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
props.class, props.class,
) )
" "

View File

@ -20,5 +20,5 @@ const modelValue = useVModel(props, 'modelValue', emits, {
</script> </script>
<template> <template>
<input v-model="modelValue" :class="cn('flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50', props.class ?? '')"> <input v-model="modelValue" :class="cn('flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50', props.class)">
</template> </template>

View File

@ -1,16 +1,23 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { Label, type LabelProps } from 'radix-vue' import { Label, type LabelProps } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<LabelProps & { class?: string }>() const props = defineProps<LabelProps & { class?: HTMLAttributes['class'] }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
</script> </script>
<template> <template>
<Label <Label
v-bind="props" v-bind="delegatedProps"
:class=" :class="
cn( cn(
'block text-sm tracking-tight font-medium text-foreground text-left', 'text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70',
props.class, props.class,
) )
" "

View File

@ -1,26 +1,34 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
MenubarRoot, MenubarRoot,
type MenubarRootEmits, type MenubarRootEmits,
type MenubarRootProps, type MenubarRootProps,
useForwardPropsEmits,
} from 'radix-vue' } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<MenubarRootProps & { class?: string }>() const props = defineProps<MenubarRootProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<MenubarRootEmits>() const emits = defineEmits<MenubarRootEmits>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script> </script>
<template> <template>
<MenubarRoot <MenubarRoot
v-bind="props" v-bind="forwarded"
:class=" :class="
cn( cn(
'flex h-10 items-center space-x-1 rounded-md border border-border p-1', 'flex h-10 items-center gap-x-1 rounded-md border bg-background p-1',
props.class, props.class,
) )
" "
@update:model-value="emits('update:modelValue', $event)"
> >
<slot /> <slot />
</MenubarRoot> </MenubarRoot>

View File

@ -1,35 +1,40 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
MenubarCheckboxItem, MenubarCheckboxItem,
type MenubarCheckboxItemEmits, type MenubarCheckboxItemEmits,
type MenubarCheckboxItemProps, type MenubarCheckboxItemProps,
MenubarItemIndicator, MenubarItemIndicator,
useForwardPropsEmits,
} from 'radix-vue' } from 'radix-vue'
import { Check } from 'lucide-vue-next' import { Check } from 'lucide-vue-next'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<MenubarCheckboxItemProps & { class?: string }>() const props = defineProps<MenubarCheckboxItemProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<MenubarCheckboxItemEmits>()
const emit = defineEmits<MenubarCheckboxItemEmits>() const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script> </script>
<template> <template>
<MenubarCheckboxItem <MenubarCheckboxItem
v-bind="props" v-bind="forwarded"
:class="[ :class="cn(
cn( 'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50', props.class,
props.class, )"
),
]"
@update:checked="emit('update:checked', $event)"
@select="emit('select', $event)"
> >
<MenubarItemIndicator <span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center" <MenubarItemIndicator>
> <Check class="w-4 h-4" />
<Check class="w-4 h-4" /> </MenubarItemIndicator>
</MenubarItemIndicator> </span>
<slot /> <slot />
</MenubarCheckboxItem> </MenubarCheckboxItem>
</template> </template>

View File

@ -1,30 +1,35 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
MenubarContent, MenubarContent,
type MenubarContentProps, type MenubarContentProps,
MenubarPortal, MenubarPortal,
useForwardProps,
} from 'radix-vue' } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = withDefaults( const props = withDefaults(
defineProps<MenubarContentProps & { class?: string }>(), defineProps<MenubarContentProps & { class?: HTMLAttributes['class'] }>(),
{ {
align: 'start', align: 'start',
alignOffset: -4, alignOffset: -4,
sideOffset: 8, sideOffset: 8,
}, },
) )
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwardedProps = useForwardProps(delegatedProps)
</script> </script>
<template> <template>
<MenubarPortal> <MenubarPortal>
<MenubarContent <MenubarContent
:loop="props.loop" v-bind="forwardedProps"
:as-child="props.asChild"
:side-offset="props.sideOffset"
:side="props.side"
:align="props.align"
:align-offset="props.alignOffset"
:class=" :class="
cn( cn(
'z-50 min-w-[12rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2', 'z-50 min-w-[12rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',

View File

@ -1,27 +1,34 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
MenubarItem, MenubarItem,
type MenubarItemEmits, type MenubarItemEmits,
type MenubarItemProps, type MenubarItemProps,
useForwardPropsEmits,
} from 'radix-vue' } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<MenubarItemProps & { inset?: boolean; class?: string }>() const props = defineProps<MenubarItemProps & { class?: HTMLAttributes['class']; inset?: boolean }>()
const emits = defineEmits<MenubarItemEmits>() const emits = defineEmits<MenubarItemEmits>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script> </script>
<template> <template>
<MenubarItem <MenubarItem
v-bind="props" v-bind="forwarded"
:class="[ :class="cn(
cn( 'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50', inset && 'pl-8',
inset && 'pl-8', props.class,
props.class, )"
),
]"
@select="emits('select', $event)"
> >
<slot /> <slot />
</MenubarItem> </MenubarItem>

View File

@ -1,8 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { MenubarLabel, type MenubarLabelProps } from 'radix-vue' import { MenubarLabel, type MenubarLabelProps } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<MenubarLabelProps & { inset?: boolean; class?: string }>() const props = defineProps<MenubarLabelProps & { class?: HTMLAttributes['class']; inset?: boolean }>()
</script> </script>
<template> <template>

View File

@ -3,18 +3,18 @@ import {
MenubarRadioGroup, MenubarRadioGroup,
type MenubarRadioGroupEmits, type MenubarRadioGroupEmits,
type MenubarRadioGroupProps, type MenubarRadioGroupProps,
useForwardPropsEmits,
} from 'radix-vue' } from 'radix-vue'
const props = defineProps<MenubarRadioGroupProps>() const props = defineProps<MenubarRadioGroupProps>()
const emits = defineEmits<MenubarRadioGroupEmits>() const emits = defineEmits<MenubarRadioGroupEmits>()
const forwarded = useForwardPropsEmits(props, emits)
</script> </script>
<template> <template>
<MenubarRadioGroup <MenubarRadioGroup v-bind="forwarded">
v-bind="props"
@update:model-value="emits('update:modelValue', $event)"
>
<slot /> <slot />
</MenubarRadioGroup> </MenubarRadioGroup>
</template> </template>

View File

@ -1,35 +1,40 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
MenubarItemIndicator, MenubarItemIndicator,
MenubarRadioItem, MenubarRadioItem,
type MenubarRadioItemEmits, type MenubarRadioItemEmits,
type MenubarRadioItemProps, type MenubarRadioItemProps,
useForwardPropsEmits,
} from 'radix-vue' } from 'radix-vue'
import { Circle } from 'lucide-vue-next' import { Circle } from 'lucide-vue-next'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<MenubarRadioItemProps & { class?: string }>() const props = defineProps<MenubarRadioItemProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<MenubarRadioItemEmits>() const emits = defineEmits<MenubarRadioItemEmits>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script> </script>
<template> <template>
<MenubarRadioItem <MenubarRadioItem
v-bind="props" v-bind="forwarded"
:class="[ :class="cn(
cn( 'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50', props.class,
props.class, )"
),
]"
@select="emits('select', $event)"
> >
<MenubarItemIndicator <span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center" <MenubarItemIndicator>
> <Circle class="h-2 w-2 fill-current" />
<Circle class="h-2 w-2 fill-curren" /> </MenubarItemIndicator>
</MenubarItemIndicator> </span>
<slot /> <slot />
</MenubarRadioItem> </MenubarRadioItem>
</template> </template>

View File

@ -1,10 +1,19 @@
<script setup lang="ts"> <script setup lang="ts">
import { MenubarSeparator, type MenubarSeparatorProps } from 'radix-vue' import { type HTMLAttributes, computed } from 'vue'
import { MenubarSeparator, type MenubarSeparatorProps, useForwardProps } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<MenubarSeparatorProps>() const props = defineProps<MenubarSeparatorProps & { class?: HTMLAttributes['class'] }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwardedProps = useForwardProps(delegatedProps)
</script> </script>
<template> <template>
<MenubarSeparator :class=" cn('-mx-1 my-1 h-px bg-secondary', $attrs.class ?? '')" v-bind="props" /> <MenubarSeparator :class=" cn('-mx-1 my-1 h-px bg-muted', props.class)" v-bind="forwardedProps" />
</template> </template>

View File

@ -1,9 +1,14 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<{
class?: HTMLAttributes['class']
}>()
</script> </script>
<template> <template>
<span :class="cn('text-xxs ml-auto tracking-widest opacity-50', $attrs.class ?? '')"> <span :class="cn('ml-auto text-xs tracking-widest text-muted-foreground', props.class)">
<slot /> <slot />
</span> </span>
</template> </template>

View File

@ -1,32 +1,31 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
MenubarPortal, MenubarPortal,
MenubarSubContent, MenubarSubContent,
type MenubarSubContentEmits, type MenubarSubContentEmits,
type MenubarSubContentProps, type MenubarSubContentProps,
useForwardPropsEmits,
} from 'radix-vue' } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = withDefaults( const props = defineProps<MenubarSubContentProps & { class?: HTMLAttributes['class'] }>()
defineProps<MenubarSubContentProps & { class?: string }>(),
{
sideOffset: 2,
alignOffset: 0,
},
)
const emits = defineEmits<MenubarSubContentEmits>() const emits = defineEmits<MenubarSubContentEmits>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script> </script>
<template> <template>
<MenubarPortal> <MenubarPortal>
<MenubarSubContent <MenubarSubContent
:loop="props.loop" v-bind="forwarded"
:as-child="props.asChild"
:side-offset="props.sideOffset"
:side="props.side"
:align="props.align"
:align-offset="props.alignOffset"
:class=" :class="
cn( cn(
'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2', 'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',

View File

@ -1,21 +1,28 @@
<script setup lang="ts"> <script setup lang="ts">
import { MenubarSubTrigger, type MenubarSubTriggerProps } from 'radix-vue' import { type HTMLAttributes, computed } from 'vue'
import { MenubarSubTrigger, type MenubarSubTriggerProps, useForwardProps } from 'radix-vue'
import { ChevronRight } from 'lucide-vue-next' import { ChevronRight } from 'lucide-vue-next'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<MenubarSubTriggerProps & { inset?: boolean; class?: string }>() const props = defineProps<MenubarSubTriggerProps & { class?: HTMLAttributes['class']; inset?: boolean }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwardedProps = useForwardProps(delegatedProps)
</script> </script>
<template> <template>
<MenubarSubTrigger <MenubarSubTrigger
v-bind="props" v-bind="forwardedProps"
:class="[ :class="cn(
cn( 'flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground',
'flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground', inset && 'pl-8',
inset && 'pl-8', props.class,
props.class, )"
),
]"
> >
<slot /> <slot />
<ChevronRight class="ml-auto h-4 w-4" /> <ChevronRight class="ml-auto h-4 w-4" />

Some files were not shown because too many files have changed in this diff Show More