Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14,207 changes: 14,207 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/components/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@lambdacurry/forms",
"version": "0.11.3",
"version": "0.11.4",
"main": "./index.ts",
"types": "./index.ts",
"exports": {
Expand Down
46 changes: 24 additions & 22 deletions packages/components/src/remix/remix-form.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import { type ReactNode, forwardRef, useContext } from 'react';
import type { BaseSyntheticEvent, ComponentPropsWithoutRef } from 'react';
// biome-ignore lint/style/noNamespaceImport: prevents React undefined errors when exporting as a component library
import * as React from 'react';
import type { FieldValues, KeepStateOptions, UseFormRegister, UseFormReturn } from 'react-hook-form';
import { useRemixFormContext } from 'remix-hook-form';
import { FormControl, FormDescription, FormFieldContext, FormItemContext, FormLabel, FormMessage } from '../ui/form';

export interface RemixFormProviderProps<T extends FieldValues>
extends Omit<UseFormReturn<T>, 'handleSubmit' | 'reset'> {
children: ReactNode;
handleSubmit: (e?: BaseSyntheticEvent) => Promise<void>;
children: React.ReactNode;
handleSubmit: (e?: React.BaseSyntheticEvent) => Promise<void>;
register: UseFormRegister<T>;
reset: (values?: T, keepStateOptions?: KeepStateOptions) => void;
}

export const useRemixFormField = () => {
const fieldContext = useContext(FormFieldContext);
const itemContext = useContext(FormItemContext);
const fieldContext = React.useContext(FormFieldContext);
const itemContext = React.useContext(FormItemContext);
const { getFieldState, formState } = useRemixFormContext();

const fieldState = getFieldState(fieldContext.name, formState);
Expand All @@ -35,12 +35,12 @@ export const useRemixFormField = () => {
};
};

export const RemixFormLabel = forwardRef<HTMLLabelElement, ComponentPropsWithoutRef<typeof FormLabel>>((props, ref) => (
<FormLabel ref={ref} {...props} />
));
export const RemixFormLabel = React.forwardRef<HTMLLabelElement, React.ComponentPropsWithoutRef<typeof FormLabel>>(
(props, ref) => <FormLabel ref={ref} {...props} />,
);
RemixFormLabel.displayName = 'RemixFormLabel';

export const RemixFormControl = forwardRef<HTMLDivElement, ComponentPropsWithoutRef<typeof FormControl>>(
export const RemixFormControl = React.forwardRef<HTMLDivElement, React.ComponentPropsWithoutRef<typeof FormControl>>(
(props, ref) => {
const { error, formItemId, formDescriptionId, formMessageId } = useRemixFormField();
return (
Expand All @@ -57,18 +57,20 @@ export const RemixFormControl = forwardRef<HTMLDivElement, ComponentPropsWithout
);
RemixFormControl.displayName = 'RemixFormControl';

export const RemixFormDescription = forwardRef<HTMLParagraphElement, ComponentPropsWithoutRef<typeof FormDescription>>(
(props, ref) => {
const { formDescriptionId } = useRemixFormField();
return <FormDescription ref={ref} formDescriptionId={formDescriptionId} {...props} />;
},
);
export const RemixFormDescription = React.forwardRef<
HTMLParagraphElement,
React.ComponentPropsWithoutRef<typeof FormDescription>
>((props, ref) => {
const { formDescriptionId } = useRemixFormField();
return <FormDescription ref={ref} formDescriptionId={formDescriptionId} {...props} />;
});
RemixFormDescription.displayName = 'RemixFormDescription';

export const RemixFormMessage = forwardRef<HTMLParagraphElement, ComponentPropsWithoutRef<typeof FormMessage>>(
(props, ref) => {
const { error, formMessageId } = useRemixFormField();
return <FormMessage ref={ref} formMessageId={formMessageId} error={error?.message} {...props} />;
},
);
export const RemixFormMessage = React.forwardRef<
HTMLParagraphElement,
React.ComponentPropsWithoutRef<typeof FormMessage>
>((props, ref) => {
const { error, formMessageId } = useRemixFormField();
return <FormMessage ref={ref} formMessageId={formMessageId} error={error?.message} {...props} />;
});
RemixFormMessage.displayName = 'RemixFormMessage';
6 changes: 3 additions & 3 deletions packages/components/src/remix/remix-switch.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import type { ComponentPropsWithoutRef } from 'react';
import type * as React from 'react';
import { useRemixFormContext } from 'remix-hook-form';
import { SwitchField } from '../ui/switch-field';
import { RemixFormControl, RemixFormDescription, RemixFormLabel, RemixFormMessage } from './remix-form';

export interface RemixSwitchProps extends Omit<ComponentPropsWithoutRef<typeof Switch>, 'control'> {
export interface RemixSwitchProps extends Omit<React.ComponentPropsWithoutRef<typeof SwitchField>, 'control'> {
name: string;
label?: string;
description?: string;
}

export function RemixSwitch({ name, label, description, ...props }: RemixSwitchProps) {
export function RemixSwitch({ name, label, description, className, ...props }: RemixSwitchProps) {
const { control } = useRemixFormContext();

const components = {
Expand Down
17 changes: 8 additions & 9 deletions packages/components/src/ui/checkbox-field.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// biome-ignore lint/style/noNamespaceImport: from Radix
// biome-ignore lint/style/noNamespaceImport: fromRadix
import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
import { Check } from 'lucide-react';
import { type ComponentPropsWithoutRef, type ReactNode, forwardRef } from 'react';
// biome-ignore lint/style/noNamespaceImport: prevents React undefined errors when exporting as a component library
import * as React from 'react';

import type { Control, FieldPath, FieldValues } from 'react-hook-form';
import { cn } from '../../lib/utils';
import {
Expand All @@ -17,16 +19,16 @@ import {
export interface CheckboxProps<
TFieldValues extends FieldValues = FieldValues,
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
> extends ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root> {
> extends React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root> {
control?: Control<TFieldValues>;
name: TName;
label?: ReactNode;
label?: React.ReactNode;
description?: string;
className?: string;
components?: Partial<FieldComponents>;
}

const CheckboxField = forwardRef<HTMLDivElement, CheckboxProps>(
const CheckboxField = React.forwardRef<HTMLDivElement, CheckboxProps>(
({ control, name, className, label, description, components, ...props }, ref) => (
<FormField
control={control}
Expand All @@ -48,10 +50,7 @@ const CheckboxField = forwardRef<HTMLDivElement, CheckboxProps>(
</FormControl>
<div className="space-y-1 leading-none">
{label && (
<FormLabel
Component={components?.FormLabel}
className="!text-inherit" // Note: adding text-inherit here so the checkbox labels aren't also red during an error state since they are closer to their error text
>
<FormLabel Component={components?.FormLabel} className="!text-inherit">
{label}
</FormLabel>
)}
Expand Down
7 changes: 4 additions & 3 deletions packages/components/src/ui/date-picker-field.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { format } from 'date-fns';
import { Calendar as CalendarIcon } from 'lucide-react';
import { forwardRef } from 'react';
// biome-ignore lint/style/noNamespaceImport: prevents React undefined errors when exporting as a component library
import * as React from 'react';
import type { Control, FieldPath, FieldValues } from 'react-hook-form';
import { cn } from '../../lib/utils';
import { Button } from './button';
Expand Down Expand Up @@ -30,7 +31,7 @@ export interface DatePickerFieldProps<
components?: Partial<FieldComponents>;
}

export const DatePickerField = forwardRef<HTMLDivElement, DatePickerFieldProps>(
export const DatePickerField = React.forwardRef<HTMLDivElement, DatePickerFieldProps>(
({ control, name, label, description, className, labelClassName, buttonClassName, components }, ref) => {
return (
<FormField
Expand Down Expand Up @@ -76,4 +77,4 @@ export const DatePickerField = forwardRef<HTMLDivElement, DatePickerFieldProps>(
},
);

DatePickerField.displayName = 'DatePicker';
DatePickerField.displayName = 'DatePickerField';
3 changes: 1 addition & 2 deletions packages/components/src/ui/date-picker.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { ChevronLeft, ChevronRight } from 'lucide-react';
import type * as React from 'react';
import { type CustomComponents, DayPicker } from 'react-day-picker';

import { cn } from '../../lib/utils';
import { buttonVariants } from './button';

export type DatePickerProps = React.ComponentProps<typeof DayPicker>;

const DatePicker = ({ className, classNames, showOutsideDays = true, ...props }: CalendarProps) => {
const DatePicker = ({ className, classNames, showOutsideDays = true, ...props }: DatePickerProps) => {
return (
<DayPicker
showOutsideDays={showOutsideDays}
Expand Down
11 changes: 6 additions & 5 deletions packages/components/src/ui/dropdown-menu-select-field.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// biome-ignore lint/style/noNamespaceImport: from Radix
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
import { type ComponentPropsWithoutRef, type ElementRef, type ReactNode, forwardRef } from 'react';
// biome-ignore lint/style/noNamespaceImport: prevents React undefined errors when exporting as a component library
import * as React from 'react';
import type { Control, FieldPath, FieldValues } from 'react-hook-form';
import { Button } from './button';
import { DropdownMenuContent } from './dropdown-menu';
Expand All @@ -17,20 +18,20 @@ import {
export interface DropdownMenuSelectProps<
TFieldValues extends FieldValues = FieldValues,
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
> extends Omit<ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Root>, 'onChange' | 'value'> {
> extends Omit<React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Root>, 'onChange' | 'value'> {
control?: Control<TFieldValues>;
name: TName;
label?: string;
description?: string;
children: ReactNode;
children: React.ReactNode;
className?: string;
labelClassName?: string;
dropdownClassName?: string;
components?: Partial<FieldComponents>;
}

export const DropdownMenuSelectField = forwardRef<
ElementRef<typeof DropdownMenuPrimitive.Root>,
export const DropdownMenuSelectField = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Root>,
DropdownMenuSelectProps
>(
(
Expand Down
54 changes: 27 additions & 27 deletions packages/components/src/ui/dropdown-menu.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// biome-ignore lint/style/noNamespaceImport: from Radix
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
import { Check, ChevronRight, Circle } from 'lucide-react';
import { type ComponentPropsWithoutRef, type ElementRef, type HTMLAttributes, forwardRef } from 'react';

// biome-ignore lint/style/noNamespaceImport: prevents React undefined errors when exporting as a component library
import * as React from 'react';
import { cn } from '../../lib/utils';

const DropdownMenu = DropdownMenuPrimitive.Root;
Expand All @@ -17,9 +17,9 @@ const DropdownMenuSub = DropdownMenuPrimitive.Sub;

const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;

const DropdownMenuSubTrigger = forwardRef<
ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,
ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {
const DropdownMenuSubTrigger = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {
inset?: boolean;
}
>(({ className, inset, children, ...props }, ref) => (
Expand All @@ -38,9 +38,9 @@ const DropdownMenuSubTrigger = forwardRef<
));
DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;

const DropdownMenuSubContent = forwardRef<
ElementRef<typeof DropdownMenuPrimitive.SubContent>,
ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>
const DropdownMenuSubContent = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>
>(({ className, ...props }, ref) => (
<DropdownMenuPrimitive.SubContent
ref={ref}
Expand All @@ -53,9 +53,9 @@ const DropdownMenuSubContent = forwardRef<
));
DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;

const DropdownMenuContent = forwardRef<
ElementRef<typeof DropdownMenuPrimitive.Content>,
ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>
const DropdownMenuContent = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>
>(({ className, sideOffset = 4, ...props }, ref) => (
<DropdownMenuPrimitive.Portal>
<DropdownMenuPrimitive.Content
Expand All @@ -71,9 +71,9 @@ const DropdownMenuContent = forwardRef<
));
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;

const DropdownMenuItem = forwardRef<
ElementRef<typeof DropdownMenuPrimitive.Item>,
ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
const DropdownMenuItem = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
inset?: boolean;
}
>(({ className, inset, ...props }, ref) => (
Expand All @@ -89,9 +89,9 @@ const DropdownMenuItem = forwardRef<
));
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;

const DropdownMenuCheckboxItem = forwardRef<
ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,
ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>
const DropdownMenuCheckboxItem = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>
>(({ className, children, checked, ...props }, ref) => (
<DropdownMenuPrimitive.CheckboxItem
ref={ref}
Expand All @@ -112,9 +112,9 @@ const DropdownMenuCheckboxItem = forwardRef<
));
DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;

const DropdownMenuRadioItem = forwardRef<
ElementRef<typeof DropdownMenuPrimitive.RadioItem>,
ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>
const DropdownMenuRadioItem = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>
>(({ className, children, ...props }, ref) => (
<DropdownMenuPrimitive.RadioItem
ref={ref}
Expand All @@ -134,9 +134,9 @@ const DropdownMenuRadioItem = forwardRef<
));
DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;

const DropdownMenuLabel = forwardRef<
ElementRef<typeof DropdownMenuPrimitive.Label>,
ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
const DropdownMenuLabel = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Label>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
inset?: boolean;
}
>(({ className, inset, ...props }, ref) => (
Expand All @@ -148,15 +148,15 @@ const DropdownMenuLabel = forwardRef<
));
DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;

const DropdownMenuSeparator = forwardRef<
ElementRef<typeof DropdownMenuPrimitive.Separator>,
ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
const DropdownMenuSeparator = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
>(({ className, ...props }, ref) => (
<DropdownMenuPrimitive.Separator ref={ref} className={cn('-mx-1 my-1 h-px bg-muted', className)} {...props} />
));
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;

const DropdownMenuShortcut = ({ className, ...props }: HTMLAttributes<HTMLSpanElement>) => {
const DropdownMenuShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => {
return <span className={cn('ml-auto text-xs tracking-widest opacity-60', className)} {...props} />;
};
DropdownMenuShortcut.displayName = 'DropdownMenuShortcut';
Expand Down
Loading
Loading