@@ -71,15 +71,14 @@ import Effect (Effect)
71
71
import Effect.Aff (Aff )
72
72
import Effect.Class (liftEffect )
73
73
import Effect.Unsafe (unsafePerformEffect )
74
- import Heterogeneous.Mapping (class Mapping )
75
74
import JSS (JSS , jss )
76
75
import Lumi.Components.Color (colors )
77
76
import Lumi.Components.Column (column )
78
77
import Lumi.Components.FetchCache as FetchCache
79
78
import Lumi.Components.Form.Defaults (formDefaults ) as Defaults
80
79
import Lumi.Components.Form.Internal (Forest , FormBuilder' (..), FormBuilder , SeqFormBuilder , Tree (..), formBuilder , formBuilder_ , invalidate , pruneTree , sequential )
81
80
import Lumi.Components.Form.Internal (Forest , FormBuilder' , FormBuilder , SeqFormBuilder' , SeqFormBuilder , formBuilder , formBuilder_ , invalidate , listen , parallel , revalidate , sequential ) as Internal
82
- import Lumi.Components.Form.Validation (ModifyValidated , setModified )
81
+ import Lumi.Components.Form.Validation (setModified )
83
82
import Lumi.Components.Form.Validation (Validated (..), Validator , _Validated , fromValidated , mustBe , mustEqual , nonEmpty , nonEmptyArray , nonNull , validNumber , validInt , validDate , optional , setFresh , setModified , validated , warn ) as Validation
84
83
import Lumi.Components.Input (alignToInput )
85
84
import Lumi.Components.Input as Input
@@ -94,14 +93,13 @@ import Lumi.Components.Select as Select
94
93
import Lumi.Components.Text (body , body_ , subsectionHeader , text )
95
94
import Lumi.Components.Textarea as Textarea
96
95
import Lumi.Components.Upload as Upload
97
- import Prim.Row (class Lacks , class Nub , class Union )
96
+ import Prim.Row (class Nub , class Union )
98
97
import React.Basic (JSX , createComponent , element , empty , fragment , keyed , makeStateless )
99
98
import React.Basic.Components.Async (async , asyncWithLoader )
100
99
import React.Basic.DOM as R
101
100
import React.Basic.DOM.Events (capture , stopPropagation , targetChecked , targetValue )
102
101
import React.Basic.Events as Events
103
102
import React.Basic.Hooks as Hooks
104
- import Record as Record
105
103
import Unsafe.Coerce (unsafeCoerce )
106
104
107
105
-- | Create a React component for a form from a `FormBuilder`.
@@ -111,25 +109,12 @@ import Unsafe.Coerce (unsafeCoerce)
111
109
112
110
build
113
111
:: forall props unvalidated result
114
- . Union
115
- ( forceTopLabels :: Boolean
116
- , inlineTable :: Boolean
117
- )
118
- ( readonly :: Boolean
119
- | props
120
- )
121
- ( forceTopLabels :: Boolean
122
- , inlineTable :: Boolean
123
- , readonly :: Boolean
124
- | props
125
- )
126
- => FormBuilder { readonly :: Boolean | props } unvalidated result
112
+ . FormBuilder { readonly :: Boolean | props } unvalidated result
127
113
-> { value :: unvalidated
128
114
, onChange :: (unvalidated -> unvalidated ) -> Effect Unit
129
115
, forceTopLabels :: Boolean
130
116
, inlineTable :: Boolean
131
- , readonly :: Boolean
132
- | props
117
+ , formProps :: { readonly :: Boolean | props }
133
118
}
134
119
-> JSX
135
120
build = build' defaultRenderForm
@@ -140,37 +125,30 @@ build = build' defaultRenderForm
140
125
-- | _Note_: this function should be fully applied, to avoid remounting
141
126
-- | the component on each render.
142
127
build'
143
- :: forall ui renderProps formProps props unvalidated result
144
- . Union renderProps formProps props
145
- => ({ | props } -> ui -> JSX )
146
- -> FormBuilder' ui { | formProps } unvalidated result
128
+ :: forall ui renderProps formProps unvalidated result
129
+ . ({ | renderProps } -> formProps -> ui -> JSX )
130
+ -> FormBuilder' ui formProps unvalidated result
147
131
-> { value :: unvalidated
148
132
, onChange :: (unvalidated -> unvalidated ) -> Effect Unit
149
- | props
133
+ , formProps :: formProps
134
+ | renderProps
150
135
}
151
136
-> JSX
152
137
build' render editor =
153
- makeStateless (createComponent " Form" ) \props@{ value, onChange } ->
138
+ makeStateless (createComponent " Form" ) \props@{ value, onChange, formProps } ->
154
139
let
155
- { edit } = un FormBuilder editor (contractFormProps props) value
140
+ { edit } = un FormBuilder editor formProps value
156
141
in
157
- render (contractProps props) (edit onChange)
142
+ render (contractRenderProps props) formProps (edit onChange)
158
143
where
159
- contractFormProps
160
- :: { value :: unvalidated
161
- , onChange :: (unvalidated -> unvalidated ) -> Effect Unit
162
- | props
163
- }
164
- -> { | formProps }
165
- contractFormProps = unsafeCoerce
166
-
167
- contractProps
144
+ contractRenderProps
168
145
:: { value :: unvalidated
169
146
, onChange :: (unvalidated -> unvalidated ) -> Effect Unit
170
- | props
147
+ , formProps :: formProps
148
+ | renderProps
171
149
}
172
- -> { | props }
173
- contractProps = unsafeCoerce
150
+ -> { | renderProps }
151
+ contractRenderProps = unsafeCoerce
174
152
175
153
176
154
-- | The default Lumi implementation for rendering a forest of JSX
@@ -179,12 +157,13 @@ defaultRenderForm
179
157
:: forall props
180
158
. { forceTopLabels :: Boolean
181
159
, inlineTable :: Boolean
182
- , readonly :: Boolean
160
+ }
161
+ -> { readonly :: Boolean
183
162
| props
184
163
}
185
164
-> Forest
186
165
-> JSX
187
- defaultRenderForm { inlineTable, forceTopLabels, readonly } forest =
166
+ defaultRenderForm { inlineTable, forceTopLabels } { readonly } forest =
188
167
element (R .unsafeCreateDOMComponent " lumi-form" )
189
168
{ class:
190
169
String .joinWith " " $ fold
@@ -224,21 +203,16 @@ defaultRenderForm { inlineTable, forceTopLabels, readonly } forest =
224
203
-- | Render a form with state managed automatically.
225
204
useForm
226
205
:: forall props unvalidated result
227
- . Mapping ModifyValidated unvalidated unvalidated
228
- => FormBuilder
229
- { initialState :: unvalidated
230
- , readonly :: Boolean
231
- , inlineTable :: Boolean
232
- , forceTopLabels :: Boolean
206
+ . FormBuilder
207
+ { readonly :: Boolean
233
208
| props
234
209
}
235
210
unvalidated
236
211
result
237
212
-> { initialState :: unvalidated
238
- , readonly :: Boolean
239
213
, inlineTable :: Boolean
240
214
, forceTopLabels :: Boolean
241
- | props
215
+ , formProps :: { readonly :: Boolean | props }
242
216
}
243
217
-> Hooks.Hook (Hooks.UseState unvalidated )
244
218
{ formData :: unvalidated
@@ -251,30 +225,22 @@ useForm
251
225
useForm editor props = Hooks .do
252
226
let
253
227
renderer = defaultRenderForm
254
- { readonly: props.readonly
255
- , inlineTable: props.inlineTable
228
+ { inlineTable: props.inlineTable
256
229
, forceTopLabels: props.forceTopLabels
257
230
}
231
+ props.formProps
258
232
259
- f <- useForm' editor props
233
+ f <- useForm' editor props.initialState props.formProps
260
234
pure f { form = renderer f.form }
261
235
262
236
263
237
-- | Like `useForm`, but allows an alternative render implementation
264
238
-- | to be provided as an additional argument.
265
239
useForm'
266
240
:: forall ui props unvalidated result
267
- . Mapping ModifyValidated unvalidated unvalidated
268
- => FormBuilder'
269
- ui
270
- { initialState :: unvalidated
271
- | props
272
- }
273
- unvalidated
274
- result
275
- -> { initialState :: unvalidated
276
- | props
277
- }
241
+ . FormBuilder' ui props unvalidated result
242
+ -> unvalidated
243
+ -> props
278
244
-> Hooks.Hook (Hooks.UseState unvalidated )
279
245
{ formData :: unvalidated
280
246
, setFormData :: (unvalidated -> unvalidated ) -> Effect Unit
@@ -283,8 +249,8 @@ useForm'
283
249
, validated :: Maybe result
284
250
, form :: ui
285
251
}
286
- useForm' editor props = Hooks .do
287
- formData /\ setFormData <- Hooks .useState props. initialState
252
+ useForm' editor initialState props = Hooks .do
253
+ formData /\ setFormData <- Hooks .useState initialState
288
254
289
255
let
290
256
{ edit, validate: validated } = un FormBuilder editor props formData
@@ -294,7 +260,7 @@ useForm' editor props = Hooks.do
294
260
{ formData
295
261
, setFormData
296
262
, setModified: setFormData setModified
297
- , reset: setFormData \_ -> props. initialState
263
+ , reset: setFormData \_ -> initialState
298
264
, validated
299
265
, form: ui
300
266
}
@@ -308,22 +274,12 @@ useForm' editor props = Hooks.do
308
274
-- | the component on each render.
309
275
formState
310
276
:: forall props unvalidated result
311
- . Lacks " render" props
312
- => Mapping ModifyValidated unvalidated unvalidated
313
- => FormBuilder
314
- { initialState :: unvalidated
315
- , readonly :: Boolean
316
- , inlineTable :: Boolean
317
- , forceTopLabels :: Boolean
318
- | props
319
- }
320
- unvalidated
321
- result
322
- -> Hooks.ReactComponent
277
+ . Hooks.ReactComponent
323
278
{ initialState :: unvalidated
324
- , readonly :: Boolean
279
+ , form :: FormBuilder { readonly :: Boolean | props } unvalidated result
325
280
, inlineTable :: Boolean
326
281
, forceTopLabels :: Boolean
282
+ , formProps :: { readonly :: Boolean | props }
327
283
, render
328
284
:: { formData :: unvalidated
329
285
, setFormData :: (unvalidated -> unvalidated ) -> Effect Unit
@@ -333,11 +289,15 @@ formState
333
289
, form :: JSX
334
290
}
335
291
-> JSX
336
- | props
337
292
}
338
- formState editor = unsafePerformEffect do
293
+ formState = unsafePerformEffect do
339
294
Hooks .component " FormState" \props -> Hooks .do
340
- state <- useForm editor (Record .delete (SProxy :: SProxy " render" ) props)
295
+ state <- useForm props.form
296
+ { initialState: props.initialState
297
+ , inlineTable: props.inlineTable
298
+ , forceTopLabels: props.forceTopLabels
299
+ , formProps: props.formProps
300
+ }
341
301
pure (props.render state)
342
302
343
303
0 commit comments