@timmons-group/config-form
Version:
React Components and helpers to build a form via configuration with react-hook-form and MUI
206 lines (205 loc) • 7.82 kB
TypeScript
/**
* @module FormTypes
* @see {@link https://stackoverflow.com/questions/49836644/how-to-import-a-typedef-from-one-file-to-another-in-jsdoc-using-node-js/73232942#73232942|stackoverflow}
*/
import { Schema } from 'yup';
/**
* @typedef {Object} ParsedFormLayout
* @property {Array<ParsedSection>} sections - array of parsed sections
* @property {Map<String, Object>} fields - map of fieldId to field object
* @property {Map<String, Object>} triggerFields - map of fieldId to field object
*/
export interface ParsedFormLayout {
sections: ParsedSection[];
fields: Map<string, ParsedField>;
triggerFields: Map<string, TriggerField>;
}
/**
* @typedef {Object} ParsedSection
* @property {string} name - section name (title and name are both used for backwards compatibility)
* @property {string} title - section title
* @property {Array<ParsedField>} fields - array of field objects
* @property {boolean} editable - if the section is editable
* @property {Array} enabled - if the section is enabled
* @property {number} order - order of the section
*/
export interface ParsedSection {
name: string;
title: string;
fields: ParsedField[];
editable: boolean;
enabled: boolean;
order: number;
}
/**
* @typedef {object} ProcessedDynamicFormLayout
* @property {object} defaultValues - The default values for the form
* @property {object} validations - The validation schema for the form
* @property {object} fieldsToWatch - The fields that need to be watched for changes
*/
export interface ProcessedDynamicFormLayout {
defaultValues: object;
validations: object;
fieldsToWatch: object;
}
/**
* @typedef {object} ParsedField
* @property {string} id - field id
* @property {string} label - field label
* @property {string} type - field type
* @property {boolean} hidden - if the field is hidden
* @property {Array<TriggerCondition>} conditions - if the field is hidden
* @property {object} specialProps - special props for the field
* @property {object} [defaultValue] - default value for the field
* @property {object} [modelData] - model data for the field (found on the model.data)
* @property {Array<ParsedField>} [subFields] - subFields for the field if its type is FIELD_TYPES.CLUSTER (i.e. 100)
* @property {FieldRenderProps} render - render props for the field
*/
export interface ParsedField {
id: string;
label: string;
type: string;
hidden: boolean;
conditions: TriggerCondition[];
specialProps: object;
defaultValue?: object;
modelData?: object;
subFields?: ParsedField[];
render: FieldRenderProps;
}
/**
* @typedef {object} FieldRenderProps
* @property {string} type - field type
* @property {string} label - field label
* @property {string} name - field name
* @property {boolean} [hidden] - if the field is hidden
* @property {boolean} [required] - if the field is required
* @property {boolean} [disabled] - if the field is disabled
* @property {string} [iconHelperText] - icon helper text
* @property {string} [helperText] - helper text
* @property {string} [requiredErrorText] - required error text
* @property {boolean} [readOnly] - if the field is read only
* @property {boolean} [multiple] - if the field is multiple
* @property {string} [placeholder] - placeholder text
* @property {object} [linkFormat] - link format
* @property {Array<object>} [choices] - choices for the field
* @property {Schema} validations - validations for the field
* @property {string} [altHelperText] - alternative helper text
*/
export interface FieldRenderProps {
type: string;
label: string;
name: string;
hidden?: boolean;
required?: boolean;
disabled?: boolean;
iconHelperText?: string;
helperText?: string;
requiredErrorText?: string;
readOnly?: boolean;
multiple?: boolean;
placeholder?: string;
linkFormat?: object;
choices?: object[];
validations: Schema;
altHelperText?: string;
}
/**
* @typedef {object} SubmitOptions
* @property {function} [enqueueSnackbar] - function to enqueue a snackbar
* @property {function} [nav] - function to navigate to a url
* @property {function} [onSuccess] - function to call on successful submit (if provided will NOT call setModifying OR nav)
* @property {function} [formatSubmitError] - function to format the error message
* @property {function} [checkSuccess] - function to check if the submit was successful
* @property {function} [onError] - function to call on error (if provided will NOT call setModifying)
* @property {string} [unitLabel] - label for the unit being submitted
* @property {string} [successUrl] - url to navigate to on success
* @property {string} [submitUrl] - url to submit to
* @property {function} [setModifying] - function to set the modifying state
* @property {function} [formatSubmitMessage] - function to format the success message
* @property {boolean} [suppressSuccessToast] - true to suppress the success toast
* @property {boolean} [suppressErrorToast] - true to suppress the error toast *
*/
export interface SubmitOptions {
enqueueSnackbar?: Function;
nav?: Function;
onSuccess?: Function;
formatSubmitError?: Function;
checkSuccess?: Function;
onError?: Function;
unitLabel?: string;
successUrl?: string;
submitUrl?: string;
setModifying?: Function;
formatSubmitMessage?: Function;
suppressSuccessToast?: boolean;
suppressErrorToast?: boolean;
}
/**
* @typedef {object} TriggerCondition
* @property {string} when - trigger field id
* @property {string} is - value to trigger on
* @property {object} then - conditions
* @property {boolean} isValid - if the field is valid
*/
export interface TriggerCondition {
when: string;
is: string;
then: object;
isValid: boolean;
}
export type TriggerFieldValues = Map<string, Map<string, any[]>>;
export type TriggerFieldTouches = Map<string, Map<string, boolean>>;
/**
* @typedef {object} TriggerField
* @property {string} id - field id
* @property {TriggerFieldValues} fieldValues - map of field values
* @property {TriggerFieldTouches} touches - map of fields that trigger field could influence
*/
export interface TriggerField {
id: string;
fieldValues: TriggerFieldValues;
touches: TriggerFieldTouches;
hasOnChange?: boolean;
}
/**
* @typedef {object} FormSection
* @property {string} [name] - The name of the section
* @property {string} [description] - The description of the section
* @property {Array} fields - The fields in the section
* @property {boolean} [visible] - Whether the section is visible
*/
export interface FormSection {
name?: string;
description?: string;
fields: any[];
visible?: boolean;
}
/**
* @typedef {object} FormSubmitOptions
* @property {function} [enqueueSnackbar] - function to enqueue a snackbar
* @property {function} [nav] - function to navigate to a url
* @property {boolean} [modifying] - true if the form is currently being modified
* @property {function} [setModifying] - function to set the modifying state
*/
export interface FormSubmitOptions {
enqueueSnackbar?: Function;
nav?: Function;
modifying?: boolean;
setModifying?: Function;
}
/**
* @typedef {object} RowFields
* @property {ParsedField[]} fields - array of fields in the row
* @property {number} [size] - column size of the row (12 is full width, 6 is half width, etc)
* @property {number} [maxColumns] - maximum number of columns in the row
* @property {boolean} [solitary] - true if the row is a solitary field
* @property {boolean} [isInline] - true if the row is an inline field
*/
export interface RowFields {
fields: ParsedField[];
size?: number;
maxColumns?: number;
solitary?: boolean;
isInline?: boolean;
}