Tabcordion¶
A responsive and accessible solution for tabs for a tab / accordion hybrid implementation.
Some notable features supported by the extension:
- Keyboard support
- Accordion-like display that can be explicitly set or auto detected based on screen width
- Automatic scroll to panel behavior
- Automatic window history state replacement when activating panels
- Robust API including the ability to programmatically show / hide panels, set the initial active panel, customize the scroll to panel behavior, and much more!
Installation¶
Note: This class is pre-installed and loaded asynchronously with Genesis out of the box in the PROD.js
file. The extension styling is loaded in when the Tabcordion
class is imported.
Import the Tabcordion
extension class in your desired JavaScript file.
import {Tabcordion} from 'extensions/tabs';
Example Usage¶
Product Page Setup¶
A tabcordion set includes:
- A tab control for the associated panel
- An accordion control for the associated panel
- The associated panel containing the main content
By default, the product page tabcordions include the product description as the first tabcordion set if the description value is not empty. Additional tabcordion sets are loaded from the tabs
custom field group. This custom field group will need to be created if it is not already present and all product custom fields to be utilized as tabs assigned to the group.
The tab and accordion control titles will correlate to the custom field Name, however, this can be adjusted if needed in the template code. Additional template adjustments can be made to load in and customize the desired tabcordion sets by configuring the l.settings:product:tabs
variable to suit your needs. The l.settings:product:tabs
variable is an array of structures that support the following members:
:code
- Used for generate the HTMLid
attributes for the elements in each tabcordion set.:name
- Used for the tab and accordion control titles.:value
- Used for the panel content.
.mvt¶
Add the tabcordion pattern markup resembling the HTML structure shown below. See the notes below the example HTML that correlate to the comments for more details on the structure.
<!-- [1] -->
<article class="g-tabcordion">
<!-- [2] -->
<div class="g-tabcordion__tabs">
<!-- [3] -->
<button type="button" id="tab-list-descrip" class="g-tabcordion__tab is-active" aria-expanded="true" aria-controls="panel-descrip">
<h2 class="g-tabcordion__tab-title">Description</h2>
</button>
<button type="button" id="tab-list-prod_tab1" class="g-tabcordion__tab" aria-expanded="false" aria-controls="panel-prod_tab1">
<h2 class="g-tabcordion__tab-title">Product Tab 1</h2>
</button>
</div>
<!-- [4] -->
<div id="tab-list-descrip-accordion-control" class="g-tabcordion__accordion-control is-active" aria-expanded="true" aria-controls="panel-descrip">
<h2 class="g-tabcordion__tab-title">Description</h2>
<span class="g-tabcordion__accordion-control-icon" aria-hidden="true"></span>
</div>
<!-- [5] -->
<div id="panel-descrip" class="g-tabcordion__panel is-active" role="region" aria-labelledby="tab-list-descrip tab-list-descrip-accordion-control">
<!-- [6] -->
<div class="g-tabcordion__panel-content">I come from a land down under</div>
</div>
<div id="tab-list-prod_tab1-accordion-control" class="g-tabcordion__accordion-control" aria-expanded="false" aria-controls="panel-prod_tab1">
<h2 class="g-tabcordion__tab-title">Product Tab 1</h2>
<span class="g-tabcordion__accordion-control-icon" aria-hidden="true"></span>
</div>
<div id="panel-prod_tab1" class="g-tabcordion__panel" role="region" aria-labelledby="tab-list-prod_tab1 tab-list-prod_tab1-accordion-control">
<div class="g-tabcordion__panel-content">
Product Tab 1 content...
</div>
</div>
</article>
- This is the root container for the tab content and is targeted by the extension styling. This is also the container element that must be passed in as the first parameter for the
Tabcordion
class. - The
g-tabcordion__tabs
class indicates that the element serves as the container for the set of tabs (tab list). This element's width is also targeted when theaccordionMode
setting is set toauto
. Each element with the
g-tabcordion__tab
class within the tab list indicates the element serves as a tab control. The associated panel is linked by its ownid
attribute that matches thearia-controls
attribute value on the tab control element.The default active tab control must contain the
is-active
class or set to the class specified by thetabActiveClass
configuration setting. Additionally, the active tab control must have itsaria-expanded
attribute set totrue
. All other tab control elements must have aaria-expanded
attribute set tofalse
.Each element with the
g-tabcordion__accordion-control
class indicates the elements serves as an accordion control. The associated panel is linked by its ownid
attribute that matches thearia-controls
attribute value on the accordion control element.The default active accordion control must contain the
is-active
class or set to the class specified by thetabActiveClass
configuration setting. Additionally, the active accordion control must have itsaria-expanded
attribute set totrue
. All other accordion control elements must have aaria-expanded
attribute set tofalse
.- Each tab panel element must have an
id
attribute and arole="region"
attribute in conjunction with thearia-labelledby
attribute to indicate the element serves as a container for the panel content and is associated properly to its control elements. Thearia-labelledby
value is a space separated value containing theid
attributes for each of the panel's control elements. - The panel content is placed within an element with the
g-tabcordion__panel-content
class.
.js¶
After loading in the Tabcordion
class, initialize the class by passing the root container element as the first parameter.
Preferred asynchronous initialization:
(async () => {
const productTabs = document.getElementsByClassName('g-tabcordion');
if (!productTabs.length) {
return;
}
const {Tabcordion} = await import('extensions/tabs');
for (const tab of productTabs) {
new Tabcordion(tab);
}
})();
Alternatively:
import {Tabcordion} from 'extensions/tabs';
for (const tab of document.getElementsByClassName('g-tabcordion')) {
new Tabcordion(tab);
}
Options¶
The Tabcordion
class can take an optional configuration object for the second parameter to override any of the default configuration settings.
The following table defines the available configuration options:
Name | Type | Description | Default Value |
---|---|---|---|
accordionActiveClass | String | Accordion mode class name. | 'is-accordion' |
accordionMode | String|Integer | Accordion mode setting that controls when the tabs display like an accordion. This can be set to 'auto' to automatically detect and switch to the accordion view when the width of the tabs exceeds the container width. An integer value can also be provided to explicitly set the width to switch to the accordion view. |
'auto' |
hashOptions | Object | Configuration object for URL hash features. If overriding the default object, you MUST provide all properties listed below. | See following properties below for default values. |
hashOptions.enabled | Boolean | Flag to determine if URL hash features are enabled or disabled. Enabling this option will override the tabActiveIndex setting for the initial tab panel activation if a URL location hash is present and matches the id attribute of a tab panel element. |
true |
hashOptions.scrollIntoView | Object | Scroll into view options object. Reference article here for more information on available options https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView. | {behavior: 'smooth', block: 'center'} |
hashOptions.updateLocation | Boolean | Flag to determine if window location state is updated with hash value corresponding to the active tab panel. |
true |
tabActiveClass | String | Active tab class name. | 'is-active' |
tabActiveIndex | Integer | Sets the index of the initial active panel. | 0 |
tabControlSelector | String | The selector for the tab conrol elements. | '.g-tabcordion__tab' |
tabListSelector | String | The selector for the tab list element. | '.g-tabcordion__tabs' |
tabPanelSelector | String | The selector for the tab panel elements. | '.g-tabcordion__panel' |
tabPanelContentSelector | String | The selector for the tab panel content elements. | '.g-tabcordion__panel-content' |
Features¶
The following section describes common use-case features supported by the Tabcordion
class.
Show Panel¶
The showPanel
method may be utilized to programmatically show a panel element. Simply pass in the panel element to the showPanel
method to display the panel. Alternatively, a tabcordion element
object can be passed in as well as the first parameter. More details for the tabcordion element
object can be found below.
const tabcordion = new Tabcordion(container);
const panelElement = container.querySelector('#target-panel');
tabcordion.showPanel(panelElement);
The showPanel
method takes an optional object for a second parameter if you wish to override the default method behavior. The object supports the following properties:
Name | Type | Description | Default Value |
---|---|---|---|
disableLocationUpdate | Boolean | If true, disables the hash window location state update functionality if the configuration setting is enabled. |
false |
focus | Boolean | Boolean to determine if focus should be set on the panel. | true |
scrollIntoView | Null|Object | Scroll in to view behavior. If null , scroll behavior is disabled. The object utilizes a scrollIntoView object https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView. |
null |
A common use case to apply the second parameter is to display and scroll to the panel after interacting with a control or target element.
For example, clicking a Reviews link to activate and scroll to a Reviews panel.
HTML
<a id="js-reviews" class="g-display-link" href="https://www.example.com#panel-reviews">See Reviews</a>
JavaScript
const reviewsTriggerElement = document.getElementById('js-reviews');
reviewsTriggerElement.addEventListener('click', (event) => {
event.preventDefault();
const hashElements = tabcordion.getElementsByHash(reviewsTriggerElement.hash);
if (hashElements) {
tabcordion.showPanel(hashElements, {
scrollIntoView: tabcordion.hashOptions.scrollIntoView
});
}
});
Tabcordion Element Object¶
NOTE the use of the getElementsByHash(hashVal)
method in the example above. This method receives a hash value argument corresponding to an id
attribute of a panel element. If a matching panel element is found, it will return a tabcordion element
object with the following properties:
accordionControl
- The accordion control elementpanel
- The tab panel elementtabControl
- The tab control element
Other helper methods for retrieving a tabcordion element
object include:
getActiveElement()
- Returns the activetabcordion element
objectgetElementsByControlElement(controlElement)
- Returns atabcordion element
object associated to the providedcontrolElement
getElementsByPanelElement(panelElement)
- Returns atabcordion element
object associated to the providedpanelElement
Auto Tab Activate And Scroll¶
Alternative to the above use case example, automatic panel display and scroll to functionality is available when the hashOptions.enabled
flag is set to true
. When this option is enabled, window.location
hash changes will be observed and trigger this functionality when the hash value matches the id
attribute of a panel element. Essentially, the HTML example above can be output and will automatically apply similar behavior as the JavaScript example when the hash options are enabled. The scroll to behavior in this case is driven by the hashOptions.scrollIntoView
configuration option value.
On Page Load¶
When the hashOptions.enabled
flag is true
and the window location contains a hash value that matches the id
attribute of a panel element, the associated tab and accordion control elements will be activated and the panel element will be scrolled into view.
Tab View¶
When the tab view is enabled, only the active panel will be shown and all other panels will be hidden.
Accordion View¶
The accordion view is activated when meeting the criteria for the value provided in the accordionMode
setting. When the accordion view is active, panels are shown and hidden individually when interacting with the accordion control elements.
Window Location State¶
When the hashOptions.enabled
and hashOptions.updateLocation
settings are enabled, the window.history
state will continually be replaced with a location value containing the id
attribute of the most recently shown panel element as the location's hash value.
Keyboard Support¶
The sections below outline the keyboard support for the tab and accordion views.
Tab View¶
Key | Function |
---|---|
Tab |
|
→ |
|
← |
|
Home |
|
End |
|
Space or Enter |
|
Shift + Tab |
|
Accordion View¶
Key | Function |
---|---|
Tab |
|
↓ |
|
↑ |
|
Home |
|
End |
|
Space or Enter |
|