Skip to content

Add default renderer for form's Forest structure #153

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"purescript-integers": "^4.0.0",
"purescript-maybe": "^4.0.0",
"purescript-nullable": "^4.0.0",
"purescript-numbers": "^6.0.0",
"purescript-numbers": "^7.0.0",
"purescript-prelude": "^4.0.1",
"purescript-profunctor-lenses": ">=4.0.0 <7.0.0",
"purescript-random": "^4.0.0",
Expand Down
61 changes: 36 additions & 25 deletions src/Lumi/Components/Form.purs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module Lumi.Components.Form
, build
, build'
, defaultRenderForm
, defaultRenderForest
, useForm
, useForm'
, formState
Expand Down Expand Up @@ -80,7 +81,7 @@ import Lumi.Components.Column (column)
import Lumi.Components.FetchCache as FetchCache
import Lumi.Components.Form.Defaults (formDefaults) as Defaults
import Lumi.Components.Form.Internal (Forest, FormBuilder'(..), FormBuilder, SeqFormBuilder, Tree(..), formBuilder, formBuilder_, invalidate, pruneTree, sequential)
import Lumi.Components.Form.Internal (Forest, FormBuilder', FormBuilder, SeqFormBuilder', SeqFormBuilder, formBuilder, formBuilder_, invalidate, listen, parallel, revalidate, sequential) as Internal
import Lumi.Components.Form.Internal (Forest(..), FormBuilder', FormBuilder, SeqFormBuilder', SeqFormBuilder, formBuilder, formBuilder_, invalidate, listen, parallel, revalidate, sequential) as Internal
import Lumi.Components.Form.Validation (setModified)
import Lumi.Components.Form.Validation (Validated(..), Validator, _Validated, fromValidated, mustBe, mustEqual, nonEmpty, nonEmptyArray, nonNull, validNumber, validInt, validDate, optional, setFresh, setModified, validated, warn) as Validation
import Lumi.Components.Input (alignToInput)
Expand Down Expand Up @@ -166,42 +167,52 @@ defaultRenderForm
}
-> Forest
-> JSX
defaultRenderForm { inlineTable, forceTopLabels } { readonly } forest =
defaultRenderForm renderProps@{ inlineTable, forceTopLabels } { readonly } forest =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're not using the renderProps binding here, I think?

element (R.unsafeCreateDOMComponent "lumi-form")
{ class:
String.joinWith " " $ fold
[ guard inlineTable ["inline-table"]
, guard readonly ["readonly"]
]
, children:
surround fieldDivider (map toRow (Array.mapMaybe pruneTree forest))
surround fieldDivider
$ defaultRenderForest { forceTopLabels }
$ Array.mapMaybe pruneTree
$ forest
}
where
fieldDivider = R.hr { className: "lumi field-divider" }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is defined twice now, not a big deal though


toRow :: Tree -> JSX
toRow = case _ of
Child { key, child } ->
maybe identity keyed key $ child
Wrapper { key, wrap: f, children } ->
maybe identity keyed key
$ f
$ intercalate [fieldDivider]
$ map (pure <<< toRow)
$ children
Node { label, key, required, validationError, children } ->
maybe identity keyed key $
labeledField
{ label: text body
{ children = [ label ]
, className = toNullable (pure "field-label")
}
, value: intercalate fieldDivider (map toRow children)
, validationError
, required
, forceTopLabel: forceTopLabels
, style: R.css {}
defaultRenderForest
:: { forceTopLabels :: Boolean
}
-> Forest
-> Array JSX
defaultRenderForest renderProps@{ forceTopLabels } = map case _ of
Child { key, child } ->
maybe identity keyed key $ child
Wrapper { key, wrap: f, children } ->
maybe identity keyed key
$ f
$ intercalate [fieldDivider]
$ map pure
$ defaultRenderForest renderProps
$ children
Node { label, key, required, validationError, children } ->
maybe identity keyed key $
labeledField
{ label: text body
{ children = [ label ]
, className = toNullable (pure "field-label")
}
, value: intercalate fieldDivider (defaultRenderForest renderProps children)
, validationError
, required
, forceTopLabel: forceTopLabels
, style: R.css {}
}
where
fieldDivider = R.hr { className: "lumi field-divider" }

-- | Render a form with state managed automatically.
useForm
Expand Down