feat: dialog, alertdialog (#9)

* feat: dialog

* feat: alert-dialog

* chore: add demo
This commit is contained in:
zernonia 2023-08-23 18:12:48 +08:00 committed by GitHub
parent 5087741e93
commit 81197d1e02
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 266 additions and 1 deletions

View File

@ -6,6 +6,7 @@ module.exports = {
extends: '@antfu',
rules: {
'vue/one-component-per-file': 'off',
'vue/no-reserved-component-names': 'off',
'symbol-description': 'off',
'no-console': 'warn',

View File

@ -1,12 +1,18 @@
<script setup lang="ts">
import AccordionDemo from '@/registry/default/examples/AccordionDemo.vue'
import PopoverDemo from '@/registry/default/examples/PopoverDemo.vue'
import DialogDemo from '@/registry/default/examples/DialogDemo.vue'
import AlertDialogDemo from '@/registry/default/examples/AlertDialogDemo.vue'
</script>
<template>
<div class="p-8 grid gap-8 grid-cols-3 place-items-center">
<div class="p-8 grid gap-12 grid-cols-3 place-items-center">
<AccordionDemo class="max-w-[20rem]" />
<PopoverDemo />
<DialogDemo />
<AlertDialogDemo />
</div>
</template>

View File

@ -0,0 +1,37 @@
<script setup lang="ts">
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
} from '@/registry/default/ui/alert-dialog'
import { Button } from '@/registry/default/ui/button'
</script>
<template>
<AlertDialog>
<AlertDialogTrigger as-child>
<Button variant="outline">
Show Dialog
</Button>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
<AlertDialogDescription>
This action cannot be undone. This will permanently delete your
account and remove your data from our servers.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogAction>Continue</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</template>

View File

@ -0,0 +1,51 @@
<script setup lang="ts">
import { Button } from '@/registry/default/ui/button'
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from '@/registry/default/ui/dialog'
import { Input } from '@/registry/default/ui/input'
import { Label } from '@/registry/default/ui/label'
</script>
<template>
<Dialog>
<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>
<div class="grid gap-4 py-4">
<div class="grid grid-cols-4 items-center gap-4">
<Label for="name" class="text-right">
Name
</Label>
<Input id="name" value="Pedro Duarte" class="col-span-3" />
</div>
<div class="grid grid-cols-4 items-center gap-4">
<Label for="username" class="text-right">
Username
</Label>
<Input id="username" value="@peduarte" class="col-span-3" />
</div>
</div>
<DialogFooter>
<Button type="submit">
Save changes
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
</template>

View File

@ -0,0 +1,92 @@
import { defineComponent, h } from 'vue'
import {
AlertDialogAction as AlertDialogActionPrimitive, type AlertDialogActionProps,
AlertDialogCancel as AlertDialogCancelPrimitive, type AlertDialogCancelProps,
AlertDialogContent as AlertDialogContentPrimitive, type AlertDialogContentProps,
AlertDialogDescription as AlertDialogDescriptionPrimitive, type AlertDialogDescriptionProps,
AlertDialogOverlay as AlertDialogOverlayPrimitive, type AlertDialogOverlayProps,
AlertDialogPortal as AlertDialogPortalPrimitive,
AlertDialogRoot, AlertDialogTitle as AlertDialogTitlePrimitive,
type AlertDialogTitleProps, AlertDialogTrigger as AlertDialogTriggerPrimitive,
} from 'radix-vue'
import { cn } from '@/utils'
import { buttonVariants } from '@/registry/default/ui/button'
export const AlertDialog = AlertDialogRoot
export const AlertDialogTrigger = AlertDialogTriggerPrimitive
export const AlertDialogPortal = AlertDialogPortalPrimitive
export const AlertDialogOverlay = defineComponent<AlertDialogOverlayProps>(
(props, { attrs, slots }) => {
return () => h(AlertDialogOverlayPrimitive,
{ class: cn('fixed inset-0 z-50 bg-background/80 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0', attrs.class), ...props },
slots,
)
}, { name: 'AlertDialogOverlay' },
)
export const AlertDialogContent = defineComponent<AlertDialogContentProps>(
(props, { attrs, slots }) => {
return () => h(AlertDialogPortal, () => [
h(AlertDialogOverlay),
h(AlertDialogContentPrimitive, {
class: cn('fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg md:w-full', attrs.class ?? ''),
...props,
}, slots),
])
}, { name: 'AlertDialogContent' },
)
export const AlertDialogHeader = defineComponent(
(_props, { attrs, slots }) => {
return () => h('div',
{ class: cn('flex flex-col space-y-2 text-center sm:text-left', attrs.class) },
slots,
)
}, { name: 'AlertDialogHeader' },
)
export const AlertDialogFooter = defineComponent(
(_props, { attrs, slots }) => {
return () => h('div',
{ class: cn('flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2', attrs.class) },
slots,
)
}, { name: 'AlertDialogFooter' },
)
export const AlertDialogTitle = defineComponent<AlertDialogTitleProps>(
(props, { attrs, slots }) => {
return () => h(AlertDialogTitlePrimitive,
{ class: cn('text-lg font-semibold', attrs.class), ...props },
slots,
)
}, { name: 'AlertDialogTitle' },
)
export const AlertDialogDescription = defineComponent<AlertDialogDescriptionProps>(
(props, { attrs, slots }) => {
return () => h(AlertDialogDescriptionPrimitive,
{ class: cn('text-sm text-muted-foreground', attrs.class), ...props },
slots,
)
}, { name: 'AlertDialogDescription' },
)
export const AlertDialogAction = defineComponent<AlertDialogActionProps>(
(props, { attrs, slots }) => {
return () => h(AlertDialogActionPrimitive,
{ class: cn(buttonVariants(), attrs.class), ...props },
slots,
)
}, { name: 'AlertDialogAction' },
)
export const AlertDialogCancel = defineComponent<AlertDialogCancelProps>(
(props, { attrs, slots }) => {
return () => h(AlertDialogCancelPrimitive,
{ class: cn(buttonVariants({ variant: 'outline' }), 'mt-2 sm:mt-0', attrs.class), ...props },
slots,
)
}, { name: 'AlertDialogCancel' },
)

View File

@ -0,0 +1,78 @@
import { defineComponent, h } from 'vue'
import {
DialogClose, DialogContent as DialogContentPrimitive, type DialogContentProps,
DialogDescription as DialogDescriptionPrimitive, type DialogDescriptionProps,
DialogOverlay as DialogOverlayPrimitive, type DialogOverlayProps,
DialogPortal as DialogPortalPrimitive, DialogRoot,
DialogTitle as DialogTitlePrimitive, type DialogTitleProps,
DialogTrigger as DialogTriggerPrimitive,
} from 'radix-vue'
import { X } from 'lucide-vue-next'
import { cn } from '@/utils'
export const Dialog = DialogRoot
export const DialogTrigger = DialogTriggerPrimitive
export const DialogPortal = DialogPortalPrimitive
export const DialogOverlay = defineComponent<DialogOverlayProps>(
(props, { attrs, slots }) => {
return () => h(DialogOverlayPrimitive,
{ class: cn('fixed inset-0 z-50 bg-background/80 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0', attrs.class), ...props },
slots,
)
}, { name: 'DialogOverlay' },
)
export const DialogContent = defineComponent<DialogContentProps>(
(props, { attrs, slots }) => {
return () => h(DialogPortal, () => [
h(DialogOverlay),
h(DialogContentPrimitive, {
class: cn('fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg md:w-full', attrs.class ?? ''),
...props,
}, () => [
slots.default(),
h(DialogClose,
{ class: 'absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground' },
() => [h(X, { class: 'h-4 w-4' }), h('span', { class: 'sr-only' }, 'Close')],
),
]),
])
}, { name: 'DialogContent' },
)
export const DialogHeader = defineComponent(
(_props, { attrs, slots }) => {
return () => h('div',
{ class: cn('flex flex-col space-y-1.5 text-center sm:text-left', attrs.class) },
slots,
)
}, { name: 'DialogHeader' },
)
export const DialogFooter = defineComponent(
(_props, { attrs, slots }) => {
return () => h('div',
{ class: cn('flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2', attrs.class) },
slots,
)
}, { name: 'DialogFooter' },
)
export const DialogTitle = defineComponent<DialogTitleProps>(
(props, { attrs, slots }) => {
return () => h(DialogTitlePrimitive,
{ class: cn('text-lg font-semibold leading-none tracking-tight', attrs.class), ...props },
slots,
)
}, { name: 'DialogTitle' },
)
export const DialogDescription = defineComponent<DialogDescriptionProps>(
(props, { attrs, slots }) => {
return () => h(DialogDescriptionPrimitive,
{ class: cn('text-lg font-semibold leading-none tracking-tight', attrs.class), ...props },
slots,
)
}, { name: 'DialogDescription' },
)