react-whitelabel-form
v0.0.6
Published
Let's you easily create strongly typed forms you can customize to your particular use case.
Downloads
3
Readme
React Whitelabel Form (alpha)
Let's you easily create strongly typed forms you can customize to your particular use case.
Objectives
- inline validation
- performance
- less verbose
- don't use wrapper components (hard to read)
- build in state management specific to the form
- types all the way
- ability to handle any existing existing comp libraries
- makes it much easier to have uniformity with your forms (since it creates the "blessed" components)
Example
import {
createUseWhitelabelForm,
createWhitelabelComponent,
} from "react-whitelabel-form";
const useAcmeForm = createUseWhitelabelForm({
TextInput: createWhitelabelComponent<string, { label: string }>((p) => {
return (
<div>
<div>{p.customProps.label}</div>
<div>
<input
type="text"
value={p.requiredProps.value}
onBlur={p.requiredProps.onBlur}
onFocus={p.requiredProps.onFocus}
onChange={(e) => p.requiredProps.onChangeValue(e.target.value)}
/>
</div>
{p.requiredProps.errors ? (
<div>
{p.requiredProps.errors.map((e, index) => {
return <div key={index}>{e}</div>;
})}
</div>
) : null}
</div>
);
}),
NumberInput: createWhitelabelComponent<number, { label: string }>((p) => {
return (
<div>
<div>{p.customProps.label}</div>
<div>
<input
type="number"
value={p.requiredProps.value}
onBlur={p.requiredProps.onBlur}
onFocus={p.requiredProps.onFocus}
onChange={(e) =>
p.requiredProps.onChangeValue(parseFloat(e.target.value))
}
/>
</div>
{p.requiredProps.errors ? (
<div>
{p.requiredProps.errors.map((e, index) => {
return <div key={index}>{e}</div>;
})}
</div>
) : null}
</div>
);
}),
SelectInput: createWhitelabelComponent<
string,
{ label: string; options: { prettyVal: string; val: string }[] }
>((p) => {
return (
<div>
<div>{p.customProps.label}</div>
<div>
<select
onChange={(e) => p.requiredProps.onChangeValue(e.target.value)}
value={p.requiredProps.value}
onBlur={p.requiredProps.onBlur}
onFocus={p.requiredProps.onFocus}
>
{p.customProps.options.map((o) => {
return (
<option key={o.val} value={o.val}>
{o.prettyVal}
</option>
);
})}
</select>
</div>
{p.requiredProps.errors ? (
<div>
{p.requiredProps.errors.map((e, index) => {
return <div key={index}>{e}</div>;
})}
</div>
) : null}
</div>
);
}),
});
function App() {
const { TextInput, NumberInput, SelectInput, store, useStoreValue } =
useAcmeForm({
initState: { email: "", name: "", age: 0, favFood: "" },
});
return (
<div>
<form
onSubmit={(e) => {
store.validate();
console.log(store.get());
e.preventDefault();
}}
>
<TextInput
label="Enter your name"
validate={(v) => {
return "";
}}
field={(s) => s.name}
minLength={3}
maxLength={[50, "Name is too long "]}
/>
<TextInput
label="Enter your email"
field={(s) => s.email}
pattern={["email", "Not a valid email"]}
required={true}
/>
<NumberInput
label="Enter your age"
min={0}
max={120}
field={(s) => s.age}
/>
<SelectInput
field={(s) => s.favFood}
label={"Fav Food"}
validate={(s) => {
if (store.get().age < 10 && s === "sushi") {
return "Sushi is much too tasty for small children.";
}
return "";
}}
options={[
{ prettyVal: "Pizza", val: "pizza" },
{ prettyVal: "Sushi", val: "sushi" },
]}
/>
<input type={"submit"} />
</form>
</div>
);
}
export default App;