jodit
Version:
Jodit is an awesome and useful wysiwyg editor with filebrowser
125 lines (124 loc) • 4.01 kB
JavaScript
/*!
* Jodit Editor (https://xdsoft.net/jodit/)
* Released under MIT see LICENSE.txt in the project root for license information.
* Copyright (c) 2013-2025 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
*/
import { Component } from "../../../core/component/index.js";
import { Dom } from "../../../core/dom/dom.js";
import { isFunction } from "../../../core/helpers/checker/is-function.js";
import { attr } from "../../../core/helpers/utils/attr.js";
import { Button, UIElement } from "../../../core/ui/index.js";
/**
* Build tabs system
*
* @param tabs - PlainObject where 'key' will be tab's Title and `value` is tab's content
* @param state - You can use for this param any HTML element for remembering active tab
*
* @example
* ```javascript
* const editor = Jodit.make('#editor');
* const tabs = Jodit.modules.TabsWidget(editor, [
* { name: 'Images', content: '<div>Images</div>' },
* {
* name: 'Title 2',
* content: editor.c.fromHTML('<div>Some content</div>')
* },
* {
* name: 'Color Picker',
* content: ColorPickerWidget(
* editor,
* function (color) {
* box.style.color = color;
* },
* box.style.color
* )
* }
* ]);
* ```
*/
export const TabsWidget = (jodit, tabs, state) => {
const box = jodit.c.div('jodit-tabs');
const tabBox = jodit.c.div('jodit-tabs__wrapper');
const buttons = jodit.c.div('jodit-tabs__buttons');
attr(buttons, {
role: 'tablist',
'aria-orientation': 'horizontal'
});
const nameToTab = {};
const buttonList = [];
let firstTab = '';
box.appendChild(buttons);
box.appendChild(tabBox);
const setActive = (tab) => {
if (!nameToTab[tab]) {
return;
}
buttonList.forEach(b => {
b.state.activated = false;
});
Object.values(nameToTab).forEach(({ tab }) => tab.classList.remove('jodit-tab_active'));
nameToTab[tab].button.state.activated = true;
nameToTab[tab].tab.classList.add('jodit-tab_active');
};
tabs.forEach(({ icon, name, content }) => {
const tab = jodit.c.div('jodit-tab');
attr(tab, {
role: 'tabpanel'
});
const button = Button(jodit, icon || name, name);
button.state.role = 'tab';
// Stop lose the focus
jodit.e.on(button.container, 'pointerdown', (e) => e.preventDefault());
if (!firstTab) {
firstTab = name;
}
buttons.appendChild(button.container);
buttonList.push(button);
button.container.classList.add('jodit-tabs__button', 'jodit-tabs__button_columns_' + tabs.length);
if (!isFunction(content)) {
tab.appendChild(Component.isInstanceOf(content, UIElement)
? content.container
: content);
}
else {
tab.appendChild(jodit.c.div('jodit-tab_empty'));
}
tabBox.appendChild(tab);
button.onAction(() => {
setActive(name);
if (isFunction(content) && !Dom.isElement(content)) {
content.call(jodit);
}
if (state) {
state.activeTab = name;
}
return false;
});
nameToTab[name] = {
button,
tab
};
});
Object.values(nameToTab).forEach(({ button }) => {
button.container.style.width = (100 / tabs.length).toFixed(10) + '%';
});
const tab = !state || !state.activeTab || !nameToTab[state.activeTab]
? firstTab
: state.activeTab;
setActive(tab);
if (state) {
let activeTab = state.activeTab;
Object.defineProperty(state, 'activeTab', {
configurable: true,
enumerable: false,
get() {
return activeTab;
},
set(value) {
activeTab = value;
setActive(value);
}
});
}
return box;
};