docs: adding remaining usages of drawer (#380)
This commit is contained in:
parent
3ec55ada1b
commit
75cf9c40c4
54
apps/www/.vitepress/theme/components/InlineThemePicker.vue
Normal file
54
apps/www/.vitepress/theme/components/InlineThemePicker.vue
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { Color } from '../types/colors'
|
||||||
|
import { useConfigStore } from '@/stores/config'
|
||||||
|
import { colors } from '@/lib/registry'
|
||||||
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/lib/registry/new-york/ui/tooltip'
|
||||||
|
import RadixIconsCheck from '~icons/radix-icons/check'
|
||||||
|
|
||||||
|
defineProps<{
|
||||||
|
allColors: Color[]
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const { theme, setTheme } = useConfigStore()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<TooltipProvider
|
||||||
|
v-for="(color, index) in allColors.slice(0, 5)"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger as-child>
|
||||||
|
<button
|
||||||
|
:key="index"
|
||||||
|
class="flex h-9 w-9 items-center justify-center rounded-full border-2 border-border text-xs"
|
||||||
|
:class="
|
||||||
|
color === theme
|
||||||
|
? 'border-primary'
|
||||||
|
: 'border-transparent'
|
||||||
|
"
|
||||||
|
@click="setTheme(color)"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="flex h-6 w-6 items-center justify-center rounded-full"
|
||||||
|
:style="{ backgroundColor: colors[color][6].rgb }"
|
||||||
|
>
|
||||||
|
<RadixIconsCheck
|
||||||
|
v-if="color === theme"
|
||||||
|
class="h-4 w-4 text-white"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent
|
||||||
|
align="center"
|
||||||
|
:side-offset="1"
|
||||||
|
class="capitalize bg-zinc-900 text-zinc-50"
|
||||||
|
>
|
||||||
|
{{ allColors[index] }}
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
106
apps/www/.vitepress/theme/components/ThemeCustomizer.vue
Normal file
106
apps/www/.vitepress/theme/components/ThemeCustomizer.vue
Normal file
|
|
@ -0,0 +1,106 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { useData } from 'vitepress'
|
||||||
|
import type { Color } from '../types/colors'
|
||||||
|
import { RADII, useConfigStore } from '@/stores/config'
|
||||||
|
import { Button } from '@/lib/registry/new-york/ui/button'
|
||||||
|
import { Label } from '@/lib/registry/new-york/ui/label'
|
||||||
|
import { colors } from '@/lib/registry'
|
||||||
|
import RadixIconsCheck from '~icons/radix-icons/check'
|
||||||
|
import RadixIconsSun from '~icons/radix-icons/sun'
|
||||||
|
import RadixIconsMoon from '~icons/radix-icons/moon'
|
||||||
|
|
||||||
|
defineProps<{
|
||||||
|
allColors: Color[]
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const { theme, radius, setRadius, setTheme } = useConfigStore()
|
||||||
|
const { isDark } = useData()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="p-4">
|
||||||
|
<div class="grid space-y-1">
|
||||||
|
<h1 class="text-md text-foreground font-semibold">
|
||||||
|
Customize
|
||||||
|
</h1>
|
||||||
|
<p class="text-xs text-muted-foreground">
|
||||||
|
Pick a style and color for your components.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="space-y-1.5 pt-6">
|
||||||
|
<Label for="color" class="text-xs"> Color </Label>
|
||||||
|
<div class="grid grid-cols-3 gap-2 py-1.5">
|
||||||
|
<Button
|
||||||
|
v-for="(color, index) in allColors"
|
||||||
|
:key="index"
|
||||||
|
variant="outline"
|
||||||
|
class="h-8 justify-start px-3"
|
||||||
|
:class="
|
||||||
|
color === theme
|
||||||
|
? 'border-foreground border-2'
|
||||||
|
: ''
|
||||||
|
"
|
||||||
|
@click="setTheme(color)"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="h-5 w-5 rounded-full flex items-center justify-center"
|
||||||
|
:style="{ backgroundColor: colors[color][7].rgb }"
|
||||||
|
>
|
||||||
|
<RadixIconsCheck
|
||||||
|
v-if="color === theme"
|
||||||
|
class="h-3 w-3 text-white"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
<span class="ml-2 text-xs capitalize">
|
||||||
|
{{ color }}
|
||||||
|
</span>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="space-y-1.5 pt-6">
|
||||||
|
<Label for="radius" class="text-xs"> Radius </Label>
|
||||||
|
<div class="grid grid-cols-5 gap-2 py-1.5">
|
||||||
|
<Button
|
||||||
|
v-for="(r, index) in RADII"
|
||||||
|
:key="index"
|
||||||
|
variant="outline"
|
||||||
|
class="h-8 justify-center px-3"
|
||||||
|
:class="
|
||||||
|
r === radius
|
||||||
|
? 'border-foreground border-2'
|
||||||
|
: ''
|
||||||
|
"
|
||||||
|
@click="setRadius(r)"
|
||||||
|
>
|
||||||
|
<span class="text-xs">
|
||||||
|
{{ r }}
|
||||||
|
</span>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="space-y-1.5 pt-6">
|
||||||
|
<Label for="theme" class="text-xs"> Theme </Label>
|
||||||
|
|
||||||
|
<div class="flex space-x-2 py-1.5">
|
||||||
|
<Button
|
||||||
|
class="h-8"
|
||||||
|
variant="outline"
|
||||||
|
:class="{ 'border-2 border-foreground': !isDark }"
|
||||||
|
@click="isDark = false"
|
||||||
|
>
|
||||||
|
<RadixIconsSun class="w-4 h-4 mr-2" />
|
||||||
|
<span class="text-xs">Light</span>
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
class="h-8"
|
||||||
|
variant="outline"
|
||||||
|
:class="{ 'border-2 border-foreground': isDark }"
|
||||||
|
@click="isDark = true"
|
||||||
|
>
|
||||||
|
<RadixIconsMoon class="w-4 h-4 mr-2" />
|
||||||
|
<span class="text-xs">Dark</span>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
@ -1,35 +1,19 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, watch } from 'vue'
|
import { onMounted, watch } from 'vue'
|
||||||
import { Paintbrush } from 'lucide-vue-next'
|
import { Paintbrush } from 'lucide-vue-next'
|
||||||
import { useData } from 'vitepress'
|
|
||||||
import PageHeader from '../components/PageHeader.vue'
|
import PageHeader from '../components/PageHeader.vue'
|
||||||
import PageHeaderHeading from '../components/PageHeaderHeading.vue'
|
import PageHeaderHeading from '../components/PageHeaderHeading.vue'
|
||||||
import PageHeaderDescription from '../components/PageHeaderDescription.vue'
|
import PageHeaderDescription from '../components/PageHeaderDescription.vue'
|
||||||
import CustomizerCode from '../components/CustomizerCode.vue'
|
import CustomizerCode from '../components/CustomizerCode.vue'
|
||||||
import { RADII, useConfigStore } from '@/stores/config'
|
import type { Color } from '../types/colors'
|
||||||
import { colors } from '@/lib/registry'
|
import ThemeCustomizer from '../components/ThemeCustomizer.vue'
|
||||||
|
import InlineThemePicker from '../components/InlineThemePicker.vue'
|
||||||
|
import PageAction from '../components/PageAction.vue'
|
||||||
|
import { useConfigStore } from '@/stores/config'
|
||||||
import { Button } from '@/lib/registry/new-york/ui/button'
|
import { Button } from '@/lib/registry/new-york/ui/button'
|
||||||
import { Label } from '@/lib/registry/new-york/ui/label'
|
|
||||||
import { Popover, PopoverContent, PopoverTrigger } from '@/lib/registry/new-york/ui/popover'
|
import { Popover, PopoverContent, PopoverTrigger } from '@/lib/registry/new-york/ui/popover'
|
||||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/lib/registry/new-york/ui/tooltip'
|
|
||||||
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from '@/lib/registry/new-york/ui/dialog'
|
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from '@/lib/registry/new-york/ui/dialog'
|
||||||
import RadixIconsCheck from '~icons/radix-icons/check'
|
import { Drawer, DrawerContent, DrawerTrigger } from '@/lib/registry/new-york/ui/drawer'
|
||||||
import RadixIconsSun from '~icons/radix-icons/sun'
|
|
||||||
import RadixIconsMoon from '~icons/radix-icons/moon'
|
|
||||||
|
|
||||||
type Color =
|
|
||||||
| 'zinc'
|
|
||||||
| 'slate'
|
|
||||||
| 'stone'
|
|
||||||
| 'gray'
|
|
||||||
| 'neutral'
|
|
||||||
| 'red'
|
|
||||||
| 'rose'
|
|
||||||
| 'orange'
|
|
||||||
| 'green'
|
|
||||||
| 'blue'
|
|
||||||
| 'yellow'
|
|
||||||
| 'violet'
|
|
||||||
|
|
||||||
// Create an array of color values
|
// Create an array of color values
|
||||||
const allColors: Color[] = [
|
const allColors: Color[] = [
|
||||||
|
|
@ -47,8 +31,7 @@ const allColors: Color[] = [
|
||||||
'violet',
|
'violet',
|
||||||
]
|
]
|
||||||
|
|
||||||
const { theme, radius, setRadius, setTheme } = useConfigStore()
|
const { theme, radius } = useConfigStore()
|
||||||
const { isDark } = useData()
|
|
||||||
|
|
||||||
// Whenever the component is mounted, update the document class list
|
// Whenever the component is mounted, update the document class list
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|
@ -72,173 +55,63 @@ watch(radius, (radius) => {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="container relative">
|
<div class="container relative">
|
||||||
<div class="flex justify-between items-center">
|
<PageHeader>
|
||||||
<div>
|
<PageHeaderHeading class="hidden md:block">
|
||||||
<PageHeader class="page-header pb-8">
|
Add colors. Make it yours.
|
||||||
<PageHeaderHeading class="hidden md:block">
|
</PageHeaderHeading>
|
||||||
Make it yours.
|
<PageHeaderHeading class="md:hidden">
|
||||||
</PageHeaderHeading>
|
Make it yours
|
||||||
<PageHeaderDescription>
|
</PageHeaderHeading>
|
||||||
Hand-picked themes that you can copy and paste into your apps.
|
<PageHeaderDescription>
|
||||||
</PageHeaderDescription>
|
Hand-picked themes that you can copy and paste into your apps.
|
||||||
</PageHeader>
|
</PageHeaderDescription>
|
||||||
</div>
|
|
||||||
<div class="px-4 pb-8 md:ml-auto md:pb-0">
|
<PageAction>
|
||||||
<div class="flex items-center space-x-2">
|
<InlineThemePicker class="gap-x-1 me-4 hidden lg:flex" :all-colors="allColors" />
|
||||||
<div class="hidden md:flex">
|
|
||||||
<div class="mr-4 hidden items-center space-x-1 lg:flex">
|
<Drawer>
|
||||||
<TooltipProvider
|
<DrawerTrigger as-child>
|
||||||
v-for="(color, index) in allColors.slice(0, 5)"
|
<Button variant="outline" class="md:hidden h-9 rounded-[0.5rem]">
|
||||||
:key="index"
|
<Paintbrush class="w-4 h-4 mr-2" />
|
||||||
>
|
Customize
|
||||||
<Tooltip>
|
</Button>
|
||||||
<TooltipTrigger as-child>
|
</DrawerTrigger>
|
||||||
<button
|
<DrawerContent class="p-6 pt-0">
|
||||||
:key="index"
|
<ThemeCustomizer :all-colors="allColors" />
|
||||||
class="flex h-9 w-9 items-center justify-center rounded-full border-2 border-border text-xs"
|
</DrawerContent>
|
||||||
:class="
|
</Drawer>
|
||||||
color === theme
|
|
||||||
? 'border-primary'
|
<Popover>
|
||||||
: 'border-transparent'
|
<PopoverTrigger as-child>
|
||||||
"
|
<Button variant="outline" class="hidden md:flex h-9 rounded-[0.5rem]">
|
||||||
@click="setTheme(color)"
|
<Paintbrush class="w-4 h-4 mr-2" />
|
||||||
>
|
Customize
|
||||||
<span
|
</Button>
|
||||||
class="flex h-6 w-6 items-center justify-center rounded-full"
|
</PopoverTrigger>
|
||||||
:style="{ backgroundColor: colors[color][6].rgb }"
|
<PopoverContent :side-offset="8" align="end" class="w-96">
|
||||||
>
|
<ThemeCustomizer :all-colors="allColors" />
|
||||||
<RadixIconsCheck
|
</PopoverContent>
|
||||||
v-if="color === theme"
|
</Popover>
|
||||||
class="h-4 w-4 text-white"
|
|
||||||
/>
|
<Dialog>
|
||||||
</span>
|
<DialogTrigger as-child>
|
||||||
</button>
|
<Button class="h-9 ml-2 rounded-[0.5rem]">
|
||||||
</TooltipTrigger>
|
Copy code
|
||||||
<TooltipContent
|
</Button>
|
||||||
align="center"
|
</DialogTrigger>
|
||||||
:side-offset="1"
|
<DialogContent class="sm:max-w-[625px]">
|
||||||
class="capitalize bg-zinc-900 text-zinc-50"
|
<DialogHeader>
|
||||||
>
|
<DialogTitle>Theme</DialogTitle>
|
||||||
{{ allColors[index] }}
|
<DialogDescription>
|
||||||
</TooltipContent>
|
Copy and paste the following code into your CSS file.
|
||||||
</Tooltip>
|
</DialogDescription>
|
||||||
</TooltipProvider>
|
</DialogHeader>
|
||||||
</div>
|
<CustomizerCode />
|
||||||
<Popover>
|
</DialogContent>
|
||||||
<PopoverTrigger as-child>
|
</Dialog>
|
||||||
<Button variant="outline" class="h-9 rounded-[0.5rem]">
|
</PageAction>
|
||||||
<Paintbrush class="w-4 h-4 mr-2" />
|
</PageHeader>
|
||||||
Customize
|
|
||||||
</Button>
|
|
||||||
</PopoverTrigger>
|
|
||||||
<PopoverContent :side-offset="8" align="end" class="w-96">
|
|
||||||
<div class="p-4">
|
|
||||||
<div class="grid space-y-1">
|
|
||||||
<h1 class="text-md text-foreground font-semibold">
|
|
||||||
Customize
|
|
||||||
</h1>
|
|
||||||
<p class="text-xs text-muted-foreground">
|
|
||||||
Pick a style and color for your components.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="space-y-1.5 pt-6">
|
|
||||||
<Label for="color" class="text-xs"> Color </Label>
|
|
||||||
<div class="grid grid-cols-3 gap-2 py-1.5">
|
|
||||||
<Button
|
|
||||||
v-for="(color, index) in allColors"
|
|
||||||
:key="index"
|
|
||||||
variant="outline"
|
|
||||||
class="h-8 justify-start px-3"
|
|
||||||
:class="
|
|
||||||
color === theme
|
|
||||||
? 'border-foreground border-2'
|
|
||||||
: ''
|
|
||||||
"
|
|
||||||
@click="setTheme(color)"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="h-5 w-5 rounded-full flex items-center justify-center"
|
|
||||||
:style="{ backgroundColor: colors[color][7].rgb }"
|
|
||||||
>
|
|
||||||
<RadixIconsCheck
|
|
||||||
v-if="color === theme"
|
|
||||||
class="h-3 w-3 text-white"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
<span class="ml-2 text-xs capitalize">
|
|
||||||
{{ color }}
|
|
||||||
</span>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="space-y-1.5 pt-6">
|
|
||||||
<Label for="radius" class="text-xs"> Radius </Label>
|
|
||||||
<div class="grid grid-cols-5 gap-2 py-1.5">
|
|
||||||
<Button
|
|
||||||
v-for="(r, index) in RADII"
|
|
||||||
:key="index"
|
|
||||||
variant="outline"
|
|
||||||
class="h-8 justify-center px-3"
|
|
||||||
:class="
|
|
||||||
r === radius
|
|
||||||
? 'border-foreground border-2'
|
|
||||||
: ''
|
|
||||||
"
|
|
||||||
@click="setRadius(r)"
|
|
||||||
>
|
|
||||||
<span class="text-xs">
|
|
||||||
{{ r }}
|
|
||||||
</span>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="space-y-1.5 pt-6">
|
|
||||||
<Label for="theme" class="text-xs"> Theme </Label>
|
|
||||||
|
|
||||||
<div class="flex space-x-2 py-1.5">
|
|
||||||
<Button
|
|
||||||
class="h-8"
|
|
||||||
variant="outline"
|
|
||||||
:class="{ 'border-2 border-foreground': !isDark }"
|
|
||||||
@click="isDark = false"
|
|
||||||
>
|
|
||||||
<RadixIconsSun class="w-4 h-4 mr-2" />
|
|
||||||
<span class="text-xs">Light</span>
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
class="h-8"
|
|
||||||
variant="outline"
|
|
||||||
:class="{ 'border-2 border-foreground': isDark }"
|
|
||||||
@click="isDark = true"
|
|
||||||
>
|
|
||||||
<RadixIconsMoon class="w-4 h-4 mr-2" />
|
|
||||||
<span class="text-xs">Dark</span>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</PopoverContent>
|
|
||||||
</Popover>
|
|
||||||
<Dialog>
|
|
||||||
<DialogTrigger as-child>
|
|
||||||
<Button class="h-9 ml-2 rounded-[0.5rem]">
|
|
||||||
Copy code
|
|
||||||
</Button>
|
|
||||||
</DialogTrigger>
|
|
||||||
<DialogContent class="sm:max-w-[625px]">
|
|
||||||
<DialogHeader>
|
|
||||||
<DialogTitle>Theme</DialogTitle>
|
|
||||||
<DialogDescription>
|
|
||||||
Copy and paste the following code into your CSS file.
|
|
||||||
</DialogDescription>
|
|
||||||
</DialogHeader>
|
|
||||||
<CustomizerCode />
|
|
||||||
</DialogContent>
|
|
||||||
</Dialog>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<section>
|
<section>
|
||||||
<slot />
|
<slot />
|
||||||
</section>
|
</section>
|
||||||
|
|
|
||||||
13
apps/www/.vitepress/theme/types/colors.ts
Normal file
13
apps/www/.vitepress/theme/types/colors.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
export type Color =
|
||||||
|
| 'zinc'
|
||||||
|
| 'slate'
|
||||||
|
| 'stone'
|
||||||
|
| 'gray'
|
||||||
|
| 'neutral'
|
||||||
|
| 'red'
|
||||||
|
| 'rose'
|
||||||
|
| 'orange'
|
||||||
|
| 'green'
|
||||||
|
| 'blue'
|
||||||
|
| 'yellow'
|
||||||
|
| 'violet'
|
||||||
|
|
@ -4,7 +4,7 @@ import { dependencies as deps } from '../../../package.json'
|
||||||
import { Index as demoIndex } from '../../../../www/__registry__'
|
import { Index as demoIndex } from '../../../../www/__registry__'
|
||||||
import tailwindConfigRaw from '../../../tailwind.config?raw'
|
import tailwindConfigRaw from '../../../tailwind.config?raw'
|
||||||
import cssRaw from '../../../../../packages/cli/test/fixtures/nuxt/assets/css/tailwind.css?raw'
|
import cssRaw from '../../../../../packages/cli/test/fixtures/nuxt/assets/css/tailwind.css?raw'
|
||||||
import { type Style } from '@/lib/registry/styles'
|
import type { Style } from '@/lib/registry/styles'
|
||||||
|
|
||||||
export function makeCodeSandboxParams(componentName: string, style: Style, sources: Record<string, string>) {
|
export function makeCodeSandboxParams(componentName: string, style: Style, sources: Record<string, string>) {
|
||||||
let files: Record<string, any> = {}
|
let files: Record<string, any> = {}
|
||||||
|
|
@ -54,7 +54,7 @@ export default defineConfig({
|
||||||
<title>Vite + Vue + TS</title>
|
<title>Vite + Vue + TS</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div vaul-drawer-wrapper id="app"></div>
|
||||||
<script type="module" src="/src/main.ts"></script>
|
<script type="module" src="/src/main.ts"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
@ -90,6 +90,9 @@ function constructFiles(componentName: string, style: Style, sources: Record<str
|
||||||
[iconPackage]: 'latest',
|
[iconPackage]: 'latest',
|
||||||
'shadcn-vue': 'latest',
|
'shadcn-vue': 'latest',
|
||||||
'typescript': 'latest',
|
'typescript': 'latest',
|
||||||
|
'vaul-vue': 'latest',
|
||||||
|
'@unovis/vue': 'latest',
|
||||||
|
'@unovis/ts': 'latest',
|
||||||
}
|
}
|
||||||
|
|
||||||
const devDependencies = {
|
const devDependencies = {
|
||||||
|
|
|
||||||
|
|
@ -297,6 +297,13 @@ export const Index = {
|
||||||
component: () => import("../src/lib/registry/default/example/ComboboxPopover.vue").then((m) => m.default),
|
component: () => import("../src/lib/registry/default/example/ComboboxPopover.vue").then((m) => m.default),
|
||||||
files: ["../src/lib/registry/default/example/ComboboxPopover.vue"],
|
files: ["../src/lib/registry/default/example/ComboboxPopover.vue"],
|
||||||
},
|
},
|
||||||
|
"ComboboxResponsive": {
|
||||||
|
name: "ComboboxResponsive",
|
||||||
|
type: "components:example",
|
||||||
|
registryDependencies: ["button","command","drawer","popover"],
|
||||||
|
component: () => import("../src/lib/registry/default/example/ComboboxResponsive.vue").then((m) => m.default),
|
||||||
|
files: ["../src/lib/registry/default/example/ComboboxResponsive.vue"],
|
||||||
|
},
|
||||||
"CommandDemo": {
|
"CommandDemo": {
|
||||||
name: "CommandDemo",
|
name: "CommandDemo",
|
||||||
type: "components:example",
|
type: "components:example",
|
||||||
|
|
@ -1278,6 +1285,13 @@ export const Index = {
|
||||||
component: () => import("../src/lib/registry/new-york/example/ComboboxPopover.vue").then((m) => m.default),
|
component: () => import("../src/lib/registry/new-york/example/ComboboxPopover.vue").then((m) => m.default),
|
||||||
files: ["../src/lib/registry/new-york/example/ComboboxPopover.vue"],
|
files: ["../src/lib/registry/new-york/example/ComboboxPopover.vue"],
|
||||||
},
|
},
|
||||||
|
"ComboboxResponsive": {
|
||||||
|
name: "ComboboxResponsive",
|
||||||
|
type: "components:example",
|
||||||
|
registryDependencies: ["button","command","drawer","popover"],
|
||||||
|
component: () => import("../src/lib/registry/new-york/example/ComboboxResponsive.vue").then((m) => m.default),
|
||||||
|
files: ["../src/lib/registry/new-york/example/ComboboxResponsive.vue"],
|
||||||
|
},
|
||||||
"CommandDemo": {
|
"CommandDemo": {
|
||||||
name: "CommandDemo",
|
name: "CommandDemo",
|
||||||
type: "components:example",
|
type: "components:example",
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
---
|
---
|
||||||
title: Combobox
|
title: Combobox
|
||||||
description: Autocomplete input and command palette with a list of suggestions.
|
description: Autocomplete input and command palette with a list of suggestions.
|
||||||
---
|
---
|
||||||
|
|
||||||
<ComponentPreview name="ComboboxDemo" />
|
<ComponentPreview name="ComboboxDemo" />
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
<Callout title="Note" class="bg-destructive">
|
<Callout title="Note" class="bg-destructive">
|
||||||
|
|
@ -11,14 +11,13 @@ description: Autocomplete input and command palette with a list of suggestions.
|
||||||
[Radix Vue](https://github.com/radix-vue/radix-vue/releases/tag/v1.2.0) introduced a breaking change. You will need to wrap `ComboboxGroup` and `ComboboxItem` inside of `ComboboxList` now.
|
[Radix Vue](https://github.com/radix-vue/radix-vue/releases/tag/v1.2.0) introduced a breaking change. You will need to wrap `ComboboxGroup` and `ComboboxItem` inside of `ComboboxList` now.
|
||||||
|
|
||||||
</Callout>
|
</Callout>
|
||||||
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
The Combobox is built using a composition of the `<Popover />` and the `<Command />` components.
|
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.
|
See installation instructions for the [Popover](/docs/components/popover#installation) and the [Command](/docs/components/command#installation) components.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
```vue
|
```vue
|
||||||
|
|
@ -110,6 +109,12 @@ const value = ref({})
|
||||||
|
|
||||||
<ComponentPreview name="ComboboxDropdownMenu" />
|
<ComponentPreview name="ComboboxDropdownMenu" />
|
||||||
|
|
||||||
|
### Responsive
|
||||||
|
|
||||||
|
You can create a responsive combobox by using the `<Popover />` on desktop and the `<Drawer />` components on mobile.
|
||||||
|
|
||||||
|
<ComponentPreview name="ComboboxResponsive" />
|
||||||
|
|
||||||
### Form
|
### Form
|
||||||
|
|
||||||
<ComponentPreview name="ComboboxForm" />
|
<ComponentPreview name="ComboboxForm" />
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,94 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { createReusableTemplate, useMediaQuery } from '@vueuse/core'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { Button } from '@/lib/registry/default/ui/button'
|
||||||
|
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/lib/registry/default/ui/command'
|
||||||
|
import { Drawer, DrawerContent, DrawerTrigger } from '@/lib/registry/default/ui/drawer'
|
||||||
|
import { Popover, PopoverContent, PopoverTrigger } from '@/lib/registry/default/ui/popover'
|
||||||
|
|
||||||
|
interface Status {
|
||||||
|
value: string
|
||||||
|
label: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const statuses: Status[] = [
|
||||||
|
{
|
||||||
|
value: 'backlog',
|
||||||
|
label: 'Backlog',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'todo',
|
||||||
|
label: 'Todo',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'in progress',
|
||||||
|
label: 'In Progress',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'done',
|
||||||
|
label: 'Done',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'canceled',
|
||||||
|
label: 'Canceled',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
const [UseTemplate, StatusList] = createReusableTemplate()
|
||||||
|
const isDesktop = useMediaQuery('(min-width: 768px)')
|
||||||
|
|
||||||
|
const isOpen = ref(false)
|
||||||
|
const selectedStatus = ref<Status | null>(null)
|
||||||
|
|
||||||
|
function onStatusSelect(status: Status) {
|
||||||
|
selectedStatus.value = status
|
||||||
|
isOpen.value = false
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<UseTemplate>
|
||||||
|
<Command>
|
||||||
|
<CommandInput placeholder="Filter status..." />
|
||||||
|
<CommandList>
|
||||||
|
<CommandEmpty>No results found.</CommandEmpty>
|
||||||
|
<CommandGroup>
|
||||||
|
<CommandItem
|
||||||
|
v-for="status of statuses"
|
||||||
|
:key="status.value"
|
||||||
|
:value="status.value"
|
||||||
|
@select="onStatusSelect(status)"
|
||||||
|
>
|
||||||
|
{{ status.label }}
|
||||||
|
</CommandItem>
|
||||||
|
</CommandGroup>
|
||||||
|
</CommandList>
|
||||||
|
</Command>
|
||||||
|
</UseTemplate>
|
||||||
|
|
||||||
|
<Popover v-if="isDesktop" v-model:open="isOpen">
|
||||||
|
<PopoverTrigger as-child>
|
||||||
|
<Button variant="outline" class="w-[150px] justify-start">
|
||||||
|
{{ selectedStatus ? selectedStatus.label : "+ Set status" }}
|
||||||
|
</Button>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent class="w-[200px] p-0" align="start">
|
||||||
|
<StatusList />
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
|
|
||||||
|
<Drawer v-else :open="isOpen" @update:open="(newOpenValue) => isOpen = newOpenValue">
|
||||||
|
<DrawerTrigger as-child>
|
||||||
|
<Button variant="outline" class="w-[150px] justify-start">
|
||||||
|
{{ selectedStatus ? selectedStatus.label : "+ Set status" }}
|
||||||
|
</Button>
|
||||||
|
</DrawerTrigger>
|
||||||
|
<DrawerContent>
|
||||||
|
<div class="mt-4 border-t">
|
||||||
|
<StatusList />
|
||||||
|
</div>
|
||||||
|
</DrawerContent>
|
||||||
|
</Drawer>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,94 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { createReusableTemplate, useMediaQuery } from '@vueuse/core'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { Button } from '@/lib/registry/new-york/ui/button'
|
||||||
|
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/lib/registry/new-york/ui/command'
|
||||||
|
import { Drawer, DrawerContent, DrawerTrigger } from '@/lib/registry/new-york/ui/drawer'
|
||||||
|
import { Popover, PopoverContent, PopoverTrigger } from '@/lib/registry/new-york/ui/popover'
|
||||||
|
|
||||||
|
interface Status {
|
||||||
|
value: string
|
||||||
|
label: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const statuses: Status[] = [
|
||||||
|
{
|
||||||
|
value: 'backlog',
|
||||||
|
label: 'Backlog',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'todo',
|
||||||
|
label: 'Todo',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'in progress',
|
||||||
|
label: 'In Progress',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'done',
|
||||||
|
label: 'Done',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'canceled',
|
||||||
|
label: 'Canceled',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
const [UseTemplate, StatusList] = createReusableTemplate()
|
||||||
|
const isDesktop = useMediaQuery('(min-width: 768px)')
|
||||||
|
|
||||||
|
const isOpen = ref(false)
|
||||||
|
const selectedStatus = ref<Status | null>(null)
|
||||||
|
|
||||||
|
function onStatusSelect(status: Status) {
|
||||||
|
selectedStatus.value = status
|
||||||
|
isOpen.value = false
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<UseTemplate>
|
||||||
|
<Command>
|
||||||
|
<CommandInput placeholder="Filter status..." />
|
||||||
|
<CommandList>
|
||||||
|
<CommandEmpty>No results found.</CommandEmpty>
|
||||||
|
<CommandGroup>
|
||||||
|
<CommandItem
|
||||||
|
v-for="status of statuses"
|
||||||
|
:key="status.value"
|
||||||
|
:value="status.value"
|
||||||
|
@select="onStatusSelect(status)"
|
||||||
|
>
|
||||||
|
{{ status.label }}
|
||||||
|
</CommandItem>
|
||||||
|
</CommandGroup>
|
||||||
|
</CommandList>
|
||||||
|
</Command>
|
||||||
|
</UseTemplate>
|
||||||
|
|
||||||
|
<Popover v-if="isDesktop" v-model:open="isOpen">
|
||||||
|
<PopoverTrigger as-child>
|
||||||
|
<Button variant="outline" class="w-[150px] justify-start">
|
||||||
|
{{ selectedStatus ? selectedStatus.label : "+ Set status" }}
|
||||||
|
</Button>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent class="w-[200px] p-0" align="start">
|
||||||
|
<StatusList />
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
|
|
||||||
|
<Drawer v-else v-model:open="isOpen">
|
||||||
|
<DrawerTrigger as-child>
|
||||||
|
<Button variant="outline" class="w-[150px] justify-start">
|
||||||
|
{{ selectedStatus ? selectedStatus.label : "+ Set status" }}
|
||||||
|
</Button>
|
||||||
|
</DrawerTrigger>
|
||||||
|
<DrawerContent>
|
||||||
|
<div class="mt-4 border-t">
|
||||||
|
<StatusList />
|
||||||
|
</div>
|
||||||
|
</DrawerContent>
|
||||||
|
</Drawer>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
Loading…
Reference in New Issue
Block a user