docs: add dialog with form example (#682)
This commit is contained in:
parent
dbb29de523
commit
0ee23fb53d
|
|
@ -570,6 +570,13 @@ export const Index = {
|
||||||
component: () => import("../src/lib/registry/default/example/DialogDemo.vue").then((m) => m.default),
|
component: () => import("../src/lib/registry/default/example/DialogDemo.vue").then((m) => m.default),
|
||||||
files: ["../src/lib/registry/default/example/DialogDemo.vue"],
|
files: ["../src/lib/registry/default/example/DialogDemo.vue"],
|
||||||
},
|
},
|
||||||
|
"DialogForm": {
|
||||||
|
name: "DialogForm",
|
||||||
|
type: "components:example",
|
||||||
|
registryDependencies: ["button","form","dialog","input","toast"],
|
||||||
|
component: () => import("../src/lib/registry/default/example/DialogForm.vue").then((m) => m.default),
|
||||||
|
files: ["../src/lib/registry/default/example/DialogForm.vue"],
|
||||||
|
},
|
||||||
"DialogScrollBodyDemo": {
|
"DialogScrollBodyDemo": {
|
||||||
name: "DialogScrollBodyDemo",
|
name: "DialogScrollBodyDemo",
|
||||||
type: "components:example",
|
type: "components:example",
|
||||||
|
|
@ -2041,6 +2048,13 @@ export const Index = {
|
||||||
component: () => import("../src/lib/registry/new-york/example/DialogDemo.vue").then((m) => m.default),
|
component: () => import("../src/lib/registry/new-york/example/DialogDemo.vue").then((m) => m.default),
|
||||||
files: ["../src/lib/registry/new-york/example/DialogDemo.vue"],
|
files: ["../src/lib/registry/new-york/example/DialogDemo.vue"],
|
||||||
},
|
},
|
||||||
|
"DialogForm": {
|
||||||
|
name: "DialogForm",
|
||||||
|
type: "components:example",
|
||||||
|
registryDependencies: ["button","form","dialog","input","toast"],
|
||||||
|
component: () => import("../src/lib/registry/new-york/example/DialogForm.vue").then((m) => m.default),
|
||||||
|
files: ["../src/lib/registry/new-york/example/DialogForm.vue"],
|
||||||
|
},
|
||||||
"DialogScrollBodyDemo": {
|
"DialogScrollBodyDemo": {
|
||||||
name: "DialogScrollBodyDemo",
|
name: "DialogScrollBodyDemo",
|
||||||
type: "components:example",
|
type: "components:example",
|
||||||
|
|
|
||||||
|
|
@ -31,15 +31,15 @@
|
||||||
"date-fns": "^3.6.0",
|
"date-fns": "^3.6.0",
|
||||||
"embla-carousel-autoplay": "^8.1.7",
|
"embla-carousel-autoplay": "^8.1.7",
|
||||||
"embla-carousel-vue": "^8.1.7",
|
"embla-carousel-vue": "^8.1.7",
|
||||||
"lucide-vue-next": "^0.400.0",
|
"lucide-vue-next": "^0.416.0",
|
||||||
"magic-string": "^0.30.10",
|
"magic-string": "^0.30.10",
|
||||||
"radix-vue": "catalog:",
|
"radix-vue": "catalog:",
|
||||||
"tailwindcss-animate": "^1.0.7",
|
"tailwindcss-animate": "^1.0.7",
|
||||||
"v-calendar": "^3.1.2",
|
"v-calendar": "^3.1.2",
|
||||||
"vaul-vue": "^0.2.0",
|
"vaul-vue": "^0.2.0",
|
||||||
"vee-validate": "4.13.2",
|
"vee-validate": "4.13.2",
|
||||||
"vue": "^3.4.33",
|
"vue": "^3.4.34",
|
||||||
"vue-sonner": "^1.1.3",
|
"vue-sonner": "^1.1.4",
|
||||||
"vue-wrap-balancer": "^1.1.3",
|
"vue-wrap-balancer": "^1.1.3",
|
||||||
"zod": "catalog:"
|
"zod": "catalog:"
|
||||||
},
|
},
|
||||||
|
|
@ -54,13 +54,13 @@
|
||||||
"@iconify-json/tabler": "^1.1.116",
|
"@iconify-json/tabler": "^1.1.116",
|
||||||
"@iconify/vue": "^4.1.2",
|
"@iconify/vue": "^4.1.2",
|
||||||
"@oxc-parser/wasm": "catalog:",
|
"@oxc-parser/wasm": "catalog:",
|
||||||
"@shikijs/transformers": "^1.11.0",
|
"@shikijs/transformers": "^1.11.1",
|
||||||
"@types/lodash-es": "^4.17.12",
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/node": "^20.14.11",
|
"@types/node": "^20.14.12",
|
||||||
"@vitejs/plugin-vue": "^5.0.5",
|
"@vitejs/plugin-vue": "^5.1.0",
|
||||||
"@vitejs/plugin-vue-jsx": "^4.0.0",
|
"@vitejs/plugin-vue-jsx": "^4.0.0",
|
||||||
"@vue/compiler-core": "^3.4.33",
|
"@vue/compiler-core": "^3.4.34",
|
||||||
"@vue/compiler-dom": "^3.4.33",
|
"@vue/compiler-dom": "^3.4.34",
|
||||||
"@vue/tsconfig": "^0.5.1",
|
"@vue/tsconfig": "^0.5.1",
|
||||||
"autoprefixer": "^10.4.19",
|
"autoprefixer": "^10.4.19",
|
||||||
"fast-glob": "^3.3.2",
|
"fast-glob": "^3.3.2",
|
||||||
|
|
@ -68,14 +68,14 @@
|
||||||
"markdown-it": "^14.1.0",
|
"markdown-it": "^14.1.0",
|
||||||
"pathe": "^1.1.2",
|
"pathe": "^1.1.2",
|
||||||
"rimraf": "^6.0.1",
|
"rimraf": "^6.0.1",
|
||||||
"shiki": "^1.11.0",
|
"shiki": "^1.11.1",
|
||||||
"tailwind-merge": "^2.4.0",
|
"tailwind-merge": "^2.4.0",
|
||||||
"tailwindcss": "^3.4.6",
|
"tailwindcss": "^3.4.7",
|
||||||
"tsx": "^4.16.2",
|
"tsx": "^4.16.2",
|
||||||
"typescript": "^5.5.3",
|
"typescript": "^5.5.3",
|
||||||
"unplugin-icons": "^0.19.0",
|
"unplugin-icons": "^0.19.0",
|
||||||
"vitepress": "^1.3.1",
|
"vitepress": "^1.3.1",
|
||||||
"vue-component-meta": "^2.0.28",
|
"vue-component-meta": "^2.0.29",
|
||||||
"vue-tsc": "^2.0.28"
|
"vue-tsc": "^2.0.29"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,10 @@ import {
|
||||||
|
|
||||||
<ComponentPreview name="DialogScrollOverlayDemo" />
|
<ComponentPreview name="DialogScrollOverlayDemo" />
|
||||||
|
|
||||||
|
### Form
|
||||||
|
|
||||||
|
<ComponentPreview name="DialogForm" />
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
To activate the `Dialog` component from within a `Context Menu` or `Dropdown Menu`, you must encase the `Context Menu` or `Dropdown Menu` component in the `Dialog` component. For more information, refer to the linked issue [here](https://github.com/radix-ui/primitives/issues/1836).
|
To activate the `Dialog` component from within a `Context Menu` or `Dropdown Menu`, you must encase the `Context Menu` or `Dropdown Menu` component in the `Dialog` component. For more information, refer to the linked issue [here](https://github.com/radix-ui/primitives/issues/1836).
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ import { Button } from '@/components/ui/button'
|
||||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu'
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu'
|
||||||
|
|
||||||
// Pass { disableTransition: false } to enable transitions
|
// Pass { disableTransition: false } to enable transitions
|
||||||
const mode = useColorMode();
|
const mode = useColorMode()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,12 @@ description: Install and configure Nuxt.
|
||||||
|
|
||||||
Start by creating a new Nuxt project using `create-nuxt-app`:
|
Start by creating a new Nuxt project using `create-nuxt-app`:
|
||||||
|
|
||||||
|
<Callout>
|
||||||
|
|
||||||
|
If you're using the JS template, `jsconfig.json` must exist for the CLI to run without errors.
|
||||||
|
|
||||||
|
</Callout>
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npx nuxi@latest init my-app
|
npx nuxi@latest init my-app
|
||||||
```
|
```
|
||||||
|
|
@ -82,7 +88,8 @@ export default defineNuxtModule<ShadcnVueOptions>({
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
async setup({ componentDir, prefix }) {
|
async setup({ componentDir, prefix }) {
|
||||||
const isVeeValidateExist = await tryResolveModule('vee-validate');
|
const veeValidate = await tryResolveModule('vee-validate');
|
||||||
|
const vaulVue = await tryResolveModule('vaul-vue');
|
||||||
|
|
||||||
addComponentsDir(
|
addComponentsDir(
|
||||||
{
|
{
|
||||||
|
|
@ -96,7 +103,7 @@ export default defineNuxtModule<ShadcnVueOptions>({
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if (isVeeValidateExist !== undefined) {
|
if (veeValidate !== undefined) {
|
||||||
addComponent({
|
addComponent({
|
||||||
filePath: 'vee-validate',
|
filePath: 'vee-validate',
|
||||||
export: 'Form',
|
export: 'Form',
|
||||||
|
|
@ -112,6 +119,17 @@ export default defineNuxtModule<ShadcnVueOptions>({
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(vaulVue !== undefined) {
|
||||||
|
['DrawerPortal', 'DrawerTrigger', 'DrawerClose'].forEach((item) => {
|
||||||
|
addComponent({
|
||||||
|
filePath: 'vaul-vue',
|
||||||
|
export: item,
|
||||||
|
name: prefix + item,
|
||||||
|
priority: 999,
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
addComponent({
|
addComponent({
|
||||||
filePath: 'radix-vue',
|
filePath: 'radix-vue',
|
||||||
export: 'PaginationRoot',
|
export: 'PaginationRoot',
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ description: Re-usable components built with Radix Vue, and Tailwind CSS.
|
||||||
---
|
---
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/lib/registry/default/ui/accordion'
|
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/lib/registry/new-york/ui/accordion'
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
An unofficial, community-led [Vue](https://vuejs.org/) port of [shadcn/ui](https://ui.shadcn.com). We are not affiliated with [shadcn](https://twitter.com/shadcn), but we did get his blessing before creating a Vue version of his work. This project was born out of the need for a similar project for the Vue ecosystem.
|
An unofficial, community-led [Vue](https://vuejs.org/) port of [shadcn/ui](https://ui.shadcn.com). We are not affiliated with [shadcn](https://twitter.com/shadcn), but we did get his blessing before creating a Vue version of his work. This project was born out of the need for a similar project for the Vue ecosystem.
|
||||||
|
|
@ -19,8 +19,13 @@ Pick the components you need. Use the CLI to automatically add the components, o
|
||||||
|
|
||||||
_Use this as a reference to build your own component libraries._
|
_Use this as a reference to build your own component libraries._
|
||||||
|
|
||||||
|
<div class="[&>h2]:!mb-0">
|
||||||
|
|
||||||
## FAQ
|
## FAQ
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="[&_h3]:!mt-0">
|
||||||
<Accordion type="multiple">
|
<Accordion type="multiple">
|
||||||
|
|
||||||
<AccordionItem value="faq-1">
|
<AccordionItem value="faq-1">
|
||||||
|
|
@ -58,3 +63,4 @@ But let us know if you do use it. We'd love to see what you build with it.
|
||||||
</AccordionContent>
|
</AccordionContent>
|
||||||
</AccordionItem>
|
</AccordionItem>
|
||||||
</Accordion>
|
</Accordion>
|
||||||
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ import { Textarea } from '@/lib/registry/new-york/ui/textarea'
|
||||||
<Select default-value="2">
|
<Select default-value="2">
|
||||||
<SelectTrigger
|
<SelectTrigger
|
||||||
id="security-level"
|
id="security-level"
|
||||||
class="line-clamp-1 w-full truncate"
|
class="w-full truncate"
|
||||||
>
|
>
|
||||||
<SelectValue placeholder="Select level" />
|
<SelectValue placeholder="Select level" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
|
|
|
||||||
79
apps/www/src/lib/registry/default/example/DialogForm.vue
Normal file
79
apps/www/src/lib/registry/default/example/DialogForm.vue
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { h } from 'vue'
|
||||||
|
import { toTypedSchema } from '@vee-validate/zod'
|
||||||
|
import * as z from 'zod'
|
||||||
|
|
||||||
|
import { Button } from '@/lib/registry/default/ui/button'
|
||||||
|
import {
|
||||||
|
Form,
|
||||||
|
FormControl,
|
||||||
|
FormDescription,
|
||||||
|
FormField,
|
||||||
|
FormItem,
|
||||||
|
FormLabel,
|
||||||
|
FormMessage,
|
||||||
|
} from '@/lib/registry/default/ui/form'
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogDescription,
|
||||||
|
DialogFooter,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger,
|
||||||
|
} from '@/lib/registry/default/ui/dialog'
|
||||||
|
import { Input } from '@/lib/registry/default/ui/input'
|
||||||
|
import { toast } from '@/lib/registry/default/ui/toast'
|
||||||
|
|
||||||
|
const formSchema = toTypedSchema(z.object({
|
||||||
|
username: z.string().min(2).max(50),
|
||||||
|
}))
|
||||||
|
|
||||||
|
function onSubmit(values: any) {
|
||||||
|
toast({
|
||||||
|
title: 'You submitted the following values:',
|
||||||
|
description: h('pre', { class: 'mt-2 w-[340px] rounded-md bg-slate-950 p-4' }, h('code', { class: 'text-white' }, JSON.stringify(values, null, 2))),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Form v-slot="{ submitForm }" as="" :validation-schema="formSchema" @submit="onSubmit">
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<form @submit="submitForm">
|
||||||
|
<FormField v-slot="{ componentField }" name="username">
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Username</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input type="text" placeholder="shadcn" v-bind="componentField" />
|
||||||
|
</FormControl>
|
||||||
|
<FormDescription>
|
||||||
|
This is your public display name.
|
||||||
|
</FormDescription>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
</FormField>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<DialogFooter>
|
||||||
|
<Button type="submit" form="dialogForm">
|
||||||
|
Save changes
|
||||||
|
</Button>
|
||||||
|
</DialogFooter>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
</Form>
|
||||||
|
</template>
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
import { Check, Circle, Dot } from 'lucide-vue-next'
|
import { Check, Circle, Dot } from 'lucide-vue-next'
|
||||||
import { toTypedSchema } from '@vee-validate/zod'
|
import { toTypedSchema } from '@vee-validate/zod'
|
||||||
import * as z from 'zod'
|
import * as z from 'zod'
|
||||||
import { computed, h, nextTick, ref } from 'vue'
|
import { computed, h, ref } from 'vue'
|
||||||
import { get, set } from '@vueuse/core'
|
import { get, set } from '@vueuse/core'
|
||||||
import { Stepper, StepperDescription, StepperItem, StepperSeparator, StepperTitle, StepperTrigger } from '@/lib/registry/default/ui/stepper'
|
import { Stepper, StepperDescription, StepperItem, StepperSeparator, StepperTitle, StepperTrigger } from '@/lib/registry/default/ui/stepper'
|
||||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/lib/registry/default/ui/form'
|
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/lib/registry/default/ui/form'
|
||||||
|
|
@ -88,9 +88,7 @@ function onSubmit(values: any) {
|
||||||
<form
|
<form
|
||||||
@submit="(e) => {
|
@submit="(e) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
nextTick(() => {
|
|
||||||
validate()
|
validate()
|
||||||
})
|
|
||||||
|
|
||||||
if (stepIndex === steps.length) {
|
if (stepIndex === steps.length) {
|
||||||
onSubmit(values)
|
onSubmit(values)
|
||||||
|
|
@ -115,9 +113,8 @@ function onSubmit(values: any) {
|
||||||
:variant="state === 'completed' || state === 'active' ? 'default' : 'outline'"
|
:variant="state === 'completed' || state === 'active' ? 'default' : 'outline'"
|
||||||
size="icon"
|
size="icon"
|
||||||
class="z-10 rounded-full shrink-0"
|
class="z-10 rounded-full shrink-0"
|
||||||
:class="[state === 'active' && 'ring-2 ring-ring ring-offset-2 ring-offset-background',
|
:class="[state === 'active' && 'ring-2 ring-ring ring-offset-2 ring-offset-background']"
|
||||||
state !== 'completed' && !meta.valid && 'pointer-events-none',
|
:disabled="state !== 'completed' && !meta.valid"
|
||||||
]"
|
|
||||||
>
|
>
|
||||||
<Check v-if="state === 'completed'" class="size-5" />
|
<Check v-if="state === 'completed'" class="size-5" />
|
||||||
<Circle v-if="state === 'active'" />
|
<Circle v-if="state === 'active'" />
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Check, Circle, Dot } from 'lucide-vue-next'
|
import { Check, Circle, Dot } from 'lucide-vue-next'
|
||||||
|
|
||||||
import { Stepper, StepperDescription, StepperIndicator, StepperItem, StepperSeparator, StepperTitle, StepperTrigger } from '@/lib/registry/default/ui/stepper'
|
import { Stepper, StepperDescription, StepperItem, StepperSeparator, StepperTitle, StepperTrigger } from '@/lib/registry/default/ui/stepper'
|
||||||
import { Button } from '@/lib/registry/default/ui/button'
|
import { Button } from '@/lib/registry/default/ui/button'
|
||||||
|
|
||||||
const steps = [
|
const steps = [
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Check, Circle, Dot } from 'lucide-vue-next'
|
import { Check, Circle, Dot } from 'lucide-vue-next'
|
||||||
|
|
||||||
import { Stepper, StepperDescription, StepperIndicator, StepperItem, StepperSeparator, StepperTitle, StepperTrigger } from '@/lib/registry/default/ui/stepper'
|
import { Stepper, StepperDescription, StepperItem, StepperSeparator, StepperTitle, StepperTrigger } from '@/lib/registry/default/ui/stepper'
|
||||||
import { Button } from '@/lib/registry/default/ui/button'
|
import { Button } from '@/lib/registry/default/ui/button'
|
||||||
|
|
||||||
const steps = [
|
const steps = [
|
||||||
|
|
|
||||||
79
apps/www/src/lib/registry/new-york/example/DialogForm.vue
Normal file
79
apps/www/src/lib/registry/new-york/example/DialogForm.vue
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { h } from 'vue'
|
||||||
|
import { toTypedSchema } from '@vee-validate/zod'
|
||||||
|
import * as z from 'zod'
|
||||||
|
|
||||||
|
import { Button } from '@/lib/registry/new-york/ui/button'
|
||||||
|
import {
|
||||||
|
Form,
|
||||||
|
FormControl,
|
||||||
|
FormDescription,
|
||||||
|
FormField,
|
||||||
|
FormItem,
|
||||||
|
FormLabel,
|
||||||
|
FormMessage,
|
||||||
|
} from '@/lib/registry/new-york/ui/form'
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogDescription,
|
||||||
|
DialogFooter,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger,
|
||||||
|
} from '@/lib/registry/new-york/ui/dialog'
|
||||||
|
import { Input } from '@/lib/registry/new-york/ui/input'
|
||||||
|
import { toast } from '@/lib/registry/new-york/ui/toast'
|
||||||
|
|
||||||
|
const formSchema = toTypedSchema(z.object({
|
||||||
|
username: z.string().min(2).max(50),
|
||||||
|
}))
|
||||||
|
|
||||||
|
function onSubmit(values: any) {
|
||||||
|
toast({
|
||||||
|
title: 'You submitted the following values:',
|
||||||
|
description: h('pre', { class: 'mt-2 w-[340px] rounded-md bg-slate-950 p-4' }, h('code', { class: 'text-white' }, JSON.stringify(values, null, 2))),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Form v-slot="{ submitForm }" as="" keep-values :validation-schema="formSchema" @submit="onSubmit">
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<form @submit="submitForm">
|
||||||
|
<FormField v-slot="{ componentField }" name="username">
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Username</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input type="text" placeholder="shadcn" v-bind="componentField" />
|
||||||
|
</FormControl>
|
||||||
|
<FormDescription>
|
||||||
|
This is your public display name.
|
||||||
|
</FormDescription>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
</FormField>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<DialogFooter>
|
||||||
|
<Button type="submit" form="dialogForm">
|
||||||
|
Save changes
|
||||||
|
</Button>
|
||||||
|
</DialogFooter>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
</Form>
|
||||||
|
</template>
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
import { CheckIcon, CircleIcon, DotIcon } from '@radix-icons/vue'
|
import { CheckIcon, CircleIcon, DotIcon } from '@radix-icons/vue'
|
||||||
import { toTypedSchema } from '@vee-validate/zod'
|
import { toTypedSchema } from '@vee-validate/zod'
|
||||||
import * as z from 'zod'
|
import * as z from 'zod'
|
||||||
import { computed, h, nextTick, ref } from 'vue'
|
import { computed, h, ref } from 'vue'
|
||||||
import { get, set } from '@vueuse/core'
|
import { get, set } from '@vueuse/core'
|
||||||
import { Stepper, StepperDescription, StepperItem, StepperSeparator, StepperTitle, StepperTrigger } from '@/lib/registry/new-york/ui/stepper'
|
import { Stepper, StepperDescription, StepperItem, StepperSeparator, StepperTitle, StepperTrigger } from '@/lib/registry/new-york/ui/stepper'
|
||||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/lib/registry/new-york/ui/form'
|
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/lib/registry/new-york/ui/form'
|
||||||
|
|
@ -88,9 +88,7 @@ function onSubmit(values: any) {
|
||||||
<form
|
<form
|
||||||
@submit="(e) => {
|
@submit="(e) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
nextTick(() => {
|
|
||||||
validate()
|
validate()
|
||||||
})
|
|
||||||
|
|
||||||
if (stepIndex === steps.length) {
|
if (stepIndex === steps.length) {
|
||||||
onSubmit(values)
|
onSubmit(values)
|
||||||
|
|
@ -115,9 +113,8 @@ function onSubmit(values: any) {
|
||||||
:variant="state === 'completed' || state === 'active' ? 'default' : 'outline'"
|
:variant="state === 'completed' || state === 'active' ? 'default' : 'outline'"
|
||||||
size="icon"
|
size="icon"
|
||||||
class="z-10 rounded-full shrink-0"
|
class="z-10 rounded-full shrink-0"
|
||||||
:class="[state === 'active' && 'ring-2 ring-ring ring-offset-2 ring-offset-background',
|
:class="[state === 'active' && 'ring-2 ring-ring ring-offset-2 ring-offset-background']"
|
||||||
state !== 'completed' && !meta.valid && 'pointer-events-none',
|
:disabled="state !== 'completed' && !meta.valid"
|
||||||
]"
|
|
||||||
>
|
>
|
||||||
<CheckIcon v-if="state === 'completed'" class="size-5" />
|
<CheckIcon v-if="state === 'completed'" class="size-5" />
|
||||||
<CircleIcon v-if="state === 'active'" />
|
<CircleIcon v-if="state === 'active'" />
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { CheckIcon, CircleIcon, DotIcon } from '@radix-icons/vue'
|
import { CheckIcon, CircleIcon, DotIcon } from '@radix-icons/vue'
|
||||||
|
|
||||||
import { Stepper, StepperDescription, StepperIndicator, StepperItem, StepperSeparator, StepperTitle, StepperTrigger } from '@/lib/registry/new-york/ui/stepper'
|
import { Stepper, StepperDescription, StepperItem, StepperSeparator, StepperTitle, StepperTrigger } from '@/lib/registry/new-york/ui/stepper'
|
||||||
import { Button } from '@/lib/registry/new-york/ui/button'
|
import { Button } from '@/lib/registry/new-york/ui/button'
|
||||||
|
|
||||||
const steps = [
|
const steps = [
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { CheckIcon, CircleIcon, DotIcon } from '@radix-icons/vue'
|
import { CheckIcon, CircleIcon, DotIcon } from '@radix-icons/vue'
|
||||||
|
|
||||||
import { Stepper, StepperDescription, StepperIndicator, StepperItem, StepperSeparator, StepperTitle, StepperTrigger } from '@/lib/registry/new-york/ui/stepper'
|
import { Stepper, StepperDescription, StepperItem, StepperSeparator, StepperTitle, StepperTrigger } from '@/lib/registry/new-york/ui/stepper'
|
||||||
import { Button } from '@/lib/registry/new-york/ui/button'
|
import { Button } from '@/lib/registry/new-york/ui/button'
|
||||||
|
|
||||||
const steps = [
|
const steps = [
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import {
|
||||||
DialogPortal,
|
DialogPortal,
|
||||||
useForwardPropsEmits,
|
useForwardPropsEmits,
|
||||||
} from 'radix-vue'
|
} from 'radix-vue'
|
||||||
|
import { Cross2Icon } from '@radix-icons/vue'
|
||||||
import { cn } from '@/lib/utils'
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
const props = defineProps<DialogContentProps & { class?: HTMLAttributes['class'] }>()
|
const props = defineProps<DialogContentProps & { class?: HTMLAttributes['class'] }>()
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "DialogScrollContent.vue",
|
"name": "DialogScrollContent.vue",
|
||||||
"content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed } from 'vue'\nimport {\n DialogClose,\n DialogContent,\n type DialogContentEmits,\n type DialogContentProps,\n DialogOverlay,\n DialogPortal,\n useForwardPropsEmits,\n} from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<DialogContentProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<DialogContentEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <DialogPortal>\n <DialogOverlay\n class=\"fixed inset-0 z-50 grid place-items-center overflow-y-auto bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\"\n >\n <DialogContent\n :class=\"\n cn(\n 'relative z-50 grid w-full max-w-lg my-8 gap-4 border border-border bg-background p-6 shadow-lg duration-200 sm:rounded-lg md:w-full',\n props.class,\n )\n \"\n v-bind=\"forwarded\"\n @pointer-down-outside=\"(event) => {\n const originalEvent = event.detail.originalEvent;\n const target = originalEvent.target as HTMLElement;\n if (originalEvent.offsetX > target.clientWidth || originalEvent.offsetY > target.clientHeight) {\n event.preventDefault();\n }\n }\"\n >\n <slot />\n\n <DialogClose\n class=\"absolute top-4 right-4 p-0.5 transition-colors rounded-md hover:bg-secondary\"\n >\n <Cross2Icon class=\"w-4 h-4\" />\n <span class=\"sr-only\">Close</span>\n </DialogClose>\n </DialogContent>\n </DialogOverlay>\n </DialogPortal>\n</template>\n"
|
"content": "<script setup lang=\"ts\">\nimport { type HTMLAttributes, computed } from 'vue'\nimport {\n DialogClose,\n DialogContent,\n type DialogContentEmits,\n type DialogContentProps,\n DialogOverlay,\n DialogPortal,\n useForwardPropsEmits,\n} from 'radix-vue'\nimport { Cross2Icon } from '@radix-icons/vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<DialogContentProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<DialogContentEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <DialogPortal>\n <DialogOverlay\n class=\"fixed inset-0 z-50 grid place-items-center overflow-y-auto bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\"\n >\n <DialogContent\n :class=\"\n cn(\n 'relative z-50 grid w-full max-w-lg my-8 gap-4 border border-border bg-background p-6 shadow-lg duration-200 sm:rounded-lg md:w-full',\n props.class,\n )\n \"\n v-bind=\"forwarded\"\n @pointer-down-outside=\"(event) => {\n const originalEvent = event.detail.originalEvent;\n const target = originalEvent.target as HTMLElement;\n if (originalEvent.offsetX > target.clientWidth || originalEvent.offsetY > target.clientHeight) {\n event.preventDefault();\n }\n }\"\n >\n <slot />\n\n <DialogClose\n class=\"absolute top-4 right-4 p-0.5 transition-colors rounded-md hover:bg-secondary\"\n >\n <Cross2Icon class=\"w-4 h-4\" />\n <span class=\"sr-only\">Close</span>\n </DialogClose>\n </DialogContent>\n </DialogOverlay>\n </DialogPortal>\n</template>\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "DialogTitle.vue",
|
"name": "DialogTitle.vue",
|
||||||
|
|
|
||||||
|
|
@ -79,9 +79,9 @@
|
||||||
"@types/diff": "^5.2.1",
|
"@types/diff": "^5.2.1",
|
||||||
"@types/fs-extra": "^11.0.4",
|
"@types/fs-extra": "^11.0.4",
|
||||||
"@types/lodash-es": "^4.17.12",
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/node": "^20.14.11",
|
"@types/node": "^20.14.12",
|
||||||
"@types/prompts": "^2.4.9",
|
"@types/prompts": "^2.4.9",
|
||||||
"tsup": "^8.2.2",
|
"tsup": "^8.2.3",
|
||||||
"type-fest": "^4.23.0",
|
"type-fest": "^4.23.0",
|
||||||
"typescript": "^5.5.3",
|
"typescript": "^5.5.3",
|
||||||
"vite-tsconfig-paths": "^4.3.2"
|
"vite-tsconfig-paths": "^4.3.2"
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@
|
||||||
"@nuxt/module-builder": "^0.8.1",
|
"@nuxt/module-builder": "^0.8.1",
|
||||||
"@nuxt/schema": "^3.12.4",
|
"@nuxt/schema": "^3.12.4",
|
||||||
"@nuxt/test-utils": "^3.13.1",
|
"@nuxt/test-utils": "^3.13.1",
|
||||||
"@types/node": "^20.14.11",
|
"@types/node": "^20.14.12",
|
||||||
"nuxt": "^3.12.4"
|
"nuxt": "^3.12.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
670
pnpm-lock.yaml
670
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
|
@ -1,8 +1,7 @@
|
||||||
packages:
|
packages:
|
||||||
- 'apps/*'
|
- apps/*
|
||||||
- 'packages/*'
|
- packages/*
|
||||||
|
|
||||||
catalog:
|
catalog:
|
||||||
|
'@oxc-parser/wasm': ^0.22.0
|
||||||
radix-vue: ^1.9.2
|
radix-vue: ^1.9.2
|
||||||
zod: ^3.23.8
|
zod: ^3.23.8
|
||||||
'@oxc-parser/wasm': ^0.22.0
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user