# blockenberg/2.0.7/blocks/content-menu/index.js

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

- Page: https://pluginprobe.com/plugins/blockenberg/2.0.7/code/blocks/content-menu/index.js
- Raw: https://pluginprobe.com/plugins/blockenberg/2.0.7/raw/blocks/content-menu/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/content-menu/index.js#L10-L20`.

```javascript
( function () {
    var el = wp.element.createElement;
    var __ = wp.i18n.__;
    var useState = wp.element.useState;
    var registerBlockType = wp.blocks.registerBlockType;
    var InspectorControls = wp.blockEditor.InspectorControls;
    var useBlockProps = wp.blockEditor.useBlockProps;
    var PanelColorSettings = wp.blockEditor.PanelColorSettings;
    var PanelBody = wp.components.PanelBody;
    var ToggleControl = wp.components.ToggleControl;
    var RangeControl = wp.components.RangeControl;
    var SelectControl = wp.components.SelectControl;
    var TextControl = wp.components.TextControl;
    var Button = wp.components.Button;
    var Fragment = wp.element.Fragment;
    var IP = function () { return window.bkbgIconPicker; };

    var _TC, _tv;
    Object.defineProperty(window, '_bkbgCMgetTC', { get: function () { return _TC || (_TC = window.bkbgTypographyControl); } });
    Object.defineProperty(window, '_bkbgCMgetTV', { get: function () { return _tv || (_tv = window.bkbgTypoCssVars); } });

    registerBlockType('blockenberg/content-menu', {
        edit: function (props) {
            var attr = props.attributes;
            var set = props.setAttributes;
            var TC = window._bkbgCMgetTC;
            var tv = window._bkbgCMgetTV || function () { return {}; };
            var links = attr.links || [];

            var activeState = useState(0);
            var activeIdx = activeState[0];
            var setActiveIdx = activeState[1];

            function updateLink(idx, field, val) {
                var updated = links.map(function (lk, i) {
                    if (i !== idx) return lk;
                    var p = {}; p[field] = val;
                    return Object.assign({}, lk, p);
                });
                set({ links: updated });
            }

            function addLink() {
                set({ links: links.concat([{ label: 'New Section', anchor: 'section-' + (links.length + 1), icon: '📌', iconType: 'custom-char', iconDashicon: '', iconImageUrl: '' }]) });
            }

            function removeLink(idx) {
                set({ links: links.filter(function (_, i) { return i !== idx; }) });
            }

            var isVertical = attr.position !== 'inline' || attr.menuStyle === 'list' || attr.menuStyle === 'dots';
            var isDots = attr.menuStyle === 'dots';

            /* Style helpers */
            function linkStyle(isActive) {
                var base = { cursor: 'pointer', display: 'flex', alignItems: 'center', gap: '8px', transition: 'all 0.2s', textDecoration: 'none' };
                if (attr.menuStyle === 'pills') {
                    base.padding = '7px 16px';
                    base.borderRadius = attr.borderRadius + 'px';
                    base.background = isActive ? attr.activeBg : 'transparent';
                    base.color = isActive ? attr.activeColor : attr.linkColor;
                } else if (attr.menuStyle === 'list') {
                    base.padding = '9px 14px';
                    base.borderLeft = isActive ? ('3px solid ' + attr.accentColor) : '3px solid transparent';
                    base.color = isActive ? attr.accentColor : attr.linkColor;
                } else if (attr.menuStyle === 'tabs') {
                    base.padding = '9px 18px';
                    base.borderBottom = isActive ? ('2px solid ' + attr.accentColor) : '2px solid transparent';
                    base.color = isActive ? attr.accentColor : attr.linkColor;
                } else if (attr.menuStyle === 'dots') {
                    base.padding = '4px';
                    base.justifyContent = 'center';
                }
                return base;
            }

            /* Inspector */
            var inspector = el(InspectorControls, {},
                el(PanelBody, { title: __('Menu Settings', 'blockenberg'), initialOpen: true },
                    el(SelectControl, {
                        label: __('Position', 'blockenberg'),
                        value: attr.position,
                        options: [
                            { label: 'Inline (inside content)', value: 'inline' },
                            { label: 'Fixed — Left', value: 'fixed-left' },
                            { label: 'Fixed — Right', value: 'fixed-right' }
                        ],
                        onChange: function (v) { set({ position: v }); },
                        __nextHasNoMarginBottom: true
                    }),
                    el(SelectControl, {
                        label: __('Style', 'blockenberg'),
                        value: attr.menuStyle,
                        options: [
                            { label: 'Pills (rounded buttons)', value: 'pills' },
                            { label: 'List (left accent line)', value: 'list' },
                            { label: 'Tabs (underline)', value: 'tabs' },
                            { label: 'Dots (compact)', value: 'dots' }
                        ],
                        onChange: function (v) { set({ menuStyle: v }); },
                        __nextHasNoMarginBottom: true
                    }),
                    el(ToggleControl, { label: __('Show Icons', 'blockenberg'), checked: attr.showIcons, onChange: function (v) { set({ showIcons: v }); }, __nextHasNoMarginBottom: true }),
                    el(ToggleControl, { label: __('Show Numbers', 'blockenberg'), checked: attr.showNumbers, onChange: function (v) { set({ showNumbers: v }); }, __nextHasNoMarginBottom: true }),
                    el(ToggleControl, { label: __('Smooth Scroll on Click', 'blockenberg'), checked: attr.animateScroll, onChange: function (v) { set({ animateScroll: v }); }, __nextHasNoMarginBottom: true }),
                    attr.position !== 'inline' && el(RangeControl, {
                        label: __('Vertical Position (vh %)', 'blockenberg'),
                        value: attr.fixedTop, min: 10, max: 90,
                        onChange: function (v) { set({ fixedTop: v }); },
                        __nextHasNoMarginBottom: true
                    }),
                    attr.position !== 'inline' && el(RangeControl, {
                        label: __('Edge Offset (px)', 'blockenberg'),
                        value: attr.fixedOffset, min: 8, max: 80,
                        onChange: function (v) { set({ fixedOffset: v }); },
                        __nextHasNoMarginBottom: true
                    }),
                    el(RangeControl, {
                        label: __('Menu Width (px)', 'blockenberg'),
                        value: attr.menuWidth, min: 100, max: 320,
                        onChange: function (v) { set({ menuWidth: v }); },
                        __nextHasNoMarginBottom: true
                    }),
                    el(RangeControl, {
                        label: __('Border Radius (px)', 'blockenberg'),
                        value: attr.borderRadius, min: 0, max: 24,
                        onChange: function (v) { set({ borderRadius: v }); },
                        __nextHasNoMarginBottom: true
                    }),
                    el(RangeControl, {
                        label: __('Padding Top (px)', 'blockenberg'),
                        value: attr.paddingTop, min: 0, max: 200,
                        onChange: function (v) { set({ paddingTop: v }); },
                        __nextHasNoMarginBottom: true
                    }),
                    el(RangeControl, {
                        label: __('Padding Bottom (px)', 'blockenberg'),
                        value: attr.paddingBottom, min: 0, max: 200,
                        onChange: function (v) { set({ paddingBottom: v }); },
                        __nextHasNoMarginBottom: true
                    })
                ),
                /* Links config */
                el(PanelBody, { title: __('Links', 'blockenberg'), initialOpen: true },
                    links.map(function (lk, idx) {
                        return el('div', { key: idx, style: { borderBottom: '1px solid #e5e7eb', marginBottom: '10px', paddingBottom: '10px' } },
                            el(TextControl, { label: __('Label', 'blockenberg'), value: lk.label, onChange: function (v) { updateLink(idx, 'label', v); }, __nextHasNoMarginBottom: true }),
                            el(TextControl, { label: __('Anchor ID (no #)', 'blockenberg'), value: lk.anchor, onChange: function (v) { updateLink(idx, 'anchor', v.replace('#', '')); }, placeholder: 'section-id', __nextHasNoMarginBottom: true }),
                            attr.showIcons && el(IP().IconPickerControl, {
                                iconType: lk.iconType, customChar: lk.icon, dashicon: lk.iconDashicon, imageUrl: lk.iconImageUrl,
                                onChangeType: function (v) { updateLink(idx, 'iconType', v); },
                                onChangeChar: function (v) { updateLink(idx, 'icon', v); },
                                onChangeDashicon: function (v) { updateLink(idx, 'iconDashicon', v); },
                                onChangeImageUrl: function (v) { updateLink(idx, 'iconImageUrl', v); }
                            }),
                            el(Button, { onClick: function () { removeLink(idx); }, variant: 'link', isDestructive: true, isSmall: true, style: { marginTop: '4px' } }, __('Remove', 'blockenberg'))
                        );
                    }),
                    el(Button, { onClick: addLink, variant: 'primary', isSmall: true }, __('+ Add Link', 'blockenberg'))
                ),
                el(PanelColorSettings, {
                    title: __('Colors', 'blockenberg'), initialOpen: false,
                    colorSettings: [
                        { value: attr.bgColor, onChange: function (v) { set({ bgColor: v || '#ffffff' }); }, label: __('Menu Background', 'blockenberg') },
                        { value: attr.linkColor, onChange: function (v) { set({ linkColor: v || '#374151' }); }, label: __('Link Text', 'blockenberg') },
                        { value: attr.activeBg, onChange: function (v) { set({ activeBg: v || '#6366f1' }); }, label: __('Active Background', 'blockenberg') },
                        { value: attr.activeColor, onChange: function (v) { set({ activeColor: v || '#ffffff' }); }, label: __('Active Text', 'blockenberg') },
                        { value: attr.borderColor, onChange: function (v) { set({ borderColor: v || '#e5e7eb' }); }, label: __('Border', 'blockenberg') },
                        { value: attr.accentColor, onChange: function (v) { set({ accentColor: v || '#6366f1' }); }, label: __('Accent', 'blockenberg') }
                    ]
                }),
                el(PanelBody, { title: __('Typography', 'blockenberg'), initialOpen: false },
                    TC && el(TC, { label: __('Link Text', 'blockenberg'), value: attr.typoLink, onChange: function (v) { set({ typoLink: v }); } })
                )
            );

            /* nav container style */
            var navStyle = Object.assign({
                background: attr.bgColor,
                border: '1px solid ' + attr.borderColor,
                borderRadius: attr.borderRadius + 'px',
                boxShadow: '0 2px 12px ' + attr.shadowColor,
                overflow: 'hidden',
                maxWidth: attr.menuWidth + 'px'
            }, tv(attr.typoLink, '--bkcm-link-'));

            return el(Fragment, {},
                inspector,
                el('div', useBlockProps({ style: { paddingTop: attr.paddingTop + 'px', paddingBottom: attr.paddingBottom + 'px' } }),
                    el('div', { style: { display: 'flex', flexDirection: 'column', gap: '8px', alignItems: 'flex-start' } },
                        attr.position !== 'inline' && el('div', { className: 'bkbg-cm-editor-note' },
                            '⚠️ ' + __('This menu will be FIXED on the page in the selected position. In the editor it is shown inline.', 'blockenberg')
                        ),
                        el('nav', { className: 'bkbg-cm-nav cm-' + attr.menuStyle, style: navStyle },
                            links.map(function (lk, idx) {
                                var isAct = idx === activeIdx;
                                if (attr.menuStyle === 'dots') {
                                    return el('div', {
                                        key: idx,
                                        className: 'bkbg-cm-dot',
                                        title: lk.label,
                                        onClick: function () { setActiveIdx(idx); },
                                        style: { width: isAct ? '22px' : '10px', height: '10px', borderRadius: '999px', background: isAct ? attr.activeBg : attr.borderColor, transition: 'all 0.2s', cursor: 'pointer' }
                                    });
                                }
                                return el('div', {
                                    key: idx,
                                    className: 'bkbg-cm-link' + (isAct ? ' active' : ''),
                                    onClick: function () { setActiveIdx(idx); },
                                    style: linkStyle(isAct)
                                },
                                    attr.showNumbers && el('span', { className: 'bkbg-cm-num' }, idx + 1 + '.'),
                                    attr.showIcons && lk.icon && el('span', { className: 'bkbg-cm-link-icon' },
                                        (lk.iconType || 'custom-char') !== 'custom-char' ? IP().buildEditorIcon(lk.iconType, lk.icon, lk.iconDashicon, lk.iconImageUrl, lk.iconDashiconColor) : lk.icon
                                    ),
                                    el('span', {}, lk.label)
                                );
                            })
                        )
                    )
                )
            );
        },

        save: function (props) {
            return el('div', useBlockProps.save(),
                el('div', { className: 'bkbg-cm-app', 'data-opts': JSON.stringify(props.attributes) })
            );
        }
    });
}() );

```
