Declarative Conventions

The Basics

An activable component is formed once an element is marked with the data-activable attribute. Specific descendants of this element will be given the active class when clicked, with a behavior similar to radio or checkbox inputs.

  • @data-activable is used to make all <li> children of an <ul> activable. The value of this attribute indicates the exact behavior of the component:
    • "1" stands for "1 and always 1 is active" and means that when one item is .active the other items of the same list lose this class (default value).
    • "01" stands for "0 or 1 is active" and has the same behavior as `"1"`, but the currently active item can be deactivated.
    • "0X" stands for "0 or X are active" and means that items are toggled without affecting other items of the same group.
    • "T" stands for "0 or 1 is temporarily active" and has the same behavior as `"01"`, but active items are deactivated on the next click on the document.
  • .active should be targeted in CSS to render the elements of an activable components according to their state.

Delegation

The principle of using @data-activable on an <ul> to make all of its children items activable can be extended to any markup using a data-delegate="<selector>" attribute.

To select activable elements amongst direct children of the element bearing this attribute, prefix your selector with >, example: >.cell will turn all direct children of this element with the class cell into activable elements.

Triggers

It is possible to restrict the click-sensitive area of an activable element by specifying a unique trigger using a data-trigger="<selector>" attribute.

To select the trigger amongst direct children of the activable element, prefix your selector with >, example: >:first-child will turn the very first child of activable elements into triggers.

Internal Relations

A common pattern is to have the state of an element be reflected on another one (in a tab component, the labels are in an activable <ul> and the content is in a different wrapper, but clicking a label makes the appropriate content active). This relation can be expressed by an internal link if either the activable element is an anchor or if it defines an anchor as its trigger.

JS API

Basic Methods

Activable( selector ) & A() alias

The JS API of Activable is similar to jQuery's one: all methods of the API are executed on a DOM element previously retrieved by passing a CSS selector to the basic Activable() or A() methods. It's also possible to pass a DOM element instead of the selector.

Since Activable only aims for compatibility with IE8 and better browsers, it assumes that document.querySelector() is available and these basic methods are just shorthands for querying the DOM from the document root.

Notable differences with jQuery's API:

  • the basic methods don't search for all elements matching the selector but only the first one,
  • the methods of the API are not chainable,
  • to maintain compatibility with IE8, only CSS2.1 selectors should be used, and jQuery specific selectors such as :first, :last or :eq() should never be used. There is a helpful list of CSS2.1 (IE8 and better browsers) and CSS3 (IE9 and better browsers) selectors available on quircksmode.

Event Listeners

Every time an element is activated or deactivated, the corresponding event fires on that element and bubbles up in the DOM tree. It is possible to listen to those events using the following methods.

.on( type, callback )

This method adds, on any DOM element, an event listener that will execute the callback when an internal event fires. The two types of internal events are "activate" and "deactivate", they fire after an activable elements changed state and bubble up in the DOM tree.

Anatomy of a callback: function( event, related ) { this }

  • event is the original click event that changed the state of the activable element,
  • related is the "related target", if an internal relation was defined for this activable element,
  • this, the context of the callback, is the activable DOM element that just changed state.
.toggle( activateCallback, deactivateCallback )

This method can be used as a shorthand to add an event listener for both event types at the same time.

.off( type, [callback] )

This method removes a previously added event listener from a DOM element. It's possible to remove a specific event listener by providing its type as well as the registered callback, or to remove all listeners of a certain type by omitting the callback parameter.

Direct Modifiers

.activate()

If the element isn't already active, this method gives it the active class and fires an internal activate event. If the behavior of the component is "1" or "01", other elements of the same group are deactivated.

.deactivate()

If the element is active and if the behavior of the component is "01" or "0X", this method removes the active class and fires an internal deactivate event.

.toggle()

.activate() an inactive element or .deactivate() an active element.

Iterative Modifiers

These methods work on activable lists only and are particularily useful to create carousels (or cycle) components.

Note that you can use the selector .active ~ li to differentiate the previous sibling items from the following one.

.next( loop )

This method deactivates the currently active element in an activable list and activates its next sibling.

By default, when the last element of the list is already active, this method has no effect. If loop is true, the last element is moved to the first position of the list and the next element is activated.

.prev( loop )

This method deactivates the currently active element in an activable list and activates its previous sibling.

By default, when the first element of the list is already active, this method has no effect. If loop is true, the first element is moved to the last position of the list and the previous element is activated.

.activate( index )

This method deactivates the currently active element in an activable list and activates the element at the given index.