Merge remote-tracking branch 'upstream' into feat/cli/detype

This commit is contained in:
Dunqing 2023-09-18 10:32:07 +08:00
commit 5b85c280e3
67 changed files with 2724 additions and 1461 deletions

View File

@ -2,9 +2,13 @@ name: Publish www
on:
push:
branches:
- dev
paths:
- 'apps/www/**'
pull_request:
branches:
- dev
paths:
- 'apps/www/**'

View File

@ -0,0 +1,60 @@
<script setup lang="ts">
import { computed, ref } from 'vue'
import { useClipboard } from '@vueuse/core'
import { useConfigStore } from '@/stores/config'
import { themes } from '@/lib/registry'
import { Button } from '@/lib/registry/new-york/ui/button'
import CheckIcon from '~icons/radix-icons/check'
import CopyIcon from '~icons/radix-icons/copy'
const { theme, config } = useConfigStore()
const activeTheme = computed(() => themes.find(i => i.name === theme.value))
const { copy, copied } = useClipboard()
const codeRef = ref<HTMLElement>()
async function copyCode() {
await copy(codeRef.value?.innerText ?? '')
}
</script>
<template>
<div class="relative">
<pre class="max-h-[450px] overflow-x-auto rounded-lg border bg-zinc-950 !py-0 dark:bg-zinc-900">
<code ref="codeRef" class="relative block rounded font-mono text-sm">
<span class="line">@layer base &#123;</span>
<span class="line">:root &#123;</span>
<span class="line">&nbsp;&nbsp;--background: {{ activeTheme?.cssVars.light.background }};</span>
<span class="line">&nbsp;&nbsp;--foreground: {{ activeTheme?.cssVars.light.foreground }};</span>
<template v-for="prefix in (['card', 'popover', 'primary', 'secondary', 'muted', 'accent', 'destructive'] as const)" :key="prefix">
<span class="line">--{{ prefix }}: {{ activeTheme?.cssVars.light[prefix] }};</span>
<span class="line">--{{ prefix }}-foreground: {{ activeTheme?.cssVars.light[ `${prefix}-foreground`] }};</span>
</template>
<span class="line">&nbsp;&nbsp;--border:{{ activeTheme?.cssVars.light.border }};</span>
<span class="line">&nbsp;&nbsp;--input:{{ activeTheme?.cssVars.light.input }};</span>
<span class="line">&nbsp;&nbsp;--ring:{{ activeTheme?.cssVars.light.ring }};</span>
<span class="line">&nbsp;&nbsp;--radius: {{ config.radius }}rem;</span>
<span class="line">&#125;</span>
<span class="line">&nbsp;</span>
<span class="line">.dark &#123;</span>
<span class="line">&nbsp;&nbsp;--background:{{ activeTheme?.cssVars.dark.background }};</span>
<span class="line">&nbsp;&nbsp;--foreground:{{ activeTheme?.cssVars.dark.foreground }};</span>
<template v-for="prefix in (['card', 'popover', 'primary', 'secondary', 'muted', 'accent', 'destructive'] as const)" :key="prefix">
<span class="line">--{{ prefix }}:{{ activeTheme?.cssVars.dark[ prefix] }};</span>
<span class="line">--{{ prefix }}-foreground:{{ activeTheme?.cssVars.dark[ `${prefix}-foreground`] }};</span>
</template>
<span class="line">&nbsp;&nbsp;--border:{{ activeTheme?.cssVars.dark.border }};</span>
<span class="line">&nbsp;&nbsp;--input:{{ activeTheme?.cssVars.dark.input }};</span>
<span class="line">&nbsp;&nbsp;--ring:{{ activeTheme?.cssVars.dark.ring }};</span>
<span class="line">&#125;</span>
<span class="line">&#125;</span>
</code>
</pre>
<Button size="sm" class="absolute right-4 top-4 bg-muted text-muted-foreground hover:bg-muted hover:text-muted-foreground" @click="copyCode">
<CheckIcon v-if="copied" class="mr-2 h-4 w-4" />
<CopyIcon v-else class="mr-2 h-4 w-4" />
{{ copied ? 'Copied' : 'Copy' }}
</Button>
</div>
</template>

View File

@ -19,12 +19,11 @@ import DashboardExample from '@/examples/dashboard/Example.vue'
href="/docs/changelog"
class="inline-flex items-center rounded-lg bg-muted px-3 py-1 text-sm font-medium"
>
🎉 <Separator class="mx-2 h-4" orientation="vertical" />
<span class="sm:hidden">Style, a new CLI and more.</span>
<span class="hidden sm:inline">
Introducing Style, a new CLI and more.
🚧 <Separator class="mx-2 h-4" orientation="vertical" />
<span class="sm:hidden">WIP</span>
<span class="hidden sm:inline">WIP
</span>
<ArrowRightIcon class="ml-1 h-4 w-4" />
<!-- <ArrowRightIcon class="ml-1 h-4 w-4" /> -->
</a>
<PageHeaderHeading>Build your component library.</PageHeaderHeading>
<PageHeaderDescription>

View File

