) => {
+ let make = React.memo((props: props) => {
+ let {wrapped: Any.Any_props(props)} = props
let SArr(schema, uiSchema) = props.field
let mapToElement = Js.Array.mapi((data, i) => {
let onChange = upd =>
props.formData |> Js.Array.mapi((ci, ii) => ii == i ? upd : ci) |> props.onChange
})
{props.formData |> mapToElement |> React.array}
- }
+ })
}
diff --git a/src/rescript/FormRender.res b/src/rescript/FormRender.res
index f9baa2f..70de77f 100644
--- a/src/rescript/FormRender.res
+++ b/src/rescript/FormRender.res
@@ -14,10 +14,18 @@ let make = (
~customPrimitives: option=?,
~uiSchema: module(FieldUiSchema with type t = 'k),
) => {
- let content =
+ let content = React.useMemo5(() =>
+ , (fieldTemplate, schema, onChange, formData, uiSchema))
let customWidgets = Belt_Option.getWithDefault(customPrimitives, PrimitiveWidget.defaultValue)
{switch objectFieldTemplate {
diff --git a/src/rescript/MutualTypes.res b/src/rescript/MutualTypes.res
index fce2713..72c4897 100644
--- a/src/rescript/MutualTypes.res
+++ b/src/rescript/MutualTypes.res
@@ -2,114 +2,127 @@ open UiSchema
open UiFields
open Schema
-module type SchemaRender = {
- type props<'t, 'r, 'k, 'm> = {
- field: Schema.t<'t, 'r, 'k, 'm>,
- onChange: 'k => unit,
- formData: 'k,
- uiSchema: module(FieldUiSchema with type t = 'k),
- meta: option<'m>,
- fieldTemplate: option = {
+ field: Schema.t<'t, 'r, 'k, 'm>,
+ onChange: 'k => unit,
+ formData: 'k,
+ uiSchema: module(FieldUiSchema with type t = 'k),
+ meta: option<'m>,
+ fieldTemplate: option): t
}
+}
- @obj
- external makeProps: (
- ~field: Schema.t<'t, 'r, 'k, 'm>,
- ~onChange: 'k => unit,
- ~formData: 'k,
- ~uiSchema: module(FieldUiSchema with type t = 'k),
- ~meta: option<'m>,
- ~fieldTemplate: option = ""
+module type SchemaRender = {
+ @unboxed
+ type props = {wrapped: Schema_render_props.Any.t}
- let make: props<'t, 'r, 'k, 'm> => React.element
+ let make: props => React.element
}
+
+module Switch_render_props = {
+ module Real_props = {
+ type t<'t, 'r, 'k, 'm> = {
+ field: Schema.t<'t, 'r, 'k, 'm>,
+ onChange: 'k => unit,
+ formData: 'k,
+ widget: option,
+ meta: option<'m>,
+ }
+ }
+
+ module Any = {
+ @unboxed
+ type rec t = Any_props(Real_props.t<'t, 'r, 'k, 'm>): t
+ }
+}
+
module type SwitchRender = {
- type props<'t, 'r, 'k, 'm> = {
- field: Schema.t<'t, 'r, 'k, 'm>,
- onChange: 'k => unit,
- formData: 'k,
- widget: option,
- meta: option<'m>,
+ @unboxed
+ type props = {wrapped: Switch_render_props.Any.t}
+
+ let make: props => React.element
+}
+
+module Object_render_props = {
+ module Real_props = {
+ type t<'t, 'm> = {
+ formData: 't,
+ schema: array>,
+ onChange: 't => unit,
+ fieldTemplate: option): t
}
- @obj
- external makeProps: (
- ~field: Schema.t<'t, 'r, 'k, 'm>,
- ~onChange: 'k => unit,
- ~formData: 'k,
- ~widget: option,
- ~meta: option<'m>,
- unit,
- ) => props<'t, 'r, 'k, 'm> = ""
- let make: props<'t, 'r, 'k, 'm> => React.element
}
+
module type ObjectRender = {
- type props<'t, 'm> = {
- formData: 't,
- schema: array>,
- onChange: 't => unit,
- fieldTemplate: option = {
+ obj: 'r,
+ schema: Schema.t<'t, 'r, 'k, 'm>,
+ field: module(Field with type t = 'k and type r = 'r),
+ uiSchema: module(FieldUiSchema with type t = 'k),
+ onChange: 'r => unit,
+ meta: option<'m>,
+ fieldTemplate: option): t
}
- @obj
- external makeProps: (
- ~formData: 't,
- ~schema: array>,
- ~onChange: 't => unit,
- ~fieldTemplate: option = ""
-
- let make: props<'t, 'm> => React.element
}
+
module type ReRender = {
- type props<'t, 'r, 'k, 'm> = {
- obj: 'r,
- schema: Schema.t<'t, 'r, 'k, 'm>,
- field: module(Field with type t = 'k and type r = 'r),
- uiSchema: module(FieldUiSchema with type t = 'k),
- onChange: 'r => unit,
- meta: option<'m>,
- fieldTemplate: option = {
+ field: Schema.t,
+ onChange: 'k => unit,
+ formData: 'k,
+ meta: option<'m>,
+ fieldTemplate: option): t
}
- @obj
- external makeProps: (
- ~obj: 'r,
- ~schema: Schema.t<'t, 'r, 'k, 'm>,
- ~field: module(Field with type t = 'k and type r = 'r),
- ~uiSchema: module(FieldUiSchema with type t = 'k),
- ~onChange: 'r => unit,
- ~meta: option<'m>,
- ~fieldTemplate: option = ""
- let make: props<'t, 'r, 'k, 'm> => React.element
}
+
module type ArrayRender = {
- type props<'t, 'r, 'k, 'm> = {
- field: Schema.t,
- onChange: 'k => unit,
- formData: 'k,
- meta: option<'m>,
- fieldTemplate: option,
- ~onChange: 'k => unit,
- ~formData: 'k,
- ~meta: option<'m>,
- ~fieldTemplate: option = ""
+ @unboxed
+ type props = {wrapped: Array_render_props.Any.t}
- let make: props<'t, 'r, 'k, 'm> => React.element
+ let make: props => React.element
}
module type NullableRender = {
type props<'t, 'r, 'k, 'm> = {
@@ -119,15 +132,6 @@ module type NullableRender = {
meta: option<'m>,
fieldTemplate: option,
- ~onChange: 'k => unit,
- ~formData: 'k,
- ~meta: option<'m>,
- ~fieldTemplate: option = ""
let make: props<'t, 'r, 'k, 'm> => React.element
}
diff --git a/src/rescript/NullableRender.res b/src/rescript/NullableRender.res
index 748f366..76ef131 100644
--- a/src/rescript/NullableRender.res
+++ b/src/rescript/NullableRender.res
@@ -27,13 +27,14 @@ module Make = (Render: SchemaRender) => {
switch props.formData {
| Some(data) =>
| _ =>
switch schema {
diff --git a/src/rescript/ObjectFieldTemplate.res b/src/rescript/ObjectFieldTemplate.res
index 038ac89..89a16f2 100644
--- a/src/rescript/ObjectFieldTemplate.res
+++ b/src/rescript/ObjectFieldTemplate.res
@@ -1,19 +1,23 @@
open Schema
module type ObjectFieldTemplate = {
- @react.component
- let make: (
- ~formData: 't,
- ~schema: array>,
- ~onChange: 't => unit,
- ~content: array,
- ) => React.element
+ type props<'t, 'm> = {
+ formData: 't,
+ schema: array>,
+ onChange: 't => unit,
+ content: array,
+ }
+ let make: props<'t, 'm> => React.element
}
module DefaultObjectFieldTemplate = {
- @react.component
- let make = (~formData as _, ~schema as _, ~onChange as _, ~content: array) =>
- {React.array(content)}
+ type props<'t, 'm> = {
+ formData: 't,
+ schema: array>,
+ onChange: 't => unit,
+ content: array,
+ }
+ let make = (props: props<'t, 'm>) => {React.array(props.content)}
}
module ObjectFieldTemplateContext = {
@@ -22,11 +26,6 @@ module ObjectFieldTemplateContext = {
)
module Provider = {
- let provider = React.Context.provider(context)
-
- @react.component
- let make = (~value, ~children) => {
- React.createElement(provider, {"value": value, "children": children})
- }
+ let make = React.Context.provider(context)
}
}
diff --git a/src/rescript/ObjectRender.res b/src/rescript/ObjectRender.res
index 30a11fe..97c66e2 100644
--- a/src/rescript/ObjectRender.res
+++ b/src/rescript/ObjectRender.res
@@ -1,41 +1,34 @@
open MutualTypes
open Schema
open ObjectFieldTemplate
-open UiFields
+open Object_render_props
module Make = (Render: ReRender) => {
- type props<'t, 'm> = {
- formData: 't,
- schema: array>,
- onChange: 't => unit,
- fieldTemplate: option>,
- ~onChange: 't => unit,
- ~fieldTemplate: option = ""
+ @unboxed
+ type props = {wrapped: Any.t}
- let make = (type t m, props: props) => {
+ let make = React.memo((props: props) => {
+ let {wrapped: Any.Any_props(props)} = props
let module(Template: ObjectFieldTemplate) = React.useContext(ObjectFieldTemplateContext.context)
- let content = Js.Array.mapi(
- (SchemaListItem(schema, field, uiSchema, meta), i) =>
- ,
- props.schema,
- )
+ let content = React.useMemo4(() =>
+ Js.Array.mapi(
+ (SchemaListItem(schema, field, uiSchema, meta), i) =>
+ ,
+ props.schema,
+ )
+ , (props.formData, props.onChange, props.fieldTemplate, props.schema))
- }
+ })
let () = React.setDisplayName(make, "ObjectRender")
}
diff --git a/src/rescript/PrimitiveRender.res b/src/rescript/PrimitiveRender.res
index 616b11b..2b33fa6 100644
--- a/src/rescript/PrimitiveRender.res
+++ b/src/rescript/PrimitiveRender.res
@@ -18,19 +18,27 @@ external makeProps: (
let make = (type t r k m, props: props) => {
let Primitive(p) = props.field
let custom = React.useContext(context)
- let module(Widget: Widget with type t = k) = switch (p: primitive) {
- | SString =>
- Belt_Option.getWithDefault(
- custom.stringWidget,
- module(StringWidget: Widget with type t = string),
- )
- | SInt =>
- Belt_Option.getWithDefault(custom.intWidget, module(IntWidget: Widget with type t = int))
- | SFloat =>
- Belt_Option.getWithDefault(custom.floatWidget, module(FloatWidget: Widget with type t = float))
- | SBool =>
- Belt_Option.getWithDefault(custom.boolWidget, module(BoolWidget: Widget with type t = bool))
- }
+
+ let module(Widget: Widget with type t = k) = React.useMemo1(() => {
+ let module(Widget: Widget with type t = k) = switch (p: primitive) {
+ | SString =>
+ Belt_Option.getWithDefault(
+ custom.stringWidget,
+ module(StringWidget: Widget with type t = string),
+ )
+ | SInt =>
+ Belt_Option.getWithDefault(custom.intWidget, module(IntWidget: Widget with type t = int))
+ | SFloat =>
+ Belt_Option.getWithDefault(
+ custom.floatWidget,
+ module(FloatWidget: Widget with type t = float),
+ )
+ | SBool =>
+ Belt_Option.getWithDefault(custom.boolWidget, module(BoolWidget: Widget with type t = bool))
+ }
+ module(Widget: Widget with type t = k)
+ }, [p])
+
}
diff --git a/src/rescript/PrimitiveRender.resi b/src/rescript/PrimitiveRender.resi
deleted file mode 100644
index f0c0720..0000000
--- a/src/rescript/PrimitiveRender.resi
+++ /dev/null
@@ -1,18 +0,0 @@
-open Schema
-open Widgets
-open PrimitiveWidget
-
-type props<'t, 'r, 'k, 'm> = {
- field: Schema.t, 'r, 'k, 'm>,
- onChange: 'k => unit,
- formData: 'k,
-}
-@obj
-external makeProps: (
- ~field: Schema.t, 'r, 'k, 'm>,
- ~onChange: 'k => unit,
- ~formData: 'k,
- unit,
-) => props<'t, 'r, 'k, 'm> = ""
-
-let make: props<'t, 'r, 'k, 'm> => React.element
diff --git a/src/rescript/PrimitiveWidget.res b/src/rescript/PrimitiveWidget.res
index da13377..f1c3d86 100644
--- a/src/rescript/PrimitiveWidget.res
+++ b/src/rescript/PrimitiveWidget.res
@@ -18,10 +18,5 @@ let defaultValue = {
let context: React.Context.t = React.createContext(defaultValue)
module Provider = {
- let provider = React.Context.provider(context)
-
- @react.component
- let make = (~value, ~children) => {
- React.createElement(provider, {"value": value, "children": children})
- }
+ let make = React.Context.provider(context)
}
diff --git a/src/rescript/ReRender.res b/src/rescript/ReRender.res
index ec131f9..a4db226 100644
--- a/src/rescript/ReRender.res
+++ b/src/rescript/ReRender.res
@@ -1,35 +1,13 @@
-open Schema
open MutualTypes
-open UiSchema
-open UiFields
+open Re_render_render_props
module Make = (Render: SchemaRender): ReRender => {
- type props<'t, 'r, 'k, 'm> = {
- obj: 'r,
- schema: Schema.t<'t, 'r, 'k, 'm>,
- field: module(Field with type t = 'k and type r = 'r),
- uiSchema: module(FieldUiSchema with type t = 'k),
- onChange: 'r => unit,
- meta: option<'m>,
- fieldTemplate: option,
- ~field: module(Field with type t = 'k and type r = 'r),
- ~uiSchema: module(FieldUiSchema with type t = 'k),
- ~onChange: 'r => unit,
- ~meta: option<'m>,
- ~fieldTemplate: option = ""
-
- let make = (type t r k m, props: props) => {
- let module(Field: Field with type t = k and type r = r) = props.field
+ let make = React.memo((props: props) => {
+ let {wrapped: Any.Any_props(props)} = props
+ let module(Field) = props.field
let objRef = React.useRef(props.obj)
let onChange = React.useCallback0(val => val |> Field.set(objRef.current) |> props.onChange)
React.useEffect2(() => {
@@ -37,14 +15,15 @@ module Make = (Render: SchemaRender): ReRender => {
None
}, (props.onChange, props.obj))
- }
+ })
let () = React.setDisplayName(make, "ReRender")
}
diff --git a/src/rescript/Schema.res b/src/rescript/Schema.res
index 80b53a7..c34b5e0 100644
--- a/src/rescript/Schema.res
+++ b/src/rescript/Schema.res
@@ -7,9 +7,9 @@ module type Field = {
let set: (r, t) => r
}
-type obj = Obj
-type arr = Arr
-type nullable = Nullable
+type obj
+type arr
+type nullable
type rec primitive<'t> =
| SInt: primitive
diff --git a/src/rescript/SchemaRender.res b/src/rescript/SchemaRender.res
index 1d6aaa8..fd67886 100644
--- a/src/rescript/SchemaRender.res
+++ b/src/rescript/SchemaRender.res
@@ -1,53 +1,46 @@
-open UiSchema
-open UiFields
open MutualTypes
+open Schema_render_props
module Make = (Render: SwitchRender): SchemaRender => {
- type props<'t, 'r, 'k, 'm> = {
- field: Schema.t<'t, 'r, 'k, 'm>,
- onChange: 'k => unit,
- formData: 'k,
- uiSchema: module(FieldUiSchema with type t = 'k),
- meta: option<'m>,
- fieldTemplate: option,
- ~onChange: 'k => unit,
- ~formData: 'k,
- ~uiSchema: module(FieldUiSchema with type t = 'k),
- ~meta: option<'m>,
- ~fieldTemplate: option = ""
+ let make = React.memo((props: props) => {
+ let {wrapped: Any.Any_props(props)} = props
+ let module(UiSchema) = props.uiSchema
+ let switchRender = React.useMemo6(() =>
+
+ , (
+ props.field,
+ props.onChange,
+ props.formData,
+ props.meta,
+ props.fieldTemplate,
+ UiSchema.widget,
+ ))
- let make:
- type t r k m. React.component> =
- (props: props) => {
- let module(UiSchema: FieldUiSchema with type t = k) = props.uiSchema
- let switchRender =
-
- let withUiField = switch UiSchema.field {
- | Some(module(UiField: UiField with type t = k)) =>
+ let withUiField = React.useMemo4(() =>
+ switch UiSchema.field {
+ | Some(module(UiField)) =>
{switchRender}
| _ => switchRender
}
- switch props.fieldTemplate {
- | Some(module(Field: FieldTemplate with type m = m)) =>
- {withUiField}
- | _ => withUiField
- }
+ , (props.formData, props.onChange, switchRender, UiSchema.field))
+
+ switch props.fieldTemplate {
+ | Some(module(Field)) =>
+ {withUiField}
+ | _ => withUiField
}
+ })
let () = React.setDisplayName(make, "SchemaRender")
}
diff --git a/src/rescript/SwitchRender.res b/src/rescript/SwitchRender.res
index ad6af1f..90af4f1 100644
--- a/src/rescript/SwitchRender.res
+++ b/src/rescript/SwitchRender.res
@@ -1,63 +1,49 @@
open Schema
open MutualTypes
-open UiFields
+open Switch_render_props
module Make = (ObjRender: ObjectRender, ArrRender: ArrayRender, NullRender: NullableRender) => {
- type props<'t, 'r, 'k, 'm> = {
- field: Schema.t<'t, 'r, 'k, 'm>,
- onChange: 'k => unit,
- formData: 'k,
- widget: option,
- meta: option<'m>,
- }
+ @unboxed
+ type props = {wrapped: Any.t}
- @obj
- external makeProps: (
- ~field: Schema.t<'t, 'r, 'k, 'm>,
- ~onChange: 'k => unit,
- ~formData: 'k,
- ~widget: option,
- ~meta: option<'m>,
- unit,
- ) => props<'t, 'r, 'k, 'm> = ""
-
- let make:
- type t r k m. props => React.element =
- (props: props) => {
- let defaultWidget = switch props.field {
- | SObject(arr) =>
-
- | Primitive(_) =>
-
- | SArr(_) =>
-
- | SNull(_) =>
-
- }
-
- props.widget->Belt.Option.mapWithDefault(defaultWidget, (
- module(ComponentWidget: Widgets.Widget with type t = k),
- ) => )
+ let make = React.memo((props: props) => {
+ let {wrapped: Any.Any_props(props)} = props
+ let defaultWidget = switch props.field {
+ | SObject(arr) =>
+
+ | Primitive(_) =>
+
+ | SArr(_) =>
+
+ | SNull(_) =>
+
}
+ props.widget->Belt.Option.mapWithDefault(defaultWidget, (module(ComponentWidget)) =>
+
+ )
+ })
+
let () = React.setDisplayName(make, "SwitchRender")
}
diff --git a/src/rescript/Widgets.res b/src/rescript/Widgets.res
index b88ab1f..3203a42 100644
--- a/src/rescript/Widgets.res
+++ b/src/rescript/Widgets.res
@@ -6,9 +6,9 @@ module type Widget = {
module TextUnhadledEventWidget = {
@react.component
- let make = (~value: string, ~onChange: 'a => unit, ~type_: string) => {
+ let make = (~value: string, ~onChange: 'a => unit, @as("type") ~type_: string) => {
let onChange = React.useCallback1(e => ReactEvent.Form.target(e) |> onChange, [onChange])
-
+
}
let () = React.setDisplayName(make, "TextWidget")
}