@lifesg/web-frontend-engine 1.0.0-alpha.2 → 1.0.0-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +21 -27
  2. package/cjs/index.js +16 -16
  3. package/cjs/index.js.map +1 -1
  4. package/components/elements/section/index.d.ts +2 -0
  5. package/components/elements/section/section.d.ts +3 -0
  6. package/components/elements/section/types.d.ts +10 -0
  7. package/components/elements/sections/index.d.ts +2 -0
  8. package/components/elements/sections/sections.d.ts +15 -0
  9. package/components/elements/sections/types.d.ts +5 -0
  10. package/components/elements/wrapper/conditional-renderer.d.ts +3 -1
  11. package/components/elements/wrapper/types.d.ts +9 -2
  12. package/components/elements/wrapper/wrapper.d.ts +2 -11
  13. package/components/fields/contact-field/contact-field.d.ts +4 -0
  14. package/components/fields/contact-field/index.d.ts +2 -0
  15. package/components/fields/{contact-number → contact-field}/types.d.ts +3 -3
  16. package/components/fields/date-field/date-field.d.ts +4 -0
  17. package/components/fields/date-field/index.d.ts +2 -0
  18. package/components/fields/{date-input → date-field}/types.d.ts +2 -2
  19. package/components/fields/index.d.ts +4 -4
  20. package/components/fields/text-field/index.d.ts +2 -0
  21. package/components/fields/text-field/text-field.d.ts +4 -0
  22. package/components/fields/text-field/types.d.ts +8 -0
  23. package/components/fields/time-field/index.d.ts +2 -0
  24. package/components/fields/time-field/time-field.d.ts +4 -0
  25. package/components/fields/{time-picker → time-field}/types.d.ts +1 -1
  26. package/components/frontend-engine/frontend-engine.d.ts +2 -8
  27. package/components/frontend-engine/types.d.ts +52 -18
  28. package/index.js +16 -16
  29. package/index.js.map +1 -1
  30. package/package.json +1 -1
  31. package/components/fields/contact-number/contact-number.d.ts +0 -4
  32. package/components/fields/contact-number/index.d.ts +0 -2
  33. package/components/fields/date-input/date-input.d.ts +0 -4
  34. package/components/fields/date-input/index.d.ts +0 -2
  35. package/components/fields/textfield/index.d.ts +0 -2
  36. package/components/fields/textfield/textfield.d.ts +0 -4
  37. package/components/fields/textfield/types.d.ts +0 -8
  38. package/components/fields/time-picker/index.d.ts +0 -2
  39. package/components/fields/time-picker/time-picker.d.ts +0 -4
  40. /package/components/fields/{contact-number → contact-field}/data.d.ts +0 -0
  41. /package/components/fields/{contact-number → contact-field}/utils.d.ts +0 -0