@ -376,30 +376,24 @@ const range = ref({
<CardContent>
<div class="space-y-4">
<div
class="flex w-max max-w-[75%] flex-col gap-2 rounded-lg px-3 py-2 text-sm bg-secondary"
class="flex w-auto max-w-[75%] flex-col gap-2 rounded-lg px-3 py-2 text-sm bg-muted"
>
<p class="text-foreground">
Hi There!, I'm Bear, the founder of Bear Studios. I'm here
to help you with anything you need.
</p>
Hi, how can I help you today?
</div>
<div
class="flex w-max max-w-[75%] flex-col gap-2 rounded-lg px-3 py-2 text-sm ml-auto bg-primary text-primary-foreground"
class="flex w-auto max-w-[75%] flex-col gap-2 rounded-lg px-3 py-2 text-sm ml-auto bg-primary text-primary-foreground"
>
<p>Hey, I'm having trouble with my account.</p>
Hey, I'm having trouble with my account.
</div>
<div
class="flex w-max max-w-[75%] flex-col gap-2 rounded-lg px-3 py-2 text-sm bg-secondary"
class="flex w-auto max-w-[75%] flex-col gap-2 rounded-lg px-3 py-2 text-sm bg-muted"
>
<p class="text-foreground">
Sure, I can help you with that. What seems to be the
problem?
</p>
Sure, I can help you with that. What seems to be the problem?
</div>
<div
class="flex w-max max-w-[75%] flex-col gap-2 rounded-lg px-3 py-2 text-sm ml-auto bg-primary text-primary-foreground"
class="flex w-auto max-w-[75%] flex-col gap-2 rounded-lg px-3 py-2 text-sm ml-auto bg-primary text-primary-foreground"
>
<p>I can't log in.</p>
I can't log in.
</div>
</div>
</CardContent>

View File

@ -155,18 +155,16 @@ export const docsConfig: DocsConfig = {
},
{
title: 'Combobox',
disabled: true,
label: 'Soon',
href: '#',
href: '/docs/components/combobox',
label: 'New',
items: [],
},
{
title: 'Command',
href: '/docs/components/command',
label: 'New',
items: [],
},
// {
// title: "Command",
// href: "#",
// label: "Soon",
// disabled: true,
// items: []
// },
{
title: 'Context Menu',
href: '/docs/components/context-menu',

View File

@ -5,6 +5,7 @@ import { useData } from 'vitepress'
import PageHeader from '../components/PageHeader.vue'
import PageHeaderHeading from '../components/PageHeaderHeading.vue'
import PageHeaderDescription from '../components/PageHeaderDescription.vue'
import CustomizerCode from '../components/CustomizerCode.vue'
import { RADII, useConfigStore } from '@/stores/config'
import { colors } from '@/lib/registry'
import { Button } from '@/lib/registry/new-york/ui/button'
@ -231,6 +232,7 @@ watch(radius, (radius) => {
Copy and paste the following code into your CSS file.
</DialogDescription>
</DialogHeader>
<CustomizerCode />
</DialogContent>
</Dialog>
</div>

View File

@ -86,6 +86,20 @@ export const Index = {
component: () => import('../src/lib/registry/default/example/CollapsibleDemo.vue').then(m => m.default),
files: ['../src/lib/registry/default/example/CollapsibleDemo.vue'],
},
ComboboxDemo: {
name: 'ComboboxDemo',
type: 'components:example',
registryDependencies: ['utils', 'button', 'command', 'popover'],
component: () => import('../src/lib/registry/default/example/ComboboxDemo.vue').then(m => m.default),
files: ['../src/lib/registry/default/example/ComboboxDemo.vue'],
},
CommandDemo: {
name: 'CommandDemo',
type: 'components:example',
registryDependencies: ['command'],
component: () => import('../src/lib/registry/default/example/CommandDemo.vue').then(m => m.default),
files: ['../src/lib/registry/default/example/CommandDemo.vue'],
},
ContextMenuDemo: {
name: 'ContextMenuDemo',
type: 'components:example',
@ -466,6 +480,20 @@ export const Index = {
component: () => import('../src/lib/registry/new-york/example/CollapsibleDemo.vue').then(m => m.default),
files: ['../src/lib/registry/new-york/example/CollapsibleDemo.vue'],
},
ComboboxDemo: {
name: 'ComboboxDemo',
type: 'components:example',
registryDependencies: ['utils', 'button', 'command', 'popover'],
component: () => import('../src/lib/registry/new-york/example/ComboboxDemo.vue').then(m => m.default),
files: ['../src/lib/registry/new-york/example/ComboboxDemo.vue'],
},
CommandDemo: {
name: 'CommandDemo',
type: 'components:example',
registryDependencies: ['command'],
component: () => import('../src/lib/registry/new-york/example/CommandDemo.vue').then(m => m.default),
files: ['../src/lib/registry/new-york/example/CommandDemo.vue'],
},
ContextMenuDemo: {
name: 'ContextMenuDemo',
type: 'components:example',

View File

@ -13,7 +13,7 @@
},
"dependencies": {
"@morev/vue-transitions": "^2.3.6",
"@tanstack/vue-table": "^8.9.8",
"@tanstack/vue-table": "^8.9.9",
"@unovis/ts": "^1.2.1",
"@vueuse/core": "^10.4.1",
"class-variance-authority": "^0.7.0",
@ -32,22 +32,22 @@
"@iconify/json": "^2.2.108",
"@iconify/vue": "^4.1.1",
"@types/lodash.template": "^4.5.1",
"@types/node": "^20.5.7",
"@types/node": "^20.6.0",
"@vitejs/plugin-vue": "^4.3.4",
"@vitejs/plugin-vue-jsx": "^3.0.2",
"@vue/compiler-core": "^3.3.4",
"@vue/compiler-dom": "^3.3.4",
"autoprefixer": "^10.4.15",
"lodash.template": "^4.5.0",
"radix-vue": "^0.1.34",
"radix-vue": "^0.2.2",
"rimraf": "^5.0.1",
"tailwind-merge": "^1.14.0",
"tailwindcss": "^3.3.3",
"tsx": "^3.12.8",
"tsx": "^3.12.10",
"typescript": "^5.2.2",
"unplugin-icons": "^0.17.0",
"vite": "^4.4.9",
"vitepress": "^1.0.0-rc.12",
"vue-tsc": "^1.8.10"
"vitepress": "^1.0.0-rc.13",
"vue-tsc": "^1.8.11"
}
}

View File

@ -0,0 +1,89 @@
---
title: Combobox
description: Autocomplete input and command palette with a list of suggestions.
component: true
---
<ComponentPreview name="ComboboxDemo" />
## Installation
The Combobox is built using a composition of the `<Popover />` and the `<Command />` components.
See installation instructions for the [Popover](/docs/components/popover#installation) and the [Command](/docs/components/command#installation) components.
## Usage
```vue
<script setup lang="ts">
import { Check, ChevronsUpDown } from 'lucide-vue-next'
import { ref } from 'vue'
import { cn } from '@/lib/utils'
import { Button } from '@/lib/registry/default/ui/button'
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
} from '@/lib/registry/default/ui/command'
import {
Popover,
PopoverContent,
PopoverTrigger,
} from '@/lib/registry/default/ui/popover'
const frameworks = [
{ value: 'next.js', label: 'Next.js' },
{ value: 'sveltekit', label: 'SvelteKit' },
{ value: 'nuxt.js', label: 'Nuxt.js' },
{ value: 'remix', label: 'Remix' },
{ value: 'astro', label: 'Astro' },
]
const open = ref(false)
const value = ref({})
</script>
<template>
<Popover v-model:open="open">
<PopoverTrigger as-child>
<Button
variant="outline"
role="combobox"
:aria-expanded="open"
class="w-[200px] justify-between"
>
{{ value ? frameworks.find((framework) => framework.value === value)?.label : 'Select framework...' }}
<ChevronsUpDown class="ml-2 h-4 w-4 shrink-0 opacity-50" />
</Button>
</PopoverTrigger>
<PopoverContent class="w-[200px] p-0">
<Command v-model="value">
<CommandInput placeholder="Search framework..." />
<CommandEmpty>No framework found.</CommandEmpty>
<CommandGroup>
<CommandItem
v-for="framework in frameworks"
:key="framework.value"
:value="framework"
@select="open = false"
>
<Check
:class="cn(
'mr-2 h-4 w-4',
value === framework.value ? 'opacity-100' : 'opacity-0',
)"
/>
{{ framework.label }}
</CommandItem>
</CommandGroup>
</Command>
</PopoverContent>
</Popover>
</template>
```

View File

@ -0,0 +1,65 @@
---
title: Command
description: Displays a list of options for the user to pick from—triggered by a button.
source: apps/www/src/lib/registry/default/ui/popover
primitive: https://www.radix-vue.com/components/popover.html
---
<ComponentPreview name="CommandDemo" />
## Installation
```bash
npx shadcn-vue@latest add command
```
<ManualInstall>
1. Install `radix-vue`:
```bash
npm install radix-vue
```
2. Copy and paste the component source files linked at the top of this page into your project.
</ManualInstall>
## Usage
```vue
<script setup lang="ts">
import {
Command,
CommandDialog,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
CommandSeparator,
CommandShortcut,
} from '@/components/ui/command'
</script>
<template>
<Command>
<CommandInput placeholder="Type a command or search..." />
<CommandList>
<CommandEmpty>No results found.</CommandEmpty>
<CommandGroup heading="Suggestions">
<CommandItem>Calendar</CommandItem>
<CommandItem>Search Emoji</CommandItem>
<CommandItem>Calculator</CommandItem>
</CommandGroup>
<CommandSeparator />
<CommandGroup heading="Settings">
<CommandItem>Profile</CommandItem>
<CommandItem>Billing</CommandItem>
<CommandItem>Settings</CommandItem>
</CommandGroup>
</CommandList>
</Command>
</template>```

View File

@ -1,4 +1,5 @@
<script setup lang="ts">
import { ref } from 'vue'
import ChevronDownIcon from '~icons/radix-icons/chevron-down'
import {
@ -14,12 +15,16 @@ import {
CardHeader,
CardTitle,
} from '@/lib/registry/new-york/ui/card'
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/lib/registry/new-york/ui/command'
import {
Popover,
PopoverContent,
PopoverTrigger,
} from '@/lib/registry/new-york/ui/popover'
const sofiaRole = ref('Owner')
const jacksonRole = ref('Member')
</script>
<template>
@ -49,35 +54,35 @@ import {
<Popover>
<PopoverTrigger as-child>
<Button variant="outline" class="ml-auto">
Owner
{{ sofiaRole }}
<ChevronDownIcon class="ml-2 h-4 w-4 text-muted-foreground" />
</Button>
</PopoverTrigger>
<PopoverContent class="p-0" align="end">
<!-- <Command>
<Command v-model="sofiaRole">
<CommandInput placeholder="Select new role..." />
<CommandList>
<CommandEmpty>No roles found.</CommandEmpty>
<CommandGroup>
<CommandItem class="teamaspace-y-1 flex flex-col items-start px-4 py-2">
<CommandItem value="Viewer" class="teamaspace-y-1 flex flex-col items-start px-4 py-2">
<p>Viewer</p>
<p class="text-sm text-muted-foreground">
Can view and comment.
</p>
</CommandItem>
<CommandItem class="teamaspace-y-1 flex flex-col items-start px-4 py-2">
<CommandItem value="Developer" class="teamaspace-y-1 flex flex-col items-start px-4 py-2">
<p>Developer</p>
<p class="text-sm text-muted-foreground">
Can view, comment and edit.
</p>
</CommandItem>
<CommandItem class="teamaspace-y-1 flex flex-col items-start px-4 py-2">
<CommandItem value="Billing" class="teamaspace-y-1 flex flex-col items-start px-4 py-2">
<p>Billing</p>
<p class="text-sm text-muted-foreground">
Can view, comment and manage billing.
</p>
</CommandItem>
<CommandItem class="teamaspace-y-1 flex flex-col items-start px-4 py-2">
<CommandItem value="Owner" class="teamaspace-y-1 flex flex-col items-start px-4 py-2">
<p>Owner</p>
<p class="text-sm text-muted-foreground">
Admin-level access to all resources.
@ -85,7 +90,7 @@ import {
</CommandItem>
</CommandGroup>
</CommandList>
</Command> -->
</Command>
</PopoverContent>
</Popover>
</div>
@ -107,35 +112,35 @@ import {
<Popover>
<PopoverTrigger as-child>
<Button variant="outline" class="ml-auto">
Member
{{ jacksonRole }}
<ChevronDownIcon class="ml-2 h-4 w-4 text-muted-foreground" />
</Button>
</PopoverTrigger>
<PopoverContent class="p-0" align="end">
<!-- <Command>
<Command v-model="jacksonRole">
<CommandInput placeholder="Select new role..." />
<CommandList>
<CommandEmpty>No roles found.</CommandEmpty>
<CommandGroup class="p-1.5">
<CommandItem class="teamaspace-y-1 flex flex-col items-start px-4 py-2">
<CommandGroup>
<CommandItem value="Viewer" class="teamaspace-y-1 flex flex-col items-start px-4 py-2">
<p>Viewer</p>
<p class="text-sm text-muted-foreground">
Can view and comment.
</p>
</CommandItem>
<CommandItem class="teamaspace-y-1 flex flex-col items-start px-4 py-2">
<CommandItem value="Developer" class="teamaspace-y-1 flex flex-col items-start px-4 py-2">
<p>Developer</p>
<p class="text-sm text-muted-foreground">
Can view, comment and edit.
</p>
</CommandItem>
<CommandItem class="teamaspace-y-1 flex flex-col items-start px-4 py-2">
<CommandItem value="Billing" class="teamaspace-y-1 flex flex-col items-start px-4 py-2">
<p>Billing</p>
<p class="text-sm text-muted-foreground">
Can view, comment and manage billing.
</p>
</CommandItem>
<CommandItem class="teamaspace-y-1 flex flex-col items-start px-4 py-2">
<CommandItem value="Owner" class="teamaspace-y-1 flex flex-col items-start px-4 py-2">
<p>Owner</p>
<p class="text-sm text-muted-foreground">
Admin-level access to all resources.
@ -143,7 +148,7 @@ import {
</CommandItem>
</CommandGroup>
</CommandList>
</Command> -->
</Command>
</PopoverContent>
</Popover>
</div>

View File

@ -1,6 +1,8 @@
<script setup lang="ts">
import { ref } from 'vue'
import CaretSortIcon from '~icons/radix-icons/caret-sort'
import CheckIcon from '~icons/radix-icons/check'
import PlusCircledIcon from '~icons/radix-icons/plus-circled'
import { cn } from '@/lib/utils'
import {
@ -17,7 +19,9 @@ import {
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from '@/lib/registry/new-york/ui/dialog'
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator } from '@/lib/registry/new-york/ui/command'
import { Input } from '@/lib/registry/new-york/ui/input'
import { Label } from '@/lib/registry/new-york/ui/label'
import {
@ -88,52 +92,50 @@ const selectedTeam = ref<Team>(groups[0].teams[0])
</Button>
</PopoverTrigger>
<PopoverContent class="w-[200px] p-0">
<!-- <Command>
<Command :filter-function="(list, term) => list.filter(i => i.label?.toLowerCase()?.includes(term)) ">
<CommandList>
<CommandInput placeholder="Search team..." />
<CommandEmpty>No team found.</CommandEmpty>
{groups.map((group) => (
<CommandGroup key={group.label} heading={group.label}>
{group.teams.map((team) => (
<CommandGroup v-for="group in groups" :key="group.label" :heading="group.label">
<CommandItem
key={team.value}
onSelect={() => {
setSelectedTeam(team)
setOpen(false)
}}
v-for="team in group.teams"
:key="team.value"
:value="team"
class="text-sm"
@select="() => {
selectedTeam = team
open = false
}"
>
<Avatar class="mr-2 h-5 w-5">
<AvatarImage
src={`https://avatar.vercel.sh/${team.value}.png`}
alt={team.label}
:src="`https://avatar.vercel.sh/${team.value}.png`"
:alt="team.label"
class="grayscale"
/>
<AvatarFallback>SC</AvatarFallback>
</Avatar>
{team.label}
{{ team.label }}
<CheckIcon
class={cn(
"ml-auto h-4 w-4",
:class="cn('ml-auto h-4 w-4',
selectedTeam.value === team.value
? "opacity-100"
: "opacity-0"
)}
? 'opacity-100'
: 'opacity-0',
)"
/>
</CommandItem>
))}
</CommandGroup>
))}
</CommandList>
<CommandSeparator />
<CommandList>
<CommandGroup>
<DialogTrigger asChild>
<DialogTrigger as-child>
<CommandItem
onSelect={() => {
setOpen(false)
setShowNewTeamDialog(true)
}}
:value="{ label: 'Create Team' }"
@select="() => {
open = false
showNewTeamDialog = true
}"
>
<PlusCircledIcon class="mr-2 h-5 w-5" />
Create Team
@ -141,7 +143,7 @@ const selectedTeam = ref<Team>(groups[0].teams[0])
</DialogTrigger>
</CommandGroup>
</CommandList>
</Command> -->
</Command>
</PopoverContent>
</Popover>
<DialogContent>

View File

@ -4,7 +4,16 @@ import { Separator } from '@/lib/registry/new-york/ui/separator'
</script>
<template>
<div class="md:hidden" />
<div class="md:hidden">
<VPImage
alt="Forms"
width="1280"
height="1214" class="block" :image="{
dark: '/examples/forms-dark.png',
light: '/examples/forms-light.png',
}"
/>
</div>
<div class="hidden space-y-6 p-10 pb-16 md:block">
<div class="space-y-0.5">
<h2 class="text-2xl font-bold tracking-tight">

View File

@ -1,12 +1,14 @@
<script setup lang="ts">
import type { Column } from '@tanstack/vue-table'
import type { Component } from 'vue'
import { computed } from 'vue'
import { computed, ref } from 'vue'
import { type Task } from '../data/schema'
import PlusCircledIcon from '~icons/radix-icons/plus-circled'
import CheckIcon from '~icons/radix-icons/check'
import { Badge } from '@/lib/registry/new-york/ui/badge'
import { Button } from '@/lib/registry/new-york/ui/button'
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator } from '@/lib/registry/new-york/ui/command'
import {
Popover,
@ -14,6 +16,7 @@ import {
PopoverTrigger,
} from '@/lib/registry/new-york/ui/popover'
import { Separator } from '@/lib/registry/new-york/ui/separator'
import { cn } from '@/lib/utils'
interface DataTableFacetedFilter {
column?: Column<Task, any>
@ -70,66 +73,63 @@ const selectedValues = computed(() => new Set(props.column?.getFilterValue() as
</Button>
</PopoverTrigger>
<PopoverContent class="w-[200px] p-0" align="start">
<!-- <Command>
<CommandInput placeholder={title} />
<Command
:filter-function="(list: DataTableFacetedFilter['options'], term) => list.filter(i => i.label.toLowerCase()?.includes(term)) "
>
<CommandInput :placeholder="title" />
<CommandList>
<CommandEmpty>No results found.</CommandEmpty>
<CommandGroup>
{options.map((option) => {
const isSelected = selectedValues.has(option.value)
return (
<CommandItem
key={option.value}
onSelect={() => {
v-for="option in options"
:key="option.value"
:value="option"
@select="() => {
const isSelected = selectedValues.has(option.value)
if (isSelected) {
selectedValues.delete(option.value)
} else {
}
else {
selectedValues.add(option.value)
}
const filterValues = Array.from(selectedValues)
column?.setFilterValue(
filterValues.length ? filterValues : undefined
filterValues.length ? filterValues : undefined,
)
}}
}"
>
<div
class={cn(
"mr-2 flex h-4 w-4 items-center justify-center rounded-sm border border-primary",
isSelected
? "bg-primary text-primary-foreground"
: "opacity-50 [&_svg]:invisible"
)}
:class="cn(
'mr-2 flex h-4 w-4 items-center justify-center rounded-sm border border-primary',
selectedValues.has(option.value)
? 'bg-primary text-primary-foreground'
: 'opacity-50 [&_svg]:invisible',
)"
>
<CheckIcon class={cn("h-4 w-4")} />
<CheckIcon :class="cn('h-4 w-4')" />
</div>
{option.icon && (
<option.icon class="mr-2 h-4 w-4 text-muted-foreground" />
)}
<span>{option.label}</span>
{facets?.get(option.value) && (
<span class="ml-auto flex h-4 w-4 items-center justify-center font-mono text-xs">
{facets.get(option.value)}
<option.icon v-if="option.icon" class="mr-2 h-4 w-4 text-muted-foreground" />
<span>{{ option.label }}</span>
<span v-if="facets?.get(option.value)" class="ml-auto flex h-4 w-4 items-center justify-center font-mono text-xs">
{{ facets.get(option.value) }}
</span>
)}
</CommandItem>
)
})}
</CommandGroup>
{selectedValues.size > 0 && (
<>
<template v-if="selectedValues.size > 0">
<CommandSeparator />
<CommandGroup>
<CommandItem
onSelect={() => column?.setFilterValue(undefined)}
:value="{ label: 'Clear filters' }"
class="justify-center text-center"
@select="column?.setFilterValue(undefined)"
>
Clear filters
</CommandItem>
</CommandGroup>
</>
)}
</template>
</CommandList>
</Command> -->
</Command>
</PopoverContent>
</Popover>
</template>

View File

@ -0,0 +1,100 @@
<script setup lang="ts">
import { ref } from 'vue'
import { Button } from '@/lib/registry/default/ui/button'
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from '@/lib/registry/default/ui/card'
import { themes } from '@/lib/registry/themes'
import { useConfigStore } from '@/stores/config'
const { theme, radius, setRadius, setTheme } = useConfigStore()
const goal = ref(350)
const data = [
{ goal: 400 },
{ goal: 300 },
{ goal: 200 },
{ goal: 300 },
{ goal: 200 },
{ goal: 278 },
{ goal: 189 },
{ goal: 239 },
{ goal: 300 },
{ goal: 200 },
{ goal: 278 },
{ goal: 189 },
{ goal: 349 },
]
</script>
<template>
<Card>
<CardHeader class-name="pb-4">
<CardTitle class-name="text-base">
Move Goal
</CardTitle>
<CardDescription>Set your daily activity goal.</CardDescription>
</CardHeader>
<CardContent class-name="pb-2">
<div className="flex items-center justify-center space-x-2">
<Button
variant="outline"
size="icon"
class-name="h-8 w-8 shrink-0 rounded-full"
:disabled="goal <= 200"
@click="goal -= 10"
>
<Minus class-name="h-4 w-4" />
<span className="sr-only">Decrease</span>
</Button>
<div className="flex-1 text-center">
<div className="text-5xl font-bold tracking-tighter">
{{ goal }}
</div>
<div className="text-[0.70rem] uppercase text-muted-foreground">
Calories/day
</div>
</div>
<Button
variant="outline"
size="icon"
class-name="h-8 w-8 shrink-0 rounded-full"
:disabled="goal >= 400"
@click="goal += 10 "
>
<Plus class-name="h-4 w-4" />
<span className="sr-only">Increase</span>
</Button>
</div>
<div className="my-3 h-[60px]">
<!-- <ResponsiveContainer width="100%" height="100%">
<BarChart data="{data}">
<Bar
data-key="goal"
style="{"
{
fill: "var(--theme-primary)",
opacity: 0.2,
"--theme-primary": `hsl(${
theme?.cssVars[mode="==" "dark" ? "dark" : "light"].primary
})`,
} as React.CSSProperties
}
/>
</BarChart>
</ResponsiveContainer> -->
</div>
</CardContent>
<CardFooter>
<Button class-name="w-full">
Set Goal
</Button>
</CardFooter>
</Card>
</template>

View File

@ -0,0 +1,125 @@
<script setup lang="ts">
import { ref } from 'vue'
import { ChevronDown, Minus, Plus, Send } from 'lucide-vue-next'
import { addDays, startOfToday } from 'date-fns'
import {
months,
payments,
roles,
teamMembers,
years,
} from './utils/data'
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from '@/lib/registry/default/ui/card'
import {
Avatar,
AvatarFallback,
AvatarImage,
} from '@/lib/registry/default/ui/avatar'
import { Button } from '@/lib/registry/default/ui/button'
import { Textarea } from '@/lib/registry/default/ui/textarea'
import { Calendar } from '@/lib/registry/default/ui/calendar'
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from '@/lib/registry/default/ui/dropdown-menu'
import { Label } from '@/lib/registry/default/ui/label'
import { Switch } from '@/lib/registry/default/ui/switch'
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/lib/registry/default/ui/select'
import { Input } from '@/lib/registry/default/ui/input'
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from '@/lib/registry/default/ui/tooltip'
import { Separator } from '@/lib/registry/default/ui/separator'
import RadixIconsGithubLogo from '~icons/radix-icons/github-logo'
import RiGoogleLine from '~icons/ri/google-line'
const strictlyNecessarySwitch = ref<boolean>(true)
const functionalCookiesSwitch = ref<boolean>(false)
const performanceCookiesSwitch = ref<boolean>(false)
const selectedArea = ref('Billing')
const selectedSecurity = ref('Medium')
const selectedMonth = ref<string>(months[0])
const selectedYear = ref<string>(years[0])
const selectedPayment = ref(payments[0])
const goal = ref(350)
function switchPayment(payment: any) {
selectedPayment.value = payment
}
const range = ref({
start: startOfToday(),
end: addDays(startOfToday(), 8),
})
</script>
<template>
<div className="md:grids-col-2 grid md:gap-4 lg:grid-cols-10 xl:grid-cols-11 xl:gap-4">
<div className="space-y-4 lg:col-span-4 xl:col-span-6 xl:space-y-4">
<CardsStats />
<div className="grid gap-1 sm:grid-cols-[280px_1fr] md:hidden">
<CardsCalendar />
<div className="pt-3 sm:pl-2 sm:pt-0 xl:pl-4">
<CardsActivityGoal />
</div>
<div className="pt-3 sm:col-span-2 xl:pt-4">
<CardsMetric />
</div>
</div>
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-1 xl:grid-cols-2">
<div className="space-y-4 xl:space-y-4">
<CardsTeamMembers />
<CardsCookieSettings />
<CardsPaymentMethod />
</div>
<div className="space-y-4 xl:space-y-4">
<CardsChat />
<CardsCreateAccount />
<div className="hidden xl:block">
<CardsReportIssue />
</div>
</div>
</div>
</div>
<div className="space-y-4 lg:col-span-6 xl:col-span-5 xl:space-y-4">
<div className="hidden gap-1 sm:grid-cols-[280px_1fr] md:grid">
<CardsCalendar />
<div className="pt-3 sm:pl-2 sm:pt-0 xl:pl-3">
<CardsActivityGoal />
</div>
<div className="pt-3 sm:col-span-2 xl:pt-3">
<CardsMetric />
</div>
</div>
<div className="hidden md:block">
<CardsDataTable />
</div>
<CardsShare />
<div className="xl:hidden">
<CardsReportIssue />
</div>
</div>
</div>
</template>

View File

@ -0,0 +1,70 @@
<script setup lang="ts">
import { Check, ChevronsUpDown } from 'lucide-vue-next'
import { ref } from 'vue'
import { cn } from '@/lib/utils'
import { Button } from '@/lib/registry/default/ui/button'
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
} from '@/lib/registry/default/ui/command'
import {
Popover,
PopoverContent,
PopoverTrigger,
} from '@/lib/registry/default/ui/popover'
const frameworks = [
{ value: 'next.js', label: 'Next.js' },
{ value: 'sveltekit', label: 'SvelteKit' },
{ value: 'nuxt.js', label: 'Nuxt.js' },
{ value: 'remix', label: 'Remix' },
{ value: 'astro', label: 'Astro' },
]
const open = ref(false)
const value = ref<typeof frameworks[number]>()
const filterFunction = (list: typeof frameworks, search: string) => list.filter(i => i.value.toLowerCase().includes(search.toLowerCase()))
</script>
<template>
<Popover v-model:open="open">
<PopoverTrigger as-child>
<Button
variant="outline"
role="combobox"
:aria-expanded="open"
class="w-[200px] justify-between"
>
{{ value ? value.label : 'Select framework...' }}
<ChevronsUpDown class="ml-2 h-4 w-4 shrink-0 opacity-50" />
</Button>
</PopoverTrigger>
<PopoverContent class="w-[200px] p-0">
<Command v-model="value" :filter-function="filterFunction">
<CommandInput placeholder="Search framework..." />
<CommandEmpty>No framework found.</CommandEmpty>
<CommandGroup>
<CommandItem
v-for="framework in frameworks"
:key="framework.value"
:value="framework"
@select="open = false"
>
<Check
:class="cn(
'mr-2 h-4 w-4',
value?.value === framework.value ? 'opacity-100' : 'opacity-0',
)"
/>
{{ framework.label }}
</CommandItem>
</CommandGroup>
</Command>
</PopoverContent>
</Popover>
</template>

View File

@ -0,0 +1,62 @@
<script setup lang="ts">
import {
Calculator,
Calendar,
CreditCard,
Settings,
Smile,
User,
} from 'lucide-vue-next'
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
CommandSeparator,
CommandShortcut,
} from '@/lib/registry/default/ui/command'
</script>
<template>
<Command class="rounded-lg border shadow-md max-w-[450px]">
<CommandInput placeholder="Type a command or search..." />
<CommandList>
<CommandEmpty>No results found.</CommandEmpty>
<CommandGroup heading="Suggestions">
<CommandItem value="Calendar">
<Calendar class="mr-2 h-4 w-4" />
<span>Calendar</span>
</CommandItem>
<CommandItem value="Search Emoji">
<Smile class="mr-2 h-4 w-4" />
<span>Search Emoji</span>
</CommandItem>
<CommandItem value="Calculator">
<Calculator class="mr-2 h-4 w-4" />
<span>Calculator</span>
</CommandItem>
</CommandGroup>
<CommandSeparator />
<CommandGroup heading="Settings">
<CommandItem value="Profile">
<User class="mr-2 h-4 w-4" />
<span>Profile</span>
<CommandShortcut>P</CommandShortcut>
</CommandItem>
<CommandItem value="Billing">
<CreditCard class="mr-2 h-4 w-4" />
<span>Billing</span>
<CommandShortcut>B</CommandShortcut>
</CommandItem>
<CommandItem value="Settings">
<Settings class="mr-2 h-4 w-4" />
<span>Settings</span>
<CommandShortcut>S</CommandShortcut>
</CommandItem>
</CommandGroup>
</CommandList>
</Command>
</template>

View File

@ -0,0 +1,21 @@
<script setup lang="ts">
import type { ComboboxRootEmits, ComboboxRootProps } from 'radix-vue'
import { ComboboxRoot } from 'radix-vue'
import { cn, useEmitAsProps } from '@/lib/utils'
const props = defineProps<ComboboxRootProps>()
const emits = defineEmits<ComboboxRootEmits>()
const emitsAsProps = useEmitAsProps(emits)
</script>
<template>
<ComboboxRoot
v-bind="{ ...props, ...emitsAsProps }"
:open="true"
:model-value="''"
:class="cn('flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground', $attrs.class ?? '')"
>
<slot />
</ComboboxRoot>
</template>

View File

@ -0,0 +1,21 @@
<script setup lang="ts">
import type { DialogRootEmits, DialogRootProps } from 'radix-vue'
import Command from './Command.vue'
import { Dialog, DialogContent } from '@/lib/registry/default/ui/dialog'
import { useEmitAsProps } from '@/lib/utils'
const props = defineProps<DialogRootProps>()
const emits = defineEmits<DialogRootEmits>()
const emitsAsProps = useEmitAsProps(emits)
</script>
<template>
<Dialog v-bind="{ ...props, ...emitsAsProps }">
<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>
</DialogContent>
</Dialog>
</template>

View File

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

View File

@ -0,0 +1,21 @@
<script setup lang="ts">
import type { ComboboxGroupProps } from 'radix-vue'
import { ComboboxGroup, ComboboxLabel } from 'radix-vue'
import { cn } from '@/lib/utils'
const props = defineProps<ComboboxGroupProps & {
heading?: string
}>()
</script>
<template>
<ComboboxGroup
v-bind="props"
:class="cn('overflow-hidden p-1 text-foreground', $attrs.class ?? '')"
>
<ComboboxLabel v-if="heading" class="px-2 py-1.5 text-xs font-medium text-muted-foreground">
{{ heading }}
</ComboboxLabel>
<slot />
</ComboboxGroup>
</template>

View File

@ -0,0 +1,24 @@
<script setup lang="ts">
import { Search } from 'lucide-vue-next'
import { ComboboxInput, type ComboboxInputProps } from 'radix-vue'
import { cn } from '@/lib/utils'
const props = defineProps<ComboboxInputProps>()
</script>
<script lang="ts">
export default {
inheritAttrs: false,
}
</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 }"
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 ?? '')"
/>
</div>
</template>

View File

@ -0,0 +1,19 @@
<script setup lang="ts">
import type { ComboboxItemEmits, ComboboxItemProps } from 'radix-vue'
import { ComboboxItem } from 'radix-vue'
import { cn, useEmitAsProps } from '@/lib/utils'
const props = defineProps<ComboboxItemProps>()
const emits = defineEmits<ComboboxItemEmits>()
const emitsAsProps = useEmitAsProps(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 ?? '')"
>
<slot />
</ComboboxItem>
</template>

View File

@ -0,0 +1,16 @@
<script setup lang="ts">
import type { ComboboxContentEmits, ComboboxContentProps } from 'radix-vue'
import { ComboboxContent } from 'radix-vue'
import { cn, useEmitAsProps } from '@/lib/utils'
const props = defineProps<ComboboxContentProps>()
const emits = defineEmits<ComboboxContentEmits>()
const emitsAsProps = useEmitAsProps(emits)
</script>
<template>
<ComboboxContent v-bind="{ ...props, ...emitsAsProps }" :class="cn('max-h-[300px] overflow-y-auto overflow-x-hidden', $attrs.class ?? '')">
<slot />
</ComboboxContent>
</template>

View File

@ -0,0 +1,16 @@
<script setup lang="ts">
import type { ComboboxSeparatorProps } from 'radix-vue'
import { ComboboxSeparator } from 'radix-vue'
import { cn } from '@/lib/utils'
const props = defineProps<ComboboxSeparatorProps>()
</script>
<template>
<ComboboxSeparator
v-bind="props"
:class="cn('-mx-1 h-px bg-border', $attrs.class ?? '')"
>
<slot />
</ComboboxSeparator>
</template>

View File

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

View File

@ -0,0 +1,9 @@
export { default as Command } from './Command.vue'
export { default as CommandDialog } from './CommandDialog.vue'
export { default as CommandEmpty } from './CommandEmpty.vue'
export { default as CommandGroup } from './CommandGroup.vue'
export { default as CommandInput } from './CommandInput.vue'
export { default as CommandItem } from './CommandItem.vue'
export { default as CommandList } from './CommandList.vue'
export { default as CommandSeparator } from './CommandSeparator.vue'
export { default as CommandShortcut } from './CommandShortcut.vue'

View File

@ -1,11 +1,16 @@
<script setup lang="ts">
import { PopoverRoot, type PopoverRootProps } from 'radix-vue'
import { PopoverRoot } from 'radix-vue'
import type { PopoverRootEmits, PopoverRootProps } from 'radix-vue'
import { useEmitAsProps } from '@/lib/utils'
const props = defineProps<PopoverRootProps>()
const emits = defineEmits<PopoverRootEmits>()
const emitsAsProps = useEmitAsProps(emits)
</script>
<template>
<PopoverRoot v-bind="props">
<PopoverRoot v-bind="{ ...props, ...emitsAsProps }">
<slot />
</PopoverRoot>
</template>

View File

@ -0,0 +1,71 @@
<script setup lang="ts">
import { ref } from 'vue'
import Check from '~icons/radix-icons/check'
import CaretSort from '~icons/radix-icons/caret-sort'
import { cn } from '@/lib/utils'
import { Button } from '@/lib/registry/default/ui/button'
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
} from '@/lib/registry/default/ui/command'
import {
Popover,
PopoverContent,
PopoverTrigger,
} from '@/lib/registry/default/ui/popover'
const frameworks = [
{ value: 'next.js', label: 'Next.js' },
{ value: 'sveltekit', label: 'SvelteKit' },
{ value: 'nuxt.js', label: 'Nuxt.js' },
{ value: 'remix', label: 'Remix' },
{ value: 'astro', label: 'Astro' },
]
const open = ref(false)
const value = ref<typeof frameworks[number]>()
const filterFunction = (list: typeof frameworks, search: string) => list.filter(i => i.value.toLowerCase().includes(search.toLowerCase()))
</script>
<template>
<Popover v-model:open="open">
<PopoverTrigger as-child>
<Button
variant="outline"
role="combobox"
:aria-expanded="open"
class="w-[200px] justify-between"
>
{{ value ? value.label : 'Select framework...' }}
<CaretSort class="ml-2 h-4 w-4 shrink-0 opacity-50" />
</Button>
</PopoverTrigger>
<PopoverContent class="w-[200px] p-0">
<Command v-model="value" :filter-function="filterFunction">
<CommandInput class="h-9" placeholder="Search framework..." />
<CommandEmpty>No framework found.</CommandEmpty>
<CommandGroup>
<CommandItem
v-for="framework in frameworks"
:key="framework.value"
:value="framework"
@select="open = false"
>
{{ framework.label }}
<Check
:class="cn(
'ml-auto h-4 w-4',
value?.value === framework.value ? 'opacity-100' : 'opacity-0',
)"
/>
</CommandItem>
</CommandGroup>
</Command>
</PopoverContent>
</Popover>
</template>

View File

@ -0,0 +1,62 @@
<script setup lang="ts">
import {
Calculator,
Calendar,
CreditCard,
Settings,
Smile,
User,
} from 'lucide-vue-next'
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
CommandSeparator,
CommandShortcut,
} from '@/lib/registry/new-york/ui/command'
</script>
<template>
<Command class="rounded-lg border shadow-md max-w-[450px]">
<CommandInput placeholder="Type a command or search..." />
<CommandList>
<CommandEmpty>No results found.</CommandEmpty>
<CommandGroup heading="Suggestions">
<CommandItem value="Calendar">
<Calendar class="mr-2 h-4 w-4" />
<span>Calendar</span>
</CommandItem>
<CommandItem value="Search Emoji">
<Smile class="mr-2 h-4 w-4" />
<span>Search Emoji</span>
</CommandItem>
<CommandItem value="Calculator">
<Calculator class="mr-2 h-4 w-4" />
<span>Calculator</span>
</CommandItem>
</CommandGroup>
<CommandSeparator />
<CommandGroup heading="Settings">
<CommandItem value="Profile">
<User class="mr-2 h-4 w-4" />
<span>Profile</span>
<CommandShortcut>P</CommandShortcut>
</CommandItem>
<CommandItem value="Billing">
<CreditCard class="mr-2 h-4 w-4" />
<span>Billing</span>
<CommandShortcut>B</CommandShortcut>
</CommandItem>
<CommandItem value="Settings">
<Settings class="mr-2 h-4 w-4" />
<span>Settings</span>
<CommandShortcut>S</CommandShortcut>
</CommandItem>
</CommandGroup>
</CommandList>
</Command>
</template>

View File

@ -0,0 +1,20 @@
<script setup lang="ts">
import type { ComboboxRootEmits, ComboboxRootProps } from 'radix-vue'
import { ComboboxRoot } from 'radix-vue'
import { cn, useEmitAsProps } from '@/lib/utils'
const props = defineProps<ComboboxRootProps>()
const emits = defineEmits<ComboboxRootEmits>()
const emitsAsProps = useEmitAsProps(emits)
</script>
<template>
<ComboboxRoot
v-bind="{ ...props, ...emitsAsProps }"
:open="true"
:class="cn('flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground', $attrs.class ?? '')"
>
<slot />
</ComboboxRoot>
</template>

View File

@ -0,0 +1,21 @@
<script setup lang="ts">
import type { DialogRootEmits, DialogRootProps } from 'radix-vue'
import Command from './Command.vue'
import { Dialog, DialogContent } from '@/lib/registry/new-york/ui/dialog'
import { useEmitAsProps } from '@/lib/utils'
const props = defineProps<DialogRootProps>()
const emits = defineEmits<DialogRootEmits>()
const emitsAsProps = useEmitAsProps(emits)
</script>
<template>
<Dialog v-bind="{ ...props, ...emitsAsProps }">
<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>
</DialogContent>
</Dialog>
</template>

View File

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

View File

@ -0,0 +1,21 @@
<script setup lang="ts">
import type { ComboboxGroupProps } from 'radix-vue'
import { ComboboxGroup, ComboboxLabel } from 'radix-vue'
import { cn } from '@/lib/utils'
const props = defineProps<ComboboxGroupProps & {
heading?: string
}>()
</script>
<template>
<ComboboxGroup
v-bind="props"
:class="cn('overflow-hidden p-1 text-foreground', $attrs.class ?? '')"
>
<ComboboxLabel v-if="heading" class="px-2 py-1.5 text-xs font-medium text-muted-foreground">
{{ heading }}
</ComboboxLabel>
<slot />
</ComboboxGroup>
</template>

View File

@ -0,0 +1,24 @@
<script setup lang="ts">
import { Search } from 'lucide-vue-next'
import { ComboboxInput, type ComboboxInputProps } from 'radix-vue'
import { cn } from '@/lib/utils'
const props = defineProps<ComboboxInputProps>()
</script>
<script lang="ts">
export default {
inheritAttrs: false,
}
</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 }"
auto-focus
:class="cn('flex h-10 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 ?? '')"
/>
</div>
</template>

