Hello folks! React has “fragments” with roughly the type annotation that I put into the title.
I feel like these would sometimes be useful when writing Elm views, in a similar vein to how Html.Extra.viewIf
and Html.Attributes.Extra.attributeIf
are useful.
Motivating example
I have (after SSCCE-fication):
buttonView : String -> Msg -> Html Msg
buttonsView : Html Msg
buttonsView =
Html.div []
[ buttonView "Foo" DoFoo
, buttonView "Bar" DoBar
, buttonView "Save" Save
]
and I’ve just received an extra requirement from my project manager: if the entity is saved, show buttons "Save as new"
and "Save changes"
instead of the "Save"
button.
So, ideally I’d love to do
buttonsView : { isSaved : Bool } -> Html Msg
buttonsView {isSaved} =
let
saveButtons : Html Msg
saveButtons =
if isSaved then
Html.fragment
[ buttonView "Save as new" SaveAsNew
, buttonView "Save changes" SaveChanges
]
else
buttonView "Save" Save
in
Html.div []
[ buttonView "Foo" DoFoo
, buttonView "Bar" DoBar
, saveButtons
]
but since I don’t have Html.fragment
, my (IMHO) best solution is to do:
buttonsView : { isSaved : Bool } -> Html Msg
buttonsView {isSaved} =
Html.div []
[ buttonView "Foo" DoFoo
, buttonView "Bar" DoBar
, Html.Extra.viewIf isSaved <| buttonView "Save as new" SaveAsNew
, Html.Extra.viewIf isSaved <| buttonView "Save changes" SaveChanges
, Html.Extra.viewIf (not isSaved) <| buttonView "Save" Save
]
(or put the if
in the top level and duplicate the Foo
and Bar
cases in both branches of the if
.)
(or worse, meddle with ::
and ++
which personally I don’t like in my views because of how it messes up the otherwise regular formatting.)
(or even worse, wrap things in another Html.div
, which has, let’s say, CSS side-effects.)
That is to say, we have many workarounds, but it seems to me that our view
code might be nicer if we had Html.fragment : List (Html msg) -> Html msg
.
Questions
- Do you think
Html.fragment
would be useful? - Are there some associated risks?
(I"m only aware of the need to also have aHtml.Keyed.fragment
.)
Aside: I get unnecessarily excited by the thought that Html a
would become a Semigroup and a Monoid (we already have an identity element, but we don’t have a well-behaving concat function… Html.div []
and friends don’t cut it )