Tabbed dropdown

This example shows how to build a custom plugin that opens a tabbed dropdown with a list tab and a settings tab containing form fields.

Code

<div id="entry-dropdown-with-tabs"></div>
const app = Redactor('#entry-dropdown-with-tabs', {
    plugins: ['dropdownTabs']
});
// Plugin example
class DropdownTabsPlugin {
    static defaultLang = {
        en: {
            dropdownTabs: {
                title: 'Tools',
                insert: 'Insert',
                settings: 'Settings',
                label: 'Label',
                labelPlaceholder: 'Block label...',
                blockType: 'Block type',
                paragraph: 'Paragraph',
                blockQuote: 'Quote',
                blockCode: 'Code',
                wrapInCard: 'Wrap in card',
                list: 'Bullet list'
            }
        }
    };

    constructor(app) {
        this.app = app;
    }

    start() {
        this.app.toolbar.add('dropdownTabs', {
            title: '## dropdownTabs.title ##',
            icon: '<svg ...>',
            command: 'dropdownTabs.open',
            position: { after: 'add' }
        });
    }

    open(params = {}, { button, el } = {}) {
        const form = this.app.form.create({
            name: 'dropdownTabs',
            data: {
                label: '',
                block: 'p',
                wrapInCard: false
            },
            items: {
                label: {
                    type: 'input',
                    label: '## dropdownTabs.label ##',
                    placeholder: '## dropdownTabs.labelPlaceholder ##'
                },
                block: {
                    type: 'select',
                    label: '## dropdownTabs.blockType ##',
                    options: [
                        { value: 'p', label: '## dropdownTabs.paragraph ##' },
                        { value: 'blockquote', label: '## dropdownTabs.blockQuote ##' },
                        { value: 'pre', label: '## dropdownTabs.blockCode ##' }
                    ]
                },
                wrapInCard: {
                    type: 'checkbox',
                    text: '## dropdownTabs.wrapInCard ##'
                },
                insert: {
                    type: 'button',
                    text: '## dropdownTabs.insert ##',
                    command: 'dropdownTabs.save',
                    role: 'primary',
                    fullwidth: true
                }
            }
        });

        this.app.dropdown.create('dropdownTabs', { width: '280px' });
        this.app.dropdown.addTab('insert', {
            title: '## dropdownTabs.insert ##',
            items: {
                paragraph: {
                    icon: false,
                    title: '## dropdownTabs.paragraph ##',
                    command: 'dropdownTabs.insert',
                    params: { html: '<p>New paragraph.</p>' }
                },
                list: {
                    icon: false,
                    title: '## dropdownTabs.list ##',
                    command: 'dropdownTabs.insert',
                    params: { html: '<ul><li>First item</li><li>Second item</li></ul>' }
                }
            }
        });
        this.app.dropdown.addTab('settings', {
            title: '## dropdownTabs.settings ##',
            form,
            focus: 'label'
        });
        this.app.dropdown.open(button || el);
    }

    insert(params = {}) {
        this.app.dropdown.close();

        const html = params.html;
        if (!html) return;

        const inserter = this.app.getService('inserter');
        inserter.insertHtml(html, { caret: 'end' });
    }

    save(data = {}) {
        this.app.dropdown.close();

        const label = String(data.label || '').trim();
        if (!label) return;

        let html = '';

        if (data.block === 'blockquote') {
            html = `<blockquote>${label}</blockquote>`;
        } else if (data.block === 'pre') {
            html = `<pre>${label}</pre>`;
        } else {
            html = `<p>${label}</p>`;
        }

        if (data.wrapInCard) {
            html = `<div class="card">${html}</div>`;
        }

        const inserter = this.app.getService('inserter');
        inserter.insertHtml(html, { caret: 'end' });
    }
}

Redactor.addPlugin('dropdownTabs', DropdownTabsPlugin);