feat: vaul-vue integration (#374)
This commit is contained in:
parent
0265b48b35
commit
64e2f9c199
|
|
@ -214,6 +214,12 @@ export const docsConfig: DocsConfig = {
|
||||||
href: '/docs/components/dialog',
|
href: '/docs/components/dialog',
|
||||||
items: [],
|
items: [],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: 'Drawer',
|
||||||
|
href: '/docs/components/drawer',
|
||||||
|
items: [],
|
||||||
|
label: 'New',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: 'Dropdown Menu',
|
title: 'Dropdown Menu',
|
||||||
href: '/docs/components/dropdown-menu',
|
href: '/docs/components/dropdown-menu',
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ watch(() => $route.path, (n) => {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="flex min-h-screen flex-col bg-background">
|
<div vaul-drawer-wrapper class="flex min-h-screen flex-col bg-background">
|
||||||
<header class="sticky z-40 top-0 bg-background/80 backdrop-blur-lg border-b border-border">
|
<header class="sticky z-40 top-0 bg-background/80 backdrop-blur-lg border-b border-border">
|
||||||
<div
|
<div
|
||||||
class="container flex justify-between h-14 max-w-screen-2xl items-center"
|
class="container flex justify-between h-14 max-w-screen-2xl items-center"
|
||||||
|
|
|
||||||
|
|
@ -402,6 +402,20 @@ export const Index = {
|
||||||
component: () => import("../src/lib/registry/default/example/DialogScrollOverlayDemo.vue").then((m) => m.default),
|
component: () => import("../src/lib/registry/default/example/DialogScrollOverlayDemo.vue").then((m) => m.default),
|
||||||
files: ["../src/lib/registry/default/example/DialogScrollOverlayDemo.vue"],
|
files: ["../src/lib/registry/default/example/DialogScrollOverlayDemo.vue"],
|
||||||
},
|
},
|
||||||
|
"DrawerDemo": {
|
||||||
|
name: "DrawerDemo",
|
||||||
|
type: "components:example",
|
||||||
|
registryDependencies: ["button","drawer"],
|
||||||
|
component: () => import("../src/lib/registry/default/example/DrawerDemo.vue").then((m) => m.default),
|
||||||
|
files: ["../src/lib/registry/default/example/DrawerDemo.vue"],
|
||||||
|
},
|
||||||
|
"DrawerDialog": {
|
||||||
|
name: "DrawerDialog",
|
||||||
|
type: "components:example",
|
||||||
|
registryDependencies: ["button","dialog","drawer","label","input"],
|
||||||
|
component: () => import("../src/lib/registry/default/example/DrawerDialog.vue").then((m) => m.default),
|
||||||
|
files: ["../src/lib/registry/default/example/DrawerDialog.vue"],
|
||||||
|
},
|
||||||
"DropdownMenuDemo": {
|
"DropdownMenuDemo": {
|
||||||
name: "DropdownMenuDemo",
|
name: "DropdownMenuDemo",
|
||||||
type: "components:example",
|
type: "components:example",
|
||||||
|
|
@ -1355,6 +1369,20 @@ export const Index = {
|
||||||
component: () => import("../src/lib/registry/new-york/example/DialogScrollOverlayDemo.vue").then((m) => m.default),
|
component: () => import("../src/lib/registry/new-york/example/DialogScrollOverlayDemo.vue").then((m) => m.default),
|
||||||
files: ["../src/lib/registry/new-york/example/DialogScrollOverlayDemo.vue"],
|
files: ["../src/lib/registry/new-york/example/DialogScrollOverlayDemo.vue"],
|
||||||
},
|
},
|
||||||
|
"DrawerDemo": {
|
||||||
|
name: "DrawerDemo",
|
||||||
|
type: "components:example",
|
||||||
|
registryDependencies: ["button","drawer"],
|
||||||
|
component: () => import("../src/lib/registry/new-york/example/DrawerDemo.vue").then((m) => m.default),
|
||||||
|
files: ["../src/lib/registry/new-york/example/DrawerDemo.vue"],
|
||||||
|
},
|
||||||
|
"DrawerDialog": {
|
||||||
|
name: "DrawerDialog",
|
||||||
|
type: "components:example",
|
||||||
|
registryDependencies: ["button","dialog","drawer","label","input"],
|
||||||
|
component: () => import("../src/lib/registry/new-york/example/DrawerDialog.vue").then((m) => m.default),
|
||||||
|
files: ["../src/lib/registry/new-york/example/DrawerDialog.vue"],
|
||||||
|
},
|
||||||
"DropdownMenuDemo": {
|
"DropdownMenuDemo": {
|
||||||
name: "DropdownMenuDemo",
|
name: "DropdownMenuDemo",
|
||||||
type: "components:example",
|
type: "components:example",
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@
|
||||||
"radix-vue": "^1.4.9",
|
"radix-vue": "^1.4.9",
|
||||||
"tailwindcss-animate": "^1.0.7",
|
"tailwindcss-animate": "^1.0.7",
|
||||||
"v-calendar": "^3.1.2",
|
"v-calendar": "^3.1.2",
|
||||||
|
"vaul-vue": "^0.1.0",
|
||||||
"vee-validate": "4.12.5",
|
"vee-validate": "4.12.5",
|
||||||
"vue": "^3.4.21",
|
"vue": "^3.4.21",
|
||||||
"vue-sonner": "^1.1.1",
|
"vue-sonner": "^1.1.1",
|
||||||
|
|
|
||||||
63
apps/www/src/content/docs/components/drawer.md
Normal file
63
apps/www/src/content/docs/components/drawer.md
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
---
|
||||||
|
title: Drawer
|
||||||
|
description: A drawer component for vue.
|
||||||
|
source: apps/www/src/lib/registry/default/ui/drawer
|
||||||
|
primitive: https://github.com/radix-vue/vaul-vue
|
||||||
|
---
|
||||||
|
|
||||||
|
<ComponentPreview name="DrawerDemo" />
|
||||||
|
|
||||||
|
## About
|
||||||
|
|
||||||
|
Drawer is built on top of [Vaul Vue](https://github.com/radix-vue/vaul-vue).
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx shadcn-vue@latest add drawer
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```vue showLineNumbers
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {
|
||||||
|
Drawer,
|
||||||
|
DrawerClose,
|
||||||
|
DrawerContent,
|
||||||
|
DrawerDescription,
|
||||||
|
DrawerFooter,
|
||||||
|
DrawerHeader,
|
||||||
|
DrawerTitle,
|
||||||
|
DrawerTrigger,
|
||||||
|
} from '@/components/ui/drawer'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Drawer>
|
||||||
|
<DrawerTrigger>Open</DrawerTrigger>
|
||||||
|
<DrawerContent>
|
||||||
|
<DrawerHeader>
|
||||||
|
<DrawerTitle>Are you absolutely sure?</DrawerTitle>
|
||||||
|
<DrawerDescription>This action cannot be undone.</DrawerDescription>
|
||||||
|
</DrawerHeader>
|
||||||
|
<DrawerFooter>
|
||||||
|
<Button>Submit</Button>
|
||||||
|
<DrawerClose>
|
||||||
|
<Button variant="outline">
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
</DrawerClose>
|
||||||
|
</DrawerFooter>
|
||||||
|
</DrawerContent>
|
||||||
|
</Drawer>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Responsive Dialog
|
||||||
|
|
||||||
|
You can combine the `Dialog` and `Drawer` components to create a responsive dialog. This renders a `Dialog` component on desktop and a `Drawer` on mobile.
|
||||||
|
|
||||||
|
<ComponentPreview name="DrawerDialog" />
|
||||||
111
apps/www/src/lib/registry/default/example/DrawerDemo.vue
Normal file
111
apps/www/src/lib/registry/default/example/DrawerDemo.vue
Normal file
|
|
@ -0,0 +1,111 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { Minus, Plus } from 'lucide-vue-next'
|
||||||
|
import { VisStackedBar, VisXYContainer } from '@unovis/vue'
|
||||||
|
import { Button } from '@/lib/registry/default/ui/button'
|
||||||
|
import {
|
||||||
|
Drawer,
|
||||||
|
DrawerClose,
|
||||||
|
DrawerContent,
|
||||||
|
DrawerDescription,
|
||||||
|
DrawerFooter,
|
||||||
|
DrawerHeader,
|
||||||
|
DrawerTitle,
|
||||||
|
DrawerTrigger,
|
||||||
|
} from '@/lib/registry/default/ui/drawer'
|
||||||
|
|
||||||
|
const goal = ref(350)
|
||||||
|
|
||||||
|
type Data = typeof data[number]
|
||||||
|
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>
|
||||||
|
<Drawer>
|
||||||
|
<DrawerTrigger as-child>
|
||||||
|
<Button variant="outline">
|
||||||
|
Open Drawer
|
||||||
|
</Button>
|
||||||
|
</DrawerTrigger>
|
||||||
|
<DrawerContent>
|
||||||
|
<div class="mx-auto w-full max-w-sm">
|
||||||
|
<DrawerHeader>
|
||||||
|
<DrawerTitle>Move Goal</DrawerTitle>
|
||||||
|
<DrawerDescription>Set your daily activity goal.</DrawerDescription>
|
||||||
|
</DrawerHeader>
|
||||||
|
<div class="p-4 pb-0">
|
||||||
|
<div class="flex items-center justify-center space-x-2">
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="icon"
|
||||||
|
class="h-8 w-8 shrink-0 rounded-full"
|
||||||
|
:disabled="goal <= 200"
|
||||||
|
@click="goal -= 10"
|
||||||
|
>
|
||||||
|
<Minus class="h-4 w-4" />
|
||||||
|
<span class="sr-only">Decrease</span>
|
||||||
|
</Button>
|
||||||
|
<div class="flex-1 text-center">
|
||||||
|
<div class="text-7xl font-bold tracking-tighter">
|
||||||
|
{{ goal }}
|
||||||
|
</div>
|
||||||
|
<div class="text-[0.70rem] uppercase text-muted-foreground">
|
||||||
|
Calories/day
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="icon"
|
||||||
|
class="h-8 w-8 shrink-0 rounded-full"
|
||||||
|
:disabled="goal >= 400"
|
||||||
|
@click="goal += 10"
|
||||||
|
>
|
||||||
|
<Plus class="h-4 w-4" />
|
||||||
|
<span class="sr-only">Increase</span>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div class="my-3 px-3 h-[120px]">
|
||||||
|
<VisXYContainer
|
||||||
|
:data="data"
|
||||||
|
class="h-[120px]"
|
||||||
|
:style="{
|
||||||
|
'opacity': 0.9,
|
||||||
|
'--theme-primary': `hsl(var(--foreground))`,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<VisStackedBar
|
||||||
|
:x="(d: Data, i :number) => i"
|
||||||
|
:y="(d: Data) => d.goal"
|
||||||
|
color="var(--theme-primary)"
|
||||||
|
:bar-padding="0.1"
|
||||||
|
:rounded-corners="0"
|
||||||
|
/>
|
||||||
|
</VisXYContainer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<DrawerFooter>
|
||||||
|
<Button>Submit</Button>
|
||||||
|
<DrawerClose as-child>
|
||||||
|
<Button variant="outline">
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
</DrawerClose>
|
||||||
|
</DrawerFooter>
|
||||||
|
</div>
|
||||||
|
</DrawerContent>
|
||||||
|
</Drawer>
|
||||||
|
</template>
|
||||||
90
apps/www/src/lib/registry/default/example/DrawerDialog.vue
Normal file
90
apps/www/src/lib/registry/default/example/DrawerDialog.vue
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { createReusableTemplate, useMediaQuery } from '@vueuse/core'
|
||||||
|
import { Button } from '@/lib/registry/default/ui/button'
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogDescription,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger,
|
||||||
|
} from '@/lib/registry/default/ui/dialog'
|
||||||
|
import {
|
||||||
|
Drawer,
|
||||||
|
DrawerClose,
|
||||||
|
DrawerContent,
|
||||||
|
DrawerDescription,
|
||||||
|
DrawerFooter,
|
||||||
|
DrawerHeader,
|
||||||
|
DrawerTitle,
|
||||||
|
DrawerTrigger,
|
||||||
|
} from '@/lib/registry/default/ui/drawer'
|
||||||
|
import { Label } from '@/lib/registry/default/ui/label'
|
||||||
|
import { Input } from '@/lib/registry/default/ui/input'
|
||||||
|
|
||||||
|
// Reuse `form` section
|
||||||
|
const [UseTemplate, GridForm] = createReusableTemplate()
|
||||||
|
const isDesktop = useMediaQuery('(min-width: 768px)')
|
||||||
|
|
||||||
|
const isOpen = ref(false)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<UseTemplate>
|
||||||
|
<form class="grid items-start gap-4 px-4">
|
||||||
|
<div class="grid gap-2">
|
||||||
|
<Label html-for="email">Email</Label>
|
||||||
|
<Input id="email" type="email" default-value="shadcn@example.com" />
|
||||||
|
</div>
|
||||||
|
<div class="grid gap-2">
|
||||||
|
<Label html-for="username">Username</Label>
|
||||||
|
<Input id="username" default-value="@shadcn" />
|
||||||
|
</div>
|
||||||
|
<Button type="submit">
|
||||||
|
Save changes
|
||||||
|
</Button>
|
||||||
|
</form>
|
||||||
|
</UseTemplate>
|
||||||
|
|
||||||
|
<Dialog v-if="isDesktop" v-model:open="isOpen">
|
||||||
|
<DialogTrigger as-child>
|
||||||
|
<Button variant="outline">
|
||||||
|
Edit Profile
|
||||||
|
</Button>
|
||||||
|
</DialogTrigger>
|
||||||
|
<DialogContent class="sm:max-w-[425px]">
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>Edit profile</DialogTitle>
|
||||||
|
<DialogDescription>
|
||||||
|
Make changes to your profile here. Click save when you're done.
|
||||||
|
</DialogDescription>
|
||||||
|
</DialogHeader>
|
||||||
|
<GridForm />
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
|
||||||
|
<Drawer v-else v-model:open="isOpen">
|
||||||
|
<DrawerTrigger as-child>
|
||||||
|
<Button variant="outline">
|
||||||
|
Edit Profile
|
||||||
|
</Button>
|
||||||
|
</DrawerTrigger>
|
||||||
|
<DrawerContent>
|
||||||
|
<DrawerHeader class="text-left">
|
||||||
|
<DrawerTitle>Edit profile</DrawerTitle>
|
||||||
|
<DrawerDescription>
|
||||||
|
Make changes to your profile here. Click save when you're done.
|
||||||
|
</DrawerDescription>
|
||||||
|
</DrawerHeader>
|
||||||
|
<GridForm />
|
||||||
|
<DrawerFooter class="pt-2">
|
||||||
|
<DrawerClose as-child>
|
||||||
|
<Button variant="outline">
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
</DrawerClose>
|
||||||
|
</DrawerFooter>
|
||||||
|
</DrawerContent>
|
||||||
|
</Drawer>
|
||||||
|
</template>
|
||||||
19
apps/www/src/lib/registry/default/ui/drawer/Drawer.vue
Normal file
19
apps/www/src/lib/registry/default/ui/drawer/Drawer.vue
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { DrawerRootEmits, DrawerRootProps } from 'vaul-vue'
|
||||||
|
import { DrawerRoot } from 'vaul-vue'
|
||||||
|
import { useForwardPropsEmits } from 'radix-vue'
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<DrawerRootProps>(), {
|
||||||
|
shouldScaleBackground: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
const emits = defineEmits<DrawerRootEmits>()
|
||||||
|
|
||||||
|
const forwarded = useForwardPropsEmits(props, emits)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<DrawerRoot v-bind="forwarded">
|
||||||
|
<slot />
|
||||||
|
</DrawerRoot>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { DrawerContent, DrawerPortal } from 'vaul-vue'
|
||||||
|
import type { DialogContentEmits, DialogContentProps } from 'radix-vue'
|
||||||
|
import { useForwardPropsEmits } from 'radix-vue'
|
||||||
|
import type { HtmlHTMLAttributes } from 'vue'
|
||||||
|
import DrawerOverlay from './DrawerOverlay.vue'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
|
const props = defineProps<DialogContentProps & { class?: HtmlHTMLAttributes['class'] }>()
|
||||||
|
const emits = defineEmits<DialogContentEmits>()
|
||||||
|
|
||||||
|
const forwarded = useForwardPropsEmits(props, emits)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<DrawerPortal>
|
||||||
|
<DrawerOverlay />
|
||||||
|
<DrawerContent
|
||||||
|
v-bind="forwarded" :class="cn(
|
||||||
|
'fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border bg-background',
|
||||||
|
props.class,
|
||||||
|
)"
|
||||||
|
>
|
||||||
|
<div class="mx-auto mt-4 h-2 w-[100px] rounded-full bg-muted" />
|
||||||
|
<slot />
|
||||||
|
</DrawerContent>
|
||||||
|
</DrawerPortal>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { DrawerDescriptionProps } from 'vaul-vue'
|
||||||
|
import { DrawerDescription } from 'vaul-vue'
|
||||||
|
import { type HtmlHTMLAttributes, computed } from 'vue'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
|
const props = defineProps<DrawerDescriptionProps & { class?: HtmlHTMLAttributes['class'] }>()
|
||||||
|
|
||||||
|
const delegatedProps = computed(() => {
|
||||||
|
const { class: _, ...delegated } = props
|
||||||
|
|
||||||
|
return delegated
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<DrawerDescription v-bind="delegatedProps" :class="cn('text-sm text-muted-foreground', props.class)">
|
||||||
|
<slot />
|
||||||
|
</DrawerDescription>
|
||||||
|
</template>
|
||||||
14
apps/www/src/lib/registry/default/ui/drawer/DrawerFooter.vue
Normal file
14
apps/www/src/lib/registry/default/ui/drawer/DrawerFooter.vue
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { HtmlHTMLAttributes } from 'vue'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
class?: HtmlHTMLAttributes['class']
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div :class="cn('mt-auto flex flex-col gap-2 p-4', props.class)">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
14
apps/www/src/lib/registry/default/ui/drawer/DrawerHeader.vue
Normal file
14
apps/www/src/lib/registry/default/ui/drawer/DrawerHeader.vue
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { HtmlHTMLAttributes } from 'vue'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
class?: HtmlHTMLAttributes['class']
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div :class="cn('grid gap-1.5 p-4 text-center sm:text-left', props.class)">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { DrawerOverlay } from 'vaul-vue'
|
||||||
|
import type { DialogOverlayProps } from 'radix-vue'
|
||||||
|
import { type HtmlHTMLAttributes, computed } from 'vue'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
|
const props = defineProps<DialogOverlayProps & { class?: HtmlHTMLAttributes['class'] }>()
|
||||||
|
|
||||||
|
const delegatedProps = computed(() => {
|
||||||
|
const { class: _, ...delegated } = props
|
||||||
|
|
||||||
|
return delegated
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<DrawerOverlay v-bind="delegatedProps" :class="cn('fixed inset-0 z-50 bg-black/80', props.class)" />
|
||||||
|
</template>
|
||||||
20
apps/www/src/lib/registry/default/ui/drawer/DrawerTitle.vue
Normal file
20
apps/www/src/lib/registry/default/ui/drawer/DrawerTitle.vue
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { DrawerTitleProps } from 'vaul-vue'
|
||||||
|
import { DrawerTitle } from 'vaul-vue'
|
||||||
|
import { type HtmlHTMLAttributes, computed } from 'vue'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
|
const props = defineProps<DrawerTitleProps & { class?: HtmlHTMLAttributes['class'] }>()
|
||||||
|
|
||||||
|
const delegatedProps = computed(() => {
|
||||||
|
const { class: _, ...delegated } = props
|
||||||
|
|
||||||
|
return delegated
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<DrawerTitle v-bind="delegatedProps" :class="cn('text-lg font-semibold leading-none tracking-tight', props.class)">
|
||||||
|
<slot />
|
||||||
|
</DrawerTitle>
|
||||||
|
</template>
|
||||||
8
apps/www/src/lib/registry/default/ui/drawer/index.ts
Normal file
8
apps/www/src/lib/registry/default/ui/drawer/index.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
export { DrawerPortal, DrawerTrigger, DrawerClose } from 'vaul-vue'
|
||||||
|
export { default as Drawer } from './Drawer.vue'
|
||||||
|
export { default as DrawerOverlay } from './DrawerOverlay.vue'
|
||||||
|
export { default as DrawerContent } from './DrawerContent.vue'
|
||||||
|
export { default as DrawerHeader } from './DrawerHeader.vue'
|
||||||
|
export { default as DrawerFooter } from './DrawerFooter.vue'
|
||||||
|
export { default as DrawerTitle } from './DrawerTitle.vue'
|
||||||
|
export { default as DrawerDescription } from './DrawerDescription.vue'
|
||||||
111
apps/www/src/lib/registry/new-york/example/DrawerDemo.vue
Normal file
111
apps/www/src/lib/registry/new-york/example/DrawerDemo.vue
Normal file
|
|
@ -0,0 +1,111 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { Minus, Plus } from 'lucide-vue-next'
|
||||||
|
import { VisStackedBar, VisXYContainer } from '@unovis/vue'
|
||||||
|
import { Button } from '@/lib/registry/default/ui/button'
|
||||||
|
import {
|
||||||
|
Drawer,
|
||||||
|
DrawerClose,
|
||||||
|
DrawerContent,
|
||||||
|
DrawerDescription,
|
||||||
|
DrawerFooter,
|
||||||
|
DrawerHeader,
|
||||||
|
DrawerTitle,
|
||||||
|
DrawerTrigger,
|
||||||
|
} from '@/lib/registry/default/ui/drawer'
|
||||||
|
|
||||||
|
const goal = ref(350)
|
||||||
|
|
||||||
|
type Data = typeof data[number]
|
||||||
|
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>
|
||||||
|
<Drawer>
|
||||||
|
<DrawerTrigger as-child>
|
||||||
|
<Button variant="outline">
|
||||||
|
Open Drawer
|
||||||
|
</Button>
|
||||||
|
</DrawerTrigger>
|
||||||
|
<DrawerContent>
|
||||||
|
<div class="mx-auto w-full max-w-sm">
|
||||||
|
<DrawerHeader>
|
||||||
|
<DrawerTitle>Move Goal</DrawerTitle>
|
||||||
|
<DrawerDescription>Set your daily activity goal.</DrawerDescription>
|
||||||
|
</DrawerHeader>
|
||||||
|
<div class="p-4 pb-0">
|
||||||
|
<div class="flex items-center justify-center space-x-2">
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="icon"
|
||||||
|
class="h-8 w-8 shrink-0 rounded-full"
|
||||||
|
:disabled="goal <= 200"
|
||||||
|
@click="goal -= 10"
|
||||||
|
>
|
||||||
|
<Minus class="h-4 w-4" />
|
||||||
|
<span class="sr-only">Decrease</span>
|
||||||
|
</Button>
|
||||||
|
<div class="flex-1 text-center">
|
||||||
|
<div class="text-7xl font-bold tracking-tighter">
|
||||||
|
{{ goal }}
|
||||||
|
</div>
|
||||||
|
<div class="text-[0.70rem] uppercase text-muted-foreground">
|
||||||
|
Calories/day
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="icon"
|
||||||
|
class="h-8 w-8 shrink-0 rounded-full"
|
||||||
|
:disabled="goal >= 400"
|
||||||
|
@click="goal += 10"
|
||||||
|
>
|
||||||
|
<Plus class="h-4 w-4" />
|
||||||
|
<span class="sr-only">Increase</span>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div class="my-3 px-3 h-[120px]">
|
||||||
|
<VisXYContainer
|
||||||
|
:data="data"
|
||||||
|
class="h-[120px]"
|
||||||
|
:style="{
|
||||||
|
'opacity': 0.9,
|
||||||
|
'--theme-primary': `hsl(var(--foreground))`,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<VisStackedBar
|
||||||
|
:x="(d: Data, i :number) => i"
|
||||||
|
:y="(d: Data) => d.goal"
|
||||||
|
color="var(--theme-primary)"
|
||||||
|
:bar-padding="0.1"
|
||||||
|
:rounded-corners="0"
|
||||||
|
/>
|
||||||
|
</VisXYContainer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<DrawerFooter>
|
||||||
|
<Button>Submit</Button>
|
||||||
|
<DrawerClose as-child>
|
||||||
|
<Button variant="outline">
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
</DrawerClose>
|
||||||
|
</DrawerFooter>
|
||||||
|
</div>
|
||||||
|
</DrawerContent>
|
||||||
|
</Drawer>
|
||||||
|
</template>
|
||||||
90
apps/www/src/lib/registry/new-york/example/DrawerDialog.vue
Normal file
90
apps/www/src/lib/registry/new-york/example/DrawerDialog.vue
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { createReusableTemplate, useMediaQuery } from '@vueuse/core'
|
||||||
|
import { Button } from '@/lib/registry/default/ui/button'
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogDescription,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger,
|
||||||
|
} from '@/lib/registry/default/ui/dialog'
|
||||||
|
import {
|
||||||
|
Drawer,
|
||||||
|
DrawerClose,
|
||||||
|
DrawerContent,
|
||||||
|
DrawerDescription,
|
||||||
|
DrawerFooter,
|
||||||
|
DrawerHeader,
|
||||||
|
DrawerTitle,
|
||||||
|
DrawerTrigger,
|
||||||
|
} from '@/lib/registry/default/ui/drawer'
|
||||||
|
import { Label } from '@/lib/registry/default/ui/label'
|
||||||
|
import { Input } from '@/lib/registry/default/ui/input'
|
||||||
|
|
||||||
|
// Reuse `form` section
|
||||||
|
const [UseTemplate, GridForm] = createReusableTemplate()
|
||||||
|
const isDesktop = useMediaQuery('(min-width: 768px)')
|
||||||
|
|
||||||
|
const isOpen = ref(false)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<UseTemplate>
|
||||||
|
<form class="grid items-start gap-4 px-4">
|
||||||
|
<div class="grid gap-2">
|
||||||
|
<Label html-for="email">Email</Label>
|
||||||
|
<Input id="email" type="email" default-value="shadcn@example.com" />
|
||||||
|
</div>
|
||||||
|
<div class="grid gap-2">
|
||||||
|
<Label html-for="username">Username</Label>
|
||||||
|
<Input id="username" default-value="@shadcn" />
|
||||||
|
</div>
|
||||||
|
<Button type="submit">
|
||||||
|
Save changes
|
||||||
|
</Button>
|
||||||
|
</form>
|
||||||
|
</UseTemplate>
|
||||||
|
|
||||||
|
<Dialog v-if="isDesktop" v-model:open="isOpen">
|
||||||
|
<DialogTrigger as-child>
|
||||||
|
<Button variant="outline">
|
||||||
|
Edit Profile
|
||||||
|
</Button>
|
||||||
|
</DialogTrigger>
|
||||||
|
<DialogContent class="sm:max-w-[425px]">
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>Edit profile</DialogTitle>
|
||||||
|
<DialogDescription>
|
||||||
|
Make changes to your profile here. Click save when you're done.
|
||||||
|
</DialogDescription>
|
||||||
|
</DialogHeader>
|
||||||
|
<GridForm />
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
|
||||||
|
<Drawer v-else v-model:open="isOpen">
|
||||||
|
<DrawerTrigger as-child>
|
||||||
|
<Button variant="outline">
|
||||||
|
Edit Profile
|
||||||
|
</Button>
|
||||||
|
</DrawerTrigger>
|
||||||
|
<DrawerContent>
|
||||||
|
<DrawerHeader class="text-left">
|
||||||
|
<DrawerTitle>Edit profile</DrawerTitle>
|
||||||
|
<DrawerDescription>
|
||||||
|
Make changes to your profile here. Click save when you're done.
|
||||||
|
</DrawerDescription>
|
||||||
|
</DrawerHeader>
|
||||||
|
<GridForm />
|
||||||
|
<DrawerFooter class="pt-2">
|
||||||
|
<DrawerClose as-child>
|
||||||
|
<Button variant="outline">
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
</DrawerClose>
|
||||||
|
</DrawerFooter>
|
||||||
|
</DrawerContent>
|
||||||
|
</Drawer>
|
||||||
|
</template>
|
||||||
19
apps/www/src/lib/registry/new-york/ui/drawer/Drawer.vue
Normal file
19
apps/www/src/lib/registry/new-york/ui/drawer/Drawer.vue
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { DrawerRootEmits, DrawerRootProps } from 'vaul-vue'
|
||||||
|
import { DrawerRoot } from 'vaul-vue'
|
||||||
|
import { useForwardPropsEmits } from 'radix-vue'
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<DrawerRootProps>(), {
|
||||||
|
shouldScaleBackground: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
const emits = defineEmits<DrawerRootEmits>()
|
||||||
|
|
||||||
|
const forwarded = useForwardPropsEmits(props, emits)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<DrawerRoot v-bind="forwarded">
|
||||||
|
<slot />
|
||||||
|
</DrawerRoot>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { DrawerContent, DrawerPortal } from 'vaul-vue'
|
||||||
|
import type { DialogContentEmits, DialogContentProps } from 'radix-vue'
|
||||||
|
import { useForwardPropsEmits } from 'radix-vue'
|
||||||
|
import type { HtmlHTMLAttributes } from 'vue'
|
||||||
|
import DrawerOverlay from './DrawerOverlay.vue'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
|
const props = defineProps<DialogContentProps & { class?: HtmlHTMLAttributes['class'] }>()
|
||||||
|
const emits = defineEmits<DialogContentEmits>()
|
||||||
|
|
||||||
|
const forwarded = useForwardPropsEmits(props, emits)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<DrawerPortal>
|
||||||
|
<DrawerOverlay />
|
||||||
|
<DrawerContent
|
||||||
|
v-bind="forwarded" :class="cn(
|
||||||
|
'fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border bg-background',
|
||||||
|
props.class,
|
||||||
|
)"
|
||||||
|
>
|
||||||
|
<div class="mx-auto mt-4 h-2 w-[100px] rounded-full bg-muted" />
|
||||||
|
<slot />
|
||||||
|
</DrawerContent>
|
||||||
|
</DrawerPortal>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { DrawerDescriptionProps } from 'vaul-vue'
|
||||||
|
import { DrawerDescription } from 'vaul-vue'
|
||||||
|
import { type HtmlHTMLAttributes, computed } from 'vue'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
|
const props = defineProps<DrawerDescriptionProps & { class?: HtmlHTMLAttributes['class'] }>()
|
||||||
|
|
||||||
|
const delegatedProps = computed(() => {
|
||||||
|
const { class: _, ...delegated } = props
|
||||||
|
|
||||||
|
return delegated
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<DrawerDescription v-bind="delegatedProps" :class="cn('text-sm text-muted-foreground', props.class)">
|
||||||
|
<slot />
|
||||||
|
</DrawerDescription>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { HtmlHTMLAttributes } from 'vue'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
class?: HtmlHTMLAttributes['class']
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div :class="cn('mt-auto flex flex-col gap-2 p-4', props.class)">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { HtmlHTMLAttributes } from 'vue'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
class?: HtmlHTMLAttributes['class']
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div :class="cn('grid gap-1.5 p-4 text-center sm:text-left', props.class)">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { DrawerOverlay } from 'vaul-vue'
|
||||||
|
import type { DialogOverlayProps } from 'radix-vue'
|
||||||
|
import { type HtmlHTMLAttributes, computed } from 'vue'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
|
const props = defineProps<DialogOverlayProps & { class?: HtmlHTMLAttributes['class'] }>()
|
||||||
|
|
||||||
|
const delegatedProps = computed(() => {
|
||||||
|
const { class: _, ...delegated } = props
|
||||||
|
|
||||||
|
return delegated
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<DrawerOverlay v-bind="delegatedProps" :class="cn('fixed inset-0 z-50 bg-black/80', props.class)" />
|
||||||
|
</template>
|
||||||
20
apps/www/src/lib/registry/new-york/ui/drawer/DrawerTitle.vue
Normal file
20
apps/www/src/lib/registry/new-york/ui/drawer/DrawerTitle.vue
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { DrawerTitleProps } from 'vaul-vue'
|
||||||
|
import { DrawerTitle } from 'vaul-vue'
|
||||||
|
import { type HtmlHTMLAttributes, computed } from 'vue'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
|
const props = defineProps<DrawerTitleProps & { class?: HtmlHTMLAttributes['class'] }>()
|
||||||
|
|
||||||
|
const delegatedProps = computed(() => {
|
||||||
|
const { class: _, ...delegated } = props
|
||||||
|
|
||||||
|
return delegated
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<DrawerTitle v-bind="delegatedProps" :class="cn('text-lg font-semibold leading-none tracking-tight', props.class)">
|
||||||
|
<slot />
|
||||||
|
</DrawerTitle>
|
||||||
|
</template>
|
||||||
8
apps/www/src/lib/registry/new-york/ui/drawer/index.ts
Normal file
8
apps/www/src/lib/registry/new-york/ui/drawer/index.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
export { DrawerPortal, DrawerTrigger, DrawerClose } from 'vaul-vue'
|
||||||
|
export { default as Drawer } from './Drawer.vue'
|
||||||
|
export { default as DrawerOverlay } from './DrawerOverlay.vue'
|
||||||
|
export { default as DrawerContent } from './DrawerContent.vue'
|
||||||
|
export { default as DrawerHeader } from './DrawerHeader.vue'
|
||||||
|
export { default as DrawerFooter } from './DrawerFooter.vue'
|
||||||
|
export { default as DrawerTitle } from './DrawerTitle.vue'
|
||||||
|
export { default as DrawerDescription } from './DrawerDescription.vue'
|
||||||
|
|
@ -244,6 +244,24 @@
|
||||||
],
|
],
|
||||||
"type": "components:ui"
|
"type": "components:ui"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "drawer",
|
||||||
|
"dependencies": [],
|
||||||
|
"registryDependencies": [
|
||||||
|
"utils"
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
"ui/drawer/Drawer.vue",
|
||||||
|
"ui/drawer/DrawerContent.vue",
|
||||||
|
"ui/drawer/DrawerDescription.vue",
|
||||||
|
"ui/drawer/DrawerFooter.vue",
|
||||||
|
"ui/drawer/DrawerHeader.vue",
|
||||||
|
"ui/drawer/DrawerOverlay.vue",
|
||||||
|
"ui/drawer/DrawerTitle.vue",
|
||||||
|
"ui/drawer/index.ts"
|
||||||
|
],
|
||||||
|
"type": "components:ui"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "dropdown-menu",
|
"name": "dropdown-menu",
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
|
|
|
||||||
42
apps/www/src/public/registry/styles/default/drawer.json
Normal file
42
apps/www/src/public/registry/styles/default/drawer.json
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
{
|
||||||
|
"name": "drawer",
|
||||||
|
"dependencies": [],
|
||||||
|
"registryDependencies": [
|
||||||
|
"utils"
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
{
|
||||||
|
"name": "Drawer.vue",
|
||||||
|
"content": "<script lang=\"ts\" setup>\nimport type { DrawerRootEmits, DrawerRootProps } from 'vaul-vue'\nimport { DrawerRoot } from 'vaul-vue'\nimport { useForwardPropsEmits } from 'radix-vue'\n\nconst props = withDefaults(defineProps<DrawerRootProps>(), {\n shouldScaleBackground: true,\n})\n\nconst emits = defineEmits<DrawerRootEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <DrawerRoot v-bind=\"forwarded\">\n <slot />\n </DrawerRoot>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "DrawerContent.vue",
|
||||||
|
"content": "<script lang=\"ts\" setup>\nimport { DrawerContent, DrawerPortal } from 'vaul-vue'\nimport type { DialogContentEmits, DialogContentProps } from 'radix-vue'\nimport { useForwardPropsEmits } from 'radix-vue'\nimport type { HtmlHTMLAttributes } from 'vue'\nimport DrawerOverlay from './DrawerOverlay.vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<DialogContentProps & { class?: HtmlHTMLAttributes['class'] }>()\nconst emits = defineEmits<DialogContentEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <DrawerPortal>\n <DrawerOverlay />\n <DrawerContent\n v-bind=\"forwarded\" :class=\"cn(\n 'fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border bg-background',\n props.class,\n )\"\n >\n <div class=\"mx-auto mt-4 h-2 w-[100px] rounded-full bg-muted\" />\n <slot />\n </DrawerContent>\n </DrawerPortal>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "DrawerDescription.vue",
|
||||||
|
"content": "<script lang=\"ts\" setup>\nimport type { DrawerDescriptionProps } from 'vaul-vue'\nimport { DrawerDescription } from 'vaul-vue'\nimport { type HtmlHTMLAttributes, computed } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<DrawerDescriptionProps & { class?: HtmlHTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <DrawerDescription v-bind=\"delegatedProps\" :class=\"cn('text-sm text-muted-foreground', props.class)\">\n <slot />\n </DrawerDescription>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "DrawerFooter.vue",
|
||||||
|
"content": "<script lang=\"ts\" setup>\nimport type { HtmlHTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HtmlHTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div :class=\"cn('mt-auto flex flex-col gap-2 p-4', props.class)\">\n <slot />\n </div>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "DrawerHeader.vue",
|
||||||
|
"content": "<script lang=\"ts\" setup>\nimport type { HtmlHTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HtmlHTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div :class=\"cn('grid gap-1.5 p-4 text-center sm:text-left', props.class)\">\n <slot />\n </div>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "DrawerOverlay.vue",
|
||||||
|
"content": "<script lang=\"ts\" setup>\nimport { DrawerOverlay } from 'vaul-vue'\nimport type { DialogOverlayProps } from 'radix-vue'\nimport { type HtmlHTMLAttributes, computed } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<DialogOverlayProps & { class?: HtmlHTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <DrawerOverlay v-bind=\"delegatedProps\" :class=\"cn('fixed inset-0 z-50 bg-black/80', props.class)\" />\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "DrawerTitle.vue",
|
||||||
|
"content": "<script lang=\"ts\" setup>\nimport type { DrawerTitleProps } from 'vaul-vue'\nimport { DrawerTitle } from 'vaul-vue'\nimport { type HtmlHTMLAttributes, computed } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<DrawerTitleProps & { class?: HtmlHTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <DrawerTitle v-bind=\"delegatedProps\" :class=\"cn('text-lg font-semibold leading-none tracking-tight', props.class)\">\n <slot />\n </DrawerTitle>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "index.ts",
|
||||||
|
"content": "export { DrawerPortal, DrawerTrigger, DrawerClose } from 'vaul-vue'\nexport { default as Drawer } from './Drawer.vue'\nexport { default as DrawerOverlay } from './DrawerOverlay.vue'\nexport { default as DrawerContent } from './DrawerContent.vue'\nexport { default as DrawerHeader } from './DrawerHeader.vue'\nexport { default as DrawerFooter } from './DrawerFooter.vue'\nexport { default as DrawerTitle } from './DrawerTitle.vue'\nexport { default as DrawerDescription } from './DrawerDescription.vue'\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": "components:ui"
|
||||||
|
}
|
||||||
42
apps/www/src/public/registry/styles/new-york/drawer.json
Normal file
42
apps/www/src/public/registry/styles/new-york/drawer.json
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
{
|
||||||
|
"name": "drawer",
|
||||||
|
"dependencies": [],
|
||||||
|
"registryDependencies": [
|
||||||
|
"utils"
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
{
|
||||||
|
"name": "Drawer.vue",
|
||||||
|
"content": "<script lang=\"ts\" setup>\nimport type { DrawerRootEmits, DrawerRootProps } from 'vaul-vue'\nimport { DrawerRoot } from 'vaul-vue'\nimport { useForwardPropsEmits } from 'radix-vue'\n\nconst props = withDefaults(defineProps<DrawerRootProps>(), {\n shouldScaleBackground: true,\n})\n\nconst emits = defineEmits<DrawerRootEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <DrawerRoot v-bind=\"forwarded\">\n <slot />\n </DrawerRoot>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "DrawerContent.vue",
|
||||||
|
"content": "<script lang=\"ts\" setup>\nimport { DrawerContent, DrawerPortal } from 'vaul-vue'\nimport type { DialogContentEmits, DialogContentProps } from 'radix-vue'\nimport { useForwardPropsEmits } from 'radix-vue'\nimport type { HtmlHTMLAttributes } from 'vue'\nimport DrawerOverlay from './DrawerOverlay.vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<DialogContentProps & { class?: HtmlHTMLAttributes['class'] }>()\nconst emits = defineEmits<DialogContentEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <DrawerPortal>\n <DrawerOverlay />\n <DrawerContent\n v-bind=\"forwarded\" :class=\"cn(\n 'fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border bg-background',\n props.class,\n )\"\n >\n <div class=\"mx-auto mt-4 h-2 w-[100px] rounded-full bg-muted\" />\n <slot />\n </DrawerContent>\n </DrawerPortal>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "DrawerDescription.vue",
|
||||||
|
"content": "<script lang=\"ts\" setup>\nimport type { DrawerDescriptionProps } from 'vaul-vue'\nimport { DrawerDescription } from 'vaul-vue'\nimport { type HtmlHTMLAttributes, computed } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<DrawerDescriptionProps & { class?: HtmlHTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <DrawerDescription v-bind=\"delegatedProps\" :class=\"cn('text-sm text-muted-foreground', props.class)\">\n <slot />\n </DrawerDescription>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "DrawerFooter.vue",
|
||||||
|
"content": "<script lang=\"ts\" setup>\nimport type { HtmlHTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HtmlHTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div :class=\"cn('mt-auto flex flex-col gap-2 p-4', props.class)\">\n <slot />\n </div>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "DrawerHeader.vue",
|
||||||
|
"content": "<script lang=\"ts\" setup>\nimport type { HtmlHTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HtmlHTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div :class=\"cn('grid gap-1.5 p-4 text-center sm:text-left', props.class)\">\n <slot />\n </div>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "DrawerOverlay.vue",
|
||||||
|
"content": "<script lang=\"ts\" setup>\nimport { DrawerOverlay } from 'vaul-vue'\nimport type { DialogOverlayProps } from 'radix-vue'\nimport { type HtmlHTMLAttributes, computed } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<DialogOverlayProps & { class?: HtmlHTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <DrawerOverlay v-bind=\"delegatedProps\" :class=\"cn('fixed inset-0 z-50 bg-black/80', props.class)\" />\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "DrawerTitle.vue",
|
||||||
|
"content": "<script lang=\"ts\" setup>\nimport type { DrawerTitleProps } from 'vaul-vue'\nimport { DrawerTitle } from 'vaul-vue'\nimport { type HtmlHTMLAttributes, computed } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<DrawerTitleProps & { class?: HtmlHTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <DrawerTitle v-bind=\"delegatedProps\" :class=\"cn('text-lg font-semibold leading-none tracking-tight', props.class)\">\n <slot />\n </DrawerTitle>\n</template>\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "index.ts",
|
||||||
|
"content": "export { DrawerPortal, DrawerTrigger, DrawerClose } from 'vaul-vue'\nexport { default as Drawer } from './Drawer.vue'\nexport { default as DrawerOverlay } from './DrawerOverlay.vue'\nexport { default as DrawerContent } from './DrawerContent.vue'\nexport { default as DrawerHeader } from './DrawerHeader.vue'\nexport { default as DrawerFooter } from './DrawerFooter.vue'\nexport { default as DrawerTitle } from './DrawerTitle.vue'\nexport { default as DrawerDescription } from './DrawerDescription.vue'\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": "components:ui"
|
||||||
|
}
|
||||||
|
|
@ -98,6 +98,9 @@ importers:
|
||||||
v-calendar:
|
v-calendar:
|
||||||
specifier: ^3.1.2
|
specifier: ^3.1.2
|
||||||
version: 3.1.2(@popperjs/core@2.11.8)(vue@3.4.21)
|
version: 3.1.2(@popperjs/core@2.11.8)(vue@3.4.21)
|
||||||
|
vaul-vue:
|
||||||
|
specifier: ^0.1.0
|
||||||
|
version: 0.1.0(typescript@5.3.3)
|
||||||
vee-validate:
|
vee-validate:
|
||||||
specifier: 4.12.5
|
specifier: 4.12.5
|
||||||
version: 4.12.5(vue@3.4.21)
|
version: 4.12.5(vue@3.4.21)
|
||||||
|
|
@ -13145,6 +13148,17 @@ packages:
|
||||||
builtins: 5.0.1
|
builtins: 5.0.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/vaul-vue@0.1.0(typescript@5.3.3):
|
||||||
|
resolution: {integrity: sha512-3PYWMbN3cSdsciv3fzewskxZFnX61PYq1uNsbvizXDo/8sN4SMrWkYDqWaPdTD3GTEm6wpx7j5flRLg7A5ZXbQ==}
|
||||||
|
dependencies:
|
||||||
|
'@vueuse/core': 10.9.0(vue@3.4.21)
|
||||||
|
radix-vue: 1.4.9(vue@3.4.21)
|
||||||
|
vue: 3.4.21(typescript@5.3.3)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- '@vue/composition-api'
|
||||||
|
- typescript
|
||||||
|
dev: false
|
||||||
|
|
||||||
/vee-validate@4.12.5(vue@3.4.21):
|
/vee-validate@4.12.5(vue@3.4.21):
|
||||||
resolution: {integrity: sha512-rvaDfLPSLwTk+mf016XWE4drB8yXzOsKXiKHTb9gNXNLTtQSZ0Ww26O0/xbIFQe+n3+u8Wv1Y8uO/aLDX4fxOg==}
|
resolution: {integrity: sha512-rvaDfLPSLwTk+mf016XWE4drB8yXzOsKXiKHTb9gNXNLTtQSZ0Ww26O0/xbIFQe+n3+u8Wv1Y8uO/aLDX4fxOg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user