ensolabs/designsystemet-elm/1.0.0

Designsystemet.Badge

A small, non-interactive marker: a dot for "something new", or a count.

Mirrors Badge and Badge.Position from @digdir/designsystemet-react.

Badge.position { placement = Badge.TopRight, overlap = Badge.Rectangle }
    []
    [ Badge.view (Badge.Capped { count = model.unread, max = 99 }) [ Ds.color Color.danger ]
    , inboxIcon
    ]

The CSS draws the number from data-count, so screen readers don't read it. Put it in words where it matters, for example in the aria-label of the button the badge sits on ("Innboks, 3 uleste").

React → Elm

  • <Badge /> → Badge.view Badge.Dot []
  • <Badge count={5} /> → Badge.view (Badge.Count 5) []
  • <Badge count={120} maxCount={99} /> → Badge.view (Badge.Capped { count = 120, max = 99 }) []
  • variant="tinted" → Badge.tinted
  • <Badge.Position placement overlap> → Badge.position { placement = …, overlap = … } []

React ignores maxCount without count. Here it can't be written.

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

A <span class="ds-badge">. It has no children and shows its Content.

type Content
= Dot
| Count Int
| Capped
{ count : Int
, max : Int
}

What a badge shows.

  • Dot: a marker with no number.
  • Count n: the number n.
  • Capped { count, max }: the number, or "99+" once count passes max.
toLabel : Content -> Maybe String

The text a badge shows, or Nothing for a dot. Use it for screen-reader text.

toLabel Dot == Nothing


toLabel (Count 5) == Just "5"


toLabel (Capped { count = 5, max = 9 }) == Just "5"


toLabel (Capped { count = 10, max = 9 }) == Just "9+"

As in React, a max of 0 means no cap. Negative numbers aren't checked, so keep count and max at zero or above.

Variants

base : Attribute msg

A solid badge, the default.

tinted : Attribute msg

A softer badge with a tinted background.

Positioning

{ placement : Corner
, overlap : Overlap
}
-> List (Attribute msg)
-> List (Html msg)
-> Html msg

A <span class="ds-badge--position"> that floats the Badge inside it over a corner of the other content.

Badge.position { placement = Badge.TopRight, overlap = Badge.Circle }
    []
    [ Badge.view Badge.Dot [ Ds.color Color.success ]
    , Avatar.view { name = Avatar.Label "Kari Nordmann", content = Avatar.Initials "KN" } []
    ]

React defaults to TopRight and Rectangle. The CSS needs both, so here they are required.

type Corner
= TopRight
| TopLeft
| BottomRight
| BottomLeft

The corner of the element the badge sits on. Unlike Designsystemet.Placement, it overlaps the element.

type Overlap
= Rectangle
| Circle

The shape of the element under the badge. Over a Circle, such as an Avatar, the badge moves in to the circle's edge instead of the bounding box corner.