Merge branch 'dev' into cli-nypm-and-other-improves

This commit is contained in:
Sadegh Barati 2024-02-04 18:45:26 +03:30
commit 64e8930f38
434 changed files with 5931 additions and 5722 deletions

View File

@ -6,62 +6,27 @@ body:
- type: markdown
attributes:
value: |
**Before You Start...**
Thanks for taking the time to fill out this bug report!
This form is only for submitting bug reports. If you have a usage question
or are unsure if this is really a bug, make sure to:
- Read the [docs](https://radix-vue.com/)
- Ask on [Discord Chat](https://chat.radix-vue.com/)
- Ask on [GitHub Discussions](https://github.com/shadcn-vue/shadcn-vue/discussions)
Also try to search for your issue - it may have already been answered or even fixed.
However, if you find that an old, closed issue still persists in the latest version,
you should open a new issue using the form below instead of commenting on the old issue.
- type: textarea
id: bug-env
attributes:
label: Environment
description: Please provide the following information about your environment.
value: |
Developement/Production OS: Windows 10 19043.1110
Node version: 16.0.0
Package manager: pnpm@8.6.0
Radix Vue version: 1.0.0
Shadcn Vue version: 1.0.0
Vue version: 3.0.0
Nuxt version: 3.0.0
Nuxt mode: universal
Nuxt target: server
CSS framework: tailwindcss@3.3.3
Client OS: Windows 10 19043.1110
Browser: Chrome 90.0.4430.212
render: bash
validations:
required: true
- type: input
id: reproduction-link
id: reproduction
attributes:
label: Link to minimal reproduction
label: Reproduction
description: |
Please provide a link to a minimal reproduction of the bug.
A minimal reproduction is a CodeSandbox, CodePen, or a StackBlitz that contains the bare minimum amount of code needed to show the bug.
A minimal reproduction is required unless you are absolutely sure that the issue is obvious and the provided information is enough to understand the problem
A [minimal reproduction](https://stackoverflow.com/help/minimal-reproducible-example) is **required**, otherwise the issue might be closed without further notice. [**Why?**](https://antfu.me/posts/why-reproductions-are-required)
This is **required** for us to be able to triage your issue in a timely manner.
To get started, you can use the StackBlitz and CodeSandbox playgrounds in shadcn-vue demos:
https://www.shadcn-vue.com/docs/components/accordion.html
Please do not just fill in a random link. The issue will be closed if no valid reproduction is provided.
placeholder: Reproduction Link
validations:
required: true
- type: textarea
id: steps-to-reproduce
attributes:
label: Steps to reproduce
description: |
How do you trigger this bug? Please walk us through it step by step.
Note that you can use [Markdown](https://guides.github.com/features/mastering-markdown/) to format lists and code.
placeholder: Steps to reproduce
or use template presets
https://vite.new
https://nuxt.new
placeholder: Reproduction
validations:
required: true
- type: textarea
@ -73,14 +38,18 @@ body:
validations:
required: true
- type: textarea
id: expected-behavior
id: system-info
attributes:
label: Expected behavior
description: A clear and concise description of what you expected to happen.
- type: textarea
id: screenshots
label: System Info
description: Output of `npx envinfo --system --npmPackages vue,@vueuse/core,radix-vue,nuxt,shadcn-vue,shadcn-nuxt,unplugin-auto-import --binaries --browsers`
render: bash
placeholder: System, Binaries, Browsers
validations:
required: true
- type: checkboxes
id: contributes
attributes:
label: Conext & Screenshots (if applicable)
description: |
If applicable, provide any additional context or screenshots of the bug.
You can drag and drop images here to add them to the issue.
label: Contributes
options:
- label: I am willing to submit a PR to fix this issue
- label: I am willing to submit a PR with failing tests

View File

@ -17,8 +17,6 @@ on:
- opened
# When a labeled '🚀request-deploy' pull request from forked repo, it will be deploy to Cloudflare Pages
- labeled
paths:
- 'apps/www/**'
# Allows you to run this workflow manually from the Actions tab
# eslint-disable-next-line yml/no-empty-mapping-value
workflow_dispatch:
@ -52,9 +50,6 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha || github.ref }}
fetch-depth: 0
# Run a build step here
- name: Setup Node.js environment

View File

@ -3,9 +3,9 @@ import { defineConfig } from 'vitepress'
import Icons from 'unplugin-icons/vite'
import tailwind from 'tailwindcss'
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 ComponentPreviewPlugin from './theme/plugins/previewer'
@ -61,6 +61,7 @@ export default defineConfig({
theme: cssVariables,
codeTransformers: [
// transformerMetaWordHighlight(),
// transformerNotationWordHighlight(),
],
config(md) {
md.use(ComponentPreviewPlugin)
@ -86,8 +87,5 @@ export default defineConfig({
'@': path.resolve(__dirname, '../src'),
},
},
ssr: {
noExternal: ['vue-sonner'],
},
},
})

View File

@ -18,9 +18,9 @@ const kbdClass = computed(() => {
{
variants: {
size: {
xs: 'min-h-[16px] text-[10px] h-4 px-1',
sm: 'min-h-[20px] text-[11px] h-5 px-1',
md: 'min-h-[24px] text-[12px] h-6 px-1.5',
xs: 'min-h-4 text-[10px] h-4 px-1',
sm: 'min-h-5 text-[11px] h-5 px-1',
md: 'min-h-6 text-[12px] h-6 px-1.5',
},
},
},

View File

@ -328,7 +328,6 @@ export const docsConfig: DocsConfig = {
{
title: 'Toast',
href: '/docs/components/toast',
label: 'New',
items: [],
},
{

View File

@ -46,9 +46,9 @@ const sourceLink = 'https://github.com/radix-vue/shadcn-vue/tree/dev/'
>
{{ 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 }}
</Badge>
</span>
</a>
</div>
</div>

View File

@ -135,7 +135,7 @@ watch(() => $route.path, (n) => {
:href="link.href" target="_blank"
:variant="'ghost'" :size="'icon'"
>
<component :is="link.icon" class="w-[20px] h-[20px]" />
<component :is="link.icon" class="w-[20px] h-5" />
</Button>
<Button
@ -146,7 +146,7 @@ watch(() => $route.path, (n) => {
>
<component
:is="isDark ? RadixIconsSun : RadixIconsMoon"
class="w-[20px] h-[20px] text-foreground"
class="w-[20px] h-5 text-foreground"
/>
</Button>
</div>
@ -288,7 +288,9 @@ watch(() => $route.path, (n) => {
</DialogContent>
</Dialog>
<DefaultToaster />
<NewYorkSonner :theme="isDark ? 'dark' : 'light'" />
<ClientOnly>
<NewYorkSonner :theme="isDark ? 'dark' : 'light'" />
</ClientOnly>
<NewYorkToaster />
</div>
</template>

View File

@ -5,49 +5,49 @@
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 240 10% 3.9%;
--card: 0 0% 100%;
--card-foreground: 240 10% 3.9%;
--popover: 0 0% 100%;
--popover-foreground: 240 10% 3.9%;
--primary: 240 5.9% 10%;
--primary-foreground: 0 0% 98%;
--secondary: 240 4.8% 95.9%;
--secondary-foreground: 240 5.9% 10%;
--muted: 240 4.8% 95.9%;
--muted-foreground: 240 3.8% 46.1%;
--accent: 240 4.8% 95.9%;
--accent-foreground: 240 5.9% 10%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 0 0% 98%;
--border: 240 5.9% 90%;
--input: 240 5.9% 90%;
--ring: 240 5% 64.9%;
--radius: 0.5rem;
}
--background: 0 0% 100%;
--foreground: 240 10% 3.9%;
--card: 0 0% 100%;
--card-foreground: 240 10% 3.9%;
--popover: 0 0% 100%;
--popover-foreground: 240 10% 3.9%;
--primary: 240 5.9% 10%;
--primary-foreground: 0 0% 98%;
--secondary: 240 4.8% 95.9%;
--secondary-foreground: 240 5.9% 10%;
--muted: 240 4.8% 95.9%;
--muted-foreground: 240 3.8% 46.1%;
--accent: 240 4.8% 95.9%;
--accent-foreground: 240 5.9% 10%;
--destructive: 0 72.22% 50.59%;
--destructive-foreground: 0 0% 98%;
--border: 240 5.9% 90%;
--input: 240 5.9% 90%;
--ring: 240 5% 64.9%;
--radius: 0.5rem;
}
.dark {
--background: 240 10% 3.9%;
--foreground: 0 0% 98%;
--card: 240 10% 3.9%;
--card-foreground: 0 0% 98%;
--popover: 240 10% 3.9%;
--popover-foreground: 0 0% 98%;
--primary: 0 0% 98%;
--primary-foreground: 240 5.9% 10%;
--secondary: 240 3.7% 15.9%;
--secondary-foreground: 0 0% 98%;
--muted: 240 3.7% 15.9%;
--muted-foreground: 240 5% 64.9%;
--accent: 240 3.7% 15.9%;
--accent-foreground: 0 0% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 0 85.7% 97.3%;
--border: 240 3.7% 15.9%;
--input: 240 3.7% 15.9%;
--ring: 240 4.9% 83.9%;
}
.dark {
--background: 240 10% 3.9%;
--foreground: 0 0% 98%;
--card: 240 10% 3.9%;
--card-foreground: 0 0% 98%;
--popover: 240 10% 3.9%;
--popover-foreground: 0 0% 98%;
--primary: 0 0% 98%;
--primary-foreground: 240 5.9% 10%;
--secondary: 240 3.7% 15.9%;
--secondary-foreground: 0 0% 98%;
--muted: 240 3.7% 15.9%;
--muted-foreground: 240 5% 64.9%;
--accent: 240 3.7% 15.9%;
--accent-foreground: 0 0% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 0 85.7% 97.3%;
--border: 240 3.7% 15.9%;
--input: 240 3.7% 15.9%;
--ring: 240 4.9% 83.9%;
}
* {
@ -116,7 +116,7 @@
.step:before {
@apply absolute w-9 h-9 bg-muted rounded-full font-mono font-medium text-center text-base inline-flex items-center justify-center -indent-px border-4 border-background;
@apply ml-[-50px] mt-[-4px];
@apply -ml-[50px] -mt-1;
content: counter(step);
}
}
@ -139,7 +139,7 @@ pre code {
}
pre code .line {
@apply px-4 min-h-[1.5rem] !py-0.5 w-full inline-block;
@apply px-4 min-h-6 !py-0.5 w-full inline-block;
}
.line-number {
@ -149,4 +149,4 @@ pre code .line {
::view-transition-old(root),
::view-transition-new(root) {
animation-duration: 0.3s;
}
}

View File

@ -10,4 +10,11 @@
--shiki-token-string-expression: #ebebeb;
--shiki-token-punctuation: #ffffff;
--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

@ -1,7 +1,7 @@
{
"name": "www",
"type": "module",
"version": "0.8.7",
"version": "0.9.0",
"files": [
"dist"
],
@ -19,25 +19,25 @@
"@morev/vue-transitions": "^2.3.6",
"@radix-icons/vue": "^1.0.0",
"@stackblitz/sdk": "^1.9.0",
"@tanstack/vue-table": "^8.11.7",
"@unovis/ts": "^1.3.1",
"@unovis/vue": "^1.3.1",
"@vee-validate/zod": "^4.12.4",
"@tanstack/vue-table": "^8.11.8",
"@unovis/ts": "^1.3.3",
"@unovis/vue": "^1.3.3",
"@vee-validate/zod": "^4.12.5",
"@vueuse/core": "^10.7.2",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
"codesandbox": "^2.2.3",
"date-fns": "^2.30.0",
"embla-carousel": "8.0.0-rc19",
"embla-carousel-autoplay": "8.0.0-rc19",
"embla-carousel-vue": "8.0.0-rc19",
"embla-carousel": "^8.0.0-rc22",
"embla-carousel-autoplay": "^8.0.0-rc22",
"embla-carousel-vue": "^8.0.0-rc22",
"lucide-vue-next": "^0.276.0",
"radix-vue": "^1.3.2",
"radix-vue": "^1.4.0",
"tailwindcss-animate": "^1.0.7",
"v-calendar": "^3.1.2",
"vee-validate": "4.12.4",
"vee-validate": "4.12.5",
"vue": "^3.4.15",
"vue-sonner": "^1.0.2",
"vue-sonner": "^1.0.3",
"vue-wrap-balancer": "^1.1.3",
"zod": "^3.22.4"
},
@ -46,26 +46,27 @@
"@iconify-json/tabler": "^1.1.89",
"@iconify/json": "^2.2.108",
"@iconify/vue": "^4.1.1",
"@shikijs/transformers": "^1.0.0-beta.3",
"@types/lodash.template": "^4.5.2",
"@types/node": "^20.8.10",
"@vitejs/plugin-vue": "^5.0.3",
"@vitejs/plugin-vue-jsx": "^3.1.0",
"@vue/compiler-core": "^3.4.14",
"@vue/compiler-dom": "^3.4.14",
"@vue/compiler-core": "^3.4.15",
"@vue/compiler-dom": "^3.4.15",
"@vue/tsconfig": "^0.5.1",
"autoprefixer": "^10.4.16",
"autoprefixer": "^10.4.17",
"lodash.template": "^4.5.0",
"oxc-parser": "^0.2.0",
"pathe": "^1.1.2",
"rimraf": "^5.0.5",
"shikiji": "^0.10.0-beta.9",
"shikiji-transformers": "^0.10.0-beta.9",
"tailwind-merge": "^2.2.0",
"shiki": "^1.0.0-beta.3",
"tailwind-merge": "^2.2.1",
"tailwindcss": "^3.4.1",
"tsx": "^4.7.0",
"typescript": "^5.3.3",
"unplugin-icons": "^0.17.1",
"unplugin-icons": "^0.18.3",
"vite": "^5.0.12",
"vitepress": "^1.0.0-rc.39",
"vitepress": "^1.0.0-rc.41",
"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
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)
- [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.
```ts:line-numbers title="components/payments/columns.ts" {1,12-27}
import type { ColumnDef } from '@tanstack/vue-table'
// 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
}
```ts:line-numbers {1,12-27}
import { h } from 'vue'
export const columns: ColumnDef<Payment>[] = [
{
accessorKey: 'status',
header: 'Status',
},
{
accessorKey: 'email',
header: 'Email',
},
{
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.
```ts:line-numbers
```vue:line-numbers
<script setup lang="ts" generic="TData, TValue">
import type { ColumnDef } from '@tanstack/vue-table'
import {
@ -225,7 +217,7 @@ const table = useVueTable({
Finally, we'll render our table in our index component.
```ts:line-numbers {28}
```vue:line-numbers {28}
<script setup lang="ts">
import { ref, onMounted } from 'vue'
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:
```ts:line-numbers
```vue:line-numbers
// DataTableDropDown.vue
<script setup lang="ts">
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.
```ts:line-numbers {3,15,21-39}
// components/payments/DataTable.vue
```vue:line-numbers {3,15,21-39}
<script lang="ts" generic="TData, TValue">
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>`
```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">
import type {
ColumnDef,
@ -579,7 +570,7 @@ Let's add a search input to filter emails in our table.
### 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">
import type {
ColumnDef,
@ -664,7 +655,7 @@ Adding column visibility is fairly simple using `@tanstack/vue-table` visibility
### 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">
import type {
ColumnDef,
@ -829,7 +820,7 @@ export const columns: ColumnDef<Payment>[] = [
### Update `<DataTable>`
```ts:line-numbers {10,22,27}
```vue:line-numbers {10,22,27}
<script setup lang="ts" generic="TData, TValue">
const props = defineProps<{
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.
```ts:line-numbers
```vue:line-numbers
<script setup lang="ts">
import type { Column } from '@tanstack/vue-table'
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.
```ts:line-numbers
```vue:line-numbers
<script setup lang="ts">
import { type Table } from '@tanstack/vue-table'
import { type Task } from '../data/schema'
@ -1093,8 +1084,7 @@ defineProps<DataTablePaginationProps>()
A component to toggle column visibility.
```ts:line-numbers
```vue:line-numbers
<script setup lang="ts">
import type { Table } from '@tanstack/vue-table'
import { computed } from 'vue'

View File

@ -47,7 +47,7 @@ import {
### 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
import { navigationMenuTriggerStyle } from '@/components/ui/navigation-menu'

View File

@ -37,6 +37,6 @@ import { Skeleton } from '@/components/ui/skeleton'
</script>
<template>
<Skeleton class="w-[100px] h-[20px] rounded-full" />
<Skeleton class="w-[100px] h-5 rounded-full" />
</template>
```
```

View File

@ -26,7 +26,7 @@ import { Separator } from '@/lib/registry/new-york/ui/separator'
<template>
<Card>
<CardHeader class="grid grid-cols-[1fr_110px] items-start gap-4 space-y-0">
<CardHeader class="grid grid-cols-[minmax(0,1fr)_110px] items-start gap-4 space-y-0">
<div class="space-y-1">
<CardTitle>shadcn/ui</CardTitle>
<CardDescription>
@ -39,7 +39,7 @@ import { Separator } from '@/lib/registry/new-york/ui/separator'
<StarIcon class="mr-2 h-4 w-4" />
Star
</Button>
<Separator orientation="vertical" class="h-[20px]" />
<Separator orientation="vertical" class="h-5" />
<DropdownMenu>
<DropdownMenuTrigger as-child>
<Button variant="secondary" class="px-2 shadow-none">

View File

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

View File

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

View File

@ -101,7 +101,7 @@ const onSubmit = handleSubmit((values) => {
<div class="items-center rounded-md border-2 border-muted p-1 hover:border-accent">
<div class="space-y-2 rounded-sm bg-[#ecedef] p-2">
<div class="space-y-2 rounded-md bg-white p-2 shadow-sm">
<div class="h-2 w-[80px] rounded-lg bg-[#ecedef]" />
<div class="h-2 w-20 rounded-lg bg-[#ecedef]" />
<div class="h-2 w-[100px] rounded-lg bg-[#ecedef]" />
</div>
<div class="flex items-center space-x-2 rounded-md bg-white p-2 shadow-sm">
@ -127,7 +127,7 @@ const onSubmit = handleSubmit((values) => {
<div class="items-center rounded-md border-2 border-muted bg-popover p-1 hover:bg-accent hover:text-accent-foreground">
<div class="space-y-2 rounded-sm bg-slate-950 p-2">
<div class="space-y-2 rounded-md bg-slate-800 p-2 shadow-sm">
<div class="h-2 w-[80px] rounded-lg bg-slate-400" />
<div class="h-2 w-20 rounded-lg bg-slate-400" />
<div class="h-2 w-[100px] rounded-lg bg-slate-400" />
</div>
<div class="flex items-center space-x-2 rounded-md bg-slate-800 p-2 shadow-sm">

View File

@ -57,7 +57,7 @@ import CounterClockwiseClockIcon from '~icons/radix-icons/counter-clockwise-cloc
<Separator />
<Tabs default-value="complete" class="flex-1">
<div class="container h-full py-6">
<div class="grid h-full items-stretch gap-6 md:grid-cols-[1fr_200px]">
<div class="grid h-full items-stretch gap-6 md:grid-cols-[minmax(0,1fr)_200px]">
<div class="hidden flex-col space-y-4 sm:flex md:order-2">
<div class="grid gap-2">
<HoverCard :open-delay="200">

View File

@ -12,16 +12,16 @@ export const columns: ColumnDef<Task>[] = [
{
id: 'select',
header: ({ table }) => h(Checkbox,
{ 'checked': table.getIsAllPageRowsSelected(), 'onUpdate:checked': value => table.toggleAllPageRowsSelected(!!value), 'ariaLabel': 'Select all', 'class': 'translate-y-[2px]' }),
{ 'checked': table.getIsAllPageRowsSelected(), 'onUpdate:checked': value => table.toggleAllPageRowsSelected(!!value), 'ariaLabel': 'Select all', 'class': 'translate-y-0.5' }),
cell: ({ row }) => h(Checkbox,
{ 'checked': row.getIsSelected(), 'onUpdate:checked': value => row.toggleSelected(!!value), 'ariaLabel': 'Select row', 'class': 'translate-y-[2px]' }),
{ 'checked': row.getIsSelected(), 'onUpdate:checked': value => row.toggleSelected(!!value), 'ariaLabel': 'Select row', 'class': 'translate-y-0.5' }),
enableSorting: false,
enableHiding: false,
},
{
accessorKey: 'id',
header: ({ column }) => h(DataTableColumnHeader, { column, title: 'Task' }),
cell: ({ row }) => h('div', { class: 'w-[80px]' }, row.getValue('id')),
cell: ({ row }) => h('div', { class: 'w-20' }, row.getValue('id')),
enableSorting: false,
enableHiding: false,
},

View File

@ -51,7 +51,7 @@ const notifications = [
<div>
<div
v-for="(notification, index) in notifications" :key="index"
class="mb-4 grid grid-cols-[25px_1fr] items-start pb-4 last:mb-0 last:pb-0"
class="mb-4 grid grid-cols-[25px_minmax(0,1fr)] items-start pb-4 last:mb-0 last:pb-0"
>
<span class="flex h-2 w-2 translate-y-1 rounded-full bg-sky-500" />
<div class="space-y-1">

View File

@ -1,5 +1,12 @@
<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 {
Select,
SelectContent,

View File

@ -43,7 +43,7 @@ const lineY = (d: Data) => d.revenue
+20.1% from last month
</p>
<div class="h-[80px]">
<div class="h-20">
<VisXYContainer
height="80px"
:data="data" :margin="{
@ -79,7 +79,7 @@ const lineY = (d: Data) => d.revenue
+54.8% from last month
</p>
<div class="mt-4 h-[80px]">
<div class="mt-4 h-20">
<VisXYContainer
height="80px" :data="data" :style="{
'--theme-primary': `hsl(${

View File

@ -14,7 +14,7 @@ import {
useVueTable,
} from '@tanstack/vue-table'
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 { Button } from '@/lib/registry/default/ui/button'
@ -104,7 +104,7 @@ const columns: ColumnDef<Payment>[] = [
return h(Button, {
variant: 'ghost',
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')),
},
@ -179,7 +179,7 @@ const table = useVueTable({
<DropdownMenu>
<DropdownMenuTrigger as-child>
<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>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">

View File

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

View File

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

View File

@ -55,7 +55,7 @@ const components: { title: string; href: string; description: string }[] = [
<NavigationMenuItem>
<NavigationMenuTrigger>Getting started</NavigationMenuTrigger>
<NavigationMenuContent>
<ul class="grid gap-3 p-6 md:w-[400px] lg:w-[500px] lg:grid-cols-[.75fr_1fr]">
<ul class="grid gap-3 p-6 md:w-[400px] lg:w-[500px] lg:grid-cols-[minmax(0,.75fr)_minmax(0,1fr)]">
<li class="row-span-3">
<NavigationMenuLink as-child>
<a

View File

@ -11,5 +11,5 @@ watchEffect((cleanupFn) => {
</script>
<template>
<Progress v-model="progress" class="w-[60%]" />
<Progress v-model="progress" class="w-3/5" />
</template>

View File

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

View File

@ -11,6 +11,6 @@ const modelValue = ref([50])
v-model="modelValue"
:max="100"
:step="1"
:class="cn('w-[60%]', $attrs.class ?? '')"
:class="cn('w-3/5', $attrs.class ?? '')"
/>
</template>

View File

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

View File

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

View File

@ -1,14 +1,23 @@
<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'
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>
<template>
<AccordionItem
v-bind="props"
:class="cn('border-b', props.class ?? '')"
v-bind="forwardedProps"
:class="cn('border-b', props.class)"
>
<slot />
</AccordionItem>

View File

@ -1,4 +1,5 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import {
AccordionHeader,
AccordionTrigger,
@ -7,13 +8,19 @@ import {
import { ChevronDown } from 'lucide-vue-next'
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>
<template>
<AccordionHeader class="flex" as="div">
<AccordionHeader class="flex">
<AccordionTrigger
v-bind="props"
v-bind="delegatedProps"
:class="
cn(
'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 />
<ChevronDown
class="h-4 w-4 shrink-0 transition-transform duration-200"
/>
<slot name="icon">
<ChevronDown
class="h-4 w-4 shrink-0 transition-transform duration-200"
/>
</slot>
</AccordionTrigger>
</AccordionHeader>
</template>

View File

@ -1,13 +1,20 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { AlertDialogAction, type AlertDialogActionProps } from 'radix-vue'
import { cn } from '@/lib/utils'
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>
<template>
<AlertDialogAction v-bind="props" :class="cn(buttonVariants(), $attrs.class ?? '')">
<AlertDialogAction v-bind="delegatedProps" :class="cn(buttonVariants(), props.class)">
<slot />
</AlertDialogAction>
</template>

View File

@ -1,13 +1,20 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { AlertDialogCancel, type AlertDialogCancelProps } from 'radix-vue'
import { cn } from '@/lib/utils'
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>
<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 />
</AlertDialogCancel>
</template>

View File

@ -1,30 +1,37 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import {
AlertDialogContent,
type AlertDialogContentEmits,
type AlertDialogContentProps,
AlertDialogOverlay,
AlertDialogPortal,
useEmitAsProps,
useForwardPropsEmits,
} from 'radix-vue'
import { cn } from '@/lib/utils'
const props = defineProps<AlertDialogContentProps & { class?: string }>()
const props = defineProps<AlertDialogContentProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<AlertDialogContentEmits>()
const emitsAsProps = useEmitAsProps(emits)
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script>
<template>
<AlertDialogPortal>
<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
v-bind="{ ...props, ...emitsAsProps }"
v-bind="forwarded"
:class="
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-1/2 top-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 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,
)
"

View File

@ -1,17 +1,24 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import {
AlertDialogDescription,
type AlertDialogDescriptionProps,
} from 'radix-vue'
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>
<template>
<AlertDialogDescription
:class="cn('text-muted-foreground text-sm', props.class)"
:as-child="props.asChild"
v-bind="delegatedProps"
:class="cn('text-sm text-muted-foreground', props.class)"
>
<slot />
</AlertDialogDescription>

View File

@ -1,19 +1,17 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
const props = defineProps({
class: {
type: String,
default: '',
},
})
const props = defineProps<{
class?: HTMLAttributes['class']
}>()
</script>
<template>
<div
:class="
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,
)
"

View File

@ -1,17 +1,15 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
const props = defineProps({
class: {
type: String,
default: '',
},
})
const props = defineProps<{
class?: HTMLAttributes['class']
}>()
</script>
<template>
<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 />
</div>

View File

@ -1,14 +1,21 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { AlertDialogTitle, type AlertDialogTitleProps } from 'radix-vue'
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>
<template>
<AlertDialogTitle
:as-child="props.asChild"
:class="cn('text-lg text-foreground font-semibold', props.class)"
v-bind="delegatedProps"
:class="cn('text-lg font-semibold', props.class)"
>
<slot />
</AlertDialogTitle>

View File

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

View File

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

View File

@ -1,9 +1,14 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
const props = defineProps<{
class?: HTMLAttributes['class']
}>()
</script>
<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 />
</h5>
</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 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">
import type { HTMLAttributes } from 'vue'
import { AvatarRoot } from 'radix-vue'
import { avatarVariant } from '.'
import { type AvatarVariants, avatarVariant } from '.'
import { cn } from '@/lib/utils'
interface Props {
size?: NonNullable<Parameters<typeof avatarVariant>[0]>['size']
shape?: NonNullable<Parameters<typeof avatarVariant>[0]>['shape']
class?: string
}
const props = withDefaults(defineProps<Props>(), {
const props = withDefaults(defineProps<{
class?: HTMLAttributes['class']
size?: AvatarVariants['size']
shape?: AvatarVariants['shape']
}>(), {
size: 'sm',
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 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">
import type { VariantProps } from 'class-variance-authority'
import { badgeVariants } from '.'
import type { HTMLAttributes } from 'vue'
import { type BadgeVariants, badgeVariants } from '.'
import { cn } from '@/lib/utils'
interface BadgeVariantProps extends VariantProps<typeof badgeVariants> {}
interface Props {
variant?: BadgeVariantProps['variant']
}
defineProps<Props>()
const props = defineProps<{
variant?: BadgeVariants['variant']
class?: HTMLAttributes['class']
}>()
</script>
<template>
<div :class="cn(badgeVariants({ variant }), $attrs.class ?? '')">
<div :class="cn(badgeVariants({ variant }), props.class)">
<slot />
</div>
</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'
@ -21,3 +21,5 @@ export const badgeVariants = cva(
},
},
)
export type BadgeVariants = VariantProps<typeof badgeVariants>

View File

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

View File

@ -1,12 +1,12 @@
<script setup lang="ts">
import { useVModel } from '@vueuse/core'
import { ChevronLeft, ChevronRight } from 'lucide-vue-next'
import type { Calendar } from 'v-calendar'
import { DatePicker } from 'v-calendar'
import { ChevronLeft, ChevronRight } from 'lucide-vue-next'
import { computed, nextTick, onMounted, ref, useSlots } from 'vue'
import { isVCalendarSlot } from '.'
import { buttonVariants } from '@/lib/registry/default/ui/button'
import { cn } from '@/lib/utils'
import { buttonVariants } from '@/lib/registry/default/ui/button'
/* Extracted from v-calendar */
type DatePickerModel = DatePickerDate | DatePickerRangeObject
@ -29,8 +29,7 @@ interface SimpleDateParts {
defineOptions({
inheritAttrs: false,
})
const props = withDefaults(defineProps<{
const props = withDefaults(defineProps< {
modelValue?: string | number | Date | DatePickerModel
modelModifiers?: object
columns?: number
@ -90,8 +89,8 @@ const vCalendarSlots = computed(() => {
<DatePicker
ref="datePicker"
v-model="modelValue"
v-bind="$attrs"
v-model="modelValue"
:model-modifiers="modelModifiers"
class="calendar"
trim-weeks
@ -101,11 +100,19 @@ const vCalendarSlots = computed(() => {
<template v-for="(_, slot) of vCalendarSlots" #[slot]="scope">
<slot :name="slot" v-bind="scope" />
</template>
<template #nav-prev-button>
<ChevronLeft />
</template>
<template #nav-next-button>
<ChevronRight />
</template>
</DatePicker>
</div>
</template>
<style lang="postcss">
<style lang="css">
.calendar {
@apply p-3 text-center;
}
@ -113,7 +120,25 @@ const vCalendarSlots = computed(() => {
@apply grid gap-4;
}
.calendar .vc-title {
@apply text-sm font-medium pointer-events-none;
@apply text-sm font-medium relative z-20;
}
.vc-popover-content-wrapper .vc-popover-content {
@apply mt-3 rounded-md max-w-xs border bg-background;
}
.vc-popover-content-wrapper .vc-nav-header {
@apply flex justify-between items-center p-2;
}
.vc-popover-content-wrapper .vc-nav-items {
@apply grid grid-cols-4 gap-2 p-2;
}
.vc-popover-content-wrapper .vc-nav-items .vc-nav-item {
@apply rounded-md px-2 py-1;
}
.vc-popover-content-wrapper .vc-nav-items .vc-nav-item:hover {
@apply text-muted-foreground bg-muted;
}
.vc-popover-content-wrapper .vc-nav-items .vc-nav-item.is-active {
@apply bg-primary text-primary-foreground;
}
.calendar .vc-pane-header-wrapper {
@apply hidden;
@ -125,16 +150,22 @@ const vCalendarSlots = computed(() => {
@apply flex;
}
.calendar .vc-weekday {
@apply text-muted-foreground rounded-md w-9 font-normal text-[0.8rem];
@apply text-muted-foreground rounded-md w-full font-normal text-[0.8rem];
}
.calendar .vc-weekday-1 {
@apply pr-3;
}
.calendar .vc-weekday-7 {
@apply pl-3;
}
.calendar .vc-weeks {
@apply w-full space-y-2 flex flex-col [&>_div]:grid [&>_div]:grid-cols-7;
}
.calendar .vc-day:has(.vc-highlights) {
@apply bg-accent first:rounded-l-md last:rounded-r-md overflow-hidden;
@apply first:rounded-l-md last:rounded-r-md;
}
.calendar .vc-day.is-today:not(:has(.vc-day-layer)) {
@apply bg-secondary rounded-md;
.calendar .vc-day.is-today:not(:has(.vc-day-layer)) .vc-day-content {
@apply bg-secondary text-primary rounded-md;
}
.calendar .vc-day:has(.vc-highlight-base-start) {
@apply rounded-l-md;
@ -146,7 +177,7 @@ const vCalendarSlots = computed(() => {
@apply rounded-md;
}
.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) {
@apply rounded-md;
@ -172,6 +203,7 @@ const vCalendarSlots = computed(() => {
--vc-slide-duration: 0.15s;
--vc-slide-timing: ease;
}
.calendar .vc-fade-enter-active,
.calendar .vc-fade-leave-active,
.calendar .vc-slide-left-enter-active,
@ -198,6 +230,7 @@ const vCalendarSlots = computed(() => {
backface-visibility: hidden;
pointer-events: none;
}
.calendar .vc-none-leave-active,
.calendar .vc-fade-leave-active,
.calendar .vc-slide-left-leave-active,
@ -207,6 +240,7 @@ const vCalendarSlots = computed(() => {
position: absolute !important;
width: 100%;
}
.calendar .vc-none-enter-from,
.calendar .vc-none-leave-to,
.calendar .vc-fade-enter-from,
@ -223,6 +257,7 @@ const vCalendarSlots = computed(() => {
.calendar .vc-slide-fade-leave-to {
opacity: 0;
}
.calendar .vc-slide-left-enter-from,
.calendar .vc-slide-right-leave-to,
.calendar .vc-slide-fade-enter-from.direction-left,
@ -230,6 +265,7 @@ const vCalendarSlots = computed(() => {
-webkit-transform: translateX(var(--vc-slide-translate));
transform: translateX(var(--vc-slide-translate));
}
.calendar .vc-slide-right-enter-from,
.calendar .vc-slide-left-leave-to,
.calendar .vc-slide-fade-enter-from.direction-right,
@ -237,6 +273,7 @@ const vCalendarSlots = computed(() => {
-webkit-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-down-leave-to,
.calendar .vc-slide-fade-enter-from.direction-top,
@ -244,6 +281,7 @@ const vCalendarSlots = computed(() => {
-webkit-transform: translateY(var(--vc-slide-translate));
transform: translateY(var(--vc-slide-translate));
}
.calendar .vc-slide-down-enter-from,
.calendar .vc-slide-up-leave-to,
.calendar .vc-slide-fade-enter-from.direction-bottom,

View File

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

View File

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

View File

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

View File

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

View File

@ -1,16 +1,14 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
const props = defineProps({
class: {
type: String,
default: '',
},
})
const props = defineProps<{
class?: HTMLAttributes['class']
}>()
</script>
<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 />
</div>
</template>

View File

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

View File

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

View File

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

View File

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

View File

@ -1,13 +1,20 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import type { CheckboxRootEmits, CheckboxRootProps } from 'radix-vue'
import { CheckboxIndicator, CheckboxRoot, useForwardPropsEmits } from 'radix-vue'
import { Check } from 'lucide-vue-next'
import { cn } from '@/lib/utils'
const props = defineProps<CheckboxRootProps>()
const props = defineProps<CheckboxRootProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<CheckboxRootEmits>()
const forwarded = useForwardPropsEmits(props, emits)
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script>
<template>
@ -15,10 +22,12 @@ const forwarded = useForwardPropsEmits(props, emits)
v-bind="forwarded"
: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',
$attrs.class ?? '')"
props.class)"
>
<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>
</CheckboxRoot>
</template>

View File

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

View File

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

View File

@ -1,5 +1,5 @@
<script setup lang="ts">
import { useEmitAsProps } from 'radix-vue'
import { useForwardPropsEmits } from 'radix-vue'
import type { DialogRootEmits, DialogRootProps } from 'radix-vue'
import Command from './Command.vue'
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 emits = defineEmits<DialogRootEmits>()
const emitsAsProps = useEmitAsProps(emits)
const forwarded = useForwardPropsEmits(props, emits)
</script>
<template>
<Dialog v-bind="{ ...props, ...emitsAsProps }">
<DialogContent class="p-0 overflow-hidden shadow-lg">
<Dialog v-bind="forwarded">
<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">
<slot />
</Command>

View File

@ -1,13 +1,20 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import type { ComboboxEmptyProps } from 'radix-vue'
import { ComboboxEmpty } from 'radix-vue'
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>
<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 />
</ComboboxEmpty>
</template>

View File

@ -1,17 +1,25 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import type { ComboboxGroupProps } from 'radix-vue'
import { ComboboxGroup, ComboboxLabel } from 'radix-vue'
import { cn } from '@/lib/utils'
const props = defineProps<ComboboxGroupProps & {
class?: HTMLAttributes['class']
heading?: string
}>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
</script>
<template>
<ComboboxGroup
v-bind="props"
:class="cn('overflow-hidden p-1 text-foreground', $attrs.class ?? '')"
v-bind="delegatedProps"
: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">
{{ heading }}

View File

@ -1,24 +1,33 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
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'
const props = defineProps<ComboboxInputProps>()
</script>
<script lang="ts">
export default {
defineOptions({
inheritAttrs: false,
}
})
const props = defineProps<ComboboxInputProps & {
class?: HTMLAttributes['class']
}>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwardedProps = useForwardProps(delegatedProps)
</script>
<template>
<div class="flex items-center border-b px-3" cmdk-input-wrapper>
<Search class="mr-2 h-4 w-4 shrink-0 opacity-50" />
<ComboboxInput
v-bind="{ ...props, ...$attrs }"
v-bind="{ ...forwardedProps, ...$attrs }"
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>
</template>

View File

@ -1,18 +1,25 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from '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'
const props = defineProps<ComboboxItemProps>()
const props = defineProps<ComboboxItemProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<ComboboxItemEmits>()
const emitsAsProps = useEmitAsProps(emits)
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script>
<template>
<ComboboxItem
v-bind="{ ...props, ...emitsAsProps }"
: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 ?? '')"
v-bind="forwarded"
: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
>
<slot />

View File

@ -1,16 +1,23 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import type { ComboboxContentEmits, ComboboxContentProps } from 'radix-vue'
import { ComboboxContent, useForwardPropsEmits } from 'radix-vue'
import { cn } from '@/lib/utils'
const props = defineProps<ComboboxContentProps>()
const props = defineProps<ComboboxContentProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<ComboboxContentEmits>()
const forwarded = useForwardPropsEmits(props, emits)
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script>
<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">
<slot />
</div>

View File

@ -1,15 +1,22 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import type { ComboboxSeparatorProps } from 'radix-vue'
import { ComboboxSeparator } from 'radix-vue'
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>
<template>
<ComboboxSeparator
v-bind="props"
:class="cn('-mx-1 h-px bg-border', $attrs.class ?? '')"
v-bind="delegatedProps"
:class="cn('-mx-1 h-px bg-border', props.class)"
>
<slot />
</ComboboxSeparator>

View File

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

View File

@ -1,33 +1,38 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import {
ContextMenuCheckboxItem,
type ContextMenuCheckboxItemEmits,
type ContextMenuCheckboxItemProps,
ContextMenuItemIndicator,
useEmitAsProps,
useForwardPropsEmits,
} from 'radix-vue'
import { Check } from 'lucide-vue-next'
import { cn } from '@/lib/utils'
const props = defineProps<ContextMenuCheckboxItemProps & { class?: string }>()
const props = defineProps<ContextMenuCheckboxItemProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<ContextMenuCheckboxItemEmits>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script>
<template>
<ContextMenuCheckboxItem
v-bind="{ ...props, ...useEmitAsProps(emits) }"
:class="[
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',
props.class,
),
]"
v-bind="forwarded"
:class="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',
props.class,
)"
>
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<ContextMenuItemIndicator
class="absolute left-1.5 inline-flex w-4 h-4 items-center justify-center"
>
<Check class="h-4 h-w" />
<ContextMenuItemIndicator>
<Check class="h-4 w-4" />
</ContextMenuItemIndicator>
</span>
<slot />

View File

@ -1,4 +1,5 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import {
ContextMenuContent,
type ContextMenuContentEmits,
@ -8,23 +9,26 @@ import {
} from 'radix-vue'
import { cn } from '@/lib/utils'
const props = defineProps<ContextMenuContentProps & { class?: string }>()
const props = defineProps<ContextMenuContentProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<ContextMenuContentEmits>()
const forwarded = useForwardPropsEmits(props, emits)
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script>
<template>
<ContextMenuPortal>
<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"
:class="cn(
'z-50 min-w-32 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 />
</ContextMenuContent>

View File

@ -1,26 +1,33 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import {
ContextMenuItem,
type ContextMenuItemEmits,
type ContextMenuItemProps,
useEmitAsProps,
useForwardPropsEmits,
} from 'radix-vue'
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 delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script>
<template>
<ContextMenuItem
v-bind="{ ...props, ...useEmitAsProps(emits) }"
:class="[
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',
inset && 'pl-8',
props.class,
),
]"
v-bind="forwarded"
:class="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',
inset && 'pl-8',
props.class,
)"
>
<slot />
</ContextMenuItem>

View File

@ -1,16 +1,23 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { ContextMenuLabel, type ContextMenuLabelProps } from 'radix-vue'
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>
<template>
<ContextMenuLabel
v-bind="props"
v-bind="delegatedProps"
:class="
cn('px-2 py-1.5 text-sm font-semibold text-foreground',
inset && 'pl-8', props.class ?? '',
inset && 'pl-8', props.class,
)"
>
<slot />

View File

@ -1,4 +1,5 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import {
ContextMenuItemIndicator,
ContextMenuRadioItem,
@ -9,21 +10,25 @@ import {
import { Circle } from 'lucide-vue-next'
import { cn } from '@/lib/utils'
const props = defineProps<ContextMenuRadioItemProps & { class?: string }>()
const props = defineProps<ContextMenuRadioItemProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<ContextMenuRadioItemEmits>()
const forwarded = useForwardPropsEmits(props, emits)
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script>
<template>
<ContextMenuRadioItem
v-bind="forwarded"
:class="[
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',
props.class,
),
]"
:class="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',
props.class,
)"
>
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<ContextMenuItemIndicator>

View File

@ -1,13 +1,20 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import {
ContextMenuSeparator,
type ContextMenuSeparatorProps,
} from 'radix-vue'
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>
<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>

View File

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

View File

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

View File

@ -1,24 +1,32 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import {
ContextMenuSubTrigger,
type ContextMenuSubTriggerProps,
useForwardProps,
} from 'radix-vue'
import { ChevronRight } from 'lucide-vue-next'
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>
<template>
<ContextMenuSubTrigger
v-bind="props"
:class="[
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',
inset && 'pl-8',
props.class,
),
]"
v-bind="forwardedProps"
:class="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',
inset && 'pl-8',
props.class,
)"
>
<slot />
<ChevronRight class="ml-auto h-4 w-4" />

View File

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

View File

@ -1,14 +1,14 @@
<script setup lang="ts">
import { DialogRoot, type DialogRootEmits, type DialogRootProps, useForwardPropsEmits } from 'radix-vue'
const props = defineProps<DialogRootProps>()
const emits = defineEmits<DialogRootEmits>()
const forwarded = useForwardPropsEmits(props, emits)
</script>
<template>
<DialogRoot v-bind="forwarded">
<slot />
</DialogRoot>
</template>
<script setup lang="ts">
import { DialogRoot, type DialogRootEmits, type DialogRootProps, useForwardPropsEmits } from 'radix-vue'
const props = defineProps<DialogRootProps>()
const emits = defineEmits<DialogRootEmits>()
const forwarded = useForwardPropsEmits(props, emits)
</script>
<template>
<DialogRoot v-bind="forwarded">
<slot />
</DialogRoot>
</template>

View File

@ -1,4 +1,5 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import {
DialogClose,
DialogContent,
@ -6,35 +7,40 @@ import {
type DialogContentProps,
DialogOverlay,
DialogPortal,
useEmitAsProps,
useForwardPropsEmits,
} from 'radix-vue'
import { X } from 'lucide-vue-next'
import { cn } from '@/lib/utils'
const props = defineProps<DialogContentProps & { class?: string }>()
const props = defineProps<DialogContentProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<DialogContentEmits>()
const emitsAsProps = useEmitAsProps(emits)
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script>
<template>
<DialogPortal>
<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
v-bind="forwarded"
:class="
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-1/2 top-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 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,
)
"
v-bind="{ ...props, ...emitsAsProps }"
)"
>
<slot />
<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" />
<span class="sr-only">Close</span>

View File

@ -1,14 +1,23 @@
<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'
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>
<template>
<DialogDescription
v-bind="props"
:class="cn('text-muted-foreground text-sm', props.class)"
v-bind="forwardedProps"
:class="cn('text-sm text-muted-foreground', props.class)"
>
<slot />
</DialogDescription>

View File

@ -1,18 +1,15 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
interface DialogFooterProps {
class?: string
}
const props = defineProps<DialogFooterProps>()
const props = defineProps<{ class?: HTMLAttributes['class'] }>()
</script>
<template>
<div
:class="
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,
)
"

View File

@ -1,16 +1,15 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
interface DialogHeaderProps {
class?: string
}
const props = defineProps<DialogHeaderProps>()
const props = defineProps<{
class?: HTMLAttributes['class']
}>()
</script>
<template>
<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 />
</div>

View File

@ -1,16 +1,25 @@
<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'
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>
<template>
<DialogTitle
v-bind="props"
v-bind="forwardedProps"
:class="
cn(
'text-lg text-foreground font-semibold leading-none tracking-tight',
'text-lg font-semibold leading-none tracking-tight',
props.class,
)
"

View File

@ -1,21 +1,30 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import {
DropdownMenuCheckboxItem,
type DropdownMenuCheckboxItemEmits,
type DropdownMenuCheckboxItemProps,
DropdownMenuItemIndicator,
useEmitAsProps,
useForwardPropsEmits,
} from 'radix-vue'
import { Check } from 'lucide-vue-next'
import { cn } from '@/lib/utils'
const props = defineProps<DropdownMenuCheckboxItemProps & { class?: string }>()
const props = defineProps<DropdownMenuCheckboxItemProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<DropdownMenuCheckboxItemEmits>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script>
<template>
<DropdownMenuCheckboxItem
v-bind="{ ...props, ...useEmitAsProps(emits) }"
v-bind="forwarded"
: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',
props.class,

View File

@ -1,4 +1,5 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import {
DropdownMenuContent,
type DropdownMenuContentEmits,
@ -9,26 +10,27 @@ import {
import { cn } from '@/lib/utils'
const props = withDefaults(
defineProps<DropdownMenuContentProps & { class?: string }>(),
defineProps<DropdownMenuContentProps & { class?: HTMLAttributes['class'] }>(),
{
sideOffset: 4,
},
)
const emits = defineEmits<DropdownMenuContentEmits>()
const forwarded = useForwardPropsEmits(props, emits)
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script>
<template>
<DropdownMenuPortal>
<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"
:class="cn('z-50 min-w-32 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 />
</DropdownMenuContent>

View File

@ -1,20 +1,27 @@
<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'
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>
<template>
<DropdownMenuItem
v-bind="props"
:class="[
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',
inset && 'pl-8',
props.class,
),
]"
v-bind="forwardedProps"
:class="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',
inset && 'pl-8',
props.class,
)"
>
<slot />
</DropdownMenuItem>

View File

@ -1,19 +1,23 @@
<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'
const props = defineProps<DropdownMenuLabelProps & {
inset?: boolean
class?: string
}>()
const props = defineProps<DropdownMenuLabelProps & { class?: HTMLAttributes['class']; inset?: boolean }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwardedProps = useForwardProps(delegatedProps)
</script>
<template>
<DropdownMenuLabel
v-bind="props"
:class="
cn('px-2 py-1.5 text-sm font-semibold',
inset && 'pl-8', props.class)"
v-bind="forwardedProps"
:class="cn('px-2 py-1.5 text-sm font-semibold', inset && 'pl-8', props.class)"
>
<slot />
</DropdownMenuLabel>

View File

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

View File

@ -1,29 +1,37 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import {
DropdownMenuItemIndicator,
DropdownMenuRadioItem,
type DropdownMenuRadioItemEmits,
type DropdownMenuRadioItemProps,
useEmitAsProps,
useForwardPropsEmits,
} from 'radix-vue'
import { Circle } from 'lucide-vue-next'
import { cn } from '@/lib/utils'
const props = defineProps<DropdownMenuRadioItemProps & { class?: string }>()
const props = defineProps<DropdownMenuRadioItemProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<DropdownMenuRadioItemEmits>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script>
<template>
<DropdownMenuRadioItem
v-bind="{ ...props, ...useEmitAsProps(emits) }"
v-bind="forwarded"
: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,
)"
>
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<DropdownMenuItemIndicator>
<Circle class="h-2 w-2 fill-current" />
</DropdownMenuItemIndicator>

View File

@ -1,12 +1,22 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import {
DropdownMenuSeparator,
type DropdownMenuSeparatorProps,
} 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>
<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>

View File

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

View File

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

View File

@ -1,23 +1,31 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import {
DropdownMenuSubTrigger,
type DropdownMenuSubTriggerProps,
useForwardProps,
} from 'radix-vue'
import { ChevronRight } from 'lucide-vue-next'
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>
<template>
<DropdownMenuSubTrigger
v-bind="props"
:class="[
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',
props.class,
),
]"
v-bind="forwardedProps"
:class="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',
props.class,
)"
>
<slot />
<ChevronRight class="ml-auto h-4 w-4" />

View File

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

View File

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

View File

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

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