/** * [[include:modules/widget/tabs/README.md]] * @packageDocumentation * @module modules/widget/tabs */ import './tabs.less'; import type { IDictionary, IJodit, IUIButton } from 'jodit/types'; import { $$, isFunction } from 'jodit/core/helpers'; import { Button, UIElement } from 'jodit/core/ui'; import { Component } from 'jodit/core/component'; export interface TabOption { icon?: string; name: string; content: HTMLElement | (() => void) | UIElement; } /** * 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 * let tabs = Jodit.modules.TabsWidget(editor, [ * {name: 'Images', content: '
Images
'}, * {name: 'Title 2': Jodit.modules.Helpers.dom('
Some content
')}, * {name: 'Color Picker': ColorPickerWidget(editor, function (color) { * box.style.color = color; * }, box.style.color)}, * ]); * ``` */ export const TabsWidget = ( jodit: IJodit, tabs: TabOption[], state?: { __activeTab: string } ): HTMLDivElement => { const box = jodit.c.div('jodit-tabs'), tabBox = jodit.c.div('jodit-tabs__wrapper'), buttons = jodit.c.div('jodit-tabs__buttons'), // title = jodit.c.div('jodit-tabs__title'), nameToTab: IDictionary<{ button: IUIButton; tab: HTMLElement; }> = {}, buttonList: IUIButton[] = []; let firstTab: string = '', tabCount: number = 0; // 탭이 1개일 경우, 탭 내용만 추가합니다. box.appendChild(buttons); // if (tabs.length !== 1) { // box.appendChild(buttons); // } else { // box.appendChild(title); // tabBox.style.paddingTop = '52px'; // title.innerHTML = jodit.i18n(tabs[0].name); // } box.appendChild(tabBox); const setActive = (tab: string): void => { if (!nameToTab[tab]) { return; } buttonList.forEach(b => { b.state.activated = false; }); $$('.jodit-tab', tabBox).forEach(a => { a.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'), button = Button(jodit, icon || name, name); // Stop lose the focus jodit.e.on(button.container, 'mousedown', (e: MouseEvent) => 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)) { // @ts-ignore content.call(jodit); } if (state) { state.__activeTab = name; } return false; }); nameToTab[name] = { button, tab }; tabCount += 1; }); if (!tabCount) { return box; } $$('a', buttons).forEach(a => { a.style.width = (100 / tabCount).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: string) { __activeTab = value; setActive(value); } }); } return box; };