Skip to content

Commit

Permalink
feat(meta): add option to display mandatory field hint
Browse files Browse the repository at this point in the history
  • Loading branch information
EtienneDOYON committed Dec 13, 2023
1 parent e8ac803 commit 16b2136
Show file tree
Hide file tree
Showing 21 changed files with 135 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const Checkbox = ({
onChange,
propRef,
value,
shouldDisplayRequiredHint,
}: {
'data-testid': string;
errorMessage: string;
Expand All @@ -29,9 +30,14 @@ export const Checkbox = ({
propRef: Ref<any>;

Check warning on line 30 in apps/demo/src/app/examples/with-material-ui/dictionary/checkBox.component.tsx

View workflow job for this annotation

GitHub Actions / pr

Unexpected any. Specify a different type
type?: string;
value?: boolean;
shouldDisplayRequiredHint?: boolean;
}) => {
const inputProps = useMemo(() => ({ ref: propRef, 'aria-label': 'controlled' }), [propRef]);

if (shouldDisplayRequiredHint) {
label += ' *';
}

return (
<Box sx={{ m: 2 }}>
<FormGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export const DateInput = ({
onChange,
onBlur,
propRef,
shouldDisplayRequiredHint,
}: {
'data-testid': string;
errors: FieldErrors;
Expand All @@ -41,6 +42,7 @@ export const DateInput = ({
value?: string | number;
validation: Validations;
setFieldValue: (id: Path<FieldValues>, value: any) => void;

Check warning on line 44 in apps/demo/src/app/examples/with-material-ui/dictionary/date.component.tsx

View workflow job for this annotation

GitHub Actions / pr

Unexpected any. Specify a different type
shouldDisplayRequiredHint?: boolean;
}) => {
const inputProps = useMemo(() => ({ ref: propRef }), [propRef]);
const rules = getValidationRulesHints({
Expand All @@ -50,6 +52,10 @@ export const DateInput = ({

const hasError = !!checkRules(value, rules).length;

if (shouldDisplayRequiredHint) {
label += ' *';
}

return (
<div>
<BirthdateInput
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export const Password = ({
propRef,
value,
validation,
shouldDisplayRequiredHint,
}: {
'data-testid': string;
errors: FieldErrors;
Expand All @@ -38,6 +39,7 @@ export const Password = ({
type?: string;
value?: string | number;
validation: Validations;
shouldDisplayRequiredHint?: boolean;
}) => {
const inputProps = useMemo(() => ({ ref: propRef }), [propRef]);

Expand All @@ -48,6 +50,10 @@ export const Password = ({

const hasError = !!checkRules(value, rules).length;

if (shouldDisplayRequiredHint) {
label += ' *';
}

return (
<ValidatedTextField
type="password"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export const Select = ({
value,
choices,
multiple,
shouldDisplayRequiredHint,
}: {
'data-testid': string;
errorMessage: string;
Expand All @@ -28,9 +29,14 @@ export const Select = ({
value?: string | number;
choices: string[] | number[];
multiple?: boolean;
shouldDisplayRequiredHint?: boolean;
}) => {
const inputProps = useMemo(() => ({ ref: propRef }), [propRef]);

if (shouldDisplayRequiredHint) {
label += ' *';
}

return (
<Box sx={{ m: 2 }}>
<InputLabel id="label-id">{label}</InputLabel>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export const Text = ({
type,
value,
multiline,
shouldDisplayRequiredHint,
}: {
'data-testid': string;
errorMessage: string;
Expand All @@ -31,10 +32,15 @@ export const Text = ({
type?: string;
value?: string | number;
multiline?: boolean;
shouldDisplayRequiredHint?: boolean;
}) => {
const inputProps = useMemo(() => ({ ref: propRef }), [propRef]);
const error = errors && errors.type && errorMessage;

if (shouldDisplayRequiredHint) {
label += ' *';
}

return (
<Box sx={{ m: 2 }}>
<TextField
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,17 @@ export const Checkbox = ({
onChange,
value,
label,
shouldDisplayRequiredHint,
}: {
onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
value: boolean;
label: string;
shouldDisplayRequiredHint?: boolean;
}) => {
if (shouldDisplayRequiredHint) {
label += ' *';
}

return (
<div>
<label>{label}</label>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { RuleList } from '../atoms/rule-list.component';
export const DateInput = ({
errors,
validation,
shouldDisplayRequiredHint,
label,
...props
}: {
Expand All @@ -23,6 +24,7 @@ export const DateInput = ({
id: string;
setFieldValue: (id: Path<FieldValues>, value: any) => void;
onChange: (event: any) => void;
shouldDisplayRequiredHint?: boolean;
}) => {
const rules = getValidationRulesHints({
errors,
Expand All @@ -32,6 +34,10 @@ export const DateInput = ({
const fieldError = errors && errors.type;
const isValid = !!(props.value && !hasError && !fieldError);

if (shouldDisplayRequiredHint) {
label += ' *';
}

return (
<TextFieldMarginWrapper>
<BirthdateInput
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@ import { RuleList } from '../atoms/rule-list.component';
export const Password = ({
errors,
validation,
shouldDisplayRequiredHint,
label,
...props
}: {
errors: FieldErrors;
errorMessage: string;
label: string;
value?: string | number;
validation: Validations;
shouldDisplayRequiredHint?: boolean;
}) => {
const rules = getValidationRulesHints({
errors,
Expand All @@ -27,11 +30,16 @@ export const Password = ({
const fieldError = errors && errors.type;
const isValid = !!(props.value && !hasError && !fieldError);

if (shouldDisplayRequiredHint) {
label += ' *';
}

return (
<TextFieldTopMarginWrapper>
<ValidatedPasswordTextField
hasError={hasError}
valid={isValid}
label={label}
{...props}
rules={rules}
ruleComponent={RuleList}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,19 @@ export const Select = ({
label,
choices,
multiple,
shouldDisplayRequiredHint,
}: {
onChange: (event: React.ChangeEvent<HTMLSelectElement>) => void;
value: string | number;
label: string;
choices: string[] | number[];
multiple?: boolean;
shouldDisplayRequiredHint?: boolean;
}) => {
if (shouldDisplayRequiredHint) {
label += ' *';
}

return (
<div style={{ margin: '24px' }}>
<label>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,16 @@ const PreviousButton = styled.button`
border: 1px solid rgba(150, 100, 255);
`;

export const Submit = ({ label, formId, ...props }: { label: string; formId: string }) => {
export const Submit = ({
label,
formId,
shouldDisplayRequiredHint,
...props
}: {
label: string;
formId: string;
shouldDisplayRequiredHint?: boolean;
}) => {
const dispatch = useDispatch();

const shouldDisplayPrevious = useSelector(getCurrentStepIndex(formId)) !== 0;
Expand All @@ -29,6 +38,10 @@ export const Submit = ({ label, formId, ...props }: { label: string; formId: str
dispatch(setPreviousStep(formId));
};

if (shouldDisplayRequiredHint) {
label += ' *';
}

return (
<ActionsWrapper>
{shouldDisplayPrevious && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,33 @@ export const Text = ({
errors,
errorMessage,
validation,
shouldDisplayRequiredHint,
label,
...props
}: {
errors: FieldErrors;
errorMessage: string;
label: string;
value?: string | number;
validation: Validations;
shouldDisplayRequiredHint?: boolean;
}) => {
const error = errors && errors.type && errorMessage;

if (shouldDisplayRequiredHint) {
label += ' *';
}

return (
<TextFieldMarginWrapper>
<ValidatedTextField type="text" hasError={!!error} errorText={error} valid={!!props.value && !error} {...props} />
<ValidatedTextField
type="text"
hasError={!!error}
errorText={error}
valid={!!props.value && !error}
label={label}
{...props}
/>
</TextFieldMarginWrapper>
);
};
3 changes: 3 additions & 0 deletions apps/demo/src/app/login.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ export const config = {
},
},
},
formMeta: {
shouldDisplayRequiredHint: true,
},
steps: {
'login-step-0': {
fieldsById: ['email'],
Expand Down
3 changes: 3 additions & 0 deletions apps/demo/src/app/register.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,9 @@ export const config: Config = {
},
},
},
formMeta: {
shouldDisplayRequiredHint: true,
},
steps: {
'register-step-0': {
fieldsById: ['email', 'discloseGender', 'gender', 'firstName', 'lastName'],
Expand Down
3 changes: 3 additions & 0 deletions apps/docsite/docs/form-builder.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ export interface FormSchema {
| Path<string>;
};
};
formMeta?: {
shouldDisplayRequiredHint?: boolean;
};
steps: {
[key: string]: {
id: string;
Expand Down
3 changes: 3 additions & 0 deletions libs/form-builder/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ export interface FormSchema {
| Path<string>;
};
};
formMeta?: {
shouldDisplayRequiredHint?: boolean;
};
steps: {
[key: string]: {
id: string;
Expand Down
1 change: 1 addition & 0 deletions libs/form-builder/src/lib/__tests__/fixtures.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export const CORRECT_SCHEMA: FormSchema = {
type: 'text',
},
},
formMeta: {},
steps: { ...stepOne, ...stepTwo },
stepsById: [stepOneId, stepTwoId],
};
Expand Down
24 changes: 22 additions & 2 deletions libs/form-builder/src/lib/components/formField.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,32 @@ export interface FormFieldProps {
onClick?: (event: any) => void;
isValidating?: boolean;
formId?: string;
shouldDisplayRequiredHint?: boolean;
}

export function FormField({ id, fieldType, dictionary, ...props }: FormFieldProps) {
export function FormField({
id,
fieldType,
dictionary,
shouldDisplayRequiredHint,
validation,
...props
}: FormFieldProps) {
const Field = dictionary[fieldType];

if (!Field) return null;

return <Field data-testid={id} id={id} {...props} />;
if (!validation || !validation?.required?.value) {
shouldDisplayRequiredHint = false;
}

return (
<Field
data-testid={id}
id={id}
shouldDisplayRequiredHint={shouldDisplayRequiredHint}
validation={validation}
{...props}
/>
);
}
3 changes: 2 additions & 1 deletion libs/form-builder/src/lib/formBuilder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export function FormBuilder({

const typesAllowed = React.useMemo(() => Object.keys(dictionary || EMPTY_OBJECT), [dictionary]);

const { fields, fieldsById, stepsById, submitLabel } = React.useMemo(
const { fields, fieldsById, stepsById, submitLabel, formMeta } = React.useMemo(
() => getSchemaInfo(schema, typesAllowed, currentStepIndex),
[currentStepIndex, schema, typesAllowed],
);
Expand Down Expand Up @@ -161,6 +161,7 @@ export function FormBuilder({
triggerValidationField={triggerValidationField}
propRef={ref}
isValidating={isValidating}
{...formMeta}
{...meta}
{...fieldRest}
/>
Expand Down
Loading

0 comments on commit 16b2136

Please sign in to comment.