Skip to content

Commit 83365e7

Browse files
authored
Merge pull request #14 from lambda-curry/text-area-story
[LC-118] chore: adding a remix text area story & fix: #7 Custom attribute getting added to inputs unnecessarily
2 parents 6c1f668 + 19b0854 commit 83365e7

21 files changed

Lines changed: 217 additions & 178 deletions

.changeset/heavy-dragons-drop.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@lambdacurry/forms": minor
3+
"@lambdacurry/forms-docs": minor
4+
---
5+
6+
Added remix textarea story and fixes a react error

.github/workflows/release.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,3 @@ jobs:
3838
env:
3939
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4040
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
41-
42-
- name: Send a Slack notification if a publish happens
43-
if: steps.changesets.outputs.published == 'true'
44-
run: my-slack-bot send-notification --message "A new version of ${GITHUB_REPOSITORY} was published!"

.vscode/settings.json

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
11
{
2-
"cSpell.words": ["autodocs", "biomejs", "Filenaming", "hookform", "isbot", "lucide", "shadcn", "sonner"]
2+
"cSpell.words": ["autodocs", "biomejs", "Filenaming", "hookform", "isbot", "lucide", "shadcn", "sonner"],
3+
"editor.defaultFormatter": "biomejs.biome",
4+
"[typescript]": {
5+
"editor.defaultFormatter": "biomejs.biome"
6+
},
7+
"[typescriptreact]": {
8+
"editor.defaultFormatter": "biomejs.biome"
9+
},
10+
"editor.codeActionsOnSave": {
11+
"source.fixAll.biome": "explicit",
12+
"source.organizeImports.biome": "explicit"
13+
}
314
}

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Welcome!
22

