Can HTML attributes be used in SVG functions?

I’m trying to make something interactive using SVG. I’m building the SVG DOM using the Svg.Styled modules from rtfelman/elm-css. (Pretty sure this would apply to elm/svg too, they’re all but copies.) I’d like access to information from the actual mouse events, like the click positions, so I’m trying to make use of Html.Events.Extra.Pointer from mpizenberg/elm-pointer-events. I’m not able to get this to compile, though. Here’s an example of the code I’m trying:

import Html as H
import Svg.Styled as S
import Svg.Styled.Attributes as A
import Html.Events.Extra.Pointer as E

showPolygon fill points -> S.polygon [
        A.fill fill 
      , A.points <| pointsToString points
      , E.onDown (always Message) -- this is the bit relevant to the question
    ] []

Here’s the error message I’m getting:

This onDown call produces:

H.Attribute Message

But all the previous elements in the list are:

S.Attribute msg

Hint: Everything in a list must be the same type of value. This way, we never
run into unexpected values partway through a List.map, List.foldl, etc. Read
https://elm-lang.org/0.19.1/custom-types to learn how to “mix” types.

It’s definitely not my use of qualified imports - I checked while also exposing Attribute from both packages, and the error stayed the same except for missing the information about the source packages. I also tried to write a function to map from one type to another, and nothing I thought of compiled.

Is there a way to make this work? It looks like Svg.Styled.Attribute is an alias of Html.Attribute, so I thought it might. I see that there’s a customizable event type in the Svg.Styled.Events, but I would have to write my own decoder. I figured before I dive into working that out, it would be worth asking if there’s a way to transform from one Attribute type to the other, or if there’s some other way to make these packages work together.

I think the problem is Message vs msg.

A.fill fill has the type Svg.Styled.Attribute msg
E.onDown (always Message) has the type Html.Attribute Message

The problem is not Message vs msg, that should be ok, as the free msg can be unified to Message and the whole thing type check.

The problem is that Svg.Styled.Attribute is not an alias/the same thing as Html.Attribute. There is a function though, which can convert it:

https://package.elm-lang.org/packages/rtfeldman/elm-css/latest/Svg-Styled-Attributes#fromUnstyled

So you need E.onDown (always Message) |> A.fromUnstyled.

The rtfeldman/elm-css package defines its own Html and Attribute types. See also:

https://package.elm-lang.org/packages/rtfeldman/elm-css/latest/Html-Styled#fromUnstyled
https://package.elm-lang.org/packages/rtfeldman/elm-css/latest/Html-Styled#toUnstyled

3 Likes

Thanks for pointing those out! I think I misunderstood them on my first read of the docs. Just now I discovered you can get the full names with modules by mousing over.

I tried it out, and it works! Back to the races :racehorse:

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.