Separate State and Layout of interface elements from the main model and build accessible patterns orthogonal to the Dom tree.
List (Item region html wrapper)
none : Ui region html wrapper
none =
[]
🐚
singleton : html -> Ui region_ html wrapper_
🐌
wrap : wrapper -> Ui region_ html_ wrapper
Check out the default wrappers in Less.Ui.Html
.
inRegion : region -> Ui region html wrapper -> Ui region html wrapper
Designate a region for each descendant.
Note that the last designation "wins".
#26: Once designated, Ui
s can't be redesignated
view : CurrentLayout region narrowHtml_ html narrowWrapper_ wrapper -> Ui region html wrapper -> html
⚠️ If you can, prefer one of the functions in Less such as
application
.
{ wrap : { current : Less.Link.State
, previous : Maybe Less.Link.State } -> customWrapper -> Wrapper region narrowHtml html narrowWrapper customWrapper
, concat : List html -> html
, arrange : { header : html
, region : region -> html } -> html
}
The layout is a rule for mapping a Ui to an html
tree.
{ wrap : customWrapper -> Wrapper region narrowHtml html narrowWrapper customWrapper
, concat : List html -> html
, concatDicts : List (AssocList.Dict (OrHeader region) html) -> AssocList.Dict (OrHeader region) html
, arrange : { header : html
, region : region -> html } -> html
}
This type of Layout has its current and previous state already applied through applyStates.
Create a custom wrapper
to sneak functions into a
functionless Ui
. At the layout
phase, you decide what
your wrapper
does:
Wrapped
: Transform the rendered html
inside the current region.Keyed
: Like Html.KeyedNested
: Render a Ui
with a different html
type and then
nest it in a supplied function.
This transformation is applied parallelly within each region.Stateful
: Render a link or filter. The Url determines whether
the enclosed Ui is rendered or not. You have to apply the state early.You can either use the provided Wrapper
or roll your own.
Advantage of rolling your own wrapper
type: You don't need to store functions in the Ui,
which makes it comparable and serializable.
See Ui.Html
for an example of a mostly defunctionalized wrapper.
repeat : Basics.Int -> Ui region html wrapper -> Ui region html wrapper
repeat n =
List.repeat n >> List.concat
uncons : Ui region html wrapper -> Maybe ( Ui region html wrapper, Ui region html wrapper )
Attempt to separate the first descendant in the Ui.
Extend a sum type by a Header
constructor. Every app in Less
has a Header.
map : (html -> html2) -> Ui region html wrapper -> Ui region html2 wrapper
Modify the type of html
in the Ui.
⚠️ If you can, build up your Ui with the final html
type.
-- Todo: Tail Call Optimize.
indexedMapList : (Basics.Int -> Ui region html wrapper -> Ui region html wrapper) -> Ui region html wrapper -> Ui region html wrapper
Modify items Ui
s according to their order. For example, zip their indices between the elements:
singleton [1008] ++ singleton [2004] ++ singleton [1007]
|> indexedMapList (\i -> (++) (singleton [i]))
|> List.length
--> 6
mapEach : (Ui region html wrapper -> Ui region2 html2 wrapper2) -> Ui region html wrapper -> Ui region2 html2 wrapper2
Modify each descendent as a separate Ui and then recombine them.
region html attribute wrapper "A" ++ region html attribute wrapper "B" ++ region html attribute wrapper "C"
|> mapEach ((++) (html ", "))
---> something like A, B, C
mutateWrappers : { leafToWrapper : html -> wrapper } -> (wrapper -> wrapper2) -> Ui region html wrapper -> Ui region html wrapper2
Modify the type of wrapper
in the Ui and make sure every direct descendant is a wrapper so it can be modified
⚠️ If you can, build up your Ui with the final wrapper
type.
The following exports have no application and may be removed in the next release.
(currently nothing)