PaackEng / paack-ui / UI.Utils.ARIA

Interface for HTML's ARIA.


type alias ElementSemantics =
{ role : Role
, label : Maybe String 
}

Use roles for creating ARIA element's semantics. Roles defines the type of UI element.

See MDN article.

Building

roleButton : ElementSemantics

"The button role should be used for clickable elements that trigger a response when activated by the user." - MDN

Element.el
    (Events.onClick Msg.SomeEvent :: ARIA.toElementAttributes ARIA.roleButton)
    someChildElement

roleImage : String -> ElementSemantics

"Can be used to identify multiple elements inside page content that should be considered as a single image." - MDN

Element.el
    (ARIA.toElementAttributes <| ARIA.roleImage altText)
    [ Element.text "😺 Meow" ]

NOTE: This role enforces aria-label option.

rolePresentation : ElementSemantics

"An element whose content is completely presentational (like a spacer image, decorative graphic, or clearing element)" - W3C

Element.el
    (ARIA.toElementAttributes ARIA.rolePresentation)
    totallyRedundantElement

roleCheckbox : Basics.Bool -> ElementSemantics

"The checkbox role is used for checkable interactive controls." -MDN

Element.row
    (ARIA.toElementAttributes <| ARIA.roleCheckbox False)
    [ notCheckedIcon
    , Element.text "I accept the Terms of Service"
    ]

roleTab : Basics.Bool -> ElementSemantics

"The ARIA tab role indicates an interactive element inside a tablist." -MDN

Element.row []
    [ Element.el
        (ARIA.roleTab True
            |> ARIA.toElementAttributes
            |> (::) tabIndex 0
            |> (::) Event.onClick (Msg.SetTab TabFirst)
        )
        (Element.text "Tab label")
    , Element.el
        (ARIA.roleTab False
            |> ARIA.toElementAttributes
            |> (::) tabIndex -1
            |> (::) Event.onClick (Msg.SetTab TabSecond)
        )
        (Element.text "Another tab")
    ]

NOTE: We're missing aria-controls. And MDN recomends using tabindex as 0 on selected tab and -1 on non-active tabs.

roleSwitch : Basics.Bool -> ElementSemantics

"The ARIA switch role is functionally identical to the checkbox role, except that instead of representing checked/unchecked states, which are fairly generic in meaning, the switch role represents the states on/off." -MDN

Element.el
    (Event.onClick turnOnMsg :: (ARIA.toElementAttributes <| ARIA.roleSwitch False))
    offSwitchIcon

roleToggleButton : Basics.Bool -> ElementSemantics

A toggle button has the button role along with its pressed state

Element.el
    (Events.onClick Msg.SomeEvent
        :: ARIA.toElementAttributes ARIA.roleToggleButton isToggled
    )
    someChildElement

Radio buttons

roleRadioGroup : String -> ElementSemantics

"A radiogroup is a type of select list that can only have a single entry checked at any one time." - W3C

Element.column
    (ARIA.toElementAttributes <| ARIA.roleRadioGroup "Pick an ice cream flavor")
    [ chocolateIceCream
    , strawberryIceCream
    ]

NOTE: This role enforces aria-label option.

roleRadio : Basics.Bool -> ElementSemantics

"A checkable input in a group of elements with the same role, only one of which can be checked at a time." - W3C

Element.row
    (ARIA.toElementAttributes <| ARIA.roleRadio True)
    [ checkedIcon
    , Element.text "Chocolate"
    ]

Global options

withLabel : String -> ElementSemantics -> ElementSemantics

"Defines a string value that labels the current element" -W3C

ARIA.roleCheckbox False
    |> ARIA.withLabel "I agree with the policy"
    |> ARIA.toElementAttributes

NOTE: This is a global optional parameter, roles builders enforce it when necessary.

Rendering

toElementAttributes : ElementSemantics -> List (Element.Attribute msg)

Transform a ElementSemantics in a list of Element.Attribute.