Description
Currently, DOM elements accept an array of Props
. An alternative to this could be to define a row representing the known attributes one may pass as props to a DOM element. Using a row was briefly mentioned in #113 (comment).
For instance, we could define two rows: one for HTML attributes and one for SVG attributes. Going this route, we would need a way to handle passing event handler callbacks. Also, if we wanted an attribute to have a type other than a primitive one or one known to React, then we would need a way to map the attribute's value to something React can use.
I think using rows could prove to be nicer in terms of syntax and perhaps a bit more convenient. I wanted to bring up this idea to see if there is interest in going this route. I'd be happy to discuss other ideas or dig in deeper with rows if there is interest. Any comments, questions, or suggestions are most welcome.
Also, below are some options for what this could look like. Option 1 presents passing a record where the row must be a subrow of all HTML attributes. Option 2 is similar, but passes a Data.Record.Builder
. Using a builder we have the opportunity to pass data types other than primitive ones; e.g., instead of the target
function accepting a String
, we could make a Target
data type and map it to a String
in the function. Just a couple of ideas, others are most welcome.
Option 1 - Records
type HTMLAttributes r
= ( href :: String
, target :: String
| r
)
a
:: forall r s t
. Union r t (HTMLAttributes s)
=> Record r
-> Array React.ReactElement
-> React.ReactElement
a props children = React.createElementTagName "a" props children
foo :: React.ReactElement
foo =
a
{ href: "https://github.com/purescript-contrib/purescript-react"
, target: "_blank"
} [ ... ]
Option 2 - Builder
type HTMLAttributes r
= ( href :: String
, target :: String
| r
)
href
:: forall r
. RowLacks "href" r
=> String
-> Builder { | r } { href :: Int | r }
href = Builder.insert (SProxy :: SProxy "href")
target
:: forall r
. RowLacks "target" r
=> String
-> Builder { | r } { target :: String | r }
target = Builder.insert (SProxy :: SProxy "target")
a
:: forall r s t
. Union r t (HTMLAttributes s)
=> Builder { } (Record r)
-> Array React.ReactElement
-> React.ReactElement
a builder children = React.createElementTagName "a" (Builder.build builder {}) children
foo :: React.ReactElement
foo =
a
( href "https://github.com/purescript-contrib/purescript-react"
>>> target "_blank"
) []
// @natefaubion