app/scripts/ui-lib/widgets/tabs.coffee

Tabs

The Tabs class provides a tabs widget.

author: Julien Ramboz version: 1.0 references: WAI-ARIA tab role, AOL's Tab Panel style guide usage: Tabs examples requires: Accordions

AMD loader

Try loading as AMD module or fall back to default loading

((widget) -> if typeof define is "function" and define.amd define ["jslib", "core", "widget", "accordions"], widget else widget @$, _, _.AbstractWidget, _.Accordions ) tabs = ($, _, AbstractWidget, Accordions) -> "use strict"

Widget

The actual widget class

class Tabs extends Accordions

Default options for the widget

@defaultOptions:
  • event: the event to react to
event: "click"
  • tabs: the tabs specified as a selector relative to the element
tabs: ""
  • panels: the panels specified as a selector relative to the element
panels: ""
  • position: where to put the tabs (top, bottom, left and right)
position: "top"

Initialisation

Initializer function.

initialize: (options) -> super options @selectTab()

Accessibility markup

Add aria attributes

aria: () -> super @element.attr "aria-multiselectable", false $tabs = @tabs $tabsContainer = @tabs.parents( () -> $(this).find($tabs).length ).eq(0) if not $tabsContainer.attr("role") $tabsContainer.attr("data-role", "tabs") $panels = @panels $panelsContainer = @panels.parents( () -> $(this).find($panels).length ).eq(0) if not $panelsContainer.attr("role") $panelsContainer.attr("data-role", "panels")

Event handling

Attach evenets to the widget

bindEvents: () -> super @handleKeys(@panels) @element .off(@options.event+".#{_.namespace}accordions") .on @options.event+".#{_.namespace}tabs", "[role='tab']", (e) => e.preventDefault() return if e.target.getAttribute("aria-disabled") is "true" $target = $(e.target) @selectTab($target) if @tabs.index($target) > -1 @element .off("focus.#{_.namespace}accordions", "[role='tab']") .on "focus.#{_.namespace}tabs", "[role='tab']", (e) => if e.target.getAttribute("aria-disabled") is "true" return e.preventDefault() $target = $(e.target) @selectTab($target) if @tabs.index($target) > -1

Activate the specified tab

selectTab: ($tab) -> super($tab) @tabs["#{_.namespace}collapse"]("hide") @currentTab["#{_.namespace}collapse"]("show")

Structure discovery

Find the widget structure using the specified configuration

Tabs

Find the tabs using:

  • elements with role="tab"
  • using tabs option (selector relative to the element)
  • the children of the first child if the tabs are not at the bottom
  • the children of the second child otherwise
findTabs: () -> $tabs = @element.find("[role='tab']") return $tabs if $tabs.length if @options.tabs $(@options.tabs, @element) else switch @options.position when "bottom", "right" @element.children().eq(1).children() else @element.children().eq(0).children()

Panels

Find the panels using:

  • elements with role="tab"
  • using panels options (relative to the element's parent)
  • the children of the second child if the tabs are not at the bottom
  • the children of the first child otherwise
findPanels: () -> $panels = @element.find("[role='tabpanel']") return $panels if $panels.length if @options.panels $(@options.panels, @element.parent()) else switch @options.position when "bottom", "right" @element.children().eq(0).children() else @element.children().eq(1).children()

Installation

Install the widget into the JS library

Tabs.install("Tabs", () -> $("[data-widget='tabs']")["#{_.namespace}tabs"]() )