1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-01-19 08:52:25 +01:00

(archi) organize react-hook-form components in a separate folder

This commit is contained in:
Sylvain 2022-04-05 14:25:58 +02:00
parent 5bc20075ed
commit 7beb1466bf
8 changed files with 29 additions and 28 deletions

View File

@ -4,9 +4,9 @@ import { react2angular } from 'react2angular';
import { AuthenticationProvider } from '../../models/authentication-provider'; import { AuthenticationProvider } from '../../models/authentication-provider';
import { Loader } from '../base/loader'; import { Loader } from '../base/loader';
import { IApplication } from '../../models/application'; import { IApplication } from '../../models/application';
import { RHFInput } from '../base/rhf-input'; import { FormInput } from '../form/form-input';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { FabSelect } from '../base/fab-select'; import { FormSelect } from '../form/form-select';
declare const Application: IApplication; declare const Application: IApplication;
@ -46,8 +46,8 @@ export const ProviderForm: React.FC<ProviderFormProps> = ({ action, provider, on
return ( return (
<form className="provider-form" onSubmit={handleSubmit(onSubmit)}> <form className="provider-form" onSubmit={handleSubmit(onSubmit)}>
<RHFInput id="name" register={register} readOnly={action === 'update'} rules={{ required: true }} label={t('app.shared.authentication.name')} /> <FormInput id="name" register={register} readOnly={action === 'update'} rules={{ required: true }} label={t('app.shared.authentication.name')} />
<FabSelect id="providable_type" control={control} options={buildProvidableTypeOptions()} label={t('app.shared.authentication.authentication_type')} rules={{ required: true }} /> <FormSelect id="providable_type" control={control} options={buildProvidableTypeOptions()} label={t('app.shared.authentication.authentication_type')} rules={{ required: true }} />
<input type={'submit'} /> <input type={'submit'} />
</form> </form>
); );

View File

@ -4,7 +4,7 @@ import { FieldValues } from 'react-hook-form/dist/types/fields';
import { FieldPath } from 'react-hook-form/dist/types/path'; import { FieldPath } from 'react-hook-form/dist/types/path';
import { FormComponent } from '../../models/form-component'; import { FormComponent } from '../../models/form-component';
interface RHFInputProps<TFieldValues> extends InputHTMLAttributes<HTMLInputElement>, FormComponent<TFieldValues>{ interface FormInputProps<TFieldValues> extends InputHTMLAttributes<HTMLInputElement>, FormComponent<TFieldValues>{
id: string, id: string,
label?: string, label?: string,
tooltip?: string, tooltip?: string,
@ -16,10 +16,10 @@ interface RHFInputProps<TFieldValues> extends InputHTMLAttributes<HTMLInputEleme
/** /**
* This component is a template for an input component to use within React Hook Form * This component is a template for an input component to use within React Hook Form
*/ */
export const RHFInput = <TFieldValues extends FieldValues>({ id, register, label, tooltip, defaultValue, icon, className, rules, readOnly, disabled, type, addOn, addOnClassName, placeholder, error, step }: RHFInputProps<TFieldValues>) => { export const FormInput = <TFieldValues extends FieldValues>({ id, register, label, tooltip, defaultValue, icon, className, rules, readOnly, disabled, type, addOn, addOnClassName, placeholder, error, step }: FormInputProps<TFieldValues>) => {
// Compose classnames from props // Compose classnames from props
const classNames = ` const classNames = `
rhf-input ${className || ''} form-input ${className || ''}
${error && error[id] ? 'is-incorrect' : ''} ${error && error[id] ? 'is-incorrect' : ''}
${rules && rules.required ? 'is-required' : ''} ${rules && rules.required ? 'is-required' : ''}
${readOnly ? 'is-readOnly' : ''} ${readOnly ? 'is-readOnly' : ''}
@ -27,12 +27,12 @@ export const RHFInput = <TFieldValues extends FieldValues>({ id, register, label
return ( return (
<label className={classNames}> <label className={classNames}>
{label && <div className='rhf-input-header'> {label && <div className='form-input-header'>
<p>{label}</p> <p>{label}</p>
{/* TODO: Create tooltip component */} {/* TODO: Create tooltip component */}
{tooltip && <span>{tooltip}</span>} {tooltip && <span>{tooltip}</span>}
</div>} </div>}
<div className='rhf-input-field'> <div className='form-input-field'>
{icon && <span className="icon">{icon}</span>} {icon && <span className="icon">{icon}</span>}
<input id={id} <input id={id}
{...register(id as FieldPath<TFieldValues>, { {...register(id as FieldPath<TFieldValues>, {
@ -47,7 +47,7 @@ export const RHFInput = <TFieldValues extends FieldValues>({ id, register, label
placeholder={placeholder} /> placeholder={placeholder} />
{addOn && <span className={`addon ${addOnClassName || ''}`}>{addOn}</span>} {addOn && <span className={`addon ${addOnClassName || ''}`}>{addOn}</span>}
</div> </div>
{(error && error[id]) && <div className="rhf-input-error">{error[id].message}</div> } {(error && error[id]) && <div className="form-input-error">{error[id].message}</div> }
</label> </label>
); );
}; };

View File

@ -6,7 +6,7 @@ import { FieldPath } from 'react-hook-form/dist/types/path';
import { FieldPathValue, UnpackNestedValue } from 'react-hook-form/dist/types'; import { FieldPathValue, UnpackNestedValue } from 'react-hook-form/dist/types';
import { FormControlledComponent } from '../../models/form-component'; import { FormControlledComponent } from '../../models/form-component';
interface FabSelectProps<TFieldValues, TContext extends object, TOptionValue> extends SelectHTMLAttributes<HTMLSelectElement>, FormControlledComponent<TFieldValues, TContext> { interface FormSelectProps<TFieldValues, TContext extends object, TOptionValue> extends SelectHTMLAttributes<HTMLSelectElement>, FormControlledComponent<TFieldValues, TContext> {
id: string, id: string,
label?: string, label?: string,
options: Array<selectOption<TOptionValue>>, options: Array<selectOption<TOptionValue>>,
@ -23,19 +23,19 @@ type selectOption<TOptionValue> = { value: TOptionValue, label: string };
* This component is a wrapper around react-select to use with react-hook-form. * This component is a wrapper around react-select to use with react-hook-form.
* It is a multi-select component. * It is a multi-select component.
*/ */
export const FabMultiSelect = <TFieldValues extends FieldValues, TContext extends object, TOptionValue>({ id, label, className, control, placeholder, options, valuesDefault, error, rules, disabled }: FabSelectProps<TFieldValues, TContext, TOptionValue>) => { export const FormMultiSelect = <TFieldValues extends FieldValues, TContext extends object, TOptionValue>({ id, label, className, control, placeholder, options, valuesDefault, error, rules, disabled }: FormSelectProps<TFieldValues, TContext, TOptionValue>) => {
const classNames = ` const classNames = `
fab-multi-select ${className || ''} form-multi-select ${className || ''}
${error && error[id] ? 'is-incorrect' : ''} ${error && error[id] ? 'is-incorrect' : ''}
${rules && rules.required ? 'is-required' : ''} ${rules && rules.required ? 'is-required' : ''}
${disabled ? 'is-disabled' : ''}`; ${disabled ? 'is-disabled' : ''}`;
return ( return (
<label className={classNames}> <label className={classNames}>
{label && <div className="fab-multi-select-header"> {label && <div className="form-multi-select-header">
<p>{label}</p> <p>{label}</p>
</div>} </div>}
<div className="fab-multi-select-field"> <div className="form-multi-select-field">
<Controller name={id as FieldPath<TFieldValues>} <Controller name={id as FieldPath<TFieldValues>}
control={control} control={control}
defaultValue={valuesDefault as UnpackNestedValue<FieldPathValue<TFieldValues, Path<TFieldValues>>>} defaultValue={valuesDefault as UnpackNestedValue<FieldPathValue<TFieldValues, Path<TFieldValues>>>}

View File

@ -6,7 +6,7 @@ import { FieldPath } from 'react-hook-form/dist/types/path';
import { FieldPathValue, UnpackNestedValue } from 'react-hook-form/dist/types'; import { FieldPathValue, UnpackNestedValue } from 'react-hook-form/dist/types';
import { FormControlledComponent } from '../../models/form-component'; import { FormControlledComponent } from '../../models/form-component';
interface FabSelectProps<TFieldValues, TContext extends object, TOptionValue> extends SelectHTMLAttributes<HTMLSelectElement>, FormControlledComponent<TFieldValues, TContext> { interface FormSelectProps<TFieldValues, TContext extends object, TOptionValue> extends SelectHTMLAttributes<HTMLSelectElement>, FormControlledComponent<TFieldValues, TContext> {
id: string, id: string,
label?: string, label?: string,
options: Array<selectOption<TOptionValue>>, options: Array<selectOption<TOptionValue>>,
@ -22,25 +22,25 @@ type selectOption<TOptionValue> = { value: TOptionValue, label: string };
/** /**
* This component is a wrapper for react-select to use with react-hook-form * This component is a wrapper for react-select to use with react-hook-form
*/ */
export const FabSelect = <TFieldValues extends FieldValues, TContext extends object, TOptionValue>({ id, label, className, control, placeholder, options, valueDefault, error, rules, disabled }: FabSelectProps<TFieldValues, TContext, TOptionValue>) => { export const FormSelect = <TFieldValues extends FieldValues, TContext extends object, TOptionValue>({ id, label, className, control, placeholder, options, valueDefault, error, rules, disabled }: FormSelectProps<TFieldValues, TContext, TOptionValue>) => {
const classNames = ` const classNames = `
fab-select ${className || ''} form-select ${className || ''}
${error && error[id] ? 'is-incorrect' : ''} ${error && error[id] ? 'is-incorrect' : ''}
${rules && rules.required ? 'is-required' : ''} ${rules && rules.required ? 'is-required' : ''}
${disabled ? 'is-disabled' : ''}`; ${disabled ? 'is-disabled' : ''}`;
return ( return (
<label className={classNames}> <label className={classNames}>
{label && <div className="fab-select-header"> {label && <div className="form-select-header">
<p>{label}</p> <p>{label}</p>
</div>} </div>}
<div className="fab-select-field"> <div className="form-select-field">
<Controller name={id as FieldPath<TFieldValues>} <Controller name={id as FieldPath<TFieldValues>}
control={control} control={control}
defaultValue={valueDefault as UnpackNestedValue<FieldPathValue<TFieldValues, Path<TFieldValues>>>} defaultValue={valueDefault as UnpackNestedValue<FieldPathValue<TFieldValues, Path<TFieldValues>>>}
render={({ field: { onChange, value, ref } }) => render={({ field: { onChange, value, ref } }) =>
<Select inputRef={ref} <Select inputRef={ref}
className="fab-select-field-input" className="form-select-field-input"
value={options.find(c => c.value === value)} value={options.find(c => c.value === value)}
onChange={val => onChange(val.value)} onChange={val => onChange(val.value)}
placeholder={placeholder} placeholder={placeholder}

View File

@ -5,7 +5,7 @@ import { PlanCategory } from '../../models/plan-category';
import { Loader } from '../base/loader'; import { Loader } from '../base/loader';
import { useForm, Controller, SubmitHandler } from 'react-hook-form'; import { useForm, Controller, SubmitHandler } from 'react-hook-form';
import { FabTextEditor } from '../base/text-editor/fab-text-editor'; import { FabTextEditor } from '../base/text-editor/fab-text-editor';
import { RHFInput } from '../base/rhf-input'; import { FormInput } from '../form/form-input';
import { FabAlert } from '../base/fab-alert'; import { FabAlert } from '../base/fab-alert';
import { FabButton } from '../base/fab-button'; import { FabButton } from '../base/fab-button';
@ -45,13 +45,13 @@ const PlanCategoryFormComponent: React.FC<PlanCategoryFormProps> = ({ action, ca
return ( return (
<form onSubmit={handleSubmit(onSubmit)}> <form onSubmit={handleSubmit(onSubmit)}>
<RHFInput id='name' register={register} rules={{ required: 'true' }} label={t('app.admin.manage_plan_category.name')} /> <FormInput id='name' register={register} rules={{ required: 'true' }} label={t('app.admin.manage_plan_category.name')} />
<Controller name="description" control={control} render={({ field: { onChange, value } }) => <Controller name="description" control={control} render={({ field: { onChange, value } }) =>
<FabTextEditor label={t('app.admin.manage_plan_category.description')} onChange={onChange} content={value} limit={100} /> <FabTextEditor label={t('app.admin.manage_plan_category.description')} onChange={onChange} content={value} limit={100} />
} /> } />
<RHFInput id='weight' register={register} type='number' label={t('app.admin.manage_plan_category.significance')} /> <FormInput id='weight' register={register} type='number' label={t('app.admin.manage_plan_category.significance')} />
<FabAlert level="info" className="significance-info"> <FabAlert level="info" className="significance-info">
{t('app.admin.manage_plan_category.info')} {t('app.admin.manage_plan_category.info')}
</FabAlert> </FabAlert>

View File

@ -22,7 +22,8 @@
@import "modules/base/fab-popover"; @import "modules/base/fab-popover";
@import "modules/base/fab-text-editor"; @import "modules/base/fab-text-editor";
@import "modules/base/labelled-input"; @import "modules/base/labelled-input";
@import "modules/base/rhf-input"; @import "modules/form/form-input";
@import "modules/form/form-select";
@import "modules/machines/machine-card"; @import "modules/machines/machine-card";
@import "modules/machines/machines-filters"; @import "modules/machines/machines-filters";
@import "modules/machines/machines-list"; @import "modules/machines/machines-list";

View File

@ -1,4 +1,4 @@
.rhf-input { .form-input {
width: 100%; width: 100%;
margin-bottom: 1.6rem; margin-bottom: 1.6rem;

View File

@ -1,5 +1,5 @@
.fab-select, .form-select,
.fab-multi-select { .form-multi-select {
width: 100%; width: 100%;
margin-bottom: 1.6rem; margin-bottom: 1.6rem;