-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update typings & fields, add MuiRhfForm component
- Loading branch information
1 parent
828a686
commit ee4e815
Showing
12 changed files
with
271 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
import React from "react"; | ||
|
||
import { Grid } from "@material-ui/core"; | ||
|
||
import { | ||
MuiRhfFormProps, | ||
fieldComponentMap, | ||
defaultFieldComponent, | ||
} from "~/models/form"; | ||
|
||
const MuiRhfForm: React.FC<MuiRhfFormProps> = ({ | ||
fields, | ||
headers, | ||
spacing = 1, | ||
watch, | ||
}) => { | ||
return ( | ||
<> | ||
{React.Children.toArray( | ||
fields.map((fieldArray, key) => { | ||
// Format of fieldArray is NOT valid, must be array of array | ||
if (!Array.isArray(fieldArray)) { | ||
return null; | ||
} | ||
|
||
const header = headers?.[key]; | ||
|
||
return ( | ||
<Grid container spacing={spacing}> | ||
{header && ( | ||
<Grid item xs={12}> | ||
{header.title && <h2>{header.title}</h2>} | ||
</Grid> | ||
)} | ||
{fieldArray.map( | ||
({ | ||
name, | ||
label, | ||
props, | ||
gridProps = {}, | ||
type, | ||
condition, | ||
conditions, | ||
conditionalProps, | ||
}) => { | ||
// Initialize dynamic props based on watched values | ||
const extra: { [key: string]: any } = {}; | ||
|
||
// Construct field, take textField by default | ||
const MuiRhfField = | ||
fieldComponentMap[type] || defaultFieldComponent; | ||
|
||
if (watch) { | ||
// Union will be used in condition keys | ||
if (condition) { | ||
let conditionHidden = true; | ||
|
||
// Retrieve conditions keys | ||
const conditionKeys = Object.keys(condition); | ||
|
||
// Retrieve watched values | ||
const conditionWatchedValues = watch(conditionKeys); | ||
|
||
// Check conditions, we are actually doing an union of conditions | ||
// If at least one condition has been satisfied, display | ||
conditionKeys.forEach((conditionKey) => { | ||
if ( | ||
condition[conditionKey]( | ||
conditionWatchedValues[conditionKey] | ||
) | ||
) { | ||
conditionHidden = false; | ||
} | ||
}); | ||
|
||
if (conditionHidden) { | ||
return null; | ||
} | ||
} | ||
|
||
// Intersection will be used in conditions keys | ||
if (conditions) { | ||
let conditionsHidden = false; | ||
|
||
// Retrieve conditions keys | ||
const conditionsKeys = Object.keys(conditions); | ||
|
||
// Retrieve watched values | ||
const conditionsWatchedValues = watch(conditionsKeys); | ||
|
||
// Check conditions, we are actually doing an union of conditions | ||
// All condition needs to be satisfied to display the field | ||
conditionsKeys.forEach((conditionsKey) => { | ||
if ( | ||
!conditions[conditionsKey]( | ||
conditionsWatchedValues[conditionsKey] | ||
) | ||
) { | ||
conditionsHidden = true; | ||
} | ||
}); | ||
|
||
if (conditionsHidden) { | ||
return null; | ||
} | ||
} | ||
|
||
if (conditionalProps) { | ||
// Retrieve conditions keys | ||
const conditionalKeys = Object.keys(conditionalProps); | ||
|
||
// Retrieve watched values | ||
const conditionalWatchedValues = watch(conditionalKeys); | ||
|
||
// Check conditions | ||
conditionalKeys.forEach((conditionalKey) => { | ||
const [path, customCondition] = conditionalProps[ | ||
conditionalKey | ||
]; | ||
|
||
// FIXME: Support nested paths | ||
extra[path] = customCondition( | ||
conditionalWatchedValues[conditionalKey] | ||
); | ||
}); | ||
} | ||
} | ||
return ( | ||
<Grid | ||
key={name || label} | ||
item | ||
xs={4} // Will be overwrite if specified in gridProps | ||
{...gridProps} | ||
> | ||
<MuiRhfField | ||
label={label} | ||
name={name || label} | ||
{...props} | ||
{...extra} | ||
/> | ||
</Grid> | ||
); | ||
} | ||
)} | ||
</Grid> | ||
); | ||
}) | ||
)} | ||
</> | ||
); | ||
}; | ||
|
||
export default MuiRhfForm; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,13 @@ | ||
import MuiRhfForm from "./MuiRhfForm"; | ||
import MuiRhfTextField from "./MuiRhfTextField"; | ||
import MuiRhfSelect from "./MuiRhfSelect"; | ||
import MuiRhfCheckbox from "./MuiRhfCheckbox"; | ||
import MuiRhfAutocomplete from "./MuiRhfAutocomplete"; | ||
|
||
export { MuiRhfTextField, MuiRhfSelect, MuiRhfCheckbox, MuiRhfAutocomplete }; | ||
export { | ||
MuiRhfForm, | ||
MuiRhfTextField, | ||
MuiRhfSelect, | ||
MuiRhfCheckbox, | ||
MuiRhfAutocomplete, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./typing"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { Control, FieldErrors } from "react-hook-form"; | ||
import { TextFieldProps, SelectProps, CheckboxProps } from "@material-ui/core"; | ||
|
||
/** Common fields props */ | ||
export type MuiRhfFieldProps = { | ||
control: Control; | ||
errors: FieldErrors; | ||
name: string; | ||
label?: string; | ||
}; | ||
|
||
/** TextField */ | ||
export type MuiRhfTextFieldProps = MuiRhfFieldProps & | ||
Omit<TextFieldProps, "onChange"> & { | ||
defaultValue?: unknown; | ||
}; | ||
|
||
/** Select */ | ||
export type MuiRhfSelectProps = MuiRhfFieldProps & { | ||
defaultValue?: unknown; | ||
select?: SelectProps; | ||
options: { | ||
value: string | number | readonly string[] | undefined; | ||
label: string; | ||
}[]; | ||
}; | ||
|
||
/** Checkbox */ | ||
export type MuiRhfCheckboxProps = MuiRhfFieldProps & | ||
Omit<CheckboxProps, "defaultValue" | "onChange" | "label"> & { | ||
defaultValue?: unknown; | ||
}; | ||
|
||
/** Autocomplete */ | ||
export type MuiRhfAutocompleteProps = MuiRhfFieldProps & { | ||
defaultValue?: unknown; | ||
textField?: Omit<TextFieldProps, "onChange">; | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
autocomplete?: any; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { | ||
MuiRhfTextField, | ||
MuiRhfSelect, | ||
MuiRhfCheckbox, | ||
MuiRhfAutocomplete, | ||
} from "~/components"; | ||
|
||
import { MuiRhfFieldComponentMap } from "./typing"; | ||
|
||
export const defaultFieldComponent = MuiRhfTextField; | ||
export const fieldComponentMap: MuiRhfFieldComponentMap = { | ||
textField: MuiRhfTextField, | ||
select: MuiRhfSelect, | ||
checkbox: MuiRhfCheckbox, | ||
autocomplete: MuiRhfAutocomplete, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from "./typing"; | ||
export * from "./consts"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { GridSpacing, GridProps } from "@material-ui/core"; | ||
import { | ||
MuiRhfTextFieldProps, | ||
MuiRhfSelectProps, | ||
MuiRhfCheckboxProps, | ||
MuiRhfAutocompleteProps, | ||
} from "~/models/fields"; | ||
|
||
/** react-hook-form watch */ | ||
export type RhfWatch = (names?: string | string[]) => any; | ||
|
||
/** Form field key component mapping */ | ||
export type MuiRhfFieldComponentMap = { | ||
textField: React.FC<MuiRhfTextFieldProps>; | ||
select: React.FC<MuiRhfSelectProps>; | ||
checkbox: React.FC<MuiRhfCheckboxProps>; | ||
autocomplete: React.FC<MuiRhfAutocompleteProps>; | ||
}; | ||
|
||
/** Form */ | ||
type MuiRhfFormFieldCondition = { [key: string]: (value: unknown) => boolean }; | ||
type MuiRhfFormFieldConditionalProps = { | ||
[key: string]: [string, (value: unknown) => unknown]; | ||
}; | ||
|
||
type MuiRhfFormField = { | ||
label?: string; | ||
name?: string; | ||
type: keyof MuiRhfFieldComponentMap; | ||
props: any; | ||
gridProps?: Pick<GridProps, "xs" | "sm" | "md" | "lg" | "xl">; | ||
condition?: MuiRhfFormFieldCondition; // Union | ||
conditions?: MuiRhfFormFieldCondition; // Intersection | ||
conditionalProps?: MuiRhfFormFieldConditionalProps; // Props applied when condition is satisfied | ||
}; | ||
|
||
type MuiRhfFormHeader = { | ||
title?: string; | ||
}; | ||
|
||
export type MuiRhfFormProps = { | ||
fields: MuiRhfFormField[][]; | ||
headers?: MuiRhfFormHeader[]; | ||
spacing?: GridSpacing; | ||
watch?: RhfWatch; | ||
}; |
This file was deleted.
Oops, something went wrong.