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.fragmentwould 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
)