@@ -0,0 +1,2 @@
1
+ export * from "./section";
2
+ export * from "./types";
@@ -0,0 +1,3 @@
1
+ /// <reference types="react" />
2
+ import { ISectionProps } from "./types";
3
+ export declare const Section: (props: ISectionProps) => JSX.Element;
@@ -0,0 +1,10 @@
1
+ import { IFrontendEngineElementJsonSchema, TComponentOmitProps, TFrontendEngineFieldSchema } from "../../frontend-engine";
2
+ import { IWrapperSchema } from "../wrapper";
3
+ export interface ISectionSchema<V = undefined> extends IFrontendEngineElementJsonSchema<"section">, TComponentOmitProps<IWrapperSchema> {
4
+ children: Record<string, TFrontendEngineFieldSchema<V>>;
5
+ }
6
+ export interface ISectionProps {
7
+ id: string;
8
+ sectionSchema: ISectionSchema;
9
+ warnings?: Record<string, string> | undefined;
10
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./sections";
2
+ export * from "./types";
@@ -0,0 +1,15 @@
1
+ /// <reference types="react" />
2
+ import { ISectionsProps } from "./types";
3
+ /**
4
+ * this component is meant to render "pages" which consists of individual Section component
5
+ * it is not rendering in pages yet because there are no use cases yet
6
+ * so this is just a placeholder for now
7
+ *
8
+ * this component renders the sections object and cannot be defined via `uiType`
9
+ * i.e. it is used internally only
10
+ *
11
+ * TODO:
12
+ * - render pages properly
13
+ * - handle validation and errors in each section before navigating away
14
+ */
15
+ export declare const Sections: (props: ISectionsProps) => JSX.Element;
@@ -0,0 +1,5 @@
1
+ import { ISectionSchema } from "../section";
2
+ export interface ISectionsProps {
3
+ schema?: Record<string, ISectionSchema> | undefined;
4
+ warnings?: Record<string, string> | undefined;
5
+ }
@@ -1,14 +1,16 @@
1
1
  import React from "react";
2
+ import { TFrontendEngineFieldSchema } from "../../frontend-engine";
2
3
  import { TRenderRules } from "../../frontend-engine/yup";
3
4
  interface IProps {
4
5
  id: string;
5
6
  renderRules?: TRenderRules[] | undefined;
6
7
  children: React.ReactNode;
8
+ schema: TFrontendEngineFieldSchema;
7
9
  }
8
10
  /**
9
11
  * conditionally render children according to render rules provided
10
12
  * render conditions are based on Yup schema and the base schema is derived from corresponding validation config
11
13
  * automatically remove validation config on hide / unmount, for more complex fields, it still has to be done via the field itself
12
14
  */
13
- export declare const ConditionalRenderer: ({ id, renderRules, children }: IProps) => JSX.Element;
15
+ export declare const ConditionalRenderer: ({ id, renderRules, children, schema }: IProps) => JSX.Element;
14
16
  export {};
@@ -1,9 +1,16 @@
1
1
  /// <reference types="react" />
2
2
  import { TComponentOmitProps, TFrontendEngineFieldSchema } from "../../frontend-engine";
3
3
  import { TRenderRules } from "../../frontend-engine/yup";
4
- export type TWrapperType = "div" | "span" | "section" | "header" | "footer" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "p";
4
+ export type TWrapperType = "div" | "span" | "header" | "footer" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "p";
5
5
  export interface IWrapperSchema extends TComponentOmitProps<React.HTMLAttributes<HTMLElement>, "children"> {
6
- fieldType: TWrapperType;
6
+ uiType: TWrapperType;
7
7
  showIf?: TRenderRules[] | undefined;
8
8
  children: Record<string, TFrontendEngineFieldSchema> | string;
9
9
  }
10
+ export interface IWrapperProps {
11
+ id?: string | undefined;
12
+ schema?: IWrapperSchema | undefined;
13
+ /** only used internally by FrontendEngine */
14
+ children?: Record<string, TFrontendEngineFieldSchema> | undefined;
15
+ warnings?: Record<string, string> | undefined;
16
+ }
@@ -1,12 +1,3 @@
1
1
  /// <reference types="react" />
2
- import { TFrontendEngineFieldSchema } from "../../frontend-engine/types";
3
- import { IWrapperSchema } from "./types";
4
- interface IWrapperProps {
5
- id?: string | undefined;
6
- schema?: IWrapperSchema | undefined;
7
- /** only used internally by FrontendEngine */
8
- children?: Record<string, TFrontendEngineFieldSchema> | undefined;
9
- warnings?: Record<string, string> | undefined;
10
- }
11
- export declare const Wrapper: (props: IWrapperProps) => JSX.Element;
12
- export {};
2
+ import { IWrapperProps } from "./types";
3
+ export declare const Wrapper: (props: IWrapperProps) => JSX.Element | null;
@@ -0,0 +1,4 @@
1
+ /// <reference types="react" />
2
+ import { IGenericFieldProps } from "../../frontend-engine/types";
3
+ import { IContactFieldSchema } from "./types";
4
+ export declare const ContactField: (props: IGenericFieldProps<IContactFieldSchema>) => JSX.Element;
@@ -0,0 +1,2 @@
1
+ export * from "./contact-field";
2
+ export * from "./types";
@@ -2,12 +2,12 @@ import { FormInputProps } from "@lifesg/react-design-system/form/types";
2
2
  import { IFrontendEngineBaseFieldJsonSchema, TComponentOmitProps } from "../../frontend-engine/types";
3
3
  import { InternationalCallingCodeMap } from "./data";
4
4
  export type TCountry = keyof typeof InternationalCallingCodeMap;
5
- interface IContactNumberProps extends FormInputProps {
5
+ interface IContactFieldProps extends FormInputProps {
6
6
  country?: TCountry;
7
7
  enableSearch?: boolean | undefined;
8
8
  }
9
9
  export type TSingaporeNumberRule = "default" | "house" | "mobile";
10
- export interface IContactNumberValidationRule {
10
+ export interface IContactFieldValidationRule {
11
11
  contactNumber?: {
12
12
  internationalNumber: true;
13
13
  singaporeNumber?: never;
@@ -24,6 +24,6 @@ export interface IParsedPhoneNumber {
24
24
  prefix: string;
25
25
  number: string;
26
26
  }
27
- export interface IContactNumberSchema<V = undefined> extends IFrontendEngineBaseFieldJsonSchema<"contact", V, IContactNumberValidationRule>, TComponentOmitProps<IContactNumberProps> {
27
+ export interface IContactFieldSchema<V = undefined> extends IFrontendEngineBaseFieldJsonSchema<"contact-field", V, IContactFieldValidationRule>, TComponentOmitProps<IContactFieldProps> {
28
28
  }
29
29
  export {};
@@ -0,0 +1,4 @@
1
+ /// <reference types="react" />
2
+ import { IGenericFieldProps } from "../../frontend-engine/types";
3
+ import { IDateFieldSchema } from "./types";
4
+ export declare const DateField: (props: IGenericFieldProps<IDateFieldSchema>) => JSX.Element;
@@ -0,0 +1,2 @@
1
+ export * from "./date-field";
2
+ export * from "./types";
@@ -1,6 +1,6 @@
1
1
  import { DateInputProps } from "@lifesg/react-design-system/date-input";
2
2
  import { IFrontendEngineBaseFieldJsonSchema, TComponentOmitProps } from "../../frontend-engine/types";
3
- export interface IDateInputValidationRule {
3
+ export interface IDateFieldValidationRule {
4
4
  future?: boolean | undefined;
5
5
  past?: boolean | undefined;
6
6
  notFuture?: boolean | undefined;
@@ -8,7 +8,7 @@ export interface IDateInputValidationRule {
8
8
  minDate?: string | undefined;
9
9
  maxDate?: string | undefined;
10
10
  }
11
- export interface IDateInputSchema<V = undefined> extends IFrontendEngineBaseFieldJsonSchema<"date", V, IDateInputValidationRule>, TComponentOmitProps<DateInputProps> {
11
+ export interface IDateFieldSchema<V = undefined> extends IFrontendEngineBaseFieldJsonSchema<"date-field", V, IDateFieldValidationRule>, TComponentOmitProps<DateInputProps> {
12
12
  useCurrentDate?: boolean | undefined;
13
13
  dateFormat?: string | undefined;
14
14
  }
@@ -1,11 +1,11 @@
1
1
  export * from "./checkbox-group";
2
2
  export * from "./chips";
3
- export * from "./contact-number";
4
- export * from "./date-input";
3
+ export * from "./contact-field";
4
+ export * from "./date-field";
5
5
  export * from "./multi-select";
6
6
  export * from "./radio-button";
7
7
  export * from "./select";
8
8
  export * from "./submit-button";
9
+ export * from "./text-field";
9
10
  export * from "./textarea";
10
- export * from "./textfield";
11
- export * from "./time-picker";
11
+ export * from "./time-field";
@@ -0,0 +1,2 @@
1
+ export * from "./text-field";
2
+ export * from "./types";
@@ -0,0 +1,4 @@
1
+ /// <reference types="react" />
2
+ import { IGenericFieldProps } from "../../frontend-engine";
3
+ import { IEmailFieldSchema, INumericFieldSchema, ITextFieldSchema } from "./types";
4
+ export declare const TextField: (props: IGenericFieldProps<ITextFieldSchema | IEmailFieldSchema | INumericFieldSchema>) => JSX.Element;
@@ -0,0 +1,8 @@
1
+ import { FormInputProps } from "@lifesg/react-design-system/form/types";
2
+ import { IFrontendEngineBaseFieldJsonSchema, TComponentOmitProps } from "../../frontend-engine";
3
+ export interface ITextFieldSchema<V = undefined> extends IFrontendEngineBaseFieldJsonSchema<"text-field", V>, TComponentOmitProps<FormInputProps, "type" | "maxLength"> {
4
+ }
5
+ export interface IEmailFieldSchema<V = undefined> extends IFrontendEngineBaseFieldJsonSchema<"email-field", V>, TComponentOmitProps<FormInputProps, "type" | "maxLength"> {
6
+ }
7
+ export interface INumericFieldSchema<V = undefined> extends IFrontendEngineBaseFieldJsonSchema<"numeric-field", V>, TComponentOmitProps<FormInputProps, "type" | "max" | "min"> {
8
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./time-field";
2
+ export * from "./types";
@@ -0,0 +1,4 @@
1
+ /// <reference types="react" />
2
+ import { IGenericFieldProps } from "../../frontend-engine";
3
+ import { ITimeFieldSchema } from "./types";
4
+ export declare const TimeField: (props: IGenericFieldProps<ITimeFieldSchema>) => JSX.Element;
@@ -1,6 +1,6 @@
1
1
  import { TimepickerProps } from "@lifesg/react-design-system/timepicker";
2
2
  import { IFrontendEngineBaseFieldJsonSchema, TComponentOmitProps } from "../../frontend-engine";
3
- export interface ITimePickerSchema<V = undefined> extends IFrontendEngineBaseFieldJsonSchema<"time", V>, TComponentOmitProps<TimepickerProps> {
3
+ export interface ITimeFieldSchema<V = undefined> extends IFrontendEngineBaseFieldJsonSchema<"time-field", V>, TComponentOmitProps<TimepickerProps> {
4
4
  useCurrentTime?: boolean | undefined;
5
5
  is24HourFormat?: boolean | undefined;
6
6
  }
@@ -1,20 +1,14 @@
1
1
  import { ReactElement, Ref } from "react";
2
- import { IFrontendEngineProps, IFrontendEngineRef } from "./types";
2
+ import { IFrontendEngineProps, IFrontendEngineRef, TNoInfer } from "./types";
3
3
  import { IYupValidationRule } from "./yup";
4
- /**
5
- * prevents inferrence
6
- * https://stackoverflow.com/questions/56687668/a-way-to-disable-type-argument-inference-in-generics
7
- */
8
- type NoInfer<T, U> = [T][T extends U ? 0 : never];
9
4
  /**
10
5
  * The one and only component needed to create your form
11
6
  *
12
7
  * Minimally you will need to set the `data` props which is the JSON schema to define the form
13
8
  */
14
- export declare const FrontendEngine: <V = undefined>(props: IFrontendEngineProps<NoInfer<V, IYupValidationRule>> & {
9
+ export declare const FrontendEngine: <V = undefined>(props: IFrontendEngineProps<TNoInfer<V, IYupValidationRule>> & {
15
10
  ref?: Ref<IFrontendEngineRef>;
16
11
  }) => ReactElement;
17
- export {};
18
12
  /**
19
13
  * casting as a function with generics as a way to define generics with forwardRef
20
14
  * the generics are a way to set custom definition of Yup validation config
@@ -1,13 +1,14 @@
1
1
  import { ControllerFieldState, ControllerRenderProps, UseFormSetValue, ValidationMode } from "react-hook-form";
2
2
  import { IAlertSchema, ITextSchema } from "../elements";
3
+ import { ISectionSchema } from "../elements/section";
3
4
  import { IWrapperSchema } from "../elements/wrapper";
4
- import { ICheckboxGroupSchema, IChipsSchema, IContactNumberSchema, IDateInputSchema, IEmailSchema, IMultiSelectSchema, INumberSchema, IRadioButtonGroupSchema, ISelectSchema, ISubmitButtonSchema, ITextareaSchema, ITextfieldSchema, ITimePickerSchema } from "../fields";
5
+ import { ICheckboxGroupSchema, IChipsSchema, IContactFieldSchema, IDateFieldSchema, IEmailFieldSchema, IMultiSelectSchema, INumericFieldSchema, IRadioButtonGroupSchema, ISelectSchema, ISubmitButtonSchema, ITextFieldSchema, ITextareaSchema, ITimeFieldSchema } from "../fields";
5
6
  import { IYupValidationRule, TRenderRules, TYupSchemaType } from "./yup";
6
7
  export type { IYupValidationRule } from "./yup";
7
8
  export interface IFrontendEngineProps<V = undefined> {
8
9
  /** HTML class attribute that is applied on the `<form>` element */
9
10
  className?: string;
10
- /** JSON configuration to define the fields and functionalities of the form */
11
+ /** JSON configuration to define the components and functionalities of the form */
11
12
  data?: IFrontendEngineData<V> | undefined;
12
13
  /** Fires every time a value changes in any fields */
13
14
  onChange?: ((values: TFrontendEngineValues, isValid?: boolean | undefined) => unknown) | undefined;
@@ -19,8 +20,14 @@ export interface IFrontendEngineData<V = undefined> {
19
20
  className?: string | undefined;
20
21
  /** Fields' initial values on mount. The key of each field needs to match the id used in the field */
21
22
  defaultValues?: TFrontendEngineValues | undefined;
22
- /** All elements within the form in key-value format, key refers to the id of the field while value refers to the JSON schema of the field */
23
- fields: Record<string, TFrontendEngineFieldSchema<V>>;
23
+ /**
24
+ * Specifies the components to be rendered
25
+ *
26
+ * All components within the form are in key-value format, key refers to the id of the components while value refers to its JSON schema
27
+ *
28
+ * Note: sections accept only section `uiType`, the subsequent children accepts uiType other than section
29
+ * */
30
+ sections: Record<string, ISectionSchema<V>>;
24
31
  /** Unique HTML id attribute that is applied on the `<form>` element */
25
32
  id?: string | undefined;
26
33
  /** Validation strategy when inputs with errors get re-validated after a user submits the form (onSubmit event) */
@@ -28,7 +35,7 @@ export interface IFrontendEngineData<V = undefined> {
28
35
  /** Validation strategy before a user submits the form (onSubmit event) */
29
36
  validationMode?: TValidationMode | undefined;
30
37
  }
31
- export type TFrontendEngineFieldSchema<V = undefined> = ITextareaSchema<V> | ITextfieldSchema<V> | IEmailSchema<V> | INumberSchema<V> | ISubmitButtonSchema | ISelectSchema<V> | IMultiSelectSchema<V> | ICheckboxGroupSchema<V> | IDateInputSchema<V> | IWrapperSchema | IContactNumberSchema<V> | IRadioButtonGroupSchema<V> | ITimePickerSchema<V> | IChipsSchema<V> | IAlertSchema | ITextSchema;
38
+ export type TFrontendEngineFieldSchema<V = undefined> = ITextareaSchema<V> | ITextFieldSchema<V> | IEmailFieldSchema<V> | INumericFieldSchema<V> | ISubmitButtonSchema | ISelectSchema<V> | IMultiSelectSchema<V> | ICheckboxGroupSchema<V> | IDateFieldSchema<V> | IWrapperSchema | IContactFieldSchema<V> | IRadioButtonGroupSchema<V> | ITimeFieldSchema<V> | IChipsSchema<V> | IAlertSchema | ITextSchema | ICustomComponentJsonSchema;
32
39
  export type TFrontendEngineValues<T = any> = Record<keyof T, T[keyof T]>;
33
40
  export type TRevalidationMode = Exclude<keyof ValidationMode, "onTouched" | "all">;
34
41
  export type TValidationMode = keyof ValidationMode;
@@ -37,19 +44,20 @@ export type TErrorPayload = Record<string, TErrorMessage>;
37
44
  export interface IFrontendEngineRef extends HTMLFormElement {
38
45
  /** gets form values */
39
46
  getValues: () => TFrontendEngineValues;
40
- /** set field value by id */
47
+ /** sets field value by id */
41
48
  setValue: UseFormSetValue<TFrontendEngineValues>;
42
- /** check if form is valid */
49
+ /** checks if form is valid */
43
50
  isValid: () => boolean;
44
51
  /** triggers form submission */
45
52
  submit: () => void;
53
+ /** adds custom validation rule */
46
54
  addCustomValidation: (type: TYupSchemaType | "mixed", name: string, fn: (value: unknown, arg: unknown) => boolean) => void;
47
- /** allow setting of custom errors thrown by endpoints */
55
+ /** allows setting of custom errors thrown by endpoints */
48
56
  setErrors: (errors: TErrorPayload) => void;
49
57
  }
50
58
  export interface IFrontendEngineBaseFieldJsonSchema<T, V = undefined, U = undefined> {
51
- /** defines what kind of field to be rendered */
52
- fieldType: T;
59
+ /** defines what kind of component to be rendered */
60
+ uiType: T;
53
61
  /** caption for the field */
54
62
  label: string;
55
63
  /** render conditions
@@ -58,32 +66,54 @@ export interface IFrontendEngineBaseFieldJsonSchema<T, V = undefined, U = undefi
58
66
  showIf?: TRenderRules[] | undefined;
59
67
  /** validation config, can be customised by passing generics */
60
68
  validation?: (V | U | IYupValidationRule)[];
69
+ /** escape hatch for other form / frontend engines to have unsupported attributes */
70
+ customOptions?: Record<string, unknown> | undefined;
71
+ }
72
+ /**
73
+ * to support custom components from other form / frontend engines
74
+ */
75
+ export interface ICustomComponentJsonSchema {
76
+ referenceKey: string;
77
+ [otherOptions: string]: unknown;
78
+ uiType?: never | undefined;
61
79
  }
62
80
  /**
63
81
  * JSON keys to omit from field schema when extending from other interfaces
64
82
  * - keys already defined in `IFrontendEngineBaseFieldJsonSchema` to prevent collision
65
83
  * - some inherited HTML attributes
66
84
  */
67
- export type TFrontendEngineFieldJsonSchemaOmitKeys = "id" | "label" | "validation" | "fieldType" | "showIf" | "children" | "value";
85
+ export type TFrontendEngineFieldJsonSchemaOmitKeys = "id" | "label" | "validation" | "uiType" | "showIf" | "children" | "value";
68
86
  export interface IFrontendEngineElementJsonSchema<T> extends Omit<IFrontendEngineBaseFieldJsonSchema<T>, "label" | "validation"> {
69
87
  }
70
88
  type UnionOptionalKeys<T = undefined> = T extends string | number | symbol ? TFrontendEngineFieldJsonSchemaOmitKeys | T : TFrontendEngineFieldJsonSchemaOmitKeys;
89
+ /**
90
+ * Omits clashing keys between native props and frontend engine
91
+ */
71
92
  export type TComponentOmitProps<T, V = undefined> = Omit<T, UnionOptionalKeys<V>>;
93
+ /**
94
+ * Field types
95
+ * - components that can contain values that can get submitted
96
+ */
72
97
  export declare enum EFieldType {
73
98
  TEXTAREA = "Textarea",
74
- TEXT = "TextField",
75
- NUMERIC = "TextField",
76
- EMAIL = "TextField",
99
+ "TEXT-FIELD" = "TextField",
100
+ "NUMERIC-FIELD" = "TextField",
101
+ "EMAIL-FIELD" = "TextField",
77
102
  SUBMIT = "SubmitButton",
78
103
  SELECT = "Select",
79
104
  "MULTI-SELECT" = "MultiSelect",
80
- DATE = "DateInput",
105
+ "DATE-FIELD" = "DateField",
81
106
  CHECKBOX = "CheckboxGroup",
82
- CONTACT = "ContactNumber",
107
+ "CONTACT-FIELD" = "ContactField",
83
108
  RADIO = "RadioButtonGroup",
84
- TIME = "TimePicker",
109
+ "TIME-FIELD" = "TimeField",
85
110
  CHIPS = "Chips"
86
111
  }
112
+ /**
113
+ * Non-field types
114
+ * - components that do not have values
115
+ * - typically used for layouts and messages
116
+ */
87
117
  export declare enum EElementType {
88
118
  ALERT = "Alert",
89
119
  "TEXT-D1" = "Text",
@@ -100,7 +130,6 @@ export declare enum EElementType {
100
130
  "TEXT-XSMALL" = "Text",
101
131
  DIV = "Wrapper",
102
132
  SPAN = "Wrapper",
103
- SECTION = "Wrapper",
104
133
  HEADER = "Wrapper",
105
134
  FOOTER = "Wrapper",
106
135
  H1 = "Wrapper",
@@ -115,3 +144,8 @@ export interface IGenericFieldProps<T = TFrontendEngineFieldSchema> extends Part
115
144
  id: string;
116
145
  schema: T;
117
146
  }
147
+ /**
148
+ * prevents inferrence
149
+ * https://stackoverflow.com/questions/56687668/a-way-to-disable-type-argument-inference-in-generics
150
+ */
151
+ export type TNoInfer<T, U> = [T][T extends U ? 0 : never];