export type PossibleValues = Array; export type AbstractControl = { template: string; properties: object; }; export type HorizontalLayout = { template: 'HorizontalLayout'; properties: { components: Array; label?: string; }; }; export type VerticalLayout = { template: 'VerticalLayout'; properties: { components: Array; label?: string; }; }; export type ArrayLayout = { template: 'ArrayLayout'; properties: { component: AbstractControl; ref: string; label?: string; }; }; /** * Describes a component that goes into a GridLayout */ export type GridLayoutComponent = { /** * Component to show in this position in the grid */ component: AbstractControl; /** * the row index to insert this component in the grid. Will default to the next available grid cell. */ row?: number; /** * the column index to insert this component in the grid. Will default to the next available grid cell. */ column?: number; /** * the number of rows this component should span in the grid */ rows?: number; /** * the number of columns this component should span in the grid */ columns?: number; }; /** * A Grid form layout with rows and columns */ export type GridLayout = { template: 'GridLayout'; properties: { label?: string; gap?: string; columns?: number; dense?: boolean; flow?: 'row' | 'column'; components: Array; }; }; /** * a data grid component. For example, could be implemented with HTML TABLE, or AG Grid, etc. */ export type GridComponent = { template: 'GridComponent'; properties: { ref: string; label?: string; components: Array; }; }; export type Label = { template: 'Label'; properties: { label: string; }; }; /** * Layout component that renders form controls based on data type */ export type ControlType = { template: 'Control'; }; export type ControlValidation = { /** * for text based controls */ minLength?: number; /** * for text based controls */ maxLength?: number; /** * for number based controls */ min?: number; /** * for number based controls */ max?: number; /** * for number based controls. Can be used for number of decimal places or precision. Default is 1 (integer) */ step?: number; /** * whether the control value is required */ required?: boolean; /** * regular expression to validate text input values against */ pattern?: string; }; export type ControlProperties = { properties: { ref: string; type: "hidden" | "text" | "search" | "tel" | "url" | "email" | "password" | "datetime" | "date" | "month" | "week" | "time" | "datetime-local" | "number" | "range" | "color" | "checkbox" | "radio" | "file" | "submit" | "image" | "reset" | "button"; label?: string; description?: string; readOnly?: boolean; possibleValues?: PossibleValues; validation?: ControlValidation; }; }; export type Control = ControlType & ControlProperties; export type TextareaType = { template: 'Textarea'; }; export type TextareaValidation = { /** * the minimum number of characters required that the user should enter. */ minLength?: number; /** * the maximum number of characters that the user can enter. If this value isn't specified, the user can enter an unlimited number of characters. */ maxLength?: number; /** * whether the control value is required */ required?: boolean; }; export type TextareaProperties = { properties: { ref: string; label?: string; description?: string; cols?: number; rows?: number; readOnly?: boolean; validation?: TextareaValidation; }; }; export type Textarea = TextareaType & TextareaProperties; export type ArrayType = { template: 'ArrayControl'; }; export type ArrayValidation = { /** * whether the control value is required */ required?: boolean; }; export type ArrayProperties = { properties: { ref: string; label?: string; description?: string; readOnly?: boolean; possibleValues?: PossibleValues; validation?: ArrayValidation; }; }; /** * Can be thought of as a multi-select */ export type ArrayComponent = ArrayType & ArrayProperties; export type ComponentTemplate = HorizontalLayout | VerticalLayout | GridComponent | Label | Control | Textarea | ArrayComponent | GridLayout | ArrayLayout; export type LayoutContext = { /** * currently being rendered */ component: TComponent; };