View File

@ -0,0 +1,19 @@
<script setup lang="ts">
import type { ComboboxItemEmits, ComboboxItemProps } from 'radix-vue'
import { ComboboxItem } from 'radix-vue'
import { cn, useEmitAsProps } from '@/lib/utils'
const props = defineProps<ComboboxItemProps>()
const emits = defineEmits<ComboboxItemEmits>()
const emitsAsProps = useEmitAsProps(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 ?? '')"
>
<slot />
</ComboboxItem>
</template>

View File

@ -0,0 +1,16 @@
<script setup lang="ts">
import type { ComboboxContentEmits, ComboboxContentProps } from 'radix-vue'
import { ComboboxContent } from 'radix-vue'
import { cn, useEmitAsProps } from '@/lib/utils'
const props = defineProps<ComboboxContentProps>()
const emits = defineEmits<ComboboxContentEmits>()
const emitsAsProps = useEmitAsProps(emits)
</script>
<template>
<ComboboxContent v-bind="{ ...props, ...emitsAsProps }" :class="cn('max-h-[300px] overflow-y-auto overflow-x-hidden', $attrs.class ?? '')">
<slot />
</ComboboxContent>
</template>

View File

@ -0,0 +1,16 @@
<script setup lang="ts">
import type { ComboboxSeparatorProps } from 'radix-vue'
import { ComboboxSeparator } from 'radix-vue'
import { cn } from '@/lib/utils'
const props = defineProps<ComboboxSeparatorProps>()
</script>
<template>
<ComboboxSeparator
v-bind="props"
:class="cn('-mx-1 h-px bg-border', $attrs.class ?? '')"
>
<slot />
</ComboboxSeparator>
</template>

