From d2aa7534fe36ec47c5187df2a4855291b72ab9be Mon Sep 17 00:00:00 2001 From: zernonia Date: Fri, 6 Oct 2023 13:26:59 +0800 Subject: [PATCH] chore: build registry --- .eslintrc.cjs | 1 + apps/www/.vitepress/theme/config/docs.ts | 2 - apps/www/__registry__/index.ts | 294 ++++++++++++++++++ apps/www/src/lib/registry/registry.ts | 2 +- apps/www/src/public/registry/index.json | 22 ++ .../public/registry/styles/default/form.json | 40 ++- .../styles/new-york/alert-dialog.json | 4 +- .../public/registry/styles/new-york/form.json | 40 ++- 8 files changed, 382 insertions(+), 23 deletions(-) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index db30a80c..d901d874 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -13,5 +13,6 @@ module.exports = { 'no-tabs': 'off', 'no-invalid-character': 'off', 'import/first': 'off', + '@stylistic/js/no-tabs': 'off', }, } diff --git a/apps/www/.vitepress/theme/config/docs.ts b/apps/www/.vitepress/theme/config/docs.ts index 43908ea9..5aba6230 100644 --- a/apps/www/.vitepress/theme/config/docs.ts +++ b/apps/www/.vitepress/theme/config/docs.ts @@ -181,13 +181,11 @@ export const docsConfig: DocsConfig = { { title: 'Combobox', href: '/docs/components/combobox', - label: 'New', items: [], }, { title: 'Command', href: '/docs/components/command', - label: 'New', items: [], }, { diff --git a/apps/www/__registry__/index.ts b/apps/www/__registry__/index.ts index 73cd6b10..306df795 100644 --- a/apps/www/__registry__/index.ts +++ b/apps/www/__registry__/index.ts @@ -100,6 +100,27 @@ export const Index = { component: () => import('../src/lib/registry/default/example/CheckboxDisabled.vue').then(m => m.default), files: ['../src/lib/registry/default/example/CheckboxDisabled.vue'], }, + CheckboxFormMultiple: { + name: 'CheckboxFormMultiple', + type: 'components:example', + registryDependencies: ['button', 'form', 'checkbox'], + component: () => import('../src/lib/registry/default/example/CheckboxFormMultiple.vue').then(m => m.default), + files: ['../src/lib/registry/default/example/CheckboxFormMultiple.vue'], + }, + CheckboxFormSingle: { + name: 'CheckboxFormSingle', + type: 'components:example', + registryDependencies: ['button', 'form', 'checkbox'], + component: () => import('../src/lib/registry/default/example/CheckboxFormSingle.vue').then(m => m.default), + files: ['../src/lib/registry/default/example/CheckboxFormSingle.vue'], + }, + CheckboxWithText: { + name: 'CheckboxWithText', + type: 'components:example', + registryDependencies: ['checkbox'], + component: () => import('../src/lib/registry/default/example/CheckboxWithText.vue').then(m => m.default), + files: ['../src/lib/registry/default/example/CheckboxWithText.vue'], + }, CollapsibleDemo: { name: 'CollapsibleDemo', type: 'components:example', @@ -114,6 +135,27 @@ export const Index = { component: () => import('../src/lib/registry/default/example/ComboboxDemo.vue').then(m => m.default), files: ['../src/lib/registry/default/example/ComboboxDemo.vue'], }, + ComboboxDropdownMenu: { + name: 'ComboboxDropdownMenu', + type: 'components:example', + registryDependencies: ['button', 'command', 'dropdown-menu'], + component: () => import('../src/lib/registry/default/example/ComboboxDropdownMenu.vue').then(m => m.default), + files: ['../src/lib/registry/default/example/ComboboxDropdownMenu.vue'], + }, + ComboboxForm: { + name: 'ComboboxForm', + type: 'components:example', + registryDependencies: ['utils', 'button', 'command', 'form', 'popover'], + component: () => import('../src/lib/registry/default/example/ComboboxForm.vue').then(m => m.default), + files: ['../src/lib/registry/default/example/ComboboxForm.vue'], + }, + ComboboxPopover: { + name: 'ComboboxPopover', + type: 'components:example', + registryDependencies: ['utils', 'button', 'command', 'popover'], + component: () => import('../src/lib/registry/default/example/ComboboxPopover.vue').then(m => m.default), + files: ['../src/lib/registry/default/example/ComboboxPopover.vue'], + }, CommandDemo: { name: 'CommandDemo', type: 'components:example', @@ -149,6 +191,20 @@ export const Index = { component: () => import('../src/lib/registry/default/example/DatePickerDemo.vue').then(m => m.default), files: ['../src/lib/registry/default/example/DatePickerDemo.vue'], }, + DatePickerForm: { + name: 'DatePickerForm', + type: 'components:example', + registryDependencies: ['utils', 'button', 'calendar', 'form', 'popover'], + component: () => import('../src/lib/registry/default/example/DatePickerForm.vue').then(m => m.default), + files: ['../src/lib/registry/default/example/DatePickerForm.vue'], + }, + DatePickerWithPresets: { + name: 'DatePickerWithPresets', + type: 'components:example', + registryDependencies: ['utils', 'button', 'calendar', 'popover', 'select'], + component: () => import('../src/lib/registry/default/example/DatePickerWithPresets.vue').then(m => m.default), + files: ['../src/lib/registry/default/example/DatePickerWithPresets.vue'], + }, DatePickerWithRange: { name: 'DatePickerWithRange', type: 'components:example', @@ -184,6 +240,41 @@ export const Index = { component: () => import('../src/lib/registry/default/example/InputDemo.vue').then(m => m.default), files: ['../src/lib/registry/default/example/InputDemo.vue'], }, + InputDisabled: { + name: 'InputDisabled', + type: 'components:example', + registryDependencies: ['input'], + component: () => import('../src/lib/registry/default/example/InputDisabled.vue').then(m => m.default), + files: ['../src/lib/registry/default/example/InputDisabled.vue'], + }, + InputFile: { + name: 'InputFile', + type: 'components:example', + registryDependencies: ['input', 'label'], + component: () => import('../src/lib/registry/default/example/InputFile.vue').then(m => m.default), + files: ['../src/lib/registry/default/example/InputFile.vue'], + }, + InputForm: { + name: 'InputForm', + type: 'components:example', + registryDependencies: ['button', 'form', 'input'], + component: () => import('../src/lib/registry/default/example/InputForm.vue').then(m => m.default), + files: ['../src/lib/registry/default/example/InputForm.vue'], + }, + InputWithButton: { + name: 'InputWithButton', + type: 'components:example', + registryDependencies: ['input', 'button'], + component: () => import('../src/lib/registry/default/example/InputWithButton.vue').then(m => m.default), + files: ['../src/lib/registry/default/example/InputWithButton.vue'], + }, + InputWithLabel: { + name: 'InputWithLabel', + type: 'components:example', + registryDependencies: ['input', 'label'], + component: () => import('../src/lib/registry/default/example/InputWithLabel.vue').then(m => m.default), + files: ['../src/lib/registry/default/example/InputWithLabel.vue'], + }, LabelDemo: { name: 'LabelDemo', type: 'components:example', @@ -233,6 +324,13 @@ export const Index = { component: () => import('../src/lib/registry/default/example/RadioGroupDemo.vue').then(m => m.default), files: ['../src/lib/registry/default/example/RadioGroupDemo.vue'], }, + RadioGroupForm: { + name: 'RadioGroupForm', + type: 'components:example', + registryDependencies: ['button', 'form', 'radio-group'], + component: () => import('../src/lib/registry/default/example/RadioGroupForm.vue').then(m => m.default), + files: ['../src/lib/registry/default/example/RadioGroupForm.vue'], + }, ScrollAreaDemo: { name: 'ScrollAreaDemo', type: 'components:example', @@ -247,6 +345,13 @@ export const Index = { component: () => import('../src/lib/registry/default/example/SelectDemo.vue').then(m => m.default), files: ['../src/lib/registry/default/example/SelectDemo.vue'], }, + SelectForm: { + name: 'SelectForm', + type: 'components:example', + registryDependencies: ['button', 'form', 'select'], + component: () => import('../src/lib/registry/default/example/SelectForm.vue').then(m => m.default), + files: ['../src/lib/registry/default/example/SelectForm.vue'], + }, SeparatorDemo: { name: 'SeparatorDemo', type: 'components:example', @@ -282,6 +387,13 @@ export const Index = { component: () => import('../src/lib/registry/default/example/SwitchDemo.vue').then(m => m.default), files: ['../src/lib/registry/default/example/SwitchDemo.vue'], }, + SwitchForm: { + name: 'SwitchForm', + type: 'components:example', + registryDependencies: ['button', 'form', 'switch'], + component: () => import('../src/lib/registry/default/example/SwitchForm.vue').then(m => m.default), + files: ['../src/lib/registry/default/example/SwitchForm.vue'], + }, TableDemo: { name: 'TableDemo', type: 'components:example', @@ -303,6 +415,41 @@ export const Index = { component: () => import('../src/lib/registry/default/example/TextareaDemo.vue').then(m => m.default), files: ['../src/lib/registry/default/example/TextareaDemo.vue'], }, + TextareaDisabled: { + name: 'TextareaDisabled', + type: 'components:example', + registryDependencies: ['textarea'], + component: () => import('../src/lib/registry/default/example/TextareaDisabled.vue').then(m => m.default), + files: ['../src/lib/registry/default/example/TextareaDisabled.vue'], + }, + TextareaForm: { + name: 'TextareaForm', + type: 'components:example', + registryDependencies: ['button', 'form', 'textarea'], + component: () => import('../src/lib/registry/default/example/TextareaForm.vue').then(m => m.default), + files: ['../src/lib/registry/default/example/TextareaForm.vue'], + }, + TextareaWithButton: { + name: 'TextareaWithButton', + type: 'components:example', + registryDependencies: ['textarea', 'button'], + component: () => import('../src/lib/registry/default/example/TextareaWithButton.vue').then(m => m.default), + files: ['../src/lib/registry/default/example/TextareaWithButton.vue'], + }, + TextareaWithLabel: { + name: 'TextareaWithLabel', + type: 'components:example', + registryDependencies: ['textarea', 'label'], + component: () => import('../src/lib/registry/default/example/TextareaWithLabel.vue').then(m => m.default), + files: ['../src/lib/registry/default/example/TextareaWithLabel.vue'], + }, + TextareaWithText: { + name: 'TextareaWithText', + type: 'components:example', + registryDependencies: ['textarea', 'label'], + component: () => import('../src/lib/registry/default/example/TextareaWithText.vue').then(m => m.default), + files: ['../src/lib/registry/default/example/TextareaWithText.vue'], + }, ToggleDemo: { name: 'ToggleDemo', type: 'components:example', @@ -536,6 +683,27 @@ export const Index = { component: () => import('../src/lib/registry/new-york/example/CheckboxDisabled.vue').then(m => m.default), files: ['../src/lib/registry/new-york/example/CheckboxDisabled.vue'], }, + CheckboxFormMultiple: { + name: 'CheckboxFormMultiple', + type: 'components:example', + registryDependencies: ['button', 'form', 'checkbox'], + component: () => import('../src/lib/registry/new-york/example/CheckboxFormMultiple.vue').then(m => m.default), + files: ['../src/lib/registry/new-york/example/CheckboxFormMultiple.vue'], + }, + CheckboxFormSingle: { + name: 'CheckboxFormSingle', + type: 'components:example', + registryDependencies: ['button', 'form', 'checkbox'], + component: () => import('../src/lib/registry/new-york/example/CheckboxFormSingle.vue').then(m => m.default), + files: ['../src/lib/registry/new-york/example/CheckboxFormSingle.vue'], + }, + CheckboxWithText: { + name: 'CheckboxWithText', + type: 'components:example', + registryDependencies: ['checkbox'], + component: () => import('../src/lib/registry/new-york/example/CheckboxWithText.vue').then(m => m.default), + files: ['../src/lib/registry/new-york/example/CheckboxWithText.vue'], + }, CollapsibleDemo: { name: 'CollapsibleDemo', type: 'components:example', @@ -550,6 +718,27 @@ export const Index = { component: () => import('../src/lib/registry/new-york/example/ComboboxDemo.vue').then(m => m.default), files: ['../src/lib/registry/new-york/example/ComboboxDemo.vue'], }, + ComboboxDropdownMenu: { + name: 'ComboboxDropdownMenu', + type: 'components:example', + registryDependencies: ['button', 'command', 'dropdown-menu'], + component: () => import('../src/lib/registry/new-york/example/ComboboxDropdownMenu.vue').then(m => m.default), + files: ['../src/lib/registry/new-york/example/ComboboxDropdownMenu.vue'], + }, + ComboboxForm: { + name: 'ComboboxForm', + type: 'components:example', + registryDependencies: ['utils', 'button', 'command', 'form', 'popover'], + component: () => import('../src/lib/registry/new-york/example/ComboboxForm.vue').then(m => m.default), + files: ['../src/lib/registry/new-york/example/ComboboxForm.vue'], + }, + ComboboxPopover: { + name: 'ComboboxPopover', + type: 'components:example', + registryDependencies: ['utils', 'button', 'command', 'popover'], + component: () => import('../src/lib/registry/new-york/example/ComboboxPopover.vue').then(m => m.default), + files: ['../src/lib/registry/new-york/example/ComboboxPopover.vue'], + }, CommandDemo: { name: 'CommandDemo', type: 'components:example', @@ -585,6 +774,20 @@ export const Index = { component: () => import('../src/lib/registry/new-york/example/DatePickerDemo.vue').then(m => m.default), files: ['../src/lib/registry/new-york/example/DatePickerDemo.vue'], }, + DatePickerForm: { + name: 'DatePickerForm', + type: 'components:example', + registryDependencies: ['utils', 'button', 'calendar', 'form', 'popover'], + component: () => import('../src/lib/registry/new-york/example/DatePickerForm.vue').then(m => m.default), + files: ['../src/lib/registry/new-york/example/DatePickerForm.vue'], + }, + DatePickerWithPresets: { + name: 'DatePickerWithPresets', + type: 'components:example', + registryDependencies: ['utils', 'button', 'calendar', 'popover', 'select'], + component: () => import('../src/lib/registry/new-york/example/DatePickerWithPresets.vue').then(m => m.default), + files: ['../src/lib/registry/new-york/example/DatePickerWithPresets.vue'], + }, DatePickerWithRange: { name: 'DatePickerWithRange', type: 'components:example', @@ -620,6 +823,41 @@ export const Index = { component: () => import('../src/lib/registry/new-york/example/InputDemo.vue').then(m => m.default), files: ['../src/lib/registry/new-york/example/InputDemo.vue'], }, + InputDisabled: { + name: 'InputDisabled', + type: 'components:example', + registryDependencies: ['input'], + component: () => import('../src/lib/registry/new-york/example/InputDisabled.vue').then(m => m.default), + files: ['../src/lib/registry/new-york/example/InputDisabled.vue'], + }, + InputFile: { + name: 'InputFile', + type: 'components:example', + registryDependencies: ['input', 'label'], + component: () => import('../src/lib/registry/new-york/example/InputFile.vue').then(m => m.default), + files: ['../src/lib/registry/new-york/example/InputFile.vue'], + }, + InputForm: { + name: 'InputForm', + type: 'components:example', + registryDependencies: ['button', 'form', 'input'], + component: () => import('../src/lib/registry/new-york/example/InputForm.vue').then(m => m.default), + files: ['../src/lib/registry/new-york/example/InputForm.vue'], + }, + InputWithButton: { + name: 'InputWithButton', + type: 'components:example', + registryDependencies: ['input', 'button'], + component: () => import('../src/lib/registry/new-york/example/InputWithButton.vue').then(m => m.default), + files: ['../src/lib/registry/new-york/example/InputWithButton.vue'], + }, + InputWithLabel: { + name: 'InputWithLabel', + type: 'components:example', + registryDependencies: ['input', 'label'], + component: () => import('../src/lib/registry/new-york/example/InputWithLabel.vue').then(m => m.default), + files: ['../src/lib/registry/new-york/example/InputWithLabel.vue'], + }, LabelDemo: { name: 'LabelDemo', type: 'components:example', @@ -669,6 +907,13 @@ export const Index = { component: () => import('../src/lib/registry/new-york/example/RadioGroupDemo.vue').then(m => m.default), files: ['../src/lib/registry/new-york/example/RadioGroupDemo.vue'], }, + RadioGroupForm: { + name: 'RadioGroupForm', + type: 'components:example', + registryDependencies: ['button', 'form', 'radio-group'], + component: () => import('../src/lib/registry/new-york/example/RadioGroupForm.vue').then(m => m.default), + files: ['../src/lib/registry/new-york/example/RadioGroupForm.vue'], + }, ScrollAreaDemo: { name: 'ScrollAreaDemo', type: 'components:example', @@ -683,6 +928,13 @@ export const Index = { component: () => import('../src/lib/registry/new-york/example/SelectDemo.vue').then(m => m.default), files: ['../src/lib/registry/new-york/example/SelectDemo.vue'], }, + SelectForm: { + name: 'SelectForm', + type: 'components:example', + registryDependencies: ['button', 'form', 'select'], + component: () => import('../src/lib/registry/new-york/example/SelectForm.vue').then(m => m.default), + files: ['../src/lib/registry/new-york/example/SelectForm.vue'], + }, SeparatorDemo: { name: 'SeparatorDemo', type: 'components:example', @@ -718,6 +970,13 @@ export const Index = { component: () => import('../src/lib/registry/new-york/example/SwitchDemo.vue').then(m => m.default), files: ['../src/lib/registry/new-york/example/SwitchDemo.vue'], }, + SwitchForm: { + name: 'SwitchForm', + type: 'components:example', + registryDependencies: ['button', 'form', 'switch'], + component: () => import('../src/lib/registry/new-york/example/SwitchForm.vue').then(m => m.default), + files: ['../src/lib/registry/new-york/example/SwitchForm.vue'], + }, TableDemo: { name: 'TableDemo', type: 'components:example', @@ -739,6 +998,41 @@ export const Index = { component: () => import('../src/lib/registry/new-york/example/TextareaDemo.vue').then(m => m.default), files: ['../src/lib/registry/new-york/example/TextareaDemo.vue'], }, + TextareaDisabled: { + name: 'TextareaDisabled', + type: 'components:example', + registryDependencies: ['textarea'], + component: () => import('../src/lib/registry/new-york/example/TextareaDisabled.vue').then(m => m.default), + files: ['../src/lib/registry/new-york/example/TextareaDisabled.vue'], + }, + TextareaForm: { + name: 'TextareaForm', + type: 'components:example', + registryDependencies: ['button', 'form', 'textarea'], + component: () => import('../src/lib/registry/new-york/example/TextareaForm.vue').then(m => m.default), + files: ['../src/lib/registry/new-york/example/TextareaForm.vue'], + }, + TextareaWithButton: { + name: 'TextareaWithButton', + type: 'components:example', + registryDependencies: ['textarea', 'button'], + component: () => import('../src/lib/registry/new-york/example/TextareaWithButton.vue').then(m => m.default), + files: ['../src/lib/registry/new-york/example/TextareaWithButton.vue'], + }, + TextareaWithLabel: { + name: 'TextareaWithLabel', + type: 'components:example', + registryDependencies: ['textarea', 'label'], + component: () => import('../src/lib/registry/new-york/example/TextareaWithLabel.vue').then(m => m.default), + files: ['../src/lib/registry/new-york/example/TextareaWithLabel.vue'], + }, + TextareaWithText: { + name: 'TextareaWithText', + type: 'components:example', + registryDependencies: ['textarea', 'label'], + component: () => import('../src/lib/registry/new-york/example/TextareaWithText.vue').then(m => m.default), + files: ['../src/lib/registry/new-york/example/TextareaWithText.vue'], + }, ToggleDemo: { name: 'ToggleDemo', type: 'components:example', diff --git a/apps/www/src/lib/registry/registry.ts b/apps/www/src/lib/registry/registry.ts index 3ffd3248..748d46d9 100644 --- a/apps/www/src/lib/registry/registry.ts +++ b/apps/www/src/lib/registry/registry.ts @@ -8,7 +8,7 @@ const DEPENDENCIES = new Map([ ['radix-vue', []], ['v-calendar', []], ['@tanstack/vue-table', []], - ['formsnap', ['zod']], + ['vee-validate', ['@vee-validate/zod', 'zod']], ]) const REGISTRY_DEPENDENCY = '@/' diff --git a/apps/www/src/public/registry/index.json b/apps/www/src/public/registry/index.json index 5c64658a..b1dd237c 100644 --- a/apps/www/src/public/registry/index.json +++ b/apps/www/src/public/registry/index.json @@ -262,6 +262,28 @@ ], "type": "components:ui" }, + { + "name": "form", + "dependencies": [ + "radix-vue", + "vee-validate", + "@vee-validate/zod", + "zod" + ], + "registryDependencies": [ + "utils" + ], + "files": [ + "ui/form/FormControl.vue", + "ui/form/FormDescription.vue", + "ui/form/FormItem.vue", + "ui/form/FormLabel.vue", + "ui/form/FormMessage.vue", + "ui/form/index.ts", + "ui/form/useFormField.ts" + ], + "type": "components:ui" + }, { "name": "hover-card", "dependencies": [ diff --git a/apps/www/src/public/registry/styles/default/form.json b/apps/www/src/public/registry/styles/default/form.json index 965b08e7..590b4882 100644 --- a/apps/www/src/public/registry/styles/default/form.json +++ b/apps/www/src/public/registry/styles/default/form.json @@ -1,20 +1,42 @@ { "name": "form", "dependencies": [ - "@radix-ui/react-label", - "@radix-ui/react-slot", - "@hookform/resolvers", - "zod", - "react-hook-form" + "radix-vue", + "vee-validate", + "@vee-validate/zod", + "zod" ], "registryDependencies": [ - "button", - "label" + "utils" ], "files": [ { - "name": "form.tsx", - "content": "import * as React from \"react\"\nimport * as LabelPrimitive from \"@radix-ui/react-label\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport {\n Controller,\n ControllerProps,\n FieldPath,\n FieldValues,\n FormProvider,\n useFormContext,\n} from \"react-hook-form\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Label } from \"@/registry/default/ui/label\"\n\nconst Form = FormProvider\n\ntype FormFieldContextValue<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath = FieldPath\n> = {\n name: TName\n}\n\nconst FormFieldContext = React.createContext(\n {} as FormFieldContextValue\n)\n\nconst FormField = <\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath = FieldPath\n>({\n ...props\n}: ControllerProps) => {\n return (\n \n \n \n )\n}\n\nconst useFormField = () => {\n const fieldContext = React.useContext(FormFieldContext)\n const itemContext = React.useContext(FormItemContext)\n const { getFieldState, formState } = useFormContext()\n\n const fieldState = getFieldState(fieldContext.name, formState)\n\n if (!fieldContext) {\n throw new Error(\"useFormField should be used within \")\n }\n\n const { id } = itemContext\n\n return {\n id,\n name: fieldContext.name,\n formItemId: `${id}-form-item`,\n formDescriptionId: `${id}-form-item-description`,\n formMessageId: `${id}-form-item-message`,\n ...fieldState,\n }\n}\n\ntype FormItemContextValue = {\n id: string\n}\n\nconst FormItemContext = React.createContext(\n {} as FormItemContextValue\n)\n\nconst FormItem = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes\n>(({ class, ...props }, ref) => {\n const id = React.useId()\n\n return (\n \n
\n \n )\n})\nFormItem.displayName = \"FormItem\"\n\nconst FormLabel = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ class, ...props }, ref) => {\n const { error, formItemId } = useFormField()\n\n return (\n \n )\n})\nFormLabel.displayName = \"FormLabel\"\n\nconst FormControl = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ ...props }, ref) => {\n const { error, formItemId, formDescriptionId, formMessageId } = useFormField()\n\n return (\n \n )\n})\nFormControl.displayName = \"FormControl\"\n\nconst FormDescription = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes\n>(({ class, ...props }, ref) => {\n const { formDescriptionId } = useFormField()\n\n return (\n \n )\n})\nFormDescription.displayName = \"FormDescription\"\n\nconst FormMessage = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes\n>(({ class, children, ...props }, ref) => {\n const { error, formMessageId } = useFormField()\n const body = error ? String(error?.message) : children\n\n if (!body) {\n return null\n }\n\n return (\n \n {body}\n

\n )\n})\nFormMessage.displayName = \"FormMessage\"\n\nexport {\n useFormField,\n Form,\n FormItem,\n FormLabel,\n FormControl,\n FormDescription,\n FormMessage,\n FormField,\n}\n" + "name": "FormControl.vue", + "content": "\n\n\n" + }, + { + "name": "FormDescription.vue", + "content": "\n\n\n" + }, + { + "name": "FormItem.vue", + "content": "\n\n\n\n\n" + }, + { + "name": "FormLabel.vue", + "content": "\n\n\n" + }, + { + "name": "FormMessage.vue", + "content": "\n\n\n" + }, + { + "name": "index.ts", + "content": "export { Form, Field as FormField } from 'vee-validate'\nexport { default as FormItem } from './FormItem.vue'\nexport { default as FormLabel } from './FormLabel.vue'\nexport { default as FormControl } from './FormControl.vue'\nexport { default as FormMessage } from './FormMessage.vue'\nexport { default as FormDescription } from './FormDescription.vue'\n" + }, + { + "name": "useFormField.ts", + "content": "import { FieldContextKey, useFieldError, useIsFieldDirty, useIsFieldTouched, useIsFieldValid } from 'vee-validate'\nimport { inject } from 'vue'\nimport { FORMI_TEM_INJECTION_KEY } from './FormItem.vue'\n\nexport function useFormField() {\n const fieldContext = inject(FieldContextKey)\n const fieldItemContext = inject(FORMI_TEM_INJECTION_KEY)\n\n const fieldState = {\n valid: useIsFieldValid(),\n isDirty: useIsFieldDirty(),\n isTouched: useIsFieldTouched(),\n error: useFieldError(),\n }\n\n if (!fieldContext)\n throw new Error('useFormField should be used within ')\n\n const { name } = fieldContext\n const id = fieldItemContext\n\n return {\n id,\n name,\n formItemId: `${id}-form-item`,\n formDescriptionId: `${id}-form-item-description`,\n formMessageId: `${id}-form-item-message`,\n ...fieldState,\n }\n}\n" } ], "type": "components:ui" diff --git a/apps/www/src/public/registry/styles/new-york/alert-dialog.json b/apps/www/src/public/registry/styles/new-york/alert-dialog.json index eb66609e..2cf70dc1 100644 --- a/apps/www/src/public/registry/styles/new-york/alert-dialog.json +++ b/apps/www/src/public/registry/styles/new-york/alert-dialog.json @@ -14,11 +14,11 @@ }, { "name": "AlertDialogAction.vue", - "content": "\n\n\n" + "content": "\n\n\n" }, { "name": "AlertDialogCancel.vue", - "content": "\n\n\n" + "content": "\n\n\n" }, { "name": "AlertDialogContent.vue", diff --git a/apps/www/src/public/registry/styles/new-york/form.json b/apps/www/src/public/registry/styles/new-york/form.json index 6720291c..6c1ee60b 100644 --- a/apps/www/src/public/registry/styles/new-york/form.json +++ b/apps/www/src/public/registry/styles/new-york/form.json @@ -1,20 +1,42 @@ { "name": "form", "dependencies": [ - "@radix-ui/react-label", - "@radix-ui/react-slot", - "@hookform/resolvers", - "zod", - "react-hook-form" + "radix-vue", + "vee-validate", + "@vee-validate/zod", + "zod" ], "registryDependencies": [ - "button", - "label" + "utils" ], "files": [ { - "name": "form.tsx", - "content": "import * as React from \"react\"\nimport * as LabelPrimitive from \"@radix-ui/react-label\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport {\n Controller,\n ControllerProps,\n FieldPath,\n FieldValues,\n FormProvider,\n useFormContext,\n} from \"react-hook-form\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Label } from \"@/registry/new-york/ui/label\"\n\nconst Form = FormProvider\n\ntype FormFieldContextValue<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath = FieldPath\n> = {\n name: TName\n}\n\nconst FormFieldContext = React.createContext(\n {} as FormFieldContextValue\n)\n\nconst FormField = <\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath = FieldPath\n>({\n ...props\n}: ControllerProps) => {\n return (\n \n \n \n )\n}\n\nconst useFormField = () => {\n const fieldContext = React.useContext(FormFieldContext)\n const itemContext = React.useContext(FormItemContext)\n const { getFieldState, formState } = useFormContext()\n\n const fieldState = getFieldState(fieldContext.name, formState)\n\n if (!fieldContext) {\n throw new Error(\"useFormField should be used within \")\n }\n\n const { id } = itemContext\n\n return {\n id,\n name: fieldContext.name,\n formItemId: `${id}-form-item`,\n formDescriptionId: `${id}-form-item-description`,\n formMessageId: `${id}-form-item-message`,\n ...fieldState,\n }\n}\n\ntype FormItemContextValue = {\n id: string\n}\n\nconst FormItemContext = React.createContext(\n {} as FormItemContextValue\n)\n\nconst FormItem = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes\n>(({ class, ...props }, ref) => {\n const id = React.useId()\n\n return (\n \n
\n \n )\n})\nFormItem.displayName = \"FormItem\"\n\nconst FormLabel = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ class, ...props }, ref) => {\n const { error, formItemId } = useFormField()\n\n return (\n \n )\n})\nFormLabel.displayName = \"FormLabel\"\n\nconst FormControl = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ ...props }, ref) => {\n const { error, formItemId, formDescriptionId, formMessageId } = useFormField()\n\n return (\n \n )\n})\nFormControl.displayName = \"FormControl\"\n\nconst FormDescription = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes\n>(({ class, ...props }, ref) => {\n const { formDescriptionId } = useFormField()\n\n return (\n \n )\n})\nFormDescription.displayName = \"FormDescription\"\n\nconst FormMessage = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes\n>(({ class, children, ...props }, ref) => {\n const { error, formMessageId } = useFormField()\n const body = error ? String(error?.message) : children\n\n if (!body) {\n return null\n }\n\n return (\n \n {body}\n

\n )\n})\nFormMessage.displayName = \"FormMessage\"\n\nexport {\n useFormField,\n Form,\n FormItem,\n FormLabel,\n FormControl,\n FormDescription,\n FormMessage,\n FormField,\n}\n" + "name": "FormControl.vue", + "content": "\n\n\n" + }, + { + "name": "FormDescription.vue", + "content": "\n\n\n" + }, + { + "name": "FormItem.vue", + "content": "\n\n\n\n\n" + }, + { + "name": "FormLabel.vue", + "content": "\n\n\n" + }, + { + "name": "FormMessage.vue", + "content": "\n\n\n" + }, + { + "name": "index.ts", + "content": "export { Form, Field as FormField } from 'vee-validate'\nexport { default as FormItem } from './FormItem.vue'\nexport { default as FormLabel } from './FormLabel.vue'\nexport { default as FormControl } from './FormControl.vue'\nexport { default as FormMessage } from './FormMessage.vue'\nexport { default as FormDescription } from './FormDescription.vue'\n" + }, + { + "name": "useFormField.ts", + "content": "import { FieldContextKey, useFieldError, useIsFieldDirty, useIsFieldTouched, useIsFieldValid } from 'vee-validate'\nimport { inject } from 'vue'\nimport { FORMI_TEM_INJECTION_KEY } from './FormItem.vue'\n\nexport function useFormField() {\n const fieldContext = inject(FieldContextKey)\n const fieldItemContext = inject(FORMI_TEM_INJECTION_KEY)\n\n const fieldState = {\n valid: useIsFieldValid(),\n isDirty: useIsFieldDirty(),\n isTouched: useIsFieldTouched(),\n error: useFieldError(),\n }\n\n if (!fieldContext)\n throw new Error('useFormField should be used within ')\n\n const { name } = fieldContext\n const id = fieldItemContext\n\n return {\n id,\n name,\n formItemId: `${id}-form-item`,\n formDescriptionId: `${id}-form-item-description`,\n formMessageId: `${id}-form-item-message`,\n ...fieldState,\n }\n}\n" } ], "type": "components:ui"