# blockenberg/2.0.7/blocks/split-panel/index.js

Blockenberg — 600+ Advanced Gutenberg Blocks &amp; AI Agent for WordPress Block Editor, version 2.0.7. 164 lines.

- Page: https://pluginprobe.com/plugins/blockenberg/2.0.7/code/blocks/split-panel/index.js
- Raw: https://pluginprobe.com/plugins/blockenberg/2.0.7/raw/blocks/split-panel/index.js
- Modified: 2026-03-06T12:32:40+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/blockenberg/2.0.7/code/blocks/split-panel/index.js#L10-L20`.

```javascript
( function () {
    const el = window.wp.element.createElement;
    const { registerBlockType } = window.wp.blocks;
    const { InspectorControls, useBlockProps, PanelColorSettings } = window.wp.blockEditor;
    const { PanelBody, RangeControl, ToggleControl, TextControl, Button } = window.wp.components;
    const { __ } = window.wp.i18n;

    /* Lazy typography helpers */
    let _tc, _tv;
    function getTypoControl() { return _tc || (_tc = window.bkbgTypographyControl); }
    function getTypoCssVars()  { return _tv || (_tv = window.bkbgTypoCssVars); }
    const IP = function () { return window.bkbgIconPicker; };

    function renderIconPart(type, charVal, dashicon, imageUrl, dashiconColor, forSave) {
        if (!type || type === 'custom-char') return charVal;
        var fn = forSave ? IP().buildSaveIcon : IP().buildEditorIcon;
        return fn(type, charVal, dashicon, imageUrl, dashiconColor);
    }

    function buildWrapStyle(a) {
        const tv = getTypoCssVars();
        const s = {
            background: a.bgColor,
            boxSizing: 'border-box',
            '--bksp-hd-sz': (a.titleFontSize + 2) + 'px',
            '--bksp-tt-sz': a.titleFontSize + 'px',
            '--bksp-tt-w':  String(a.titleFontWeight),
            '--bksp-tt-lh': String(a.titleLineHeight),
            '--bksp-bd-sz': a.fontSize + 'px',
            '--bksp-it-sz': a.itemFontSize + 'px',
            '--bksp-it-w':  String(a.itemFontWeight),
            '--bksp-it-lh': String(a.itemLineHeight),
        };
        if (tv) {
            Object.assign(s, tv(a.headingTypo, '--bksp-hd-'));
            Object.assign(s, tv(a.titleTypo,   '--bksp-tt-'));
            Object.assign(s, tv(a.bodyTypo,    '--bksp-bd-'));
            Object.assign(s, tv(a.itemTypo,    '--bksp-it-'));
        }
        return s;
    }

    // ── Panel component ───────────────────────────────────────────────────────
    function Panel( { icon, iconType, iconDashicon, iconImageUrl, iconDashiconColor, forSave, iconSize, title, body, items, bg, accent, textColor, titleColor, padding, borderRadius, side } ) {
        return el( 'div', { className: 'bkbg-sp-panel bkbg-sp-panel--' + side, style: {
            flex: '1 1 0',
            background: bg,
            borderRadius: borderRadius + 'px',
            padding: padding + 'px',
            borderLeft: '4px solid ' + accent,
            boxSizing: 'border-box',
        } },
            // Icon + title
            el( 'div', { style: { display: 'flex', alignItems: 'center', gap: 10, marginBottom: 14 } },
                el( 'span', { className: 'bkbg-sp-icon', style: { fontSize: iconSize + 'px', lineHeight: 1 } }, renderIconPart(iconType, icon, iconDashicon, iconImageUrl, iconDashiconColor, forSave) ),
                el( 'strong', { className: 'bkbg-sp-title', style: { color: titleColor } }, title ),
            ),
            // Body
            body && el( 'p', { className: 'bkbg-sp-body', style: { color: textColor, margin: '0 0 14px' } }, body ),
            // Items
            items && items.length > 0 && el( 'ul', { style: { listStyle: 'none', margin: 0, padding: 0, display: 'flex', flexDirection: 'column', gap: 8 } },
                items.map( ( item, i ) =>
                    el( 'li', { key: i, className: 'bkbg-sp-item', style: { display: 'flex', alignItems: 'flex-start', gap: 8, color: textColor } },
                        el( 'span', { style: { flexShrink: 0, width: 8, height: 8, borderRadius: '50%', background: accent, marginTop: 6 } } ),
                        el( 'span', {}, item ),
                    )
                ),
            ),
        );
    }

    // ── Renderer ──────────────────────────────────────────────────────────────
    function renderSplitPanel( a, forSave ) {
        return el( 'div', { className: 'bkbg-sp-row', style: { display: 'flex', gap: a.showDivider ? 0 : 20, alignItems: 'stretch' } },
            el( Panel, { side: 'left',  icon: a.leftIcon,  iconType: a.leftIconType, iconDashicon: a.leftIconDashicon, iconImageUrl: a.leftIconImageUrl, iconDashiconColor: a.leftIconDashiconColor, forSave: forSave, iconSize: a.iconSize, title: a.leftTitle,  body: a.leftBody,  items: a.leftItems,  bg: a.leftBg,  accent: a.leftAccent,  textColor: a.textColor, titleColor: a.titleColor, padding: a.padding, borderRadius: a.borderRadius } ),
            a.showDivider && el( 'div', { className: 'bkbg-sp-divider', style: { width: 1, margin: '0 20px', background: 'linear-gradient(to bottom, transparent, #d1d5db 30%, #d1d5db 70%, transparent)', flexShrink: 0, alignSelf: 'stretch' } } ),
            el( Panel, { side: 'right', icon: a.rightIcon, iconType: a.rightIconType, iconDashicon: a.rightIconDashicon, iconImageUrl: a.rightIconImageUrl, iconDashiconColor: a.rightIconDashiconColor, forSave: forSave, iconSize: a.iconSize, title: a.rightTitle, body: a.rightBody, items: a.rightItems, bg: a.rightBg, accent: a.rightAccent, textColor: a.textColor, titleColor: a.titleColor, padding: a.padding, borderRadius: a.borderRadius } ),
        );
    }

    // ── Item list helper ──────────────────────────────────────────────────────
    function ItemListEditor( { label, items, setItems } ) {
        return el( PanelBody, { title: label, initialOpen: false },
            el( Button, { variant: 'secondary', style: { marginBottom: 8 }, onClick: () => setItems( [ ...( items || [] ), 'New item' ] ) }, __( '+ Add Item', 'blockenberg' ) ),
            ( items || [] ).map( ( item, i ) =>
                el( 'div', { key: i, style: { display: 'flex', gap: 4, marginBottom: 4, alignItems: 'center' } },
                    el( TextControl, { value: item, style: { flex: 1, margin: 0 }, onChange: v => setItems( items.map( ( x, j ) => j === i ? v : x ) ) } ),
                    el( Button, { isDestructive: true, isSmall: true, onClick: () => setItems( items.filter( ( _, j ) => j !== i ) ) }, '✕' ),
                )
            ),
        );
    }

    // ── Block ─────────────────────────────────────────────────────────────────
    registerBlockType( 'blockenberg/split-panel', {
        edit: function ( props ) {
            const { attributes: a, setAttributes } = props;
            const blockProps = useBlockProps( { className: 'bkbg-sp-wrap', style: buildWrapStyle(a) } );

            return el( 'div', blockProps,
                el( InspectorControls, {},

                    el( PanelBody, { title: __( 'Settings', 'blockenberg' ), initialOpen: true },
                        el( ToggleControl, { label: __( 'Show Heading', 'blockenberg' ),  checked: a.showTitle,  onChange: v => setAttributes( { showTitle:  v } ) } ),
                        a.showTitle && el( TextControl, { label: __( 'Heading', 'blockenberg' ), value: a.title, onChange: v => setAttributes( { title: v } ) } ),
                        el( ToggleControl, { label: __( 'Show Divider', 'blockenberg' ), checked: a.showDivider, onChange: v => setAttributes( { showDivider: v } ) } ),
                    ),

                    el( PanelBody, { title: __( 'Left Panel', 'blockenberg' ), initialOpen: false },
                        el( IP().IconPickerControl, IP().iconPickerProps( a, setAttributes, { charAttr: 'leftIcon', typeAttr: 'leftIconType', dashiconAttr: 'leftIconDashicon', imageUrlAttr: 'leftIconImageUrl', colorAttr: 'leftIconDashiconColor' } ) ),
                        el( TextControl, { label: __( 'Title', 'blockenberg' ),         value: a.leftTitle, onChange: v => setAttributes( { leftTitle: v } ) } ),
                        el( TextControl, { label: __( 'Body Text', 'blockenberg' ),     value: a.leftBody,  onChange: v => setAttributes( { leftBody:  v } ) } ),
                        el( ItemListEditor, { label: __( 'Bullet Items', 'blockenberg' ), items: a.leftItems, setItems: v => setAttributes( { leftItems: v } ) } ),
                    ),

                    el( PanelBody, { title: __( 'Right Panel', 'blockenberg' ), initialOpen: false },
                        el( IP().IconPickerControl, IP().iconPickerProps( a, setAttributes, { charAttr: 'rightIcon', typeAttr: 'rightIconType', dashiconAttr: 'rightIconDashicon', imageUrlAttr: 'rightIconImageUrl', colorAttr: 'rightIconDashiconColor' } ) ),
                        el( TextControl, { label: __( 'Title', 'blockenberg' ),         value: a.rightTitle, onChange: v => setAttributes( { rightTitle: v } ) } ),
                        el( TextControl, { label: __( 'Body Text', 'blockenberg' ),     value: a.rightBody,  onChange: v => setAttributes( { rightBody:  v } ) } ),
                        el( ItemListEditor, { label: __( 'Bullet Items', 'blockenberg' ), items: a.rightItems, setItems: v => setAttributes( { rightItems: v } ) } ),
                    ),

                    el( PanelBody, { title: __( 'Style', 'blockenberg' ), initialOpen: false },
                        el( RangeControl, { label: __( 'Border Radius', 'blockenberg' ), value: a.borderRadius, onChange: v => setAttributes( { borderRadius: v } ), min: 0, max: 32 } ),
                        el( RangeControl, { label: __( 'Padding', 'blockenberg' ),        value: a.padding,      onChange: v => setAttributes( { padding:      v } ), min: 12, max: 56 } ),
                        el( RangeControl, { label: __( 'Icon Size', 'blockenberg' ),      value: a.iconSize,     onChange: v => setAttributes( { iconSize:     v } ), min: 16, max: 64 } ),
                    ),

                    
        el( PanelBody, { title: __( 'Typography', 'blockenberg' ), initialOpen: false },
            getTypoControl() && getTypoControl()({ label: __('Heading', 'blockenberg'), value: a.headingTypo, onChange: v => setAttributes({ headingTypo: v }) }),
            getTypoControl() && getTypoControl()({ label: __('Panel title', 'blockenberg'), value: a.titleTypo, onChange: v => setAttributes({ titleTypo: v }) }),
            getTypoControl() && getTypoControl()({ label: __('Body', 'blockenberg'), value: a.bodyTypo, onChange: v => setAttributes({ bodyTypo: v }) }),
            getTypoControl() && getTypoControl()({ label: __('Item', 'blockenberg'), value: a.itemTypo, onChange: v => setAttributes({ itemTypo: v }) })
        ),
el( PanelColorSettings, {
                        title: __( 'Colors', 'blockenberg' ), initialOpen: false,
                        colorSettings: [
                            { label: __( 'Outer Background', 'blockenberg' ), value: a.bgColor,     onChange: v => setAttributes( { bgColor:     v || '#ffffff' } ) },
                            { label: __( 'Text', 'blockenberg' ),             value: a.textColor,   onChange: v => setAttributes( { textColor:   v || '#374151' } ) },
                            { label: __( 'Title', 'blockenberg' ),            value: a.titleColor,  onChange: v => setAttributes( { titleColor:  v || '#111827' } ) },
                            { label: __( 'Left Background', 'blockenberg' ),  value: a.leftBg,      onChange: v => setAttributes( { leftBg:      v || '#fef2f2' } ) },
                            { label: __( 'Left Accent', 'blockenberg' ),      value: a.leftAccent,  onChange: v => setAttributes( { leftAccent:  v || '#ef4444' } ) },
                            { label: __( 'Right Background', 'blockenberg' ), value: a.rightBg,     onChange: v => setAttributes( { rightBg:     v || '#f0fdf4' } ) },
                            { label: __( 'Right Accent', 'blockenberg' ),     value: a.rightAccent, onChange: v => setAttributes( { rightAccent: v || '#10b981' } ) },
                        ]
                    } ),
                ),

                a.showTitle && a.title && el( 'h3', { className: 'bkbg-sp-heading', style: { color: a.titleColor, margin: '0 0 20px' } }, a.title ),
                renderSplitPanel( a ),
            );
        },

        save: function ( { attributes: a } ) {
            const blockProps = useBlockProps.save( { className: 'bkbg-sp-wrap', style: buildWrapStyle(a) } );
            return el( 'div', blockProps,
                ( a.showTitle && a.title ) ? el( 'h3', { className: 'bkbg-sp-heading', style: { color: a.titleColor, margin: '0 0 20px' } }, a.title ) : null,
                renderSplitPanel( a, true ),
            );
        },
    } );
}() );

```
