kirchner/elm-wai-aria-tabs/1.0.2

Accessibility.Tabs

{ label : String
, tabs :
List
{ label : String
, panel : Html msg
}
, active : String
, onChange : String -> Task Error () -> msg
}
-> Html msg

Render a tabs widget with default styling. You have to provide the following fields:

  • label: The label of the tabs used by screen readers.
  • tabs: A list of all tabs with its panels. The label field is used for the entry in the tablist, as well as for tagging the currently active tab.
  • active: The currently active tab.
  • onChange: Message handler for changing the active tab. You must Task.attempt the second argument in your update function to make sure the correct tab receives focus.

NOTE: This function is meant to get you started with this package. If you need more then one tabs widget on your page or want custom styling and interaction, you should take a look at the view function below.

Views node msg
-> { label : Label
, tabs : List (Tab node tab)
, active : tab
, onChange : tab -> Task Error () -> msg
, orientation : Orientation
, activation : Activation
}
-> node

Render a (customized) tabs widget. You must provide Views for rendering and the following configuration fields:

  • label: Specify how the tabs are labelled. See Label for possible options.
  • tabs: A list of all tabs with its panels. See Tab for a description of its fields.
  • active: The currently active tab.
  • onChange: Message handler for changing the active tab. You must Task.attempt the second argument in your update function to make sure the correct tab receives focus.
  • orientation: Indicate if the tab list is oriented horizontally or vertically, this should match the actual layout.
  • activation: How are tabs activated? See Activation for possible options.
type Label

There are two ways to label tabs: it can be labelledby by another DOM element with the given id or it can provide its own label.

labelledby : String -> Label
label : String -> Label
type alias Tab node tag =
{ tag : tag
, id : String
, label : node
, panel : node
, focusable : Bool
}
  • tag: Unique tag to show the currently active tab.
  • id: This is used to generate CSS ids of the tab and its panel. This must be unique within your page.
  • label: Displayed label of the tab within the tab list.
  • panel: Content of the tab panel associated to the tab.
  • focusable: Indicate whether the panel itself can receive focus. Is is best practice to to make the panel focusable if it does not contain any other elements which can receive focus.
= Automatic
| Manual

From the WAI-ARIA Authoring Practices:

  • Tabs With Automatic Activation: A tabs widget where tabs are automatically activated and their panel is displayed when they receive focus.
  • Tabs With Manual Activation: A tabs widget where users activate a tab and display its panel by pressing Space or Enter.
= Horizontal
| Vertical

View customization

type Views node msg

Opaque type for providing view customization of the tabs widget.

{ container : List (Attribute msg)
, tabList : List (Attribute msg)
, tab : Bool -> List (Attribute msg)
, panel : Bool -> List (Attribute msg)
}
-> Views (Html msg) msg

Generate view customization the standard elm/html package.

The DOM structure of the tabs will be something like this:

tabs =
    Html.div
        [ ... ] -- container attributes
        [ Html.div
            [ ... ] -- tabList attributes
            [ tabs ]
        , panels
        ]


tab =
    Html.button
        [ ... ] -- tab attributes
        [ tabLabel ]


panel =
    Html.div
        [ ... ] -- panel attributes
        [ panelContent ]

Advanced customization

{ tabs :
TabsAttrs
-> { tabs : List node
, panels : List node
}
-> node
, tab :
TabAttrs msg
-> { label : node
, active : Bool
}
-> node
, panel :
PanelAttrs
-> { panel : node
, active : Bool
}
-> node
}
-> Views node msg

If you want to use other UI libraries like rtfeldman/elm-css or mdgriffith/elm-ui you have to generate Views using this function. Take a look at the implementation of html for a starting point. The examples/ folder of the package repository contains an implementation for mdgriffith/elm-ui.

type alias TabsAttrs =
{ role : String
, ariaLabel : Maybe String
, ariaLabelledBy : Maybe String
}

Make sure to add HTML attributes for all attributes in this record to the tabs list container.

  • role: The role HTML attribute.
  • ariaLabel: The aria-label HTML attribute.
  • ariaLabel: The aria-labelledby HTML attribute.
type alias TabAttrs msg =
{ role : String
, ariaSelected : Bool
, ariaControls : String
, id : String
, onClick : msg
, preventDefaultOnKeydown : Decoder ( msg, Bool )
, tabindex : Int
}

Make sure to add HTML attributes and event handlers for all attributes in this record to the tab.

  • role: The role HTML attribute.
  • ariaSelected: The aria-selected HTML attribute.
  • ariaControls: The aria-controls HTML attribute.
  • id: The CSS id.
  • onClick: Attach this to an onclick event handler.
  • preventDefaultOnKeydown: Attach this to an onkeydown event handler which can prevent default.
  • tabindex: The tabindex HTML attribute.
type alias PanelAttrs =
{ role : String
, id : String
, ariaLabelledby : String
, tabindex : Maybe Int
, hidden : Bool
}

Make sure to add HTML attributes for all attributes in this record to the panel.

  • role: The role HTML attribute.
  • id: The CSS id.
  • ariaLabelledby: The aria-labelledby HTML attribute.
  • tabindex: The tabindex HTML attribute.
  • hidden: Is the panel hidden? One way to hide it, is by adding display: none;.