UNPKG

@arolariu/components

Version:

🎨 70+ beautiful, accessible React components built on Radix UI. TypeScript-first, tree-shakeable, SSR-ready. Perfect for modern web apps, design systems & rapid prototyping. Zero config, maximum flexibility! ⚡

96 lines (95 loc) • 3.63 kB
"use client"; import { jsx } from "react/jsx-runtime"; import { Slot } from "@radix-ui/react-slot"; import { createContext, forwardRef, useContext, useId } from "react"; import { Controller, FormProvider, useFormContext } from "react-hook-form"; import { Label } from "./label.js"; import { cn } from "../../lib/utilities.js"; const Form = FormProvider; const FormFieldContext = /*#__PURE__*/ createContext(null); const FormField = ({ ...props })=>/*#__PURE__*/ jsx(FormFieldContext.Provider, { value: { name: props.name }, children: /*#__PURE__*/ jsx(Controller, { ...props }) }); const useFormField = ()=>{ const fieldContext = useContext(FormFieldContext); const itemContext = useContext(FormItemContext); const { getFieldState, formState } = useFormContext(); if (!fieldContext) throw new Error("useFormField should be used within <FormField>"); if (!itemContext) throw new Error("useFormField should be used within <FormItem>"); const fieldState = getFieldState(fieldContext.name, formState); const { id } = itemContext; return { id, name: fieldContext.name, formItemId: `${id}-form-item`, formDescriptionId: `${id}-form-item-description`, formMessageId: `${id}-form-item-message`, ...fieldState }; }; const FormItemContext = /*#__PURE__*/ createContext(null); const FormItem = /*#__PURE__*/ forwardRef(({ className, ...props }, ref)=>{ const id = useId(); return /*#__PURE__*/ jsx(FormItemContext.Provider, { value: { id }, children: /*#__PURE__*/ jsx("div", { ref: ref, className: cn("space-y-2", className), ...props }) }); }); FormItem.displayName = "FormItem"; const FormLabel = /*#__PURE__*/ forwardRef(({ className, ...props }, ref)=>{ const { error, formItemId } = useFormField(); return /*#__PURE__*/ jsx(Label, { ref: ref, className: cn(error && "text-red-500 dark:text-red-900", className), htmlFor: formItemId, ...props }); }); FormLabel.displayName = "FormLabel"; const FormControl = /*#__PURE__*/ forwardRef(({ ...props }, ref)=>{ const { error, formItemId, formDescriptionId, formMessageId } = useFormField(); return /*#__PURE__*/ jsx(Slot, { ref: ref, id: formItemId, "aria-describedby": error ? `${formDescriptionId} ${formMessageId}` : `${formDescriptionId}`, "aria-invalid": Boolean(error), ...props }); }); FormControl.displayName = "FormControl"; const FormDescription = /*#__PURE__*/ forwardRef(({ className, ...props }, ref)=>{ const { formDescriptionId } = useFormField(); return /*#__PURE__*/ jsx("p", { ref: ref, id: formDescriptionId, className: cn("text-[0.8rem] text-neutral-500 dark:text-neutral-400", className), ...props }); }); FormDescription.displayName = "FormDescription"; const FormMessage = /*#__PURE__*/ forwardRef(({ className, children, ...props }, ref)=>{ const { error, formMessageId } = useFormField(); const body = error ? String(error?.message ?? "") : children; if (!body) return null; return /*#__PURE__*/ jsx("p", { ref: ref, id: formMessageId, className: cn("text-[0.8rem] font-medium text-red-500 dark:text-red-900", className), ...props, children: body }); }); FormMessage.displayName = "FormMessage"; export { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, useFormField }; //# sourceMappingURL=form.js.map