A framework for attaching an ES6 class to a DOM element or collection of DOM elements, making it easier to organize the DOM interactions on your website.
A high-level overview on how it works. You ...
- provide a configuration and an ES6 class (which extends the base Component class).
- create a ComponentManager and call its
instanceComponents
method, passing it one or more component configurations created in the previous step.
The library will ...
- loop through every element match it finds for
data-component={componentName}
in your configuration and start an instance of the component class. - add each instance of the component to a global manifest on the
window
object, using a property provided when you instanced the manager.
This results in distinct (and encapsulated) functionality for each DOM element.
Install the js-component-framework and all the plugins:
npm install js-component-framework
Below is a basic set up for using the component framework without the included Aria plugins:
// Import the ES modules to be consumed by a bundler such as webpack append the '/es' to the end of the import statement.
import { Component } from 'js-component-framework/es';
/**
* Custom component which extends the base component class.
*/
class MyComponent extends Component {
/**
* Start the component
*/
constructor(config) {
super(config);
}
}
If you also want to use the entire framework using the CommonJS bundled scripts with Aria plugins use the default import:
import { Component, plugins } from 'js-component-framework';
It will contain the configuration file and the class.
Use the convention index.js
, as this will be the default export for the component. The configuration requires several properties:
name
- required - THIS MUST BE UNIQUE. An arbitrary name for the component. This is used to find component elements via data attributedata-component="componentName"
.name
is also used to store instances of the component in the global manifest.class
- required - The imported ES6 class for the component.querySelector
- optional - An object containing child selectors you'll need for the component logic. Each of these selectors should correspond to an element of which there is only one within the component (and will be queried using thequerySelector
JS method). The base Component class will automatically query these selectors and add them as properties to the class (using the provided object keys). For example, if you providetitle: '.site-title'
, this will be accessible in your component class asthis.children.title
.querySelectorAll
- optional - Same asquerySelector
, but will provide an array of each element it finds matching the selector.options
- optional - An object containing arbitrary additional options for the component. This could be a configuration for another JS library, values used for calculating styles, etc.
See the Header example for context.
To create a component, do the following at the top of the file:
import { Component } from 'js-component-framework';
If you are compiling your code with a bundler like webpack, only import what you need for a smaller footprint:
import { Component } from 'js-component-framework/es';
When writing a component class, are some rules you need to follow and some guidelines:
- You must provide a constructor. At minimum, the constructor should look like the following:
This constructor will be called when ComponentManager instances your component, your configuration passed in, then passed to the parent Component class using the
constructor(config) { super(config); }
super()
function. - Don't perform much logic within the class constructor. Instead, separate logic into distinct methods, each for a specific purpose. Use the constructor to call these methods and initialize any runtime component logic, event listeners, calculations, etc.
- Any method you might call from another component or use as a callback for an event listener should be bound to the component class using
this.myMethod = this.myMethod.bind(this)
. Methods can be called from other components using the component manager viamanager.callComponentMethod
. See the ComponentManager class for documentation.
See the Header example for context.
Import the component config in one of your entry point files, and pass that config to the ComponentManager's instanceComponents method.
Generally speaking, you'll want to instantiate your component in the footer or on DOMContentLoaded
.
import { ComponentManager } from `js-component-framework/es`;
import headerConfig from `./Components/Header`;
// Instantiate manager
// "namespace" can be any string to namespace this instance of the manager
const manager = new ComponentManager('namespace');
// Create component instances
document.addEventListener('DOMContentLoaded', () => {
manager.initComponents([
headerConfig
]);
});
Be sure you've added the appropriate data attribute containing your configured name
to the element(s) on which you want this component to be attached. For example, add data-component="siteHeader"
to instance the Header component, assuming you configured the Header component name
to be siteHeader
.