ensolabs/designsystemet-elm/1.0.0

Designsystemet.Card

Cards group content about one thing.

Mirrors Card and Card.Block from @digdir/designsystemet-react.

Card.view []
    [ Heading.h3 [] [ Html.text "Byggesak 2024/118" ]
    , Paragraph.view [] [ Html.text "Tilbygg, Storgata 4" ]
    ]

Split a card into sections with block. Blocks are separated by lines, and a block holding only an image or video goes edge to edge:

Card.view []
    [ Card.block [] [ Html.img [ Attr.src "/bilder/storgata-4.jpg", Attr.alt "" ] [] ]
    , Card.block [] [ Heading.h3 [] [ Html.text "Storgata 4" ] ]
    ]

React → Elm

  • <Card> → Card.view []
  • variant="tinted" → Card.tinted
  • <Card.Block> → Card.block []
  • asChild + <a href> → Card.viewAs Html.a [ Attr.href "…" ]
  • <Card.Block asChild> → Card.blockAs Html.section []
  • a <Heading><a> inside (auto-detected) → Card.clickable id [] + Card.mainLink id on the link

Managed by designsystemet-web

In a clickable card, @digdir/designsystemet-web forwards clicks to the main link and adds a :click-delegate-hover class to the link while the pointer is over the card. Keep the main link's class stable between renders, or the hover style flickers.

view : List (Attribute msg) -> List (Html msg) -> Html msg

A <div class="ds-card">.

(List (Attribute msg) -> List (Html msg) -> Html msg)
-> List (Attribute msg)
-> List (Html msg)
-> Html msg

A card rendered as another element than <div> (React's asChild). Use it for a semantic container (Html.article, Html.li), or to make the whole card one link or button:

Card.viewAs Html.a
    [ Attr.href "/saker/118" ]
    [ Heading.h3 [] [ Html.text "Byggesak 2024/118" ] ]

A card that is one <a> can't contain other links or buttons. Use clickable for that.

Variants

tinted : Attribute msg

A tinted background instead of the default surface.

Blocks

block : List (Attribute msg) -> List (Html msg) -> Html msg

A <div class="ds-card__block">: a section of a card, with a line between it and the next.

(List (Attribute msg) -> List (Html msg) -> Html msg)
-> List (Attribute msg)
-> List (Html msg)
-> Html msg

A block rendered as another element (Card.Block's asChild).

Card.blockAs Html.footer [] [ Html.text "Sist endret 3. mars" ]

Clickable cards

clickable : LinkId -> List (Attribute msg) -> List (Html msg) -> Html msg

A card where a click anywhere opens its main link. Other links and buttons inside still work.

The link stays a single <a>, so screen readers and keyboard users get one link with a short name instead of the card's whole text. Put it in the heading: the CSS underlines the heading and gives the card a hover state.

viewCase : Case -> Html Msg
viewCase case_ =
    let
        link =
            caseLink case_
    in
    Card.clickable link
        []
        [ Heading.h3 []
            [ Html.a [ Card.mainLink link, Attr.href (Route.toString (Route.Case case_.id)) ]
                [ Html.text case_.title ]
            ]
        , Paragraph.view [] [ Html.text case_.address ]
        , Button.view [ Button.tertiary, Events.onClick (Archive case_.id) ] [ Html.text "Arkiver" ]
        ]

React finds the first link in a heading after rendering. Elm doesn't read the DOM, so you name the link, and the shared LinkId keeps card and link in sync.

@digdir/designsystemet-web forwards the clicks (data-clickdelegatefor). Ctrl-, Cmd- and middle-clicks open a new tab, as on the link itself.

(List (Attribute msg) -> List (Html msg) -> Html msg)
-> LinkId
-> List (Attribute msg)
-> List (Html msg)
-> Html msg

A clickable card as another element, such as a list item or an article:

Html.ul []
    (List.map
        (\case_ ->
            Card.clickableAs Html.li (caseLink case_) [] [{- … -}]
        )
        cases
    )
type LinkId

The id of the link a clickable card sends its clicks to. A separate type, so it only fits mainLink.

linkId : String -> LinkId

Make a LinkId from an id that is unique on the page.

caseLink : Case -> Card.LinkId
caseLink case_ =
    Card.linkId ("sak-" ++ Case.idToString case_.id)

The id as a string, for Browser.Dom.focus and the like.