In Halogen, I have a table component. It receives basically an Array (Array Json) and then renders this into a, HTML table.
Now I want to have an (optional) custom column for “Actions” in each table row. An example would be “Delete this row”. My question is really simple: how do I pass the HTML for this custom column as an input?
My attempt looks like this:
type Input = { rows :: Array (Array Json), actionsColumn :: Maybe (forall w i. HTML w i) }
render state = HH.table_ [
HH.tr_ [
maybe [] (\actions -> HH.td_ [ actions ]) state.actionsColumn
]
]
However, this gives me:
Could not match type
w1
with type
w0
while trying to match type HTML w1
with type HTML w0
So it’s got something do to with the forall w i part. Which I basically guessed.
How do I do this properly? I’d love the “actions” column to contain buttons that then raise outputs so I can react to it in the parent component.
Not sure but I think this is another instance of a problem you can get with forall inside records - is it viable for you to move the forall w i outside the record?
type Input = { rows :: Array (Array Json), actionsColumn :: Maybe (forall w i. HTML w i) }
to
type Input w i = { rows :: Array (Array Json), actionsColumn :: Maybe (HTML w i) }
The difference between those is in the former, if you have a value of type Input, the compiler isn’t allowed to know anything about what type of HTML it contains. So when you say [ actions ], you’re creating an Array (forall w i. HTML w i) (as in each element is allowed to have whatever w and i it wants). With the latter, you have an Input w i and the w and i are “locked in” by the compiler. When you say [ actions ], then, it’s a forall w i. Array (HTML w i), which is what the td_ function expects.
Maybe a little late to the party but I had the same challenge.
The problem was that the mkComponent needs render to return a: HTML (ComponentSlot slots m i) i
The input is an array of:
HTML w i
This doesn’t work because, if it would, the caller of component can determine the w to be anything, while it has to be at least the ComponentSlot…
So changing the input array to
Array (HTML (ComponentSlot slots m i) i)
or the shorthand variant (Array (H.ComponentHTML i slots m))