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 / world-map / index.js

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

285 lines 18.1 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 Fragment = wp.element.Fragment;
4 var useState = wp.element.useState;
5 var __ = wp.i18n.__;
6 var registerBlockType = wp.blocks.registerBlockType;
7 var InspectorControls = wp.blockEditor.InspectorControls;
8 var useBlockProps = wp.blockEditor.useBlockProps;
9 var PanelBody = wp.components.PanelBody;
10 var Button = wp.components.Button;
11 var ToggleControl = wp.components.ToggleControl;
12 var RangeControl = wp.components.RangeControl;
13 var SelectControl = wp.components.SelectControl;
14 var TextControl = wp.components.TextControl;
15 var ColorPicker = wp.components.ColorPicker;
16 var Popover = wp.components.Popover;
17
18 /* ── Typography helpers (lazy) ───────────────────────────────── */
19 var _tc, _tvf;
20 Object.defineProperty(window, '__bkwm_tc', { get: function () { return _tc || (_tc = window.bkbgTypographyControl); } });
21 Object.defineProperty(window, '__bkwm_tvf', { get: function () { return _tvf || (_tvf = window.bkbgTypoCssVars); } });
22 function getTypoControl(label, typoObj, setAttributes, attrName) {
23 var fn = window.__bkwm_tc;
24 return fn ? fn({ label: label, value: typoObj || {}, onChange: function (v) { var o = {}; o[attrName] = v; setAttributes(o); } }) : null;
25 }
26 function getTypoCssVarsObj(a) {
27 var fn = window.__bkwm_tvf;
28 var s = {};
29 if (fn) {
30 Object.assign(s, fn(a.titleTypo || {}, '--bkwm-tt-'));
31 Object.assign(s, fn(a.subtitleTypo || {}, '--bkwm-st-'));
32 }
33 return s;
34 }
35
36 function makeId() { return 'wm' + Math.random().toString(36).substr(2,8); }
37
38 /* ── Helpers ───────────────────────────────────────────────────── */
39 function buildWrapStyle(a) {
40 var s = {
41 '--bkbg-wm-accent': a.accentColor,
42 '--bkbg-wm-title': a.titleColor,
43 '--bkbg-wm-subtitle': a.subtitleColor,
44 '--bkbg-wm-map-bg': a.mapBg,
45 '--bkbg-wm-list-bg': a.listBg,
46 '--bkbg-wm-list-border': a.listBorder,
47 paddingTop: a.paddingTop + 'px',
48 paddingBottom: a.paddingBottom + 'px',
49 backgroundColor: a.bgColor || undefined,
50 };
51 Object.assign(s, getTypoCssVarsObj(a));
52 return s;
53 }
54
55 function renderColorControl(key, label, value, onChange, openKey, setOpenKey) {
56 var isOpen = openKey === key;
57 return el('div', { key: key, style: { display:'flex', alignItems:'center', justifyContent:'space-between', padding:'4px 0', gap:'8px' } },
58 el('span', { style: { fontSize:'12px', color:'#1e1e1e', flex:1, lineHeight:1.4 } }, label),
59 el('div', { style: { position:'relative', flexShrink:0 } },
60 el('button', { type:'button', onClick: function () { setOpenKey(isOpen ? null : key); }, style: { width:'28px', height:'28px', borderRadius:'4px', border: isOpen ? '2px solid #007cba' : '2px solid #ddd', cursor:'pointer', padding:0, background: value || '#ccc' } }),
61 isOpen && el(Popover, { position:'bottom left', onClose: function () { setOpenKey(null); } },
62 el('div', { style: { padding:'8px' } },
63 el(ColorPicker, { color: value, enableAlpha: true, onChange: onChange })
64 )
65 )
66 )
67 );
68 }
69
70 /* ── Country editor row ─────────────────────────────────────────── */
71 function CountryRow(props) {
72 var item = props.item;
73 var onChange = props.onChange;
74 var onRemove = props.onRemove;
75 var openKey = props.openKey;
76 var setOpenKey = props.setOpenKey;
77
78 function upd(key, val) {
79 var copy = Object.assign({}, item);
80 copy[key] = val;
81 onChange(copy);
82 }
83
84 return el('div', { style: { background:'#f9f9f9', borderRadius:'8px', padding:'10px', marginBottom:'10px', border:'1px solid #e9e9e9' } },
85 el('div', { style: { display:'flex', gap:'8px', marginBottom:'8px' } },
86 el(TextControl, { label:__('Country name','blockenberg'), value: item.name, onChange: function(v){upd('name',v);}, style:{ flex:1 } }),
87 el(TextControl, { label:__('Code (ISO)','blockenberg'), value: item.code, onChange: function(v){upd('code',v.toUpperCase().substr(0,2));}, style:{ width:'60px', flex:'none' } })
88 ),
89 el('div', { style: { display:'flex', gap:'8px', marginBottom:'8px', alignItems:'flex-end' } },
90 el(TextControl, { label:__('Value / Count','blockenberg'), value: String(item.value), onChange: function(v){upd('value', parseFloat(v)||0);}, type:'number', style:{ flex:1 } }),
91 el(TextControl, { label:__('Link URL','blockenberg'), value: item.url || '', onChange: function(v){upd('url',v);}, style:{ flex:2 } })
92 ),
93 el('div', { style:{ display:'flex', alignItems:'center', justifyContent:'space-between', marginTop:'4px' } },
94 renderColorControl('item-'+item.id, __('Custom colour','blockenberg'), item.color, function(v){upd('color',v);}, openKey, setOpenKey),
95 el(Button, { variant:'tertiary', size:'compact', isDestructive:true, onClick:onRemove, style:{marginLeft:'8px'} }, '')
96 )
97 );
98 }
99
100 /* ── Preview card ───────────────────────────────────────────────── */
101 function MapPreview(props) {
102 var a = props.a;
103 var countries = a.countries || [];
104
105 return el('div', { style: { display:'flex', flexDirection:'column', gap:'24px' } },
106 /* Header */
107 el('div', { className: 'bkbg-wm-header', style:{ textAlign:'center' } },
108 a.showTitle && el('div', { className: 'bkbg-wm-title', style:{ color: a.titleColor||'#1e1b4b', marginBottom:'8px' } }, a.title || __('Global Presence','blockenberg')),
109 a.showSubtitle && el('p', { className: 'bkbg-wm-subtitle', style:{ color: a.subtitleColor||'#6b7280', marginTop:0 } }, a.subtitle || __('Where our customers are','blockenberg'))
110 ),
111
112 /* Map placeholder */
113 el('div', { style:{
114 background: a.mapBg || '#f0f4f8',
115 borderRadius: a.cardRadius+'px',
116 minHeight: '220px',
117 display:'flex', alignItems:'center', justifyContent:'center',
118 flexDirection:'column', gap:'8px',
119 border: '2px dashed #cbd5e1'
120 } },
121 el('span', { style:{ fontSize:'48px' } }, '🗺️'),
122 el('p', { style:{ margin:0, color:'#94a3b8', fontWeight:600, fontSize:'14px' } }, __('Interactive map renders on the frontend','blockenberg')),
123 el('p', { style:{ margin:0, color:'#94a3b8', fontSize:'12px' } }, countries.length + ' ' + __('countries configured','blockenberg'))
124 ),
125
126 /* Country tags grid */
127 countries.length > 0 && el('div', { style:{ display:'flex', flexWrap:'wrap', gap:'8px' } },
128 countries.map(function(c) {
129 return el('div', { key:c.id, style:{
130 display:'inline-flex', alignItems:'center', gap:'6px',
131 padding:'4px 10px', borderRadius:'999px',
132 background: c.color || (a.accentColor || '#ede9fe'),
133 color: '#fff', fontSize:'13px', fontWeight:600,
134 } },
135 el('span', null, c.code || '??'),
136 el('span', { style:{ fontWeight:400 } }, c.name),
137 el('span', { style:{ background:'rgba(255,255,255,0.25)', borderRadius:'999px', padding:'1px 6px', fontSize:'11px', marginLeft:'2px' } }, c.value)
138 );
139 })
140 )
141 );
142 }
143
144 /* ── Register ──────────────────────────────────────────────────── */
145 registerBlockType('blockenberg/world-map', {
146 title: __('World Map','blockenberg'),
147 icon: 'location-alt',
148 category: 'bkbg-charts',
149
150 edit: function (props) {
151 var a = props.attributes;
152 var setAttributes = props.setAttributes;
153
154 var openColorState = useState(null);
155 var openColorKey = openColorState[0];
156 var setOpenColorKey = openColorState[1];
157
158 var blockProps = useBlockProps({ style: buildWrapStyle(a) });
159
160 function cc(key, label, value, attrKey) {
161 return renderColorControl(key, label, value, function(v){ var u={}; u[attrKey]=v; setAttributes(u); }, openColorKey, setOpenColorKey);
162 }
163
164 function updateCountry(id, updated) {
165 setAttributes({ countries: a.countries.map(function(c){ return c.id===id ? updated : c; }) });
166 }
167
168 function removeCountry(id) {
169 setAttributes({ countries: a.countries.filter(function(c){ return c.id!==id; }) });
170 }
171
172 function addCountry() {
173 setAttributes({ countries: a.countries.concat([{ id:makeId(), code:'XX', name:__('New Country','blockenberg'), value:100, color:'', url:'' }]) });
174 }
175
176 return el(Fragment, null,
177 el(InspectorControls, null,
178 el(PanelBody, { title:__('Countries','blockenberg'), initialOpen:true },
179 (a.countries||[]).map(function(item) {
180 return el(CountryRow, { key:item.id, item:item, onChange:function(upd){ updateCountry(item.id, upd); }, onRemove:function(){ removeCountry(item.id); }, openKey:openColorKey, setOpenKey:setOpenColorKey });
181 }),
182 el(Button, { variant:'primary', onClick:addCountry }, '+ ' + __('Add Country','blockenberg'))
183 ),
184 el(PanelBody, { title:__('Display','blockenberg'), initialOpen:false },
185 el(ToggleControl, { label:__('Show title','blockenberg'), checked:a.showTitle, onChange:function(v){setAttributes({showTitle:v});}, __nextHasNoMarginBottom:true }),
186 a.showTitle && el(TextControl, { label:__('Title','blockenberg'), value:a.title, onChange:function(v){setAttributes({title:v});} }),
187 el(ToggleControl, { label:__('Show subtitle','blockenberg'), checked:a.showSubtitle, onChange:function(v){setAttributes({showSubtitle:v});}, __nextHasNoMarginBottom:true }),
188 a.showSubtitle && el(TextControl, { label:__('Subtitle','blockenberg'), value:a.subtitle, onChange:function(v){setAttributes({subtitle:v});} }),
189 el(ToggleControl, { label:__('Show legend','blockenberg'), checked:a.showLegend, onChange:function(v){setAttributes({showLegend:v});}, __nextHasNoMarginBottom:true }),
190 a.showLegend && el(TextControl, { label:__('Legend title','blockenberg'), value:a.legendTitle, onChange:function(v){setAttributes({legendTitle:v});} }),
191 el(ToggleControl, { label:__('Show tooltips on hover','blockenberg'), checked:a.showTooltips, onChange:function(v){setAttributes({showTooltips:v});}, __nextHasNoMarginBottom:true }),
192 el(ToggleControl, { label:__('Show country list below map','blockenberg'), checked:a.showCountryList, onChange:function(v){setAttributes({showCountryList:v});}, __nextHasNoMarginBottom:true }),
193 el(RangeControl, { label:__('Map height (px)','blockenberg'), value:a.mapHeight, min:200, max:800, onChange:function(v){setAttributes({mapHeight:v});} })
194 ),
195 el(PanelBody, { title:__('Map Style','blockenberg'), initialOpen:false },
196 el(SelectControl, { label:__('Color mode','blockenberg'), value:a.colorMode, options:[{ label:__('Gradient by value','blockenberg'), value:'gradient' },{ label:__('Uniform fill','blockenberg'), value:'uniform' },{ label:__('Per-country custom color','blockenberg'), value:'custom' }], onChange:function(v){setAttributes({colorMode:v});} }),
197 a.colorMode==='gradient' && el(Fragment, null,
198 cc('lowColor', __('Low value colour','blockenberg'), a.lowColor, 'lowColor'),
199 cc('highColor', __('High value colour','blockenberg'), a.highColor, 'highColor')
200 ),
201 cc('defaultFill', __('Default country fill','blockenberg'), a.defaultFill, 'defaultFill'),
202 cc('hoverFill', __('Hover fill','blockenberg'), a.hoverFill, 'hoverFill'),
203 cc('borderColor', __('Border colour','blockenberg'), a.borderColor, 'borderColor'),
204 cc('mapBg', __('Map background','blockenberg'), a.mapBg, 'mapBg'),
205 el(SelectControl, { label:__('Projection','blockenberg'), value:a.projection, options:[{ label:'Natural Earth', value:'NaturalEarth1' },{ label:'Mercator', value:'Mercator' },{ label:'Equirectangular', value:'Equirectangular' },{ label:'Robinson', value:'Robinson' }], onChange:function(v){setAttributes({projection:v});} })
206 ),
207 el(PanelBody, { title:__('Tooltip Style','blockenberg'), initialOpen:false },
208 cc('tooltipBg', __('Tooltip background','blockenberg'), a.tooltipBg, 'tooltipBg'),
209 cc('tooltipColor', __('Tooltip text','blockenberg'), a.tooltipColor, 'tooltipColor')
210 ),
211 el(PanelBody, { title:__('Country List Style','blockenberg'), initialOpen:false },
212 cc('listBg', __('List background','blockenberg'), a.listBg, 'listBg'),
213 cc('listBorder', __('List border','blockenberg'), a.listBorder, 'listBorder')
214 ),
215 el(PanelBody, { title:__('Colours','blockenberg'), initialOpen:false },
216 cc('accentColor', __('Accent','blockenberg'), a.accentColor, 'accentColor'),
217 cc('titleColor', __('Title','blockenberg'), a.titleColor, 'titleColor'),
218 cc('subtitleColor', __('Subtitle','blockenberg'), a.subtitleColor, 'subtitleColor'),
219 cc('bgColor', __('Section background','blockenberg'), a.bgColor, 'bgColor')
220 ),
221 el(PanelBody, { title:__('Appearance','blockenberg'), initialOpen:false },
222 el(RangeControl, { label:__('Card radius (px)','blockenberg'), value:a.cardRadius, min:0, max:40, onChange:function(v){setAttributes({cardRadius:v});} })
223 ),
224 el(PanelBody, { title:__('Spacing','blockenberg'), initialOpen:false },
225 el(RangeControl, { label:__('Padding top (px)','blockenberg'), value:a.paddingTop, min:0, max:200, onChange:function(v){setAttributes({paddingTop:v});} }),
226 el(RangeControl, { label:__('Padding bottom (px)','blockenberg'), value:a.paddingBottom, min:0, max:200, onChange:function(v){setAttributes({paddingBottom:v});} })
227 ),
228 el( PanelBody, { title: __( 'Typography', 'blockenberg' ), initialOpen: false },
229 getTypoControl('Title', a.titleTypo, setAttributes, 'titleTypo'),
230 getTypoControl('Subtitle', a.subtitleTypo, setAttributes, 'subtitleTypo')
231 )
232 ),
233
234 el('div', blockProps,
235 el(MapPreview, { a: a })
236 )
237 );
238 },
239
240 save: function (props) {
241 var a = props.attributes;
242 return el('div', wp.blockEditor.useBlockProps.save({
243 className: 'bkbg-wm-wrapper',
244 style: buildWrapStyle(a),
245 }),
246 (a.showTitle || a.showSubtitle) && el('div', { className:'bkbg-wm-header', style:{ textAlign:'center', marginBottom:'32px' } },
247 a.showTitle && el('h2', { className:'bkbg-wm-title', style:{ margin:'0 0 8px' } }, a.title),
248 a.showSubtitle && el('p', { className:'bkbg-wm-subtitle', style:{ margin:0 } }, a.subtitle)
249 ),
250 el('div', {
251 className: 'bkbg-wm-map-holder',
252 'data-countries': JSON.stringify(a.countries || []),
253 'data-opts': JSON.stringify({
254 colorMode: a.colorMode,
255 lowColor: a.lowColor,
256 highColor: a.highColor,
257 defaultFill: a.defaultFill,
258 hoverFill: a.hoverFill,
259 borderColor: a.borderColor,
260 projection: a.projection,
261 showLegend: a.showLegend,
262 legendTitle: a.legendTitle,
263 showTooltips: a.showTooltips,
264 tooltipBg: a.tooltipBg,
265 tooltipColor: a.tooltipColor,
266 mapHeight: a.mapHeight,
267 mapBg: a.mapBg,
268 cardRadius: a.cardRadius,
269 }),
270 style: { minHeight: a.mapHeight+'px', borderRadius: a.cardRadius+'px', background: a.mapBg }
271 }),
272 a.showCountryList && el('div', { className:'bkbg-wm-country-list', style:{ marginTop:'32px' } },
273 el('div', { style:{ display:'flex', flexWrap:'wrap', gap:'8px' } },
274 (a.countries||[]).map(function(c) {
275 return el('span', { key:c.id, className:'bkbg-wm-country-tag' },
276 el('strong', null, c.code), ' ', c.name, '', c.value
277 );
278 })
279 )
280 )
281 );
282 }
283 });
284 }() );
285