PluginProbe
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor / 2.0.7
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor v2.0.7
2.0.13 2.0.12 2.0.11 2.0.10 2.0.9 trunk 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8
blockenberg / blocks / one-page-nav / index.js

index.js in Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor 2.0.7, at blocks/one-page-nav/index.js

239 lines 12.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 ( function () {
2 var el = wp.element.createElement;
3 var registerBlockType = wp.blocks.registerBlockType;
4 var useBlockProps = wp.blockEditor.useBlockProps;
5 var InspectorControls = wp.blockEditor.InspectorControls;
6 var PanelColorSettings = wp.blockEditor.PanelColorSettings;
7 var PanelBody = wp.components.PanelBody;
8 var RangeControl = wp.components.RangeControl;
9 var ToggleControl = wp.components.ToggleControl;
10 var SelectControl = wp.components.SelectControl;
11 var TextControl = wp.components.TextControl;
12 var Button = wp.components.Button;
13
14 var useState = wp.element.useState;
15
16 var _tc, _tv;
17 function getTypoControl() { return _tc || (_tc = window.bkbgTypographyControl); }
18 function getTypoCssVars() { return _tv || (_tv = window.bkbgTypoCssVars); }
19
20 registerBlockType('blockenberg/one-page-nav', {
21 edit: function (props) {
22 var a = props.attributes;
23 var set = props.setAttributes;
24 var TypoCtrl = getTypoControl();
25 var blockProps = (function () {
26 var bp = useBlockProps({ className: 'bkbg-opn-editor-wrap' });
27 var _tvf = getTypoCssVars();
28 var s = {};
29 if (_tvf) {
30 Object.assign(s, _tvf(a.tooltipTypo, '--bkbg-opn-tp-'));
31 }
32 if (Object.keys(s).length) bp.style = Object.assign(s, bp.style || {});
33 return bp;
34 }());
35
36 var itemsState = useState(a.items || []);
37
38 function updateItem(idx, field, val) {
39 var newItems = a.items.map(function (it, i) {
40 return i === idx ? Object.assign({}, it, { [field]: val }) : it;
41 });
42 set({ items: newItems });
43 }
44
45 function addItem() {
46 set({ items: a.items.concat([{ label: 'Section ' + (a.items.length + 1), targetId: 'section-' + (a.items.length + 1) }]) });
47 }
48
49 function removeItem(idx) {
50 set({ items: a.items.filter(function (_, i) { return i !== idx; }) });
51 }
52
53 var isRight = (a.position || 'right') === 'right';
54 var dotSz = a.dotSize || 12;
55 var dotGap = a.dotGap || 14;
56 var accent = a.activeDotColor || '#6366f1';
57
58 // Preview: a column of dots with vertical progress line
59 var previewDots = el('div', {
60 style: {
61 display: 'inline-flex',
62 flexDirection: 'column',
63 alignItems: 'center',
64 gap: dotGap + 'px',
65 position: 'relative',
66 padding: '4px 0'
67 }
68 },
69 // progress line
70 a.progressLine !== false && el('div', {
71 style: {
72 position: 'absolute',
73 top: 0, left: '50%',
74 width: 2,
75 height: '100%',
76 background: '#e5e7eb',
77 transform: 'translateX(-50%)',
78 zIndex: 0
79 }
80 }),
81 (a.items || []).map(function (item, i) {
82 var isActive = i === 0;
83 var shape = a.dotShape || 'circle';
84 var borderRadius = shape === 'circle' ? '50%' : shape === 'square' ? '2px' : '2px';
85 var transform = shape === 'diamond' ? 'rotate(45deg)' : '';
86 return el('div', { key: i, style: { position: 'relative', zIndex: 1, display: 'flex',
87 alignItems: 'center', gap: 8, flexDirection: isRight ? 'row-reverse' : 'row' } },
88 el('div', { style: {
89 width: isActive ? dotSz * 1.35 : dotSz,
90 height: isActive ? dotSz * 1.35 : dotSz,
91 borderRadius: borderRadius,
92 transform: transform,
93 background: isActive ? accent : (a.dotColor || '#d1d5db'),
94 transition: 'all 0.2s',
95 boxShadow: isActive ? '0 0 0 4px ' + accent + '33' : 'none'
96 } }),
97 a.showTooltips !== false && el('div', { className: 'bkbg-opn-tooltip', style: {
98 color: '#fff',
99 background: a.tooltipBg || '#1e1b4b',
100 opacity: isActive ? 1 : 0.4,
101 pointerEvents: 'auto',
102 transform: 'none'
103 } }, item.label)
104 );
105 })
106 );
107
108 var previewWrap = el('div', {
109 style: {
110 background: '#f1f5f9',
111 borderRadius: 12,
112 padding: 24,
113 display: 'flex',
114 alignItems: 'flex-start',
115 gap: 24,
116 fontFamily: 'inherit'
117 }
118 },
119 el('div', { style: { flex: 1, opacity: 0.55 } },
120 // Simulated page sections
121 [0,1,2].map(function (n) {
122 return el('div', { key: n, style: {
123 height: 60, borderRadius: 8, marginBottom: 8,
124 background: n === 0 ? '#e0e7ff' : '#e5e7eb' }
125 });
126 })
127 ),
128 el('div', { style: {
129 display: 'flex',
130 flexDirection: 'column',
131 alignItems: 'center',
132 justifyContent: 'center',
133 minWidth: 80,
134 gap: 0
135 } },
136 el('p', { style: { fontSize: 11, fontWeight: 600, color: '#6366f1',
137 textTransform: 'uppercase', letterSpacing: 1, margin: '0 0 8px' } },
138 (isRight ? '↳ Right' : '↲ Left') + ' side'),
139 previewDots
140 )
141 );
142
143 return el('div', blockProps,
144 el(InspectorControls, {},
145 // Navigation items
146 el(PanelBody, { title: 'Navigation Items', initialOpen: true },
147 (a.items || []).map(function (item, i) {
148 return el('div', { key: i, style: { marginBottom: 12, padding: 10,
149 background: '#f8fafc', borderRadius: 6, border: '1px solid #e5e7eb' } },
150 el(TextControl, { label: 'Label', value: item.label,
151 onChange: function (v) { updateItem(i, 'label', v); }, __nextHasNoMarginBottom: true }),
152 el(TextControl, { label: 'Target ID (without #)', value: item.targetId,
153 onChange: function (v) { updateItem(i, 'targetId', v); }, __nextHasNoMarginBottom: true }),
154 el(Button, { isDestructive: true, isSmall: true,
155 onClick: function () { removeItem(i); } }, '✕ Remove')
156 );
157 }),
158 el(Button, { isPrimary: true, isSmall: true, onClick: addItem,
159 style: { marginTop: 4 } }, '+ Add Item')
160 ),
161 // Layout
162 el(PanelBody, { title: 'Layout', initialOpen: false },
163 el(SelectControl, { label: 'Position', value: a.position || 'right',
164 options: [
165 { label: 'Right side', value: 'right' },
166 { label: 'Left side', value: 'left' }
167 ],
168 onChange: function (v) { set({ position: v }); }, __nextHasNoMarginBottom: true }),
169 el(SelectControl, { label: 'Dot shape', value: a.dotShape || 'circle',
170 options: [
171 { label: 'Circle', value: 'circle' },
172 { label: 'Square', value: 'square' },
173 { label: 'Diamond', value: 'diamond' }
174 ],
175 onChange: function (v) { set({ dotShape: v }); }, __nextHasNoMarginBottom: true }),
176 el(RangeControl, { label: 'Dot size (px)', value: a.dotSize || 12,
177 onChange: function (v) { set({ dotSize: v }); }, min: 6, max: 24, __nextHasNoMarginBottom: true }),
178 el(RangeControl, { label: 'Gap between dots', value: a.dotGap || 14,
179 onChange: function (v) { set({ dotGap: v }); }, min: 4, max: 40, __nextHasNoMarginBottom: true }),
180 el(RangeControl, { label: 'Edge offset (px)', value: a.edgeOffset || 24,
181 onChange: function (v) { set({ edgeOffset: v }); }, min: 8, max: 80, __nextHasNoMarginBottom: true }),
182 el(RangeControl, { label: 'Scroll offset (px)', value: a.scrollOffset || 0,
183 onChange: function (v) { set({ scrollOffset: v }); }, min: -200, max: 200, __nextHasNoMarginBottom: true }),
184 el(ToggleControl, { label: 'Show tooltips', checked: a.showTooltips !== false,
185 onChange: function (v) { set({ showTooltips: v }); }, __nextHasNoMarginBottom: true }),
186 el(ToggleControl, { label: 'Animate active dot', checked: a.animateDots !== false,
187 onChange: function (v) { set({ animateDots: v }); }, __nextHasNoMarginBottom: true }),
188 el(ToggleControl, { label: 'Show progress line', checked: a.progressLine !== false,
189 onChange: function (v) { set({ progressLine: v }); }, __nextHasNoMarginBottom: true })
190 ),
191 el(PanelBody, { title: 'Typography', initialOpen: false },
192 TypoCtrl && el(TypoCtrl, { label: 'Tooltip', value: a.tooltipTypo, onChange: function (v) { set({ tooltipTypo: v }); } })
193 ),
194 el(PanelColorSettings, {
195 initialOpen: false, colorSettings: [
196 { label: 'Dot color', value: a.dotColor, onChange: function (v) { set({ dotColor: v || '#d1d5db' }); } },
197 { label: 'Active dot color', value: a.activeDotColor, onChange: function (v) { set({ activeDotColor: v || '#6366f1' }); } },
198 { label: 'Hover dot color', value: a.hoverDotColor, onChange: function (v) { set({ hoverDotColor: v || '#a5b4fc' }); } },
199 { label: 'Progress line', value: a.progressLineColor, onChange: function (v) { set({ progressLineColor: v || '#6366f1' }); } },
200 { label: 'Tooltip background', value: a.tooltipBg, onChange: function (v) { set({ tooltipBg: v || '#1e1b4b' }); } },
201 { label: 'Tooltip text', value: a.tooltipColor, onChange: function (v) { set({ tooltipColor: v || '#ffffff' }); } }
202 ],
203 disableCustomGradients: true
204 })
205 ),
206 previewWrap
207 );
208 },
209
210 save: function (props) {
211 var a = props.attributes;
212 var blockProps = useBlockProps.save();
213 var opts = {
214 items: a.items || [],
215 position: a.position || 'right',
216 dotShape: a.dotShape || 'circle',
217 dotSize: a.dotSize || 12,
218 dotGap: a.dotGap || 14,
219 edgeOffset: a.edgeOffset || 24,
220 scrollOffset: a.scrollOffset || 0,
221 showTooltips: a.showTooltips !== false,
222 animateDots: a.animateDots !== false,
223 progressLine: a.progressLine !== false,
224 dotColor: a.dotColor || '#d1d5db',
225 activeDotColor: a.activeDotColor || '#6366f1',
226 hoverDotColor: a.hoverDotColor || '#a5b4fc',
227 progressLineColor: a.progressLineColor || '#6366f1',
228 tooltipBg: a.tooltipBg || '#1e1b4b',
229 tooltipColor: a.tooltipColor || '#ffffff',
230 tooltipSize: a.tooltipSize || 11,
231 tooltipTypo: a.tooltipTypo || {}
232 };
233 return el('div', blockProps,
234 el('div', { className: 'bkbg-opn-app', 'data-opts': JSON.stringify(opts) })
235 );
236 }
237 });
238 }() );
239