0.0.5 • Published 6 years ago

@zcomp/tabs v0.0.5

Weekly downloads
-
License
MIT
Repository
github
Last release
6 years ago

What is it?

A small library that implements lightweight tabs with vanilla JS. It can be configured with data attributes on DOM elements. You can have multiple tab groups on the same page. Tabs can save its state and restore it back (even automatically). Tabs can be navigated by hash part of the page location. Tab component can be used as a "wizard": it provides convenient function for activating prev/next tab.

Installation

npm i --save @zcomp/tabs

Usage

const tabs = require('@zcomp/tabs');
tabs.TabFactory.init();

First argument to init method is options object.

A very simple tabs markup:

<div class="js-tabs">
  <div class="js-tabs__labels">
    <button class="js-tabs__label">First tab</button>
    <button class="js-tabs__label">Second tab</button>
    <button class="js-tabs__label">Third tab</button>
  </div>

  <div class="js-tabs__tab">
    First tab content
  </div>
  <div class="js-tabs__tab">
    Second tab content
  </div>
  <div class="js-tabs__tab">
    Third tab content
  </div>
</div>

Here each .js-tabs__label button activates corresponding .js-tabs__tab element. First label activates the first tab, the second label activates the second tab, and so on in order or appearance in DOM. Activation means that a js-tabs__tab--active class is added to activated tab (and js-tabs__label--active to corresponding label). .js-tabs__labels element is optional, but it is convenient to have it in many cases.

Even .js-tabs__labels elements are optional, you should manually activate tabs with activateTab method in this case.

The library does not actually hides elements, it only adds classes. You should manually set styles for active and inactive tabs to hide it. For example:

.js-tabs__tab--inactive {
  display: none;
}

After a tabs component has been initialized, js-tabs--inited class is added to the root element of a component. You can use it to show all tabs until JS is loaded and executed (or hide all tabs).

Default active tab

When tabs component is initialized, some tab can be activated by default. In most cases, it is the first tab. But you can manually set the index for default active tab by adding data-tabs-active-index to the root element:

<div class="js-tabs" data-tabs-active-index="1">
  <div class="js-tabs__tab">
    This tab will be hidden initially
  </div>
  <div class="js-tabs__tab">
    This tab will be activated by default!
  </div>
</div>

Or you can manually add --active classes to the tab (or the corresponding label) you want to activate. For example:

<div class="js-tabs">
  <div class="js-tabs__tab">
    This tab will be hidden initially
  </div>
  <div class="js-tabs__tab js-tabs__tab--active">
    This tab will be activated by default!
  </div>
</div>

Only one tab (or one label) should have --active class. data-tabs-active-index has priority over --active classes.

Saving state

You can save state of a tabs component to local storage. It will only work if root element has id attribute. In this case a component is identified by the value of this attribute. Call saveState method to save state:

<div class="js-tabs" id="cool_tabs">
  <div class="js-tabs__tab"></div>
  <div class="js-tabs__tab"></div>
  <div class="js-tabs__tab"></div>
</div>
let tabs_comp = TabsFactory.fromRoot(document.getElementById('cool_tabs'));
tabs_comp.saveState();

Call restoreState to restore state back:

tabs_comp.restoreState();

If there are no record about a component with same id in local storage, current tabs state will remain untouched. If root element has data-tabs-auto-save-state attribute, state of the component will be automatically restored when creating the component, and saved whenever active tab changes. You can set defaultAutoSaveState option to true if you want all tabs by default have this behaviour.

Navigating by hash

To navigate to a tab by its hash, the tab should have id attribute. Root element of a component should have data-tabs-hash-navigate for it to work. For example:

<div class="js-tabs" data-tabs-hash-navigate>
  <div class="js-tabs__tab" id="first_tab"></div>
  <div class="js-tabs__tab" id="second_tab"></div>
</div>

<div class="js-tabs" data-tabs-hash-navigate>
  <div class="js-tabs__tab" id="third_tab"></div>
</div>

<div class="js-tabs">
  <div class="js-tabs__tab" id="fourth_tab"></div>
</div>

If location.hash is equal to #second_tab, the second tab in the first component will be activated. Same is true if location.hash is equal to #third_tab. But if location.hash is equal to #fourth_tab, no tab will be activated, because its root element has no data-tabs-hash-navigate attribute. Additionally, a hash-navigatable component will automatically change location.hash when some of its tabs are activated.

It can be confusing for a user to have two or more hash-navigatable tabs components on a same page (although this library allows it). But if you want all tabs to be hash-navigatable by default, set defaultHashNavigate option to true.

Events

Each tabs component fires custom events when its state changes. All these events bubble. before-tabs-change-state is fired on root element of the component. It can be cancelled (by calling preventDefault) by a handler. In this case, tab will not be switched. after-tabs-change-state is fired on root element after state has been changed.

One tab-change-state is fired on tab element, and another event with same name is fired on corresponding label element after a tab has been activated or deactivated.

Options

This library is highly configurable, and you can change almost everything. Options are given as argument to TabsFactory.init method (or any @zcomp/base methods that create components, refer to @zcomp/base docs). Option list below:

Option nameMeaningDefault value
rootSelectorSelector for root element of a component'.js-tabs'
tabsInitedClassClass to add to root element of initialized component'js-tabs--inited'
tabSelectorSelector for tab elements'.js-tabs__tab'
labelSelectorSelector for label elements'.js-tabs__label'
tabActiveClassClass to add to active tabs'js-tabs__tab--active'
labelActiveClassClass to add to active labels'js-tabs__label--active'
tabInactiveClassClass to add to inactive tabs'js-tabs__tab--inactive'
labelInactiveClassClass to add to inactive labels'js-tabs__label--inactive'
beforeTabsChangeStateEventName of event fired before tabs change state'before-tabs-change-state'
afterTabsChangeStateEventName of event fired after tabs change state'after-tabs-change-state'
tabChangeStateEventName of event fired after tab of label change state'tab-change-state'
defaultActiveIndexAttrAttribute for default index'data-tabs-active-index'
stateStorageKeyName of localStorage key used for storing state'zcomp_tabs_state'
autoSaveStateAttrAttribute for marking autosaving state components'data-tabs-auto-save-state'
defaultAutoSaveStateShould components autosave state by defaultfalse
hashNavigateAttrAttribute for marking hash-navigatable components'data-tabs-hash-navigate'
defaultHashNavigateShould components be hash-navigatable by defaultfalse

Methods and properties

Refer to generated documentation on information about methods and properties of Tabs objects.

Building documentation

Install typedoc:

npm i -g typedoc
typedoc index.ts --out ./docs

Now open docs/index.html file.