|
| 1 | +{ |
| 2 | + "$schema": "https://ui.shadcn.com/schema/registry-item.json", |
| 3 | + "name": "form", |
| 4 | + "type": "registry:block", |
| 5 | + "title": "Form", |
| 6 | + "files": [ |
| 7 | + { |
| 8 | + "path": "src/components/form/FormField.tsx", |
| 9 | + "content": "'use client';\n\nimport { useId } from 'react';\nimport type { AllPathsKeys } from 'skyroc-form';\nimport { Field, useFieldError } from 'skyroc-form';\n\nimport { cn } from '@/lib/utils';\n\nimport FormLabel from '../label/Label';\n\nimport { formVariants } from './form-variants';\nimport type { FormFieldProps } from './types';\n\nconst FormField = <Values = any,>(props: FormFieldProps<Values>) => {\n const { children, className, description, label, name, size, ...rest } = props;\n\n const id = useId();\n\n const errors = useFieldError<Values, AllPathsKeys<Values>>(name);\n\n const hasError = errors.length > 0;\n\n const formItemId = `${id}-form-item`;\n const formDescriptionId = `${id}-form-item-description`;\n const formMessageId = `${id}-form-item-message`;\n\n const {\n description: descriptionCls,\n item,\n label: labelCls,\n message\n } = formVariants({ error: errors.length > 0, size });\n\n const mergedCls = {\n description: cn(descriptionCls(), className),\n item: cn(item(), className),\n label: cn(labelCls()),\n message: cn(message(), className)\n };\n\n return (\n <div className={mergedCls.item}>\n <FormLabel\n className={mergedCls.label}\n data-error={hasError}\n data-slot=\"form-label\"\n htmlFor={id}\n size={size}\n >\n {label}\n </FormLabel>\n\n <Field\n {...rest}\n aria-describedby={!hasError ? `${formDescriptionId}` : `${formDescriptionId} ${formMessageId}`}\n aria-invalid={hasError}\n id={id}\n name={name}\n >\n {children}\n </Field>\n\n {description && (\n <p\n className={mergedCls.description}\n id={formDescriptionId}\n >\n {description}\n </p>\n )}\n\n {hasError && (\n <p\n className={mergedCls.message}\n id={formMessageId}\n >\n {errors[0]}\n </p>\n )}\n </div>\n );\n};\n\nexport default FormField;\n", |
| 10 | + "type": "registry:ui", |
| 11 | + "target": "components/form/FormField.tsx" |
| 12 | + }, |
| 13 | + { |
| 14 | + "path": "src/components/form/form-variants.ts", |
| 15 | + "content": "import { tv } from 'tailwind-variants';\n\nexport const formVariants = tv({\n defaultVariants: {\n error: false,\n size: 'md'\n },\n slots: {\n description: `text-muted-foreground`,\n item: `form-item`,\n label: 'flex items-center data-[error=true]:text-destructive',\n message: `font-medium text-destructive`\n },\n variants: {\n error: {\n true: {\n message: `text-destructive`\n }\n },\n size: {\n '2xl': {\n item: 'text-xl space-y-3.5',\n label: 'gap-3.5'\n },\n lg: {\n item: 'text-base space-y-2.5',\n label: 'gap-2.5'\n },\n md: {\n item: 'text-sm space-y-2',\n label: 'gap-2'\n },\n sm: {\n item: 'text-xs space-y-1.75',\n label: 'gap-1.75'\n },\n xl: {\n item: 'text-lg space-y-3',\n label: 'gap-3'\n },\n xs: {\n item: 'text-2xs space-y-1.5',\n label: 'gap-1.5'\n }\n }\n }\n});\n\nexport type FormSlots = keyof typeof formVariants.slots;\n", |
| 16 | + "type": "registry:ui", |
| 17 | + "target": "components/form/form-variants.ts" |
| 18 | + }, |
| 19 | + { |
| 20 | + "path": "src/components/form/index.ts", |
| 21 | + "content": "'use client';\n\nexport {\n ComputedField as FormComputedField,\n Form,\n List as FormList,\n useEffectField,\n useFieldError,\n useFieldState,\n useForm,\n useSelector,\n useUndoRedo,\n useWatch\n} from 'skyroc-form';\n\nexport type { Action as FormAction, FormInstance } from 'skyroc-form';\n\nexport { default as FormField } from './FormField';\n\nexport type { FormFieldProps } from './types';\n", |
| 22 | + "type": "registry:ui", |
| 23 | + "target": "components/form/index.ts" |
| 24 | + }, |
| 25 | + { |
| 26 | + "path": "src/components/form/types.ts", |
| 27 | + "content": "import type { ReactNode } from 'react';\nimport type { FieldProps } from 'skyroc-form';\n\nimport type { BaseProps } from '@/types/other';\n\nexport type FormFieldProps<Values = any> = FieldProps<Values> &\n BaseProps<{\n description?: string;\n error?: string;\n label?: ReactNode;\n required?: boolean;\n }>;\n", |
| 28 | + "type": "registry:ui", |
| 29 | + "target": "components/form/types.ts" |
| 30 | + } |
| 31 | + ] |
| 32 | +} |
0 commit comments