Skip to content

Commit

Permalink
feat: manual rendering doesn't render anything
Browse files Browse the repository at this point in the history
BREAKING CHANGE: the manual rendering mode doesn't render anything
automatically anymore. Previously it rendered some base layout using the
`RootInner`, `SubmitButtonWrapper` and `SubmitButton` components.
  • Loading branch information
Cyrille Perois committed Jul 13, 2023
1 parent 6bb60dc commit 6084216
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 28 deletions.
10 changes: 10 additions & 0 deletions src/Form.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,16 @@ describe("when no children is given", () => {
});

describe("when children is given", () => {
test("submit button is not rendered", () => {
render(
<Basic>
<p>Children</p>
</Basic>
);

expect(screen.queryByRole("button")).not.toBeInTheDocument();
});

test("children are rendered", () => {
render(
<Basic>
Expand Down
79 changes: 51 additions & 28 deletions src/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,14 @@ export type FormProps<ResponseDataType = unknown> = {
};

export type Components = {
RootInner: ElementType<{ children?: ReactNode }>;
RootInner: ElementType<RootInnerProps>;
SubmitButton: ElementType<SubmitButtonProps>;
SubmitButtonWrapper: ElementType<{ children?: ReactNode }>;
SubmitButtonWrapper: ElementType<SubmitButtonWrapperProps>;
};

type SubmitButtonProps = {
status: FormRequestStatus;
children?: ReactNode;
};
type RootInnerProps = { children?: ReactNode };
type SubmitButtonProps = { children?: ReactNode };
type SubmitButtonWrapperProps = { children?: ReactNode };

export type CompiledFormSchema = FormSchema & {
root: true;
Expand Down Expand Up @@ -140,25 +139,31 @@ const _Form = <ResponseDataType = unknown,>(

return (
<FieldMapperContext.Provider value={fieldMapper}>
<FormContext.Provider value={context}>
<form
action={action}
method={method}
onSubmit={handleSubmit}
onReset={handleReset}
ref={ref}
id={id}
>
<components.RootInner>
{children ? children : <AutoField name={name} />}
<components.SubmitButtonWrapper>
<components.SubmitButton status={request.status}>
{submitLabel}
</components.SubmitButton>
</components.SubmitButtonWrapper>
</components.RootInner>
</form>
</FormContext.Provider>
<FormRequestContext.Provider value={request}>
<FormContext.Provider value={context}>
<form
action={action}
method={method}
onSubmit={handleSubmit}
onReset={handleReset}
ref={ref}
id={id}
>
{children ? (
children
) : (
<components.RootInner>
<AutoField name={name} />
<components.SubmitButtonWrapper>
<components.SubmitButton>
{submitLabel}
</components.SubmitButton>
</components.SubmitButtonWrapper>
</components.RootInner>
)}
</form>
</FormContext.Provider>
</FormRequestContext.Provider>
</FieldMapperContext.Provider>
);
};
Expand All @@ -171,10 +176,12 @@ declare module "react" {
): (props: P & React.RefAttributes<T>) => React.ReactElement | null;
}

const SubmitButton = ({ status, children }: SubmitButtonProps) => {
const SubmitButton = (props: SubmitButtonProps) => {
const request = useFormRequestContext();

return (
<button type="submit" disabled={status === "loading"}>
{children}
<button type="submit" disabled={request.status === "loading"}>
{props.children}
</button>
);
};
Expand Down Expand Up @@ -748,3 +755,19 @@ export const AutoField = ({ name, required = false }: AutoFieldProps) => {

return <FieldComponent {...field} required={required} />;
};

const FormRequestContext = createContext<FormRequest<unknown> | undefined>(
undefined
);

export const useFormRequestContext = () => {
const context = useContext(FormRequestContext);

if (context === undefined) {
throw new Error(
"`useFormRequest` must be used in a component wrapper in a `FormRequestContext.Provider`"
);
}

return context;
};

0 comments on commit 6084216

Please sign in to comment.