Adressing a recurring pain point in the current Api
**As it stands (v1.0.0), **
OrHeader region is a non-empty set of constructors, namely Header+Region. This means we always have at least the header region (but its content can be empty because html can be empty, as enforced by Layout.concat : List html -> html)
- Only the
Toggle, Search and GoTo patterns, as well as top-level Ui, can be placed in the Header. As soon as you place some Ui inRegion .., its descendants are barred from populating the header (except the three patterns mentioned above).
- A minimal app would use Never as the region type, meaning its layout.arrange function could only render a Header.
Original motivation for this design:
- It enforces (or at least, reflects) the convention of web and app design to place essential top-level affordances and controls (Logo, top-level nav, "global" menu, avatar) in a header bar.
- The original reason was simply that if you don't put your Ui
inRegion at all, you end up with regionless Ui in layout.arrange. So I replaced Maybe region with the equivalent but more expressive OrHeader region.
Shortcomings/Friction:
- Consistency: It reduces composability which is the second goal of this library as it introduces some unknown context: when you write a
view for a model, you don't know if it'll end up in the Header or in some region. Whereas the application view gets direct access to this region. So when you un-nest (in terms of inRegion) a view, it may change its behavior. in other words, the first inRegion creates a narrower context whereas consecutive nested inRegions preserve the context. So inRegion is in a sense no longer commutative. (does that make sense?)
- Ease of use: The Api just feels cluttered. Is it worth the trade-off? Removing
Headet would make a lot of records smaller and, perhaps more importantly, more predictable and memorizable.
- Invariant enforcement: If a user wants to put random stuff in the Header, they can still do it: just push the submodule
view up the module into the main view and voilà the library has broken ones of its two promises. The current Api is just not successful at enforcing the Invariant.
Alternatives solutions
- An elm-review rule could definitely enforce this invariant, to any degree desirable (i.e. restrictions on the use of
atRegion Header!
Adressing a recurring pain point in the current Api
**As it stands (v1.0.0), **
OrHeader regionis a non-empty set of constructors, namely Header+Region. This means we always have at least the header region (but its content can be empty because html can be empty, as enforced byLayout.concat : List html -> html)Toggle,SearchandGoTopatterns, as well as top-level Ui, can be placed in the Header. As soon as you place some UiinRegion .., its descendants are barred from populating the header (except the three patterns mentioned above).Original motivation for this design:
inRegionat all, you end up with regionless Ui inlayout.arrange. So I replacedMaybe regionwith the equivalent but more expressiveOrHeader region.Shortcomings/Friction:
viewfor a model, you don't know if it'll end up in the Header or in some region. Whereas the application view gets direct access to this region. So when you un-nest (in terms ofinRegion) aview, it may change its behavior. in other words, the firstinRegioncreates a narrower context whereas consecutive nestedinRegions preserve the context. SoinRegionis in a sense no longer commutative. (does that make sense?)Headetwould make a lot of records smaller and, perhaps more importantly, more predictable and memorizable.viewup the module into the mainviewand voilà the library has broken ones of its two promises. The current Api is just not successful at enforcing the Invariant.Alternatives solutions
atRegion Header!