3-
Checkout our [Storybook Documentation](https://lambda-curry.github.io/forms/?path=/docs/helloworld-start-here--docs) to see the components in action and get started.
3+
Checkout our [Storybook Documentation](https://lambda-curry.github.io/forms/?path=/docs/0-1-hello-world-start-here--docs) to see the components in action and get started.
44

55

66
## Getting Started
@@ -10,7 +10,7 @@ Step 1: Install the dependencies
1010
yarn install
1111
```
1212

13-
Note: You may need to enable corepack for yarn v4 by running `corepack enable` before intstalling the dependencies.
13+
Note: You may need to enable corepack for yarn v4 by running `corepack enable` before installing the dependencies.
1414

1515

1616
Step 2: Start Storybook

apps/docs/CHANGELOG.md

Lines changed: 0 additions & 9 deletions
This file was deleted.

apps/docs/src/remix/remix-textarea.stories.tsx

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import { zodResolver } from '@hookform/resolvers/zod';
2+
import { RemixTextarea } from '@lambdacurry/forms/remix/remix-textarea';
3+
import { Button } from '@lambdacurry/forms/ui/button';
24
import type { ActionFunctionArgs } from '@remix-run/node';
35
import { useFetcher } from '@remix-run/react';
46
import type { Meta, StoryContext, StoryObj } from '@storybook/react';
57
import { expect, userEvent, within } from '@storybook/test';
68
import { RemixFormProvider, getValidatedFormData, useRemixForm } from 'remix-hook-form';
79
import { z } from 'zod';
810
import { withRemixStubDecorator } from '../lib/storybook/remix-stub';
9-
import { RemixTextarea } from '@lambdacurry/forms/remix/remix-textarea';
10-
import { Button } from '@lambdacurry/forms/ui/button';
1111

1212
const formSchema = z.object({
1313
comment: z.string().min(10, 'Comment must be at least 10 characters'),
@@ -37,9 +37,6 @@ const ControlledTextareaExample = () => {
3737
Submit
3838
</Button>
3939
{fetcher.data?.message && <p className="mt-2 text-green-600">{fetcher.data.message}</p>}
40-
{methods.formState.errors.comment && (
41-
<p className="mt-2 text-red-600">{methods.formState.errors.comment.message}</p>
42-
)}
4340
</fetcher.Form>
4441
</RemixFormProvider>
4542
);
@@ -54,7 +51,7 @@ const handleFormSubmission = async (request: Request) => {
5451
} = await getValidatedFormData<FormData>(request, zodResolver(formSchema));
5552

5653
if (errors) {
57-
return { errors, defaultValues };
54+
return { defaultValues };
5855
}
5956

6057
if (data.comment.includes(BLOCKED_CONTENT)) {
@@ -108,6 +105,9 @@ const testInvalidSubmission = async ({ canvasElement }: { canvasElement: HTMLEle
108105
await userEvent.type(textarea, 'short');
109106
await userEvent.click(submitButton);
110107

108+
// Wait for any state updates
109+
await new Promise((resolve) => setTimeout(resolve, 100));
110+
111111
expect(canvas.getByText((content) => content.includes('Comment must be at least 10 characters'))).toBeInTheDocument();
112112
};
113113

@@ -149,6 +149,9 @@ const testValidSubmission = async ({ canvasElement }: { canvasElement: HTMLEleme
149149
await userEvent.type(textarea, 'This is a valid comment that is long enough');
150150
await userEvent.click(submitButton);
151151

152+
// Wait for any state updates
153+
await new Promise((resolve) => setTimeout(resolve, 100));
154+
152155
// Check for success message
153156
await expect(canvas.getByText('Comment submitted successfully')).toBeInTheDocument();
154157
};
Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,18 @@
1-
import { useRemixFormContext } from 'remix-hook-form'
2-
import { Checkbox, type CheckboxProps } from '../ui/checkbox'
1+
import { useRemixFormContext } from 'remix-hook-form';
2+
import { Checkbox, type CheckboxProps } from '../ui/checkbox';
33
import { RemixFormControl, RemixFormDescription, RemixFormLabel, RemixFormMessage } from './remix-form';
4-
import type { FieldComponents } from '../ui/form';
54

65
export type RemixCheckboxProps = Omit<CheckboxProps, 'control'>;
76

87
export function RemixCheckbox(props: RemixCheckboxProps) {
98
const { control } = useRemixFormContext();
109

11-
12-
const components: Partial<FieldComponents> = {
10+
const components = {
1311
FormDescription: RemixFormDescription,
1412
FormControl: RemixFormControl,
1513
FormLabel: RemixFormLabel,
1614
FormMessage: RemixFormMessage,
1715
};
1816

1917
return <Checkbox control={control} {...props} components={components} />;
20-
}
18+
}
Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
1-
import { type ReactNode, useContext, forwardRef } from 'react';
2-
import type {
3-
KeepStateOptions,
4-
FieldValues,
5-
UseFormReturn,
6-
UseFormRegister,
7-
} from 'react-hook-form';
1+
import { type ReactNode, forwardRef, useContext } from 'react';
2+
import type { BaseSyntheticEvent, ComponentPropsWithoutRef } from 'react';
3+
import type { FieldValues, KeepStateOptions, UseFormRegister, UseFormReturn } from 'react-hook-form';
84
import { useRemixFormContext } from 'remix-hook-form';
9-
import { FormLabel, FormControl, FormDescription, FormMessage, FormFieldContext, FormItemContext } from '../ui/form';
10-
import type { BaseSyntheticEvent, ComponentPropsWithoutRef, } from 'react';
5+
import { FormControl, FormDescription, FormFieldContext, FormItemContext, FormLabel, FormMessage } from '../ui/form';
116

127
export interface RemixFormProviderProps<T extends FieldValues>
138
extends Omit<UseFormReturn<T>, 'handleSubmit' | 'reset'> {
@@ -40,36 +35,40 @@ export const useRemixFormField = () => {
4035
};
4136
};
4237

43-
4438
export const RemixFormLabel = forwardRef<HTMLLabelElement, ComponentPropsWithoutRef<typeof FormLabel>>((props, ref) => (
4539
<FormLabel ref={ref} {...props} />
4640
));
4741
RemixFormLabel.displayName = 'RemixFormLabel';
4842

49-
export const RemixFormControl = forwardRef<HTMLElement, ComponentPropsWithoutRef<typeof FormControl>>((props, ref) => {
50-
const { error, formItemId, formDescriptionId, formMessageId } = useRemixFormField();
51-
return (
52-
<FormControl
53-
ref={ref}
54-
error={!!error}
55-
formItemId={formItemId}
56-
formDescriptionId={formDescriptionId}
57-
formMessageId={formMessageId}
58-
{...props}
59-
/>
60-
);
61-
});
43+
export const RemixFormControl = forwardRef<HTMLDivElement, ComponentPropsWithoutRef<typeof FormControl>>(
44+
(props, ref) => {
45+
const { error, formItemId, formDescriptionId, formMessageId } = useRemixFormField();
46+
return (
47+
<FormControl
48+
ref={ref}
49+
error={!!error}
50+
formItemId={formItemId}
51+
formDescriptionId={formDescriptionId}
52+
formMessageId={formMessageId}
53+
{...props}
54+
/>
55+
);
56+
},
57+
);
6258
RemixFormControl.displayName = 'RemixFormControl';
6359

64-
export const RemixFormDescription = forwardRef<HTMLParagraphElement, ComponentPropsWithoutRef<typeof FormDescription>>((props, ref) => {
65-
const { formDescriptionId } = useRemixFormField();
66-
return <FormDescription ref={ref} formDescriptionId={formDescriptionId} {...props} />;
67-
});
60+
export const RemixFormDescription = forwardRef<HTMLParagraphElement, ComponentPropsWithoutRef<typeof FormDescription>>(
61+
(props, ref) => {
62+
const { formDescriptionId } = useRemixFormField();
63+
return <FormDescription ref={ref} formDescriptionId={formDescriptionId} {...props} />;
64+
},
65+
);
6866
RemixFormDescription.displayName = 'RemixFormDescription';
6967

70-
export const RemixFormMessage = forwardRef<HTMLParagraphElement, ComponentPropsWithoutRef<typeof FormMessage>>((props, ref) => {
71-
const { error, formMessageId } = useRemixFormField();
72-
return <FormMessage ref={ref} formMessageId={formMessageId} error={error?.message} {...props} />;
73-
});
68+
export const RemixFormMessage = forwardRef<HTMLParagraphElement, ComponentPropsWithoutRef<typeof FormMessage>>(
69+
(props, ref) => {
70+
const { error, formMessageId } = useRemixFormField();
71+
return <FormMessage ref={ref} formMessageId={formMessageId} error={error?.message} {...props} />;
72+
},
73+
);
7474
RemixFormMessage.displayName = 'RemixFormMessage';
75-
Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import type { ComponentPropsWithoutRef } from 'react';
2-
import { useRemixFormContext } from 'remix-hook-form'
3-
import { Switch } from '../ui/switch'
2+
import { useRemixFormContext } from 'remix-hook-form';
3+
import { Switch } from '../ui/switch';
44
import { RemixFormControl, RemixFormDescription, RemixFormLabel, RemixFormMessage } from './remix-form';
5-
import type { FieldComponents } from '../ui/form';
65

76
export interface RemixSwitchProps extends Omit<ComponentPropsWithoutRef<typeof Switch>, 'control'> {
87
name: string;
@@ -13,22 +12,14 @@ export interface RemixSwitchProps extends Omit<ComponentPropsWithoutRef<typeof S
1312
export function RemixSwitch({ name, label, description, ...props }: RemixSwitchProps) {
1413
const { control } = useRemixFormContext();
1514

16-
const components: Partial<FieldComponents> = {
15+
const components = {
1716
FormDescription: RemixFormDescription,
1817
FormControl: RemixFormControl,
1918
FormLabel: RemixFormLabel,
2019
FormMessage: RemixFormMessage,
2120
};
2221

2322
return (
24-
<Switch
25-
control={control}
26-
name={name}
27-
label={label}
28-
description={description}
29-
components={components}
30-
{...props}
31-
/>
23+
<Switch control={control} name={name} label={label} description={description} components={components} {...props} />
3224
);
3325
}
34-

packages/components/src/remix/remix-text-field.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
import { useRemixFormContext } from 'remix-hook-form';
22
import { TextField, type TextFieldProps } from '../ui/text-field';
3-
import type { FieldComponents } from '../ui/form';
43
import { RemixFormControl, RemixFormDescription, RemixFormLabel, RemixFormMessage } from './remix-form';
54

65
export type RemixTextFieldProps = Omit<TextFieldProps, 'control'>;
76

87
export function RemixTextField(props: RemixTextFieldProps) {
98
const { control } = useRemixFormContext();
109

11-
const components: Partial<FieldComponents> = {
10+
const components = {
1211
FormControl: RemixFormControl,
1312
FormLabel: RemixFormLabel,
1413
FormDescription: RemixFormDescription,

0 commit comments

Comments
 (0)