View File

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

View File

@ -0,0 +1,9 @@
export { default as Command } from './Command.vue'
export { default as CommandDialog } from './CommandDialog.vue'
export { default as CommandEmpty } from './CommandEmpty.vue'
export { default as CommandGroup } from './CommandGroup.vue'
export { default as CommandInput } from './CommandInput.vue'
export { default as CommandItem } from './CommandItem.vue'
export { default as CommandList } from './CommandList.vue'
export { default as CommandSeparator } from './CommandSeparator.vue'
export { default as CommandShortcut } from './CommandShortcut.vue'

View File

@ -1,11 +1,16 @@
<script setup lang="ts">
import { PopoverRoot, type PopoverRootProps } from 'radix-vue'
import { PopoverRoot } from 'radix-vue'
import type { PopoverRootEmits, PopoverRootProps } from 'radix-vue'
import { useEmitAsProps } from '@/lib/utils'
const props = defineProps<PopoverRootProps>()
const emits = defineEmits<PopoverRootEmits>()
const emitsAsProps = useEmitAsProps(emits)
</script>
<template>
<PopoverRoot v-bind="props">
<PopoverRoot v-bind="{ ...props, ...emitsAsProps }">
<slot />
</PopoverRoot>
</template>

View File

@ -166,6 +166,29 @@
],
"type": "components:ui"
},
{
"name": "command",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils",
"dialog"
],
"files": [
"ui/command/Command.vue",
"ui/command/CommandDialog.vue",
"ui/command/CommandEmpty.vue",
"ui/command/CommandGroup.vue",
"ui/command/CommandInput.vue",
"ui/command/CommandItem.vue",
"ui/command/CommandList.vue",
"ui/command/CommandSeparator.vue",
"ui/command/CommandShortcut.vue",
"ui/command/index.ts"
],
"type": "components:ui"
},
{
"name": "context-menu",
"dependencies": [

View File

@ -1,15 +1,52 @@
{
"name": "command",
"dependencies": [
"cmdk"
"radix-vue"
],
"registryDependencies": [
"utils",
"dialog"
],
"files": [
{
"name": "command.tsx",
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { DialogProps } from \"@radix-ui/react-dialog\"\nimport { Command as CommandPrimitive } from \"cmdk\"\nimport { Search } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Dialog, DialogContent } from \"@/registry/default/ui/dialog\"\n\nconst Command = React.forwardRef<\n React.ElementRef<typeof CommandPrimitive>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive>\n>(({ class, ...props }, ref) => (\n <CommandPrimitive\n ref={ref}\n class={cn(\n \"flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground\",\n class\n )}\n {...props}\n />\n))\nCommand.displayName = CommandPrimitive.displayName\n\ninterface CommandDialogProps extends DialogProps {}\n\nconst CommandDialog = ({ children, ...props }: CommandDialogProps) => {\n return (\n <Dialog {...props}>\n <DialogContent class=\"overflow-hidden p-0 shadow-lg\">\n <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\">\n {children}\n </Command>\n </DialogContent>\n </Dialog>\n )\n}\n\nconst CommandInput = React.forwardRef<\n React.ElementRef<typeof CommandPrimitive.Input>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>\n>(({ class, ...props }, ref) => (\n <div class=\"flex items-center border-b px-3\" cmdk-input-wrapper=\"\">\n <Search class=\"mr-2 h-4 w-4 shrink-0 opacity-50\" />\n <CommandPrimitive.Input\n ref={ref}\n class={cn(\n \"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\",\n class\n )}\n {...props}\n />\n </div>\n))\n\nCommandInput.displayName = CommandPrimitive.Input.displayName\n\nconst CommandList = React.forwardRef<\n React.ElementRef<typeof CommandPrimitive.List>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>\n>(({ class, ...props }, ref) => (\n <CommandPrimitive.List\n ref={ref}\n class={cn(\"max-h-[300px] overflow-y-auto overflow-x-hidden\", class)}\n {...props}\n />\n))\n\nCommandList.displayName = CommandPrimitive.List.displayName\n\nconst CommandEmpty = React.forwardRef<\n React.ElementRef<typeof CommandPrimitive.Empty>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>\n>((props, ref) => (\n <CommandPrimitive.Empty\n ref={ref}\n class=\"py-6 text-center text-sm\"\n {...props}\n />\n))\n\nCommandEmpty.displayName = CommandPrimitive.Empty.displayName\n\nconst CommandGroup = React.forwardRef<\n React.ElementRef<typeof CommandPrimitive.Group>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive.Group>\n>(({ class, ...props }, ref) => (\n <CommandPrimitive.Group\n ref={ref}\n class={cn(\n \"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\",\n class\n )}\n {...props}\n />\n))\n\nCommandGroup.displayName = CommandPrimitive.Group.displayName\n\nconst CommandSeparator = React.forwardRef<\n React.ElementRef<typeof CommandPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>\n>(({ class, ...props }, ref) => (\n <CommandPrimitive.Separator\n ref={ref}\n class={cn(\"-mx-1 h-px bg-border\", class)}\n {...props}\n />\n))\nCommandSeparator.displayName = CommandPrimitive.Separator.displayName\n\nconst CommandItem = React.forwardRef<\n React.ElementRef<typeof CommandPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>\n>(({ class, ...props }, ref) => (\n <CommandPrimitive.Item\n ref={ref}\n class={cn(\n \"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\",\n class\n )}\n {...props}\n />\n))\n\nCommandItem.displayName = CommandPrimitive.Item.displayName\n\nconst CommandShortcut = ({\n class,\n ...props\n}: React.HTMLAttributes<HTMLSpanElement>) => {\n return (\n <span\n class={cn(\n \"ml-auto text-xs tracking-widest text-muted-foreground\",\n class\n )}\n {...props}\n />\n )\n}\nCommandShortcut.displayName = \"CommandShortcut\"\n\nexport {\n Command,\n CommandDialog,\n CommandInput,\n CommandList,\n CommandEmpty,\n CommandGroup,\n CommandItem,\n CommandShortcut,\n CommandSeparator,\n}\n"
"name": "Command.vue",
"content": "<script setup lang=\"ts\">\nimport type { ComboboxRootEmits, ComboboxRootProps } from 'radix-vue'\nimport { ComboboxRoot } from 'radix-vue'\nimport { cn, useEmitAsProps } from '@/lib/utils'\n\nconst props = defineProps<ComboboxRootProps>()\nconst emits = defineEmits<ComboboxRootEmits>()\n\nconst emitsAsProps = useEmitAsProps(emits)\n</script>\n\n<template>\n <ComboboxRoot\n v-bind=\"{ ...props, ...emitsAsProps }\"\n :open=\"true\"\n :model-value=\"''\"\n :class=\"cn('flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground', $attrs.class ?? '')\"\n >\n <slot />\n </ComboboxRoot>\n</template>\n"
},
{
"name": "CommandDialog.vue",
"content": "<script setup lang=\"ts\">\nimport type { DialogRootEmits, DialogRootProps } from 'radix-vue'\nimport Command from './Command.vue'\nimport { Dialog, DialogContent } from '@/lib/registry/default/ui/dialog'\nimport { useEmitAsProps } from '@/lib/utils'\n\nconst props = defineProps<DialogRootProps>()\nconst emits = defineEmits<DialogRootEmits>()\n\nconst emitsAsProps = useEmitAsProps(emits)\n</script>\n\n<template>\n <Dialog v-bind=\"{ ...props, ...emitsAsProps }\">\n <DialogContent class=\"overflow-hidden p-0 shadow-lg\">\n <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\">\n <slot />\n </Command>\n </DialogContent>\n </Dialog>\n</template>\n"
},
{
"name": "CommandEmpty.vue",
"content": "<script setup lang=\"ts\">\nimport type { ComboboxEmptyProps } from 'radix-vue'\nimport { ComboboxEmpty } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<ComboboxEmptyProps>()\n</script>\n\n<template>\n <ComboboxEmpty v-bind=\"props\" :class=\"cn('py-6 text-center text-sm', $attrs.class ?? '')\">\n <slot />\n </ComboboxEmpty>\n</template>\n"
},
{
"name": "CommandGroup.vue",
"content": "<script setup lang=\"ts\">\nimport type { ComboboxGroupProps } from 'radix-vue'\nimport { ComboboxGroup, ComboboxLabel } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<ComboboxGroupProps & {\n heading?: string\n}>()\n</script>\n\n<template>\n <ComboboxGroup\n v-bind=\"props\"\n :class=\"cn('overflow-hidden p-1 text-foreground', $attrs.class ?? '')\"\n >\n <ComboboxLabel v-if=\"heading\" class=\"px-2 py-1.5 text-xs font-medium text-muted-foreground\">\n {{ heading }}\n </ComboboxLabel>\n <slot />\n </ComboboxGroup>\n</template>\n"
},
{
"name": "CommandInput.vue",
"content": "<script setup lang=\"ts\">\nimport { Search } from 'lucide-vue-next'\nimport { ComboboxInput, type ComboboxInputProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<ComboboxInputProps>()\n</script>\n\n<script lang=\"ts\">\nexport default {\n inheritAttrs: false,\n}\n</script>\n\n<template>\n <div class=\"flex items-center border-b px-3\" cmdk-input-wrapper>\n <Search class=\"mr-2 h-4 w-4 shrink-0 opacity-50\" />\n <ComboboxInput\n v-bind=\"{ ...props, ...$attrs }\"\n auto-focus\n :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 ?? '')\"\n />\n </div>\n</template>\n"
},
{
"name": "CommandItem.vue",
"content": "<script setup lang=\"ts\">\nimport type { ComboboxItemEmits, ComboboxItemProps } from 'radix-vue'\nimport { ComboboxItem } from 'radix-vue'\nimport { cn, useEmitAsProps } from '@/lib/utils'\n\nconst props = defineProps<ComboboxItemProps>()\nconst emits = defineEmits<ComboboxItemEmits>()\n\nconst emitsAsProps = useEmitAsProps(emits)\n</script>\n\n<template>\n <ComboboxItem\n v-bind=\"{ ...props, ...emitsAsProps }\"\n :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 ?? '')\"\n >\n <slot />\n </ComboboxItem>\n</template>\n"
},
{
"name": "CommandList.vue",
"content": "<script setup lang=\"ts\">\nimport type { ComboboxContentEmits, ComboboxContentProps } from 'radix-vue'\nimport { ComboboxContent } from 'radix-vue'\nimport { cn, useEmitAsProps } from '@/lib/utils'\n\nconst props = defineProps<ComboboxContentProps>()\nconst emits = defineEmits<ComboboxContentEmits>()\n\nconst emitsAsProps = useEmitAsProps(emits)\n</script>\n\n<template>\n <ComboboxContent v-bind=\"{ ...props, ...emitsAsProps }\" :class=\"cn('max-h-[300px] overflow-y-auto overflow-x-hidden', $attrs.class ?? '')\">\n <slot />\n </ComboboxContent>\n</template>\n"
},
{
"name": "CommandSeparator.vue",
"content": "<script setup lang=\"ts\">\nimport type { ComboboxSeparatorProps } from 'radix-vue'\nimport { ComboboxSeparator } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<ComboboxSeparatorProps>()\n</script>\n\n<template>\n <ComboboxSeparator\n v-bind=\"props\"\n :class=\"cn('-mx-1 h-px bg-border', $attrs.class ?? '')\"\n >\n <slot />\n </ComboboxSeparator>\n</template>\n"
},
{
"name": "CommandShortcut.vue",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\n</script>\n\n<template>\n <span :class=\"cn('ml-auto text-xs tracking-widest text-muted-foreground', $attrs.class ?? '')\">\n <slot />\n </span>\n</template>\n"
},
{
"name": "index.ts",
"content": "export { default as Command } from './Command.vue'\nexport { default as CommandDialog } from './CommandDialog.vue'\nexport { default as CommandEmpty } from './CommandEmpty.vue'\nexport { default as CommandGroup } from './CommandGroup.vue'\nexport { default as CommandInput } from './CommandInput.vue'\nexport { default as CommandItem } from './CommandItem.vue'\nexport { default as CommandList } from './CommandList.vue'\nexport { default as CommandSeparator } from './CommandSeparator.vue'\nexport { default as CommandShortcut } from './CommandShortcut.vue'\n"
}
],
"type": "components:ui"

View File

@ -9,7 +9,7 @@
"files": [
{
"name": "Popover.vue",
"content": "<script setup lang=\"ts\">\nimport { PopoverRoot, type PopoverRootProps } from 'radix-vue'\n\nconst props = defineProps<PopoverRootProps>()\n</script>\n\n<template>\n <PopoverRoot v-bind=\"props\">\n <slot />\n </PopoverRoot>\n</template>\n"
"content": "<script setup lang=\"ts\">\nimport { PopoverRoot } from 'radix-vue'\nimport type { PopoverRootEmits, PopoverRootProps } from 'radix-vue'\nimport { useEmitAsProps } from '@/lib/utils'\n\nconst props = defineProps<PopoverRootProps>()\nconst emits = defineEmits<PopoverRootEmits>()\n\nconst emitsAsProps = useEmitAsProps(emits)\n</script>\n\n<template>\n <PopoverRoot v-bind=\"{ ...props, ...emitsAsProps }\">\n <slot />\n </PopoverRoot>\n</template>\n"
},
{
"name": "PopoverContent.vue",

View File

@ -9,7 +9,7 @@
"files": [
{
"name": "RadioGroup.vue",
"content": "<script setup lang=\"ts\">\nimport { RadioGroupRoot, type RadioGroupRootProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<RadioGroupRootProps & { class?: string }>()\n</script>\n\n<template>\n <RadioGroupRoot :class=\"cn('grid gap-2', props.class)\" v-bind=\"props\">\n <slot />\n </RadioGroupRoot>\n</template>\n"
"content": "<script setup lang=\"ts\">\nimport { RadioGroupRoot, type RadioGroupRootEmits, type RadioGroupRootProps } from 'radix-vue'\nimport { cn, useEmitAsProps } from '@/lib/utils'\n\nconst props = defineProps<RadioGroupRootProps & { class?: string }>()\n\nconst emits = defineEmits<RadioGroupRootEmits>()\n\nconst emitsAsProps = useEmitAsProps(emits)\n</script>\n\n<template>\n <RadioGroupRoot :class=\"cn('grid gap-2', props.class)\" v-bind=\"{ ...props, ...emitsAsProps }\">\n <slot />\n </RadioGroupRoot>\n</template>\n"
},
{
"name": "RadioGroupItem.vue",

File diff suppressed because one or more lines are too long

View File

@ -9,7 +9,7 @@
"files": [
{
"name": "Popover.vue",
"content": "<script setup lang=\"ts\">\nimport { PopoverRoot, type PopoverRootProps } from 'radix-vue'\n\nconst props = defineProps<PopoverRootProps>()\n</script>\n\n<template>\n <PopoverRoot v-bind=\"props\">\n <slot />\n </PopoverRoot>\n</template>\n"
"content": "<script setup lang=\"ts\">\nimport { PopoverRoot } from 'radix-vue'\nimport type { PopoverRootEmits, PopoverRootProps } from 'radix-vue'\nimport { useEmitAsProps } from '@/lib/utils'\n\nconst props = defineProps<PopoverRootProps>()\nconst emits = defineEmits<PopoverRootEmits>()\n\nconst emitsAsProps = useEmitAsProps(emits)\n</script>\n\n<template>\n <PopoverRoot v-bind=\"{ ...props, ...emitsAsProps }\">\n <slot />\n </PopoverRoot>\n</template>\n"
},
{
"name": "PopoverContent.vue",

View File

@ -9,7 +9,7 @@
"files": [
{
"name": "RadioGroup.vue",
"content": "<script setup lang=\"ts\">\nimport { RadioGroupRoot, type RadioGroupRootProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<RadioGroupRootProps & { class?: string }>()\n</script>\n\n<template>\n <RadioGroupRoot :class=\"cn('grid gap-2', props.class)\" v-bind=\"props\">\n <slot />\n </RadioGroupRoot>\n</template>\n"
"content": "<script setup lang=\"ts\">\nimport { RadioGroupRoot, type RadioGroupRootEmits, type RadioGroupRootProps } from 'radix-vue'\nimport { cn, useEmitAsProps } from '@/lib/utils'\n\nconst props = defineProps<RadioGroupRootProps & { class?: string }>()\n\nconst emits = defineEmits<RadioGroupRootEmits>()\n\nconst emitsAsProps = useEmitAsProps(emits)\n</script>\n\n<template>\n <RadioGroupRoot :class=\"cn('grid gap-2', props.class)\" v-bind=\"{ ...props, ...emitsAsProps }\">\n <slot />\n </RadioGroupRoot>\n</template>\n"
},
{
"name": "RadioGroupItem.vue",

View File

@ -13,7 +13,7 @@
},
{
"name": "SelectContent.vue",
"content": "<script setup lang=\"ts\">\nimport {\n SelectContent,\n type SelectContentEmits,\n type SelectContentProps,\n SelectPortal,\n SelectViewport,\n} from 'radix-vue'\nimport { cn, useEmitAsProps } from '@/lib/utils'\n\nconst props = withDefaults(\n defineProps<SelectContentProps & { class?: string }>(), {\n position: 'popper',\n sideOffset: 4,\n },\n)\nconst emits = defineEmits<SelectContentEmits>()\nconst emitsAsProps = useEmitAsProps(emits)\n</script>\n\n<template>\n <SelectPortal>\n <SelectContent\n v-bind=\"{ ...props, ...emitsAsProps, ...$attrs }\"\n :class=\"\n cn(\n 'relative z-50 min-w-[10rem] overflow-hidden rounded-md bg-background border border-border text-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',\n position === 'popper'\n && 'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',\n props.class,\n )\n \"\n >\n <SelectViewport\n :class=\"\n cn('p-1',\n position === 'popper'\n && 'h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]')\"\n >\n <slot />\n </SelectViewport>\n </SelectContent>\n </SelectPortal>\n</template>\n"
"content": "<script setup lang=\"ts\">\nimport {\n SelectContent,\n type SelectContentEmits,\n type SelectContentProps,\n SelectPortal,\n SelectViewport,\n} from 'radix-vue'\nimport { cn, useEmitAsProps } from '@/lib/utils'\n\nconst props = withDefaults(\n defineProps<SelectContentProps & { class?: string }>(), {\n position: 'popper',\n sideOffset: 4,\n },\n)\nconst emits = defineEmits<SelectContentEmits>()\nconst emitsAsProps = useEmitAsProps(emits)\n</script>\n\n<template>\n <SelectPortal>\n <SelectContent\n v-bind=\"{ ...props, ...emitsAsProps, ...$attrs }\"\n :class=\"\n cn(\n 'relative z-50 min-w-[10rem] overflow-hidden rounded-md bg-background border border-border text-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',\n position === 'popper'\n && 'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',\n props.class,\n )\n \"\n >\n <SelectViewport\n :class=\"\n cn('p-0',\n position === 'popper'\n && 'h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]')\"\n >\n <slot />\n </SelectViewport>\n </SelectContent>\n </SelectPortal>\n</template>\n"
},
{
"name": "SelectGroup.vue",
@ -37,7 +37,7 @@
},
{
"name": "SelectTrigger.vue",
"content": "<script setup lang=\"ts\">\nimport { SelectIcon, SelectTrigger, type SelectTriggerProps } from 'radix-vue'\nimport RadixIconsChevronDown from '~icons/radix-icons/chevron-down'\nimport { cn } from '@/lib/utils'\n\nconst props = withDefaults(\n defineProps<SelectTriggerProps & { class?: string; invalid?: boolean }>(),\n {\n class: '',\n invalid: false,\n },\n)\n</script>\n\n<template>\n <SelectTrigger\n v-bind=\"props\"\n :class=\"[\n cn(\n 'flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',\n props.class,\n ),\n props.invalid\n ? '!ring-destructive ring-2 placeholder:!text-destructive'\n : '',\n ]\"\n >\n <slot />\n <SelectIcon as-child>\n <RadixIconsChevronDown class=\"w-4 h-4 opacity-50\" />\n </SelectIcon>\n </SelectTrigger>\n</template>\n"
"content": "<script setup lang=\"ts\">\nimport { SelectIcon, SelectTrigger, type SelectTriggerProps } from 'radix-vue'\nimport RadixIconsChevronDown from '~icons/radix-icons/chevron-down'\nimport { cn } from '@/lib/utils'\n\nconst props = withDefaults(\n defineProps<SelectTriggerProps & { class?: string; invalid?: boolean }>(),\n {\n class: '',\n invalid: false,\n },\n)\n</script>\n\n<template>\n <SelectTrigger\n v-bind=\"props\"\n :class=\"[\n cn(\n 'flex h-9 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',\n props.class,\n ),\n props.invalid\n ? '!ring-destructive ring-2 placeholder:!text-destructive'\n : '',\n ]\"\n >\n <slot />\n <SelectIcon as-child>\n <RadixIconsChevronDown class=\"w-4 h-4 opacity-50\" />\n </SelectIcon>\n </SelectTrigger>\n</template>\n"
},
{
"name": "SelectValue.vue",

View File

@ -1,7 +1,7 @@
{
"name": "shadcn-vue",
"private": true,
"packageManager": "pnpm@8.6.3",
"packageManager": "pnpm@8.7.5",
"license": "MIT",
"repository": "radix-vue/shadcn-vue",
"workspaces": [
@ -19,18 +19,21 @@
"build:registry": "pnpm --filter=www build:registry",
"pub:beta": "cd packages/cli && pnpm pub:beta",
"pub:release": "cd packages/cli && pnpm pub:release",
"test": "pnpm --filter shadcn-vue test"
"test": "pnpm --filter shadcn-vue test",
"taze": "taze major -frI --ignore-paths ./packages/cli/test/** --exclude typescript,/@iconify/",
"taze:minor": "taze minor -fwri --ignore-paths ./packages/cli/test/** --exclude /@iconify/"
},
"devDependencies": {
"@antfu/eslint-config": "^0.39.7",
"@antfu/eslint-config": "^0.41.3",
"@commitlint/cli": "^17.7.1",
"@commitlint/config-conventional": "^17.7.0",
"eslint": "^8.43.0",
"lint-staged": "^14.0.0",
"pnpm": "^8.6.12",
"eslint": "^8.49.0",
"lint-staged": "^14.0.1",
"pnpm": "^8.7.5",
"simple-git-hooks": "^2.9.0",
"taze": "^0.11.2",
"typescript": "^5.2.2",
"vitest": "^0.34.3"
"vitest": "^0.34.4"
},
"commitlint": {
"extends": [

View File

@ -1,7 +1,7 @@
{
"name": "shadcn-vue",
"type": "module",
"version": "0.1.2",
"version": "0.1.3",
"description": "Add components to your apps.",
"publishConfig": {
"access": "public"
@ -45,16 +45,17 @@
"test:ui": "vitest --ui"
},
"dependencies": {
"@antfu/ni": "^0.21.6",
"@babel/parser": "^7.22.11",
"@babel/plugin-transform-typescript": "^7.22.11",
"@antfu/ni": "^0.21.8",
"@babel/core": "^7.22.17",
"@babel/parser": "^7.22.16",
"@babel/plugin-transform-typescript": "^7.22.15",
"chalk": "5.3.0",
"commander": "^11.0.0",
"cosmiconfig": "^8.2.0",
"cosmiconfig": "^8.3.6",
"diff": "^5.1.0",
"execa": "^8.0.1",
"fs-extra": "^11.1.1",
"https-proxy-agent": "^7.0.1",
"https-proxy-agent": "^7.0.2",
"lodash.template": "^4.5.0",
"magic-string": "^0.30.3",
"node-fetch": "^3.3.2",
@ -65,7 +66,7 @@
"rimraf": "^5.0.1",
"ts-morph": "^19.0.0",
"tsconfig-paths": "^4.2.0",
"vite-tsconfig-paths": "^4.2.0",
"vite-tsconfig-paths": "^4.2.1",
"zod": "^3.22.2"
},
"devDependencies": {
@ -75,10 +76,10 @@
"@types/fs-extra": "^11.0.1",
"@types/lodash.template": "^4.5.1",
"@types/prompts": "^2.4.4",
"@vitest/ui": "^0.34.3",
"@vitest/ui": "^0.34.4",
"detype": "^0.6.3",
"tsup": "^7.2.0",
"type-fest": "^4.3.0",
"type-fest": "^4.3.1",
"typescript": "^5.2.2"
}
}

View File

@ -13,7 +13,7 @@ export interface TransformOpts {
export function transformImport(content: string, config: Config) {
const s = new MagicString(content)
s.replaceAll(/@\/registry\/[^/]+/g, config.aliases.components)
s.replaceAll(/\$lib\/utils/g, config.aliases.utils)
s.replaceAll(/@\/lib\/utils/g, config.aliases.utils)
return s.toString()
}

View File

@ -1,7 +1,7 @@
{
"name": "test-cli-config-full",
"version": "1.0.0",
"main": "index.js",
"author": "shadcn",
"license": "MIT"
"license": "MIT",
"main": "index.js"
}

View File

@ -1,7 +1,7 @@
{
"name": "test-cli-config-invalid",
"version": "1.0.0",
"main": "index.js",
"author": "shadcn",
"license": "MIT"
"license": "MIT",
"main": "index.js"
}

View File

@ -1,7 +1,7 @@
{
"name": "test-cli-config-partial",
"version": "1.0.0",
"main": "index.js",
"author": "shadcn",
"license": "MIT"
"license": "MIT",
"main": "index.js"
}

View File

@ -1,7 +1,7 @@
{
"name": "test-cli-config-none",
"version": "1.0.0",
"main": "index.js",
"author": "shadcn",
"license": "MIT"
"license": "MIT",
"main": "index.js"
}

View File

@ -1,7 +1,7 @@
{
"name": "test-cli-config-partial",
"version": "1.0.0",
"main": "index.js",
"author": "shadcn",
"license": "MIT"
"license": "MIT",
"main": "index.js"
}

View File

@ -1,7 +1,7 @@
{
"name": "test-cli-project-bun",
"version": "1.0.0",
"main": "index.js",
"author": "shadcn",
"license": "MIT"
"license": "MIT",
"main": "index.js"
}

View File

@ -1,7 +1,7 @@
{
"name": "test-cli-project-npm",
"version": "1.0.0",
"main": "index.js",
"author": "shadcn",
"license": "MIT"
"license": "MIT",
"main": "index.js"
}

View File

@ -1,7 +1,7 @@
{
"name": "test-cli-project-pnpm",
"version": "1.0.0",
"main": "index.js",
"author": "shadcn",
"license": "MIT"
"license": "MIT",
"main": "index.js"
}

View File

@ -1,7 +1,7 @@
{
"name": "test-cli-project-yarn",
"version": "1.0.0",
"main": "index.js",
"author": "shadcn",
"license": "MIT"
"license": "MIT",
"main": "index.js"
}

File diff suppressed because it is too large Load Diff