bruv-ui 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/form-rhf.js CHANGED
@@ -1,3 +1,5 @@
1
+ "use client";
2
+
1
3
  // src/form-rhf.tsx
2
4
  import {
3
5
  Controller
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/form-rhf.tsx","../src/components/form/form.tsx","../src/lib/cn.ts"],"sourcesContent":["import {\n\tController,\n\ttype Control,\n\ttype FieldPath,\n\ttype FieldValues,\n} from \"react-hook-form\"\nimport type { ComponentProps, ReactElement } from \"react\"\nimport { Form } from \"./components/form\"\n\nexport interface FormFieldControllerProps<\n\tTFieldValues extends FieldValues = FieldValues,\n\tTName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n> {\n\tcontrol: Control<TFieldValues>\n\tname: TName\n\tlabel?: string\n\trequired?: boolean\n\thint?: string\n\tchildren: (field: {\n\t\tvalue: unknown\n\t\tonChange: (...event: unknown[]) => void\n\t\tonBlur: () => void\n\t\tname: string\n\t\tref: (instance: HTMLElement | null) => void\n\t}) => ReactElement\n}\n\nexport function FormFieldController<\n\tTFieldValues extends FieldValues = FieldValues,\n\tTName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n>({\n\tcontrol,\n\tname,\n\tlabel,\n\trequired,\n\thint,\n\tchildren,\n}: FormFieldControllerProps<TFieldValues, TName>) {\n\treturn (\n\t\t<Controller\n\t\t\tcontrol={control}\n\t\t\tname={name}\n\t\t\trender={({ field, fieldState }) => (\n\t\t\t\t<Form.Field name={field.name} invalid={!!fieldState.error}>\n\t\t\t\t\t{label ? <Form.Label required={required}>{label}</Form.Label> : null}\n\t\t\t\t\t{children(field)}\n\t\t\t\t\t{fieldState.error ? (\n\t\t\t\t\t\t<Form.Error>{fieldState.error.message}</Form.Error>\n\t\t\t\t\t) : hint ? (\n\t\t\t\t\t\t<Form.Hint>{hint}</Form.Hint>\n\t\t\t\t\t) : null}\n\t\t\t\t</Form.Field>\n\t\t\t)}\n\t\t/>\n\t)\n}\n\nexport type FormInputControllerProps<\n\tTFieldValues extends FieldValues = FieldValues,\n\tTName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n> = Omit<FormFieldControllerProps<TFieldValues, TName>, \"children\"> &\n\tOmit<\n\t\tComponentProps<typeof Form.Input>,\n\t\t\"name\" | \"value\" | \"onChange\" | \"onBlur\" | \"ref\"\n\t>\n\nexport function FormInputController<\n\tTFieldValues extends FieldValues = FieldValues,\n\tTName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n>({\n\tcontrol,\n\tname,\n\tlabel,\n\trequired,\n\thint,\n\t...inputProps\n}: FormInputControllerProps<TFieldValues, TName>) {\n\treturn (\n\t\t<FormFieldController\n\t\t\tcontrol={control}\n\t\t\tname={name}\n\t\t\tlabel={label}\n\t\t\trequired={required}\n\t\t\thint={hint}\n\t\t>\n\t\t\t{field => (\n\t\t\t\t<Form.Input\n\t\t\t\t\t{...inputProps}\n\t\t\t\t\tname={field.name}\n\t\t\t\t\tvalue={field.value as string}\n\t\t\t\t\tonChange={field.onChange}\n\t\t\t\t\tonBlur={field.onBlur}\n\t\t\t\t\tref={field.ref}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</FormFieldController>\n\t)\n}\n\nexport { Controller }\n","import { Field } from \"@base-ui/react/field\"\nimport {\n\tforwardRef,\n\ttype ComponentProps,\n\ttype FormHTMLAttributes,\n\ttype ReactNode,\n} from \"react\"\nimport { cn } from \"../../lib/cn\"\n\nconst inputSizeStyles = {\n\tsm: \"px-2.5 py-1 text-bruv-sm min-h-7\",\n\tmd: \"px-3 py-1.5 text-bruv-base min-h-8\",\n} as const\n\nexport type FormInputSize = keyof typeof inputSizeStyles\n\nexport interface FormRootProps extends FormHTMLAttributes<HTMLFormElement> {}\n\nexport const FormRoot = forwardRef<HTMLFormElement, FormRootProps>(\n\tfunction FormRoot({ className, noValidate = true, ...props }, ref) {\n\t\treturn (\n\t\t\t<form\n\t\t\t\tref={ref}\n\t\t\t\tnoValidate={noValidate}\n\t\t\t\tclassName={cn(\"flex flex-col gap-4\", className)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t)\n\t},\n)\n\nexport interface FormFieldProps extends ComponentProps<typeof Field.Root> {}\n\nexport const FormField = forwardRef<HTMLDivElement, FormFieldProps>(\n\tfunction FormField({ className, ...props }, ref) {\n\t\treturn (\n\t\t\t<Field.Root\n\t\t\t\tref={ref}\n\t\t\t\tclassName={cn(\"flex flex-col gap-1.5\", className)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t)\n\t},\n)\n\nexport interface FormLabelProps extends ComponentProps<typeof Field.Label> {\n\trequired?: boolean\n}\n\nexport const FormLabel = forwardRef<HTMLLabelElement, FormLabelProps>(\n\tfunction FormLabel({ required, className, children, ...props }, ref) {\n\t\treturn (\n\t\t\t<Field.Label\n\t\t\t\tref={ref}\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"text-bruv-base font-medium text-bruv-primary\",\n\t\t\t\t\t\"data-[disabled]:text-bruv-tertiary data-[disabled]:cursor-not-allowed\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t\t{required && (\n\t\t\t\t\t<span className=\"text-bruv-danger ml-0.5\" aria-hidden=\"true\">\n\t\t\t\t\t\t*\n\t\t\t\t\t</span>\n\t\t\t\t)}\n\t\t\t</Field.Label>\n\t\t)\n\t},\n)\n\n/** Shared visual styles for standalone input (no icons) */\nconst inputStyles = [\n\t\"w-full rounded-bruv-md border border-bruv-neutral bg-bruv-base-2 text-bruv-primary\",\n\t\"outline-none\",\n\t\"placeholder:text-bruv-tertiary\",\n\t\"ring-bruv-neutral ring-0 transition-[box-shadow,color,border-color] duration-150 ease-out\",\n\t\"focus:ring-2 focus:border-bruv-neutral-strong\",\n\t\"motion-reduce:transition-none\",\n\t\"data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50\",\n\t\"data-[invalid]:border-bruv-danger data-[invalid]:focus:ring-bruv-danger/30\",\n\t\"data-[valid]:border-bruv-success\",\n]\n\n/** Wrapper styles when icons are present - mirrors inputStyles but uses has-[:focus] */\nconst wrapperStyles = [\n\t\"rounded-bruv-md border border-bruv-neutral bg-bruv-base-2 py-1.5 text-bruv-base\",\n\t\"ring-bruv-neutral ring-0 transition-[box-shadow,color,border-color] duration-150 ease-out\",\n\t\"has-[:focus]:ring-2 has-[:focus]:border-bruv-neutral-strong\",\n\t\"motion-reduce:transition-none\",\n\t\"has-[*[data-disabled]]:cursor-not-allowed has-[*[data-disabled]]:opacity-50\",\n\t\"has-[*[data-invalid]]:border-bruv-danger has-[*[data-invalid]:focus]:ring-bruv-danger/30\",\n\t\"has-[*[data-valid]]:border-bruv-success\",\n]\n\nexport interface FormInputProps extends Omit<\n\tComponentProps<typeof Field.Control>,\n\t\"size\"\n> {\n\tsize?: FormInputSize\n\t/** Icon element rendered before the input */\n\ticonLeft?: ReactNode\n\t/** Icon element rendered after the input */\n\ticonRight?: ReactNode\n\t/** Additional classes on the outer wrapper (only when icons are present) */\n\twrapperClassName?: string\n}\n\nexport const FormInput = forwardRef<HTMLInputElement, FormInputProps>(\n\tfunction FormInput(\n\t\t{ size = \"md\", iconLeft, iconRight, wrapperClassName, className, ...props },\n\t\tref,\n\t) {\n\t\tconst hasIcon = !!iconLeft || !!iconRight\n\t\tconst sizeClass = inputSizeStyles[size]\n\n\t\tif (!hasIcon) {\n\t\t\treturn (\n\t\t\t\t<Field.Control\n\t\t\t\t\tref={ref}\n\t\t\t\t\tclassName={cn(inputStyles, sizeClass, className)}\n\t\t\t\t\t{...props}\n\t\t\t\t/>\n\t\t\t)\n\t\t}\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"flex items-center gap-2\",\n\t\t\t\t\tsize === \"sm\" ? \"px-2\" : \"px-2.5\",\n\t\t\t\t\twrapperStyles,\n\t\t\t\t\twrapperClassName,\n\t\t\t\t)}\n\t\t\t>\n\t\t\t\t{iconLeft && (\n\t\t\t\t\t<span className=\"text-bruv-tertiary flex size-5 shrink-0 items-center justify-center [&>svg]:size-4\">\n\t\t\t\t\t\t{iconLeft}\n\t\t\t\t\t</span>\n\t\t\t\t)}\n\t\t\t\t<Field.Control\n\t\t\t\t\tref={ref}\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\"flex-1 min-w-0 h-full bg-transparent text-bruv-primary outline-none placeholder:text-bruv-tertiary\",\n\t\t\t\t\t\tsize === \"sm\" ? \"text-bruv-sm\" : \"text-bruv-base\",\n\t\t\t\t\t\tclassName,\n\t\t\t\t\t)}\n\t\t\t\t\t{...props}\n\t\t\t\t/>\n\t\t\t\t{iconRight && (\n\t\t\t\t\t<span className=\"text-bruv-tertiary flex size-5 shrink-0 items-center justify-center [&>svg]:size-4\">\n\t\t\t\t\t\t{iconRight}\n\t\t\t\t\t</span>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t)\n\t},\n)\n\nexport interface FormTextareaProps extends Omit<\n\tComponentProps<typeof Field.Control>,\n\t\"size\"\n> {\n\tsize?: FormInputSize\n}\n\nexport const FormTextarea = forwardRef<HTMLTextAreaElement, FormTextareaProps>(\n\tfunction FormTextarea({ size = \"md\", className, ...props }, ref) {\n\t\treturn (\n\t\t\t<Field.Control\n\t\t\t\tref={ref}\n\t\t\t\trender={<textarea />}\n\t\t\t\tclassName={cn(\n\t\t\t\t\tinputStyles,\n\t\t\t\t\tinputSizeStyles[size],\n\t\t\t\t\t\"min-h-20 resize-y\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t)\n\t},\n)\n\nexport interface FormHintProps extends ComponentProps<\n\ttypeof Field.Description\n> {}\n\nexport const FormHint = forwardRef<HTMLParagraphElement, FormHintProps>(\n\tfunction FormHint({ className, ...props }, ref) {\n\t\treturn (\n\t\t\t<Field.Description\n\t\t\t\tref={ref}\n\t\t\t\tclassName={cn(\"text-bruv-sm text-bruv-tertiary\", className)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t)\n\t},\n)\n\nexport interface FormErrorProps extends ComponentProps<typeof Field.Error> {}\n\nexport const FormError = forwardRef<HTMLParagraphElement, FormErrorProps>(\n\tfunction FormError({ className, ...props }, ref) {\n\t\treturn (\n\t\t\t<Field.Error\n\t\t\t\tref={ref}\n\t\t\t\tclassName={cn(\"text-bruv-sm text-bruv-danger\", className)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t)\n\t},\n)\n\nexport const Form = {\n\tRoot: FormRoot,\n\tField: FormField,\n\tLabel: FormLabel,\n\tInput: FormInput,\n\tTextarea: FormTextarea,\n\tHint: FormHint,\n\tError: FormError,\n}\n","import { type ClassValue, clsx } from \"clsx\"\nimport { extendTailwindMerge } from \"tailwind-merge\"\n\nconst twMerge = extendTailwindMerge({\n\textend: {\n\t\tclassGroups: {\n\t\t\t\"font-size\": [{ \"text-cui\": [\"sm\", \"base\", \"lg\", \"xl\"] }],\n\t\t\t\"text-color\": [\n\t\t\t\t{\n\t\t\t\t\t\"text-cui\": [\n\t\t\t\t\t\t\"primary\",\n\t\t\t\t\t\t\"secondary\",\n\t\t\t\t\t\t\"tertiary\",\n\t\t\t\t\t\t\"inverse\",\n\t\t\t\t\t\t\"accent\",\n\t\t\t\t\t\t\"accent-on\",\n\t\t\t\t\t\t\"danger\",\n\t\t\t\t\t\t\"danger-on\",\n\t\t\t\t\t\t\"warn\",\n\t\t\t\t\t\t\"warn-on\",\n\t\t\t\t\t\t\"success\",\n\t\t\t\t\t\t\"success-on\",\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t},\n})\n\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs))\n}\n"],"mappings":"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","names":["FormRoot","FormField","FormLabel","FormInput","FormTextarea","FormHint","FormError","jsx","jsxs"]}
1
+ {"version":3,"sources":["../src/form-rhf.tsx","../src/components/form/form.tsx","../src/lib/cn.ts"],"sourcesContent":["import {\n\tController,\n\ttype Control,\n\ttype FieldPath,\n\ttype FieldValues,\n} from \"react-hook-form\"\nimport type { ComponentProps, ReactElement } from \"react\"\nimport { Form } from \"./components/form\"\n\nexport interface FormFieldControllerProps<\n\tTFieldValues extends FieldValues = FieldValues,\n\tTName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n> {\n\tcontrol: Control<TFieldValues>\n\tname: TName\n\tlabel?: string\n\trequired?: boolean\n\thint?: string\n\tchildren: (field: {\n\t\tvalue: unknown\n\t\tonChange: (...event: unknown[]) => void\n\t\tonBlur: () => void\n\t\tname: string\n\t\tref: (instance: HTMLElement | null) => void\n\t}) => ReactElement\n}\n\nexport function FormFieldController<\n\tTFieldValues extends FieldValues = FieldValues,\n\tTName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n>({\n\tcontrol,\n\tname,\n\tlabel,\n\trequired,\n\thint,\n\tchildren,\n}: FormFieldControllerProps<TFieldValues, TName>) {\n\treturn (\n\t\t<Controller\n\t\t\tcontrol={control}\n\t\t\tname={name}\n\t\t\trender={({ field, fieldState }) => (\n\t\t\t\t<Form.Field name={field.name} invalid={!!fieldState.error}>\n\t\t\t\t\t{label ? <Form.Label required={required}>{label}</Form.Label> : null}\n\t\t\t\t\t{children(field)}\n\t\t\t\t\t{fieldState.error ? (\n\t\t\t\t\t\t<Form.Error>{fieldState.error.message}</Form.Error>\n\t\t\t\t\t) : hint ? (\n\t\t\t\t\t\t<Form.Hint>{hint}</Form.Hint>\n\t\t\t\t\t) : null}\n\t\t\t\t</Form.Field>\n\t\t\t)}\n\t\t/>\n\t)\n}\n\nexport type FormInputControllerProps<\n\tTFieldValues extends FieldValues = FieldValues,\n\tTName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n> = Omit<FormFieldControllerProps<TFieldValues, TName>, \"children\"> &\n\tOmit<\n\t\tComponentProps<typeof Form.Input>,\n\t\t\"name\" | \"value\" | \"onChange\" | \"onBlur\" | \"ref\"\n\t>\n\nexport function FormInputController<\n\tTFieldValues extends FieldValues = FieldValues,\n\tTName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n>({\n\tcontrol,\n\tname,\n\tlabel,\n\trequired,\n\thint,\n\t...inputProps\n}: FormInputControllerProps<TFieldValues, TName>) {\n\treturn (\n\t\t<FormFieldController\n\t\t\tcontrol={control}\n\t\t\tname={name}\n\t\t\tlabel={label}\n\t\t\trequired={required}\n\t\t\thint={hint}\n\t\t>\n\t\t\t{field => (\n\t\t\t\t<Form.Input\n\t\t\t\t\t{...inputProps}\n\t\t\t\t\tname={field.name}\n\t\t\t\t\tvalue={field.value as string}\n\t\t\t\t\tonChange={field.onChange}\n\t\t\t\t\tonBlur={field.onBlur}\n\t\t\t\t\tref={field.ref}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</FormFieldController>\n\t)\n}\n\nexport { Controller }\n","import { Field } from \"@base-ui/react/field\"\nimport {\n\tforwardRef,\n\ttype ComponentProps,\n\ttype FormHTMLAttributes,\n\ttype ReactNode,\n} from \"react\"\nimport { cn } from \"../../lib/cn\"\n\nconst inputSizeStyles = {\n\tsm: \"px-2.5 py-1 text-bruv-sm min-h-7\",\n\tmd: \"px-3 py-1.5 text-bruv-base min-h-8\",\n} as const\n\nexport type FormInputSize = keyof typeof inputSizeStyles\n\nexport interface FormRootProps extends FormHTMLAttributes<HTMLFormElement> {}\n\nexport const FormRoot = forwardRef<HTMLFormElement, FormRootProps>(\n\tfunction FormRoot({ className, noValidate = true, ...props }, ref) {\n\t\treturn (\n\t\t\t<form\n\t\t\t\tref={ref}\n\t\t\t\tnoValidate={noValidate}\n\t\t\t\tclassName={cn(\"flex flex-col gap-4\", className)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t)\n\t},\n)\n\nexport interface FormFieldProps extends ComponentProps<typeof Field.Root> {}\n\nexport const FormField = forwardRef<HTMLDivElement, FormFieldProps>(\n\tfunction FormField({ className, ...props }, ref) {\n\t\treturn (\n\t\t\t<Field.Root\n\t\t\t\tref={ref}\n\t\t\t\tclassName={cn(\"flex flex-col gap-1.5\", className)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t)\n\t},\n)\n\nexport interface FormLabelProps extends ComponentProps<typeof Field.Label> {\n\trequired?: boolean\n}\n\nexport const FormLabel = forwardRef<HTMLLabelElement, FormLabelProps>(\n\tfunction FormLabel({ required, className, children, ...props }, ref) {\n\t\treturn (\n\t\t\t<Field.Label\n\t\t\t\tref={ref}\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"text-bruv-base font-medium text-bruv-primary\",\n\t\t\t\t\t\"data-[disabled]:text-bruv-tertiary data-[disabled]:cursor-not-allowed\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t\t{required && (\n\t\t\t\t\t<span className=\"text-bruv-danger ml-0.5\" aria-hidden=\"true\">\n\t\t\t\t\t\t*\n\t\t\t\t\t</span>\n\t\t\t\t)}\n\t\t\t</Field.Label>\n\t\t)\n\t},\n)\n\n/** Shared visual styles for standalone input (no icons) */\nconst inputStyles = [\n\t\"w-full rounded-bruv-md border border-bruv-neutral bg-bruv-base-2 text-bruv-primary\",\n\t\"outline-none\",\n\t\"placeholder:text-bruv-tertiary\",\n\t\"ring-bruv-neutral ring-0 transition-[box-shadow,color,border-color] duration-150 ease-out\",\n\t\"focus:ring-2 focus:border-bruv-neutral-strong\",\n\t\"motion-reduce:transition-none\",\n\t\"data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50\",\n\t\"data-[invalid]:border-bruv-danger data-[invalid]:focus:ring-bruv-danger/30\",\n\t\"data-[valid]:border-bruv-success\",\n]\n\n/** Wrapper styles when icons are present - mirrors inputStyles but uses has-[:focus] */\nconst wrapperStyles = [\n\t\"rounded-bruv-md border border-bruv-neutral bg-bruv-base-2 py-1.5 text-bruv-base\",\n\t\"ring-bruv-neutral ring-0 transition-[box-shadow,color,border-color] duration-150 ease-out\",\n\t\"has-[:focus]:ring-2 has-[:focus]:border-bruv-neutral-strong\",\n\t\"motion-reduce:transition-none\",\n\t\"has-[*[data-disabled]]:cursor-not-allowed has-[*[data-disabled]]:opacity-50\",\n\t\"has-[*[data-invalid]]:border-bruv-danger has-[*[data-invalid]:focus]:ring-bruv-danger/30\",\n\t\"has-[*[data-valid]]:border-bruv-success\",\n]\n\nexport interface FormInputProps extends Omit<\n\tComponentProps<typeof Field.Control>,\n\t\"size\"\n> {\n\tsize?: FormInputSize\n\t/** Icon element rendered before the input */\n\ticonLeft?: ReactNode\n\t/** Icon element rendered after the input */\n\ticonRight?: ReactNode\n\t/** Additional classes on the outer wrapper (only when icons are present) */\n\twrapperClassName?: string\n}\n\nexport const FormInput = forwardRef<HTMLInputElement, FormInputProps>(\n\tfunction FormInput(\n\t\t{ size = \"md\", iconLeft, iconRight, wrapperClassName, className, ...props },\n\t\tref,\n\t) {\n\t\tconst hasIcon = !!iconLeft || !!iconRight\n\t\tconst sizeClass = inputSizeStyles[size]\n\n\t\tif (!hasIcon) {\n\t\t\treturn (\n\t\t\t\t<Field.Control\n\t\t\t\t\tref={ref}\n\t\t\t\t\tclassName={cn(inputStyles, sizeClass, className)}\n\t\t\t\t\t{...props}\n\t\t\t\t/>\n\t\t\t)\n\t\t}\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"flex items-center gap-2\",\n\t\t\t\t\tsize === \"sm\" ? \"px-2\" : \"px-2.5\",\n\t\t\t\t\twrapperStyles,\n\t\t\t\t\twrapperClassName,\n\t\t\t\t)}\n\t\t\t>\n\t\t\t\t{iconLeft && (\n\t\t\t\t\t<span className=\"text-bruv-tertiary flex size-5 shrink-0 items-center justify-center [&>svg]:size-4\">\n\t\t\t\t\t\t{iconLeft}\n\t\t\t\t\t</span>\n\t\t\t\t)}\n\t\t\t\t<Field.Control\n\t\t\t\t\tref={ref}\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\"flex-1 min-w-0 h-full bg-transparent text-bruv-primary outline-none placeholder:text-bruv-tertiary\",\n\t\t\t\t\t\tsize === \"sm\" ? \"text-bruv-sm\" : \"text-bruv-base\",\n\t\t\t\t\t\tclassName,\n\t\t\t\t\t)}\n\t\t\t\t\t{...props}\n\t\t\t\t/>\n\t\t\t\t{iconRight && (\n\t\t\t\t\t<span className=\"text-bruv-tertiary flex size-5 shrink-0 items-center justify-center [&>svg]:size-4\">\n\t\t\t\t\t\t{iconRight}\n\t\t\t\t\t</span>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t)\n\t},\n)\n\nexport interface FormTextareaProps extends Omit<\n\tComponentProps<typeof Field.Control>,\n\t\"size\"\n> {\n\tsize?: FormInputSize\n}\n\nexport const FormTextarea = forwardRef<HTMLTextAreaElement, FormTextareaProps>(\n\tfunction FormTextarea({ size = \"md\", className, ...props }, ref) {\n\t\treturn (\n\t\t\t<Field.Control\n\t\t\t\tref={ref}\n\t\t\t\trender={<textarea />}\n\t\t\t\tclassName={cn(\n\t\t\t\t\tinputStyles,\n\t\t\t\t\tinputSizeStyles[size],\n\t\t\t\t\t\"min-h-20 resize-y\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t)\n\t},\n)\n\nexport interface FormHintProps extends ComponentProps<\n\ttypeof Field.Description\n> {}\n\nexport const FormHint = forwardRef<HTMLParagraphElement, FormHintProps>(\n\tfunction FormHint({ className, ...props }, ref) {\n\t\treturn (\n\t\t\t<Field.Description\n\t\t\t\tref={ref}\n\t\t\t\tclassName={cn(\"text-bruv-sm text-bruv-tertiary\", className)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t)\n\t},\n)\n\nexport interface FormErrorProps extends ComponentProps<typeof Field.Error> {}\n\nexport const FormError = forwardRef<HTMLParagraphElement, FormErrorProps>(\n\tfunction FormError({ className, ...props }, ref) {\n\t\treturn (\n\t\t\t<Field.Error\n\t\t\t\tref={ref}\n\t\t\t\tclassName={cn(\"text-bruv-sm text-bruv-danger\", className)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t)\n\t},\n)\n\nexport const Form = {\n\tRoot: FormRoot,\n\tField: FormField,\n\tLabel: FormLabel,\n\tInput: FormInput,\n\tTextarea: FormTextarea,\n\tHint: FormHint,\n\tError: FormError,\n}\n","import { type ClassValue, clsx } from \"clsx\"\nimport { extendTailwindMerge } from \"tailwind-merge\"\n\nconst twMerge = extendTailwindMerge({\n\textend: {\n\t\tclassGroups: {\n\t\t\t\"font-size\": [{ \"text-cui\": [\"sm\", \"base\", \"lg\", \"xl\"] }],\n\t\t\t\"text-color\": [\n\t\t\t\t{\n\t\t\t\t\t\"text-cui\": [\n\t\t\t\t\t\t\"primary\",\n\t\t\t\t\t\t\"secondary\",\n\t\t\t\t\t\t\"tertiary\",\n\t\t\t\t\t\t\"inverse\",\n\t\t\t\t\t\t\"accent\",\n\t\t\t\t\t\t\"accent-on\",\n\t\t\t\t\t\t\"danger\",\n\t\t\t\t\t\t\"danger-on\",\n\t\t\t\t\t\t\"warn\",\n\t\t\t\t\t\t\"warn-on\",\n\t\t\t\t\t\t\"success\",\n\t\t\t\t\t\t\"success-on\",\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t},\n})\n\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs))\n}\n"],"mappings":"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","names":["FormRoot","FormField","FormLabel","FormInput","FormTextarea","FormHint","FormError","jsx","jsxs"]}
package/dist/index.js CHANGED
@@ -1,3 +1,5 @@
1
+ "use client";
2
+
1
3
  // src/lib/cn.ts
2
4
  import { clsx } from "clsx";
3
5
  import { extendTailwindMerge } from "tailwind-merge";