form-preview-df
Version:
Resusable Form Preview Components
559 lines (492 loc) • 14.1 kB
text/typescript
// Form Builder Schema Model
// Defines enums and base types for form component configurations
export type TComponentCategory = 'Basic' | 'Advanced' | 'Layout' | 'Custom';
export type TBasicComponentName =
| 'text-input'
| 'number-input'
| 'email-input'
| 'textarea'
| 'select'
| 'checkbox'
| 'radio'
| 'segment'
| 'date-picker'
| 'datetime-picker'
| 'info'
| 'signature'
| 'heading'
| 'instructions'
| 'section'
| 'table'
| 'datagrid'
| 'file'
| 'location';
export type TComponentName = TBasicComponentName;
export enum ELabelAlignment {
Top = 'top',
Left = 'left',
}
export interface IOption {
label: string;
value: string;
selected?: boolean;
}
export type TCheckboxValue = string | string[];
export interface IBaseProps {
label: string;
value: string; // * user entered value
defaultValue: string | number;
placeholder?: string;
options?: any[];
description?: string;
collapsed?: boolean;
valid?: boolean;
}
export interface IBaseValidationProps {
required: boolean;
customValidationMessage: string;
readonly: boolean;
}
export interface IBaseStyleProps {
labelAlignment: ELabelAlignment;
width?: number;
height?: number;
minWidth?: number;
maxWidth?: number;
minHeight?: number;
maxHeight?: number;
column?: number; // Table column (12, 9, 6, 3)
backgroundColor?: string;
borderColor?: string;
borderWidth?: string;
borderRadius?: string;
padding?: string;
margin?: string;
}
export type TInputComponentType = 'text' | 'number' | 'email';
export interface IBaseInputComponent extends IBaseComponent {
inputType: TInputComponentType;
}
export interface IBaseComponent {
id: string;
_id: string;
name: TComponentName;
category: TComponentCategory;
basic: IBaseProps;
validation: IBaseValidationProps;
styles: IBaseStyleProps;
position: number;
options: any[];
conditional: IConditionalLogic; // Required conditional logic
}
export interface ITextInputBasicProps extends IBaseProps {
placeholder: string;
defaultValue: string;
}
export interface ITextInputValidationProps extends IBaseValidationProps {
minLength: number;
maxLength: number;
pattern: string;
}
export interface ITextInputStyleProps extends IBaseStyleProps {
labelAlignment: ELabelAlignment;
}
export interface ITextInputComponent extends IBaseInputComponent {
id: string;
name: 'text-input';
category: TComponentCategory;
inputType: TInputComponentType;
basic: ITextInputBasicProps;
validation: ITextInputValidationProps;
styles: ITextInputStyleProps;
}
export interface INumberInputBasicProps extends IBaseProps {
placeholder: string;
defaultValue: number;
decimalPlaces: number;
}
export interface INumberInputValidationProps extends IBaseValidationProps {
/* min: number;
max: number; */
minLength: number;
maxLength: number;
integerOnly: boolean;
}
export interface INumberInputStyleProps extends IBaseStyleProps {
labelAlignment: ELabelAlignment;
}
export interface INumberInputComponent extends IBaseInputComponent {
id: string;
name: 'number-input';
inputType: 'number';
basic: INumberInputBasicProps;
validation: INumberInputValidationProps;
styles: INumberInputStyleProps;
}
export interface IEmailInputBasicProps extends IBaseProps {
placeholder: string;
defaultValue: string;
}
export interface IEmailInputValidationProps extends IBaseValidationProps {
minLength: number;
maxLength: number;
}
export interface IEmailInputStyleProps extends IBaseStyleProps {
labelAlignment: ELabelAlignment;
}
export interface IEmailInputComponent extends IBaseInputComponent {
id: string;
name: 'email-input';
inputType: 'email';
basic: IEmailInputBasicProps;
validation: IEmailInputValidationProps;
styles: IEmailInputStyleProps;
}
export interface ITextareaInputBasicProps extends IBaseProps {
placeholder: string;
defaultValue: string;
rows: number;
autoExpand?: boolean; // TODO: add this feature later, also what is it??
}
export interface ITextareaInputValidationProps extends IBaseValidationProps {
minLength: number;
maxLength: number;
}
export interface ITextareaInputComponent extends IBaseComponent {
id: string;
name: 'textarea';
category: TComponentCategory;
basic: ITextareaInputBasicProps;
validation: ITextareaInputValidationProps;
styles: IBaseStyleProps;
}
export interface ISelectInputBasicProps extends IBaseProps {
placeholder: string;
options: IOption[];
}
export interface ISelectInputComponent extends IBaseComponent {
id: string;
name: 'select';
category: TComponentCategory;
basic: ISelectInputBasicProps;
validation: IBaseValidationProps;
styles: IBaseStyleProps;
}
export interface ICheckboxGroupBasicProps extends Omit<IBaseProps, 'value' | 'defaultValue'> {
options: IOption[];
value: TCheckboxValue;
defaultValue: TCheckboxValue;
inlineLayout: boolean;
}
export interface ICheckboxGroupBase extends Omit<IBaseComponent, 'basic'> {
basic: ICheckboxGroupBasicProps;
}
export interface ICheckboxGroupValidationProps extends IBaseValidationProps {
minCheckedNumber: number;
maxCheckedNumber: number;
}
export interface ICheckboxGroupComponent extends ICheckboxGroupBase {
id: string;
name: 'checkbox';
category: TComponentCategory;
basic: ICheckboxGroupBasicProps;
validation: ICheckboxGroupValidationProps;
styles: IBaseStyleProps;
}
export interface IRadioGroupBasicProps extends IBaseProps {
options: IOption[];
defaultValue: string;
inlineLayout: boolean;
// optionsLabelPosition: 'left' | 'right';
}
export interface IRadioGroupComponent extends IBaseComponent {
id: string;
name: 'radio';
category: TComponentCategory;
basic: IRadioGroupBasicProps;
validation: IBaseValidationProps;
styles: IBaseStyleProps;
}
export interface ISegmentGroupBasicProps extends IBaseProps {
options: IOption[];
defaultValue: string;
inlineLayout: boolean;
// optionsLabelPosition: 'left' | 'right';
}
export interface ISegmentGroupComponent extends IBaseComponent {
id: string;
name: 'segment';
category: TComponentCategory;
basic: ISegmentGroupBasicProps;
validation: IBaseValidationProps;
styles: IBaseStyleProps;
}
export interface IDateTimePickerBasicProps extends IBaseProps {
placeholder: string;
defaultValue: string;
timeFormat: '12hr' | '24hr';
minDateTime: string; // TODO: to use a Date object/type
maxDateTime: string;
}
export interface IDateTimePickerComponent extends IBaseComponent {
id: string;
name: 'datetime-picker';
category: TComponentCategory;
basic: IDateTimePickerBasicProps;
validation: IBaseValidationProps;
styles: IBaseStyleProps;
}
export interface IDatePickerBasicProps extends IBaseProps {
placeholder: string;
defaultValue: string;
timeFormat: '12hr' | '24hr';
minDate: string; // TODO: to use a Date object/type
maxDate: string;
}
export interface IDatePickerComponent extends IBaseComponent {
id: string;
name: 'date-picker';
category: TComponentCategory;
basic: IDatePickerBasicProps;
validation: IBaseValidationProps;
styles: IBaseStyleProps;
}
export interface ISignatureInputBasicProps extends IBaseProps {
height: number;
penColor: string;
backgroundColor: string;
}
export interface ISignatureInputComponent extends IBaseComponent {
id: string;
name: 'signature';
category: TComponentCategory;
basic: ISignatureInputBasicProps;
validation: IBaseValidationProps;
styles: IBaseStyleProps;
}
export interface IHeadingBasicProps extends IBaseProps {
// Heading only needs label, no additional properties
}
export interface IHeadingComponent extends IBaseComponent {
id: string;
name: 'heading';
category: TComponentCategory;
basic: IHeadingBasicProps;
}
export interface IInstructionBasicProps extends IBaseProps {
instructions?: string[];
}
export interface IInstructionComponent extends IBaseComponent {
id: string;
name: 'instructions';
category: TComponentCategory;
basic: IInstructionBasicProps;
validation: IBaseValidationProps & {
listStyle?: 'none' | 'numbers' | 'bullets' | 'alpha';
};
}
export interface ISectionBasicProps extends IBaseProps {
description?: string;
collapsed?: boolean;
}
export interface ISectionComponent extends IBaseComponent {
id: string;
name: 'section';
category: TComponentCategory;
basic: ISectionBasicProps;
children: TFormComponent[];
}
export interface ITableBasicProps extends IBaseProps {
description?: string;
collapsed?: boolean;
rows?: number;
columns?: number;
}
export interface ITableComponent extends IBaseComponent {
id: string;
name: 'table';
category: TComponentCategory;
basic: ITableBasicProps;
table: {
rows: number;
columns: number;
addAnotherText?: string;
removeText?: string;
displayAsTable: boolean;
columnNames: string;
showColumns: boolean;
};
cells: Array<Array<{
id: string;
row: number;
column: number;
components: TFormComponent[];
styles?: {
backgroundColor?: string;
borderColor?: string;
padding?: string;
minHeight?: string;
verticalAlign?: 'top' | 'middle' | 'bottom';
};
}>>;
}
export interface IDataGridComponent extends IBaseComponent {
id: string;
name: 'datagrid';
category: TComponentCategory;
basic: IBaseProps;
datagrid: {
maxEntries?: number;
minEntries?: number;
allowAddRemoveEntries?: boolean;
addAnotherText?: string;
removeText?: string;
displayAsGrid?: boolean;
};
entries: Array<{
id: string;
index: number;
components: TFormComponent[];
styles?: {
backgroundColor?: string;
borderColor?: string;
padding?: string;
minHeight?: string;
verticalAlign?: 'top' | 'middle' | 'bottom';
};
}>;
}
export interface ICondition {
id: string;
when: string;
operator: 'equals' | 'notEquals' | 'isEmpty' | 'isNotEmpty' | 'contains' | 'notContains' | 'greaterThan' | 'lessThan' | 'greaterThanOrEqual' | 'lessThanOrEqual';
value: string | number | boolean;
}
export interface IConditionalLogic {
action: 'show' | 'hide' | 'always';
when: 'all' | 'any';
conditions: ICondition[];
}
export interface IFileComponent extends IBaseComponent {
id: string;
name: 'file';
category: TComponentCategory;
basic: IBaseProps;
validation: IBaseValidationProps;
styles: IBaseStyleProps;
}
export interface ILocationComponent extends IBaseComponent {
id: string;
name: 'location';
category: TComponentCategory;
basic: IBaseProps;
validation: IBaseValidationProps;
styles: IBaseStyleProps;
}
export type TFormComponent =
| ITextInputComponent
| INumberInputComponent
| IEmailInputComponent
| ITextareaInputComponent
| ISelectInputComponent
| IRadioGroupComponent
| ISegmentGroupComponent
| ICheckboxGroupComponent
| IDateTimePickerComponent
| ISignatureInputComponent
| IDatePickerComponent
| IHeadingComponent
| IInstructionComponent
| ISectionComponent
| ITableComponent
| IDataGridComponent
| IFileComponent
| ILocationComponent;
export type TFormComponentName = TFormComponent['name'];
export interface IFormTemplate {
id: string;
name: string;
// version: string;
data: TFormComponent[];
}
// TODO: Refactor the code to use if statements instead
export type IUnifiedBasicProps = Partial<IBaseProps> &
Partial<ITextInputBasicProps> &
Partial<INumberInputBasicProps> &
Partial<IEmailInputBasicProps> &
Partial<ITextareaInputBasicProps> &
Partial<ISelectInputBasicProps> &
Partial<ICheckboxGroupBasicProps> &
Partial<IRadioGroupBasicProps> &
Partial<ISegmentGroupBasicProps> &
Partial<IDateTimePickerBasicProps> &
Partial<ISignatureInputBasicProps>;
export interface IUnifiedValidationProps
extends Partial<IBaseValidationProps>,
Partial<ITextInputValidationProps>,
Partial<INumberInputValidationProps>,
Partial<IEmailInputValidationProps>,
Partial<ITextareaInputValidationProps>,
Partial<ICheckboxGroupValidationProps> {}
export interface IUnifiedStyleProps
extends Partial<IBaseStyleProps>,
Partial<ITextInputStyleProps>,
Partial<INumberInputStyleProps>,
Partial<IEmailInputStyleProps> {}
// Additional enums for the configuration system
export enum EValidationOperator {
Equals = 'equals',
NotEquals = 'notEquals',
Contains = 'contains',
GreaterThan = 'greaterThan',
LessThan = 'lessThan',
IsEmpty = 'isEmpty',
IsNotEmpty = 'isNotEmpty'
}
export enum EFieldType {
Text = 'text',
Number = 'number',
Boolean = 'boolean',
Select = 'select',
Checkbox = 'checkbox',
Radio = 'radio',
Date = 'date',
DateTime = 'date-time',
Email = 'email',
Textarea = 'textarea',
Range = 'range',
Signature = 'signature',
Heading = 'heading',
Divider = 'divider',
File = 'file',
Phone = 'phone',
Url = 'url',
Password = 'password'
}
export enum EComponentType {
TextInput = 'text-input',
Textarea = 'textarea',
Select = 'select',
Radio = 'radio',
Segment = 'segment',
Checkbox = 'checkbox',
Date = 'date-picker',
DateTime = 'datetime-picker',
Email = 'email-input',
Number = 'number-input',
Signature = 'signature',
Heading = 'heading',
Divider = 'divider',
File = 'file',
Phone = 'phone',
Url = 'url',
Password = 'password',
Section = 'section'
}
export enum ETabType {
Basic = 'basic',
Validation = 'validation',
Styles = 'styles',
Conditional = 'conditional',
Advanced = 'advanced'
}