Skip to content

Commit

Permalink
Feature/base plugin (#55)
Browse files Browse the repository at this point in the history
* Update build deps

* Create an abstract plugin class closes #39

* Update the navbar plugin to use the base plugin

* Update the accordion plugin to use the abstract plugin class

* Adjust order of options

* Update the calendar plugin to use the new plugin interface

* Update the dropdown plugin to use the plugin interface

* Update the file plugin to use the plugin interface

* Move static methods to the top of the file for consistency

* Update the dismissableComponent, message and notification to use the plugin interface.

* Update the modal plugin to use the updated plugin interface

* Update the tabs plugin to use the new plugin interface

* Rename the dom parsing method, and fix a bug introduced with the priority feature
  • Loading branch information
Thomas Erbe authored Oct 14, 2018
1 parent 4ce5bc0 commit a956bcc
Show file tree
Hide file tree
Showing 16 changed files with 430 additions and 321 deletions.
4 changes: 4 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"presets": ["env"],
"plugins": ["transform-object-rest-spread"]
}
6 changes: 3 additions & 3 deletions docs/docs/0.7/calendar.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ The simplest form of the calendar plugin is to show an interactive calendar. Thi
<script>
document.addEventListener('DOMContentLoaded', function() {
Bulma.create('calendar', {
element: document.getElementById('calendar-demo1'),
parent: document.getElementById('calendar-demo1'),
navButtons: true
});
});
Expand All @@ -53,15 +53,15 @@ To begin with, attaching the calendar to an input field couldn't be easier. Simp
<script>
document.addEventListener('DOMContentLoaded', function() {
Bulma.create('calendar', {
element: document.getElementById('calendar-demo3'),
parent: document.getElementById('calendar-demo3'),
navButtons: true
});
});
</script>

{% highlight javascript %}
Bulma.create('calendar', {
element: document.getElementById('calendar-demo3'),
parent: document.getElementById('calendar-demo3'),
navButtons: true
});
{% endhighlight %}
Expand Down
16 changes: 16 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.4",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-preset-env": "^1.6.1",
"bulma": "^0.7.1",
"eslint": "^4.19.0",
Expand Down
6 changes: 2 additions & 4 deletions src/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const Bulma = {
* @return {Object} The newly created plugin instance
*/
create(key, options) {
if(!key || !Bulma.plugins.handler.hasOwnProperty(key)) {
if(!key || !Bulma.plugins.hasOwnProperty(key)) {
throw new Error('[BulmaJS] A plugin with the key \''+key+'\' has not been registered.');
}

Expand Down Expand Up @@ -55,9 +55,7 @@ const Bulma = {
let plugins = this.findCompatiblePlugins(element);

plugins.forEach((plugin) => {
if(plugin.handler.hasOwnProperty('handleDomParsing')) {
plugin.handler.handleDomParsing(element);
}
plugin.handler.parse(element);
})
});
},
Expand Down
59 changes: 35 additions & 24 deletions src/dismissableComponent.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,32 @@
import Plugin from './plugin';

/**
* @module DismissableComponent
* @since 0.2.0
* @author Thomas Erbe <vizuaalog@gmail.com>
*/
export default class DismissableComponent {
export default class DismissableComponent extends Plugin {
/**
* Returns an object containing the default options for this plugin.
* @returns {object} The default options object.
*/
static defaultOptions() {
return {
isDismissable: false,
destroyOnDismiss: true,
element: null
};
}

/**
* Plugin constructor
* @param {string} name Plugin's name
* @param {Object} options Plugin's options
* @return {this} The new plugin instance
*/
constructor(name, options) {
super(options);

/**
* The name of this component, this will be used as the root class
* @type {string}
Expand All @@ -21,52 +37,47 @@ export default class DismissableComponent {
* Body text.
* @type {string}
*/
this.body = options.hasOwnProperty('body') ? options.body : '';

/**
* The parent element to inject HTML
*/
this.parent = options.hasOwnProperty('parent') ? options.parent : document.body;
this.body = this.option('body');

/**
* Color modifier.
* @type {string} Possible values are null, primary, info, success, warning, danger
*/
this.color = options.hasOwnProperty('color') ? options.color : '';
this.color = this.option('color');

/**
* How long to wait before auto dismissing the component.
* @type {int|null} If null component must be dismissed manually.
*/
this.dismissInterval = options.hasOwnProperty('dismissInterval') ? this.createDismissInterval(options.dismissInterval) : null;
this.dismissInterval = this.option('dismissInterval') ? this.createDismissInterval(this.option('dismissInterval')) : null;

/**
* Does this component have a dismiss button?
* @type {Boolean}
*/
this.isDismissable = options.hasOwnProperty('isDismissable') ? options.isDismissable : false;
this.isDismissable = this.option('isDismissable');

/**
* Should this component be destroyed when it is dismissed.
* @type {Boolean}
*/
this.destroyOnDismiss = options.hasOwnProperty('destroyOnDismiss') ? options.destroyOnDismiss : true;
this.destroyOnDismiss = this.option('destroyOnDismiss');

/**
* The root element.
* @type {HTMLElement|null} If this is not provided a new element will be created.
*/
this.root = options.hasOwnProperty('element') ? options.element : null;
this.element = this.option('element');

/**
* The element used to close the component.
* @type {HTMLElement}
*/
this.closeButton = options.hasOwnProperty('closeButton') ? options.closeButton : this.createCloseButton();
this.closeButton = this.option('closeButton', this.createCloseButton());

if(!this.root) {
if(!this.element) {
this.createRootElement();
this.parent.appendChild(this.root);
this.parent.appendChild(this.element);
}

if(this.body) {
Expand All @@ -83,9 +94,9 @@ export default class DismissableComponent {
* @return {undefined}
*/
createRootElement() {
this.root = document.createElement('div');
this.element = document.createElement('div');

this.root.classList.add(this.name);
this.element.classList.add(this.name);
this.hide();
}

Expand All @@ -94,23 +105,23 @@ export default class DismissableComponent {
* @return {undefined}
*/
show() {
this.root.classList.remove('is-hidden');
this.element.classList.remove('is-hidden');
}

/**
* Hide the component.
* @return {undefined}
*/
hide() {
this.root.classList.add('is-hidden');
this.element.classList.add('is-hidden');
}

/**
* Insert the body text into the component.
* @return {undefined}
*/
insertBody() {
this.root.innerHTML = this.body;
this.element.innerHTML = this.body;
}

/**
Expand Down Expand Up @@ -141,7 +152,7 @@ export default class DismissableComponent {
* @return {undefined}
*/
prependCloseButton() {
this.root.insertBefore(this.closeButton, this.root.firstChild);
this.element.insertBefore(this.closeButton, this.element.firstChild);
}

/**
Expand Down Expand Up @@ -169,7 +180,7 @@ export default class DismissableComponent {
* @return {undefined}
*/
setColor() {
this.root.classList.add('is-' + this.color);
this.element.classList.add('is-' + this.color);
}

/**
Expand All @@ -183,8 +194,8 @@ export default class DismissableComponent {

clearInterval(this.dismissInterval);

this.parent.removeChild(this.root);
this.parent.removeChild(this.element);
this.parent = null;
this.root = null;
this.element = null;
}
}
41 changes: 39 additions & 2 deletions src/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,49 @@
* @author Thomas Erbe <vizuaalog@gmail.com>
*/
export default class Plugin {
/**
* Helper method used by the Bulma core to create a new instance.
* @param {Object} options The options object for this instance
* @return {Plugin|boolean} The newly created instance or false if method is not used
*/
static create(options) {
return false;
}

/**
* Handle parsing the DOM elements.
* @param {HTMLElement} element The root element for this instance
* @return {Plugin|boolean} The new plugin instance, or false if method is not used
*/
static parse(element) {
return false
}

/**
* Returns a string containing the element class this plugin supports.
* @returns {string} The class name.
* @throws {Error} Thrown if this method has not been replaced.
*/
static getRootClass() {
throw new Error('The getRootClass method should have been replaced by the plugin being created.');
}

/**
* Returns an object containing the default options for this plugin.
* @returns {object} The default options object.
*/
static defaultOptions() {
return {};
}

/**
* Create a plugin.
* @param {object} options The options for this plugin
*/
constructor(options) {
this.options = options || {};
constructor(options = {}) {
this.options = {...this.constructor.defaultOptions(), ...options};

this.parent = this.option('parent', document.body);
}

/**
Expand Down
Loading

0 comments on commit a956bcc

Please sign in to comment.