Skip to content

Instantly share code, notes, and snippets.

@jwaldrip
Created June 4, 2020 17:19
Show Gist options
  • Save jwaldrip/4d59ebfa2e4ca373958639a1f39dfca1 to your computer and use it in GitHub Desktop.
Save jwaldrip/4d59ebfa2e4ca373958639a1f39dfca1 to your computer and use it in GitHub Desktop.
import React, { ComponentType, ComponentProps } from "react";
import { useFormField, FormFieldOptions, FormFieldArgs } from "./form-field";
import {
useFormToggle,
FormToggleArgs,
FormToggleOptions
} from "./form-toggle";
import { useFormSubmit, FormSubmitArgs } from "./form-submit";
import { useFormValue, FormValueOptions, FormValueArgs } from "./form-value";
type FactoryFn<I, C extends ComponentType<any>> = (
formProps: I
) => JSX.LibraryManagedAttributes<C, ComponentProps<C>>;
type FieldComponentType<
C extends ComponentType<any>,
I,
O = {}
> = ComponentType<ReturnType<FactoryFn<I, C>> & O>;
export const createFieldInputComponent = <
T extends any,
C extends ComponentType<any>
>(
Component: C,
propsFactory: FactoryFn<FormFieldArgs<T>, C>
): FieldComponentType<C, FormFieldArgs<T>, FormFieldOptions<T>> => ({
name,
validates,
sensitive,
shouldShowErrors,
...props
}) => {
const factoryProps = propsFactory(
useFormField<T>({ name, validates, sensitive, shouldShowErrors })
);
return <Component {...factoryProps} {...props} />;
};
export const createToggleInputComponent = <C extends ComponentType<any>>(
Component: C,
propsFactory: FactoryFn<FormToggleArgs, C>
): FieldComponentType<C, FormToggleArgs, FormToggleOptions> => ({
name,
validates,
sensitive,
shouldShowErrors,
...props
}) => {
const factoryProps = propsFactory(
useFormToggle({ name, validates, sensitive, shouldShowErrors })
);
return <Component {...factoryProps} {...props} />;
};
export const createValueComponent = <
C extends ComponentType<any>,
T extends any = string
>(
Component: C,
propsFactory: FactoryFn<FormValueArgs<T>, C>
): FieldComponentType<C, FormValueArgs<T>, FormValueOptions> => ({
name,
...props
}) => {
const factoryProps = propsFactory(useFormValue({ name }));
return <Component {...factoryProps} {...props} />;
};
export const createSubmitComponent = <C extends ComponentType<any>>(
Component: C,
propsFactory: FactoryFn<FormSubmitArgs, C>
): FieldComponentType<C, FormSubmitArgs> => (props) => {
const factoryProps = propsFactory(useFormSubmit());
return <Component {...factoryProps} {...props} />;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment