From a4efa2b582490f5e9faf6500bc68f672f48251b2 Mon Sep 17 00:00:00 2001 From: Thomas Erbe Date: Thu, 5 Nov 2020 22:36:16 +0000 Subject: [PATCH] #102 WIP - First pass at adding panel tabs --- src/ConfigBag.js | 2 +- src/bulma.js | 1 + src/plugins/panelTabs.js | 143 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 src/plugins/panelTabs.js diff --git a/src/ConfigBag.js b/src/ConfigBag.js index 80451a2..12b5ab4 100644 --- a/src/ConfigBag.js +++ b/src/ConfigBag.js @@ -42,7 +42,7 @@ export default class ConfigBag { /** * Get a property by it's key. Returns the defaultValue if it doesn't exists * @param {string} key - * @param {mixed} defaultValue + * @param {mixed} defaultValue * @returns {mixed} */ get(key, defaultValue = null) { diff --git a/src/bulma.js b/src/bulma.js index d7c59ed..eaeee5a 100644 --- a/src/bulma.js +++ b/src/bulma.js @@ -9,5 +9,6 @@ import { Modal } from './plugins/modal'; import { Alert } from './plugins/alert'; import { File } from './plugins/file'; import { Tabs } from './plugins/tabs'; +import { PanelTabs } from './plugins/panelTabs'; export default Bulma; diff --git a/src/plugins/panelTabs.js b/src/plugins/panelTabs.js new file mode 100644 index 0000000..8fd0e70 --- /dev/null +++ b/src/plugins/panelTabs.js @@ -0,0 +1,143 @@ +import Bulma from '../core'; +import Plugin from '../plugin'; + +/** + * @module PanelTabs + * @since 0.12.0 + * @author Thomas Erbe + */ +export class PanelTabs extends Plugin { + /** + * Handle parsing the DOMs data attribute API. + * @param {HTMLElement} context The root element for this instance + * @returns {undefined} + */ + static parseDocument(context) { + let elements; + + if (typeof context.classList === 'object' && context.classList.contains('panel')) { + elements = [context]; + } else { + elements = context.querySelectorAll('.panel'); + } + + Bulma.each(elements, (element) => { + if(element.querySelector('.panel-tabs') === null) { + return; + } + + Bulma(element).panelTabs(); + }); + } + + /** + * Returns an object containing the default config for this plugin. + * @returns {object} The default config object. + */ + static defaultConfig() { + return {}; + } + + /** + * Plugin constructor + * @param {Object} config The config object for this plugin + * @return {this} The newly created instance + */ + constructor(config, root) { + super(config, root); + + /** + * The root tab element + * @param {HTMLElement} + */ + this.root = this.config.get('root'); + this.root.setAttribute('data-bulma-attached', 'attached'); + + /** + * The tab nav container + * @param {HTMLElement} + */ + this.nav = this.findNav(); + + /** + * The tab's nav items + * @param {HTMLElement[]} + */ + this.navItems = this.findNavItems(); + + /** + * The tab's content items + * @param {HTMLElement[]} + */ + this.contentItems = this.findContentItems(); + + this.setupNavEvents(); + + Bulma(this.root).data('panelTabs', this); + + this.trigger('init'); + } + + /** + * Find the tab navigation container. + * @returns {HTMLElement} The navigation container + */ + findNav() { + return this.root.querySelector('.panel-tabs'); + } + + /** + * Find each individual tab item + * @returns {NodeListOf} An array of the found items + */ + findNavItems() { + return this.nav.querySelectorAll('a'); + } + + /** + * Find each individual content item + * @returns {NodeListOf} An array of the found items + */ + findContentItems() { + return this.root.querySelectorAll('.panel-block[data-category]'); + } + + /** + * Setup the events to handle tab changing + * @returns {void} + */ + setupNavEvents() { + Bulma.each(this.navItems, (navItem) => { + navItem.addEventListener('click', () => { + this.setActive(navItem.getAttribute('data-target')); + }); + }); + } + + /** + * Show the correct category and mark the tab as active. + * + * @param {string|null} category The new category to set + */ + setActive(category) { + this.navItems.forEach((item) => { + if(item.getAttribute('data-target') === category) { + item.classList.add('is-active'); + } else { + item.classList.remove('is-active'); + } + }); + + this.contentItems.forEach((item) => { + if(item.getAttribute('data-category') === category || category === null) { + item.classList.remove('is-hidden'); + } else { + item.classList.add('is-hidden'); + } + }); + } +} + +Bulma.registerPlugin('panelTabs', PanelTabs); + +export default Bulma;