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 / hotspot-image / index.js

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

166 lines 8.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 ( function () {
2 const el = window.wp.element.createElement;
3 const { registerBlockType } = window.wp.blocks;
4 const { InspectorControls, MediaUpload, MediaUploadCheck, PanelColorSettings } = window.wp.blockEditor;
5 const { PanelBody, RangeControl, SelectControl, TextControl, TextareaControl, Button } = window.wp.components;
6 const { __ } = window.wp.i18n;
7
8 var _TypographyControl, _typoCssVars;
9 function getTypographyControl() { return _TypographyControl || (_TypographyControl = window.bkbgTypographyControl); }
10 function getTypoCssVars() { return _typoCssVars || (_typoCssVars = window.bkbgTypoCssVars); }
11
12 function HotspotEditor( { hs, index, onChange, onRemove } ) {
13 function upd(k,v){ onChange(index, Object.assign({}, hs, {[k]:v})); }
14 return el('div', {style:{border:'1px solid #ddd',borderRadius:'8px',padding:'10px',marginBottom:'8px',background:'#fafafa'}},
15 el('strong', {style:{display:'block',marginBottom:'6px'}}, __('Hotspot ') + (index+1) + '' + hs.x.toFixed(0) + '%, ' + hs.y.toFixed(0) + '%'),
16 el(TextControl, {label:__('Title'), value:hs.title, onChange:v=>upd('title',v)}),
17 el(TextareaControl, {label:__('Content'), value:hs.content, onChange:v=>upd('content',v), rows:2}),
18 el(RangeControl, {label:__('X Position (%)'), value:hs.x, min:5, max:95, onChange:v=>upd('x',v)}),
19 el(RangeControl, {label:__('Y Position (%)'), value:hs.y, min:5, max:95, onChange:v=>upd('y',v)}),
20 el(SelectControl, {
21 label:__('Tooltip Position'), value:hs.tooltipPos,
22 options:[{label:'Right',value:'right'},{label:'Left',value:'left'},{label:'Top',value:'top'},{label:'Bottom',value:'bottom'}],
23 onChange:v=>upd('tooltipPos',v)
24 }),
25 el(Button, {isDestructive:true, isSmall:true, onClick:()=>onRemove(index)}, __('Remove'))
26 );
27 }
28
29 registerBlockType('blockenberg/hotspot-image', {
30 edit: function(props) {
31 const { attributes: attr, setAttributes } = props;
32
33 function updateHs(idx, next){ const h=attr.hotspots.slice(); h[idx]=next; setAttributes({hotspots:h}); }
34 function removeHs(idx){ setAttributes({hotspots:attr.hotspots.filter((_,i)=>i!==idx)}); }
35
36 const wrapStyle = {
37 '--bkhi-marker': attr.markerColor,
38 '--bkhi-tip-bg': attr.tooltipBg,
39 '--bkhi-tip-text': attr.tooltipText,
40 '--bkhi-size': attr.markerSize + 'px',
41 '--bkhi-radius': attr.borderRadius + 'px',
42 position: 'relative',
43 display: 'inline-block',
44 width: '100%',
45 borderRadius: attr.borderRadius + 'px',
46 overflow: 'hidden',
47 };
48 var _tv = getTypoCssVars();
49 if (_tv) {
50 Object.assign(wrapStyle, _tv(attr.titleTypo || {}, '--bkhi-tt-'));
51 Object.assign(wrapStyle, _tv(attr.contentTypo || {}, '--bkhi-ct-'));
52 }
53
54 return el('div', {className:'bkhi-wrap', style: wrapStyle},
55
56 el(InspectorControls, null,
57 el(PanelBody, {title:__('Image'), initialOpen:true},
58 attr.imageUrl
59 ? el('div', {style:{marginBottom:'8px'}},
60 el('img', {src:attr.imageUrl, style:{width:'100%',borderRadius:'6px',display:'block',marginBottom:'6px'}}),
61 el(Button, {isDestructive:true, isSmall:true, onClick:()=>setAttributes({imageUrl:'',imageId:0,imageAlt:''})}, __('Remove'))
62 )
63 : el(MediaUploadCheck, null,
64 el(MediaUpload, {
65 onSelect:m=>setAttributes({imageUrl:m.url,imageId:m.id,imageAlt:m.alt||''}),
66 allowedTypes:['image'], value:attr.imageId,
67 render:({open})=>el(Button,{onClick:open,variant:'secondary'}, __('Upload Image'))
68 })
69 )
70 ),
71 el(PanelBody, {title:__('Hotspots'), initialOpen:true},
72 attr.hotspots.map((hs,i)=>el(HotspotEditor,{key:i,hs,index:i,onChange:updateHs,onRemove:removeHs})),
73 el(Button, {variant:'secondary', onClick:()=>setAttributes({hotspots:[...attr.hotspots,{x:50,y:50,title:'New Hotspot',content:'Description.',tooltipPos:'right'}]}),
74 style:{width:'100%',justifyContent:'center',marginTop:'8px'}}, __('+ Add Hotspot'))
75 ),
76 el(PanelBody, {title:__('Style'), initialOpen:false},
77 el(SelectControl, {label:__('Trigger'), value:attr.trigger,
78 options:[{label:__('Hover'),value:'hover'},{label:__('Click'),value:'click'}],
79 onChange:v=>setAttributes({trigger:v})}),
80 el(SelectControl, {label:__('Marker Style'), value:attr.markerStyle,
81 options:[{label:__('Pulse'),value:'pulse'},{label:__('Dot'),value:'dot'},{label:__('Plus'),value:'plus'}],
82 onChange:v=>setAttributes({markerStyle:v})}),
83 el(RangeControl, {label:__('Marker Size (px)'), value:attr.markerSize, min:10, max:40, onChange:v=>setAttributes({markerSize:v})}),
84 el(RangeControl, {label:__('Border Radius (px)'), value:attr.borderRadius, min:0, max:32, onChange:v=>setAttributes({borderRadius:v})})
85 ),
86 el(PanelColorSettings, {
87 title:__('Colors'), initialOpen:false,
88 colorSettings:[
89 {label:__('Marker Color'), value:attr.markerColor, onChange:v=>setAttributes({markerColor:v||'#6c3fb5'})},
90 {label:__('Tooltip Background'), value:attr.tooltipBg, onChange:v=>setAttributes({tooltipBg:v||'#1e1e2e'})},
91 {label:__('Tooltip Text'), value:attr.tooltipText, onChange:v=>setAttributes({tooltipText:v||'#ffffff'})},
92 ]
93 }),
94 el(PanelBody, {title:__('Typography'), initialOpen:false},
95 getTypographyControl() && el(getTypographyControl(), {
96 label: __('Tooltip Title'),
97 typo: attr.titleTypo || {},
98 onChange: function(v){ setAttributes({titleTypo: v}); }
99 }),
100 getTypographyControl() && el(getTypographyControl(), {
101 label: __('Tooltip Content'),
102 typo: attr.contentTypo || {},
103 onChange: function(v){ setAttributes({contentTypo: v}); }
104 })
105 )
106 ),
107
108 attr.imageUrl
109 ? el('img', {src:attr.imageUrl, alt:attr.imageAlt, className:'bkhi-image'})
110 : el('div', {className:'bkhi-image bkhi-placeholder'}, el('span',{className:'dashicons dashicons-format-image'})),
111
112 attr.hotspots.map((hs,i)=>
113 el('div', {
114 key: i,
115 className: 'bkhi-pin bkhi-marker-' + attr.markerStyle + ' bkhi-tip-' + hs.tooltipPos + ' bkhi-editor-open',
116 style: { left: hs.x + '%', top: hs.y + '%' }
117 },
118 el('button', {className:'bkhi-dot', 'aria-label': hs.title}),
119 el('div', {className:'bkhi-tooltip'},
120 el('strong', {className:'bkhi-tip-title'}, hs.title),
121 hs.content && el('p', {className:'bkhi-tip-content'}, hs.content)
122 )
123 )
124 )
125 );
126 },
127
128 save: function({ attributes: attr }) {
129 const wrapStyle = {
130 '--bkhi-marker': attr.markerColor,
131 '--bkhi-tip-bg': attr.tooltipBg,
132 '--bkhi-tip-text': attr.tooltipText,
133 '--bkhi-size': attr.markerSize + 'px',
134 '--bkhi-radius': attr.borderRadius + 'px',
135 };
136 var _tv = getTypoCssVars();
137 if (_tv) {
138 Object.assign(wrapStyle, _tv(attr.titleTypo || {}, '--bkhi-tt-'));
139 Object.assign(wrapStyle, _tv(attr.contentTypo || {}, '--bkhi-ct-'));
140 }
141 return el('div', {
142 className:'bkhi-wrap',
143 style: wrapStyle,
144 'data-trigger': attr.trigger
145 },
146 attr.imageUrl
147 ? el('img', {src:attr.imageUrl, alt:attr.imageAlt, className:'bkhi-image'})
148 : null,
149 attr.hotspots.map((hs,i)=>
150 el('div', {
151 key:i,
152 className:'bkhi-pin bkhi-marker-'+attr.markerStyle+' bkhi-tip-'+hs.tooltipPos,
153 style:{left:hs.x+'%', top:hs.y+'%'}
154 },
155 el('button', {className:'bkhi-dot', 'aria-label':hs.title}),
156 el('div', {className:'bkhi-tooltip'},
157 el('strong', {className:'bkhi-tip-title'}, hs.title),
158 hs.content && el('p', {className:'bkhi-tip-content'}, hs.content)
159 )
160 )
161 )
162 );
163 }
164 });
165 }() );
166