feat: add combobox, commands (#52)

* feat: add combobox, commands

* chore: add new label
This commit is contained in:
zernonia 2023-09-15 16:18:38 +08:00 committed by GitHub
parent 7abf5b29ef
commit 7dcc589a1d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 787 additions and 19 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

@ -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

@ -39,7 +39,7 @@
"@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",

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

@ -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 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

@ -115,8 +115,8 @@ importers:
specifier: ^4.5.0
version: 4.5.0
radix-vue:
specifier: ^0.1.34
version: 0.1.34(vue@3.3.4)
specifier: ^0.2.2
version: 0.2.2(vue@3.3.4)
rimraf:
specifier: ^5.0.1
version: 5.0.1
@ -6393,8 +6393,8 @@ packages:
- vue
dev: false
/radix-vue@0.1.33(vue@3.3.4):
resolution: {integrity: sha512-2nwcjrXNXML//iOxUeqyh2bBXQtQt3Xy1NqM2oHZJTNNEaL2QnMjlSN51DXMzx3QB2uex2IwqA1cFTHbJ34tyw==}
/radix-vue@0.2.2(vue@3.3.4):
resolution: {integrity: sha512-eW1VpctGY1JPafNHzlelxt/7dx340PZgj078bLsdMQDqq9lfN7tKHaj+pSyH7tdT3OtFsxKAmO65rnlaTAUqAg==}
dependencies:
'@floating-ui/dom': 1.5.1
'@floating-ui/vue': 1.0.2(vue@3.3.4)