Interactive Patterns
Calcite Web includes a small (5KB gzipped) JavaScript library. calcite-web.js
is a lightweight and dependency-free library made to enable interactive behaviors for certain patterns and components.
Currently, the following components and patterns rely on calcite-web.js
:
The JavaScript library also includes helpers for "sticky" positioning and scroll events. You can read more about these in the interactive layout helpers section of the documentation.
Import calcite-web.js
Calcite Web can be imported using ES6 modules, CommonJS, AMD, or just a plain IIFE.
ES6 Module
If your bundler supports the ES6 module syntax you can import calcite as an ES6 module with named exports:
import * as calcite from 'calcite-web/es6';
calcite.init();
If your bundler uses the module
field in package.json
(Rollup, Webpack 2) leave off the es6
:
import * as calcite from 'calcite-web';
calcite.init();
With named imports you can also just import what you need:
import {drawer} from 'calcite-web';
drawer(); // initialize only instances of the drawer pattern
This is a great way to cut down on the size of your build!
CommonJS
var calcite = require('calcite-web');
calcite.init();
AMD
require(['path/to/calcite-web.js'], function(calcite){
// use calcite
calcite.init();
});
IIFE
If calcite-web.js
is used on a page with no module syntax, it will just attach itself to window.calcite
. Here is an example which initializes Calcite from a self-hosted CDN location:
<body>
...
<script src="https://<self-hosted-url>/files/calcite-web/1.2.5/js/calcite-web.min.js"></script>
<script>
calcite.init()
</script>
</body>
Initializing
While all of the examples above use the main init()
method, you can also initialize individual patterns. For example, initialize only instances of the tab pattern like this:
calcite.tabs();
Event Bus
The event bus is used to help interactive patterns communicate with each other and the rest of your application.
Along with a set of common bus events, each pattern has a set of channels that it emits on and listens for. These events can be emitted or listened for by the larger application.
You can trigger or react to events by using the on
and emit
methods on the bus:
// assuming calcite-web.js is available as calcite
// do something when a drawer opens
calcite.bus.on('drawer:open', function (options) {
console.log(options.id) // => "top-nav"
})
// open a drawer (must pass data-drawer name as "id")
calcite.bus.emit('drawer:open', {id: "top-nav"})
Common Event Channels
Event | Description | Emits |
---|---|---|
keyboard:return | The return key was pressed |
n/a |
keyboard:escape | The escape key was pressed |
n/a |
keyboard:space | The space key was pressed |
n/a |
keyboard:arrow:up | The ↑ key was pressed |
n/a |
keyboard:arrow:down | The ↓ key was pressed |
n/a |
keyboard:arrow:left | The ← key was pressed |
n/a |
keyboard:arrow:right | The → key was pressed |
n/a |
scrolling:at | The page is scrolling | ScrollYOffset |
Pattern-Specific Event Channels
Accordions
Event | Description | Emits | Function |
---|---|---|---|
accordion:bind | Binds Dom nodes on the page to their listeners | n/a | bindToggles() |
accordion:toggle | Toggles an accordion section open and closed. | {node: domNode} |
handleToggle() |
Drawers
Event | Description | Emits | Function |
---|---|---|---|
drawer:bind | Binds dom to event listeners | n/a | bindDrawers() |
drawer:open | Opens a drawer specified by data-drawer attribute | {id: drawerid} |
openDrawer() |
drawer:close | Closes a drawer specified by data-drawer attribute | {id: drawerid} |
closeDrawer() |
keyboard:escape | Closes all drawers on escape | n/a | closeDrawer() |
Dropdown
Event | Description | Emits | Function |
---|---|---|---|
dropdown:bind | Binds dom to event listeners | n/a | bindDropdowns() |
dropdown:toggle | Toggles a dropdown open and closed | {node: domNode} |
toggleDropdown() |
dropdown:close | Closes all the dropdowns | n/a | closeAllDropdowns() |
keyboard:escape | Closes all the dropdowns when the escape key is pressed. | n/a | closeAllDropdowns() |
Filter Dropdown
Many of the filter dropdown channels emit and listen for the following options object:
{
parent: domNode,
id: filterDropdownId,
item: domNode
}
Event | Description | Emits | Function |
---|---|---|---|
filterDropdown:bind | Binds the dom to event listeners | n/a | bindFilterDropdowns() |
filterDropdown:select | An item in the dropdown list has been selected. | Options Object | toggleItem() , emitActive() |
filterDropdown:select:remove | Removes a specific selection from the list of active items. | Options Object | removeItem() |
filterDropdown:active | Emits all the currently selected items from the component. | Options Object. Replaces item with active Array of items. |
drawActive() |
filterDropdown:active:clear | Clear all active items from the dropdown | Options Object | clearActive() |
filterDropdown:toggle | Toggle a dropdown open and closed | Options Object | toggleDropdown() |
filterDropdown:open | Open a specific dropdown | Options Object | openList() |
filterDropdown:close | Closes all dropdowns | n/a | closeList() |
keyboard:escape | Closes all dropdowns | n/a | closeList() |
Modal
Event | Description | Emits | Function |
---|---|---|---|
modal:bind | Binds dom to event listeners | n/a | bindModals() |
modal:open | Opens a modal specified by data-modal attribute | {id: modalid} |
openModal() |
modal:close | Closes open modal | n/a | closeModal() |
keyboard:escape | Closes all modals | n/a | closeModal() |
Sticky
Event | Description | Emits | Function |
---|---|---|---|
sticky:stick | Dom Node to stick in place | Dom Node | stickItem() |
sticky:unstick | Dom Node to unstick and return to normal | Dom Node | unstickItem() |
scrolling:at | Current offset y position on scroll | OffsetY Number |
scrollHandler() |
Tabs
Tab events emit and listen for an Options Object.
{
id: tabId // data-tab attribute
active: domNode
}
Event | Description | Emits | Function |
---|---|---|---|
tabs:bind | Binds dom to event listeners | n/a | bindTabs() |
tabs:active | A tab to set as active | Options Object | setTab() |
Utility Functions
calcite-web.js
also has methods for DOM traversal and manipulation. If the needs of a project are not too complex it can be used in place of jQuery, Dojo, or other large frameworks.
function | action |
---|---|
calcite.click() |
Returns standard interaction event (click). Touch support will be added soon. |
calcite.addEvent(domNode, event, fn) |
Adds a callback function to an event on an element. |
calcite.removeEvent(domNode, event, fn) |
Removes a callback function from an event on an element. |
calcite.eventTarget() |
Returns the target element of an event. |
calcite.preventDefault(event) |
Prevents default behavior of an event. |
calcite.stopPropagation(event) |
Stops an event from bubbling up the DOM tree. |
calcite.hasClass(event) |
Checks if an element has a specific class. Returns boolean. |
calcite.addClass(domNode, className) |
Adds one or more classes to an element. |
calcite.removeClass(domNode, classes) |
Removes one or more classes from an element. |
calcite.toggleClass(domNode, className) |
Toggles one class on an element. |
calcite.closest(domNode, classes) |
Returns closest element up the DOM tree matching a given class. Returns DOM node. |
calcite.nodeListToArray(domNodeList) |
Takes a DOM node list and returns an array. |
DOM Utilities
The following functions allow for basic DOM manipulation and traversal. These helpers are used by JavaScript dependent patterns, and can be included in any custom JavaScript in Calcite Web projects.
Events
calcite.click()
Returns interaction event for the current browser environment. Currently only returns 'click'
. Will be more useful when touch support is added.
var click = calcite.click(); // => 'click'
calcite.addEvent(domNode, event, fn)
Adds a callback function to an event on an element.
var click = calcite.click();
var node = document.querySelector('body');
function action (event) {
console.log('hola');
};
calcite.addEvent(node, click, action); // action will now fire when body is clicked
calcite.removeEvent(domNode, event, fn)
Removes a callback function from an event on an element.
var click = calcite.click();
var node = document.querySelector('body');
function action (event) {
console.log('hola');
};
calcite.addEvent(node, click, action); // action will now fire when body is clicked
calcite.removeEvent(node, event, action); // action has been removed from body click event
calcite.eventTarget(event)
Returns the target DOM node of an event.
var click = calcite.click();
var node = document.querySelector('body');
function action (event) {
var target = calcite.eventTarget(event);
console.log(target);
};
calcite.addEvent(node, click, action);
Clicking the body will now log the contents of the <body>
DOM node.
calcite.preventDefault(event)
Prevents default behavior of an event.
var click = calcite.click();
var node = document.getElementsByTagName('a')[0];
function action (event) {
calcite.preventDefault(event);
};
calcite.addEvent(node, click, action);
This will prevent the first <a>
DOM node in the document from performing its default behavior (sending the user to the link in its href
attribute).
calcite.stopPropagation(event)
Stops an event from bubbling up the DOM tree. This is useful if events have been bound to both a parent DOM node and a child DOM node.
var click = calcite.click();
var node = document.getElementsByTagName('a')[0];
function action (event) {
calcite.stopPropagation(event);
};
calcite.addEvent(node, click, action);
If, for example, the <body>
DOM node also has a function bound to a click event, this will prevent a user's click from triggering it.
Manipulation & Traversal
calcite.hasClass(node, class)
Checks if the node
currently has the provided class
. For example, given the following html:
<div class="apple" id="test"></div>
The hasClass
utility can be used as follows:
var node = document.getElementById('test');
var isApple = calcite.hasClass(node, 'apple');
console.log(isApple); // true
calcite.addClass(domNode, classes)
Adds one or more classes to a given element. Multiple classes should be passed as a space-separated string, like this:
var node = document.getElementById('test');
calcite.addClass(node, 'apples bananas oranges');
calcite.removeClass(domNode, classes)
Removes one or more classes from an element. Like addClass
, multiple classes should be separated with a space and passed as a single string:
var node = document.getElementById('test');
calcite.removeClass(node, 'apples bananas oranges');
calcite.toggleClass(domNode, className)
Adds the class to the element if it doesn't have the class, otherwise, remove it:
var node = document.querySelector('.test');
calcite.toggleClass(node, 'test'); // remove test class
calcite.toggleClass(node, 'test'); // add test class
calcite.closest(class, element)
Searches up the DOM tree to find the closest parent element with a given class.
var nodes = document.querySelector('.child-element');
function clickHandler (event) {
var closestNode = calcite.closest('parent-class', event.target);
}
for (var i = 0; i < nodes.length; i++) {
calcite.addEvent(nodes[i], calcite.click(), clickHandler);
}
calcite.nodeListToArray(domNodeList)
Turn a node list (usually returned from a query) into an array.
var nodes = document.getElementsByTagName('a');
var nodeArray = calcite.nodeListToArray(nodes);