| 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, ToggleControl, Button } = window.wp.components; |
| 6 |
const { __ } = window.wp.i18n; |
| 7 |
const useState = window.wp.element.useState; |
| 8 |
const Fragment = window.wp.element.Fragment; |
| 9 |
let _tc; const getTypoControl = () => _tc || (_tc = window.bkbgTypographyControl); |
| 10 |
let _tv; const getTypoCssVars = () => _tv || (_tv = window.bkbgTypoCssVars); |
| 11 |
|
| 12 |
function SlideEditor( { slide, index, onChange, onRemove } ) { |
| 13 |
function upd(k,v){ onChange(index, Object.assign({}, slide, {[k]:v})); } |
| 14 |
return el('div', { style:{border:'1px solid #ddd',borderRadius:'8px',padding:'12px',marginBottom:'8px',background:'#fafafa'} }, |
| 15 |
el('strong', { style:{display:'block',marginBottom:'8px'} }, __('Slide ') + (index+1)), |
| 16 |
el('label', {style:{fontSize:'11px',fontWeight:600,display:'block',marginBottom:'4px'}} , __('Background Image')), |
| 17 |
slide.imageUrl |
| 18 |
? el('div', {style:{marginBottom:'8px'}}, |
| 19 |
el('img', {src:slide.imageUrl, style:{width:'100%',height:'80px',objectFit:'cover',borderRadius:'6px',display:'block',marginBottom:'4px'}}), |
| 20 |
el(Button, {isDestructive:true, isSmall:true, onClick:()=>{upd('imageUrl','');upd('imageId',0);}}, __('Remove')) |
| 21 |
) |
| 22 |
: el(MediaUploadCheck, null, |
| 23 |
el(MediaUpload, { |
| 24 |
onSelect: m=>{upd('imageUrl',m.url);upd('imageId',m.id);}, |
| 25 |
allowedTypes:['image'], value:slide.imageId, |
| 26 |
render:({open})=>el(Button,{onClick:open,isSmall:true,variant:'secondary'}, __('Upload Image')) |
| 27 |
}) |
| 28 |
), |
| 29 |
el(TextControl, {label:__('Title'), value:slide.title, onChange:v=>upd('title',v)}), |
| 30 |
el(TextareaControl, {label:__('Excerpt'), value:slide.excerpt, onChange:v=>upd('excerpt',v), rows:2}), |
| 31 |
el(TextControl, {label:__('Button Label'), value:slide.btnLabel, onChange:v=>upd('btnLabel',v)}), |
| 32 |
el(TextControl, {label:__('Button URL'), value:slide.btnUrl, onChange:v=>upd('btnUrl',v)}), |
| 33 |
el(Button, {isDestructive:true, isSmall:true, onClick:()=>onRemove(index)}, __('Remove Slide')) |
| 34 |
); |
| 35 |
} |
| 36 |
|
| 37 |
registerBlockType('blockenberg/post-slider', { |
| 38 |
edit: function(props) { |
| 39 |
const { attributes: attr, setAttributes } = props; |
| 40 |
const [activeIdx, setActiveIdx] = useState(0); |
| 41 |
|
| 42 |
function updateSlide(idx, next){ const s=attr.slides.slice(); s[idx]=next; setAttributes({slides:s}); } |
| 43 |
function removeSlide(idx){ const s=attr.slides.filter((_,i)=>i!==idx); setAttributes({slides:s}); setActiveIdx(Math.min(activeIdx, s.length-1)); } |
| 44 |
function addSlide(){ setAttributes({slides:[...attr.slides,{imageUrl:'',imageId:0,title:'New Slide',excerpt:'Caption here.',btnLabel:'Read More',btnUrl:'#'}]}); } |
| 45 |
|
| 46 |
const current = attr.slides[activeIdx] || attr.slides[0] || {}; |
| 47 |
const heightVal = attr.height + attr.heightUnit; |
| 48 |
|
| 49 |
const _tvFn = getTypoCssVars(); |
| 50 |
const wrapStyle = Object.assign({ |
| 51 |
'--bkps-height': heightVal, |
| 52 |
'--bkps-overlay': attr.overlayBg, |
| 53 |
'--bkps-text': attr.textColor, |
| 54 |
'--bkps-accent': attr.accentColor, |
| 55 |
'--bkps-radius': attr.borderRadius + 'px', |
| 56 |
borderRadius: attr.borderRadius + 'px', |
| 57 |
overflow: 'hidden', |
| 58 |
position: 'relative', |
| 59 |
}, _tvFn(attr.titleTypo, '--bkps-tt-'), _tvFn(attr.excerptTypo, '--bkps-ex-')); |
| 60 |
|
| 61 |
const slideStyle = { |
| 62 |
backgroundImage: current.imageUrl ? `url(${current.imageUrl})` : 'none', |
| 63 |
backgroundColor: current.imageUrl ? 'transparent' : '#1e0a3c', |
| 64 |
backgroundSize: 'cover', |
| 65 |
backgroundPosition: 'center', |
| 66 |
height: heightVal, |
| 67 |
}; |
| 68 |
|
| 69 |
const boxAlign = attr.captionAlign === 'center' ? 'center' : attr.captionAlign === 'right' ? 'flex-end' : 'flex-start'; |
| 70 |
|
| 71 |
return el('div', { className:'bkps-wrap', style: wrapStyle }, |
| 72 |
|
| 73 |
el(InspectorControls, null, |
| 74 |
el(PanelBody, {title:__('Slides'), initialOpen:true}, |
| 75 |
attr.slides.map((slide,i)=>el(SlideEditor,{key:i,slide,index:i,onChange:updateSlide,onRemove:removeSlide})), |
| 76 |
el(Button,{variant:'secondary',onClick:addSlide,style:{width:'100%',justifyContent:'center',marginTop:'8px'}}, __('+ Add Slide')) |
| 77 |
), |
| 78 |
el(PanelBody, {title:__('Slider Settings'), initialOpen:false}, |
| 79 |
el(RangeControl, {label:__('Height (px)'), value:attr.height, min:200, max:900, onChange:v=>setAttributes({height:v})}), |
| 80 |
el(SelectControl, {label:__('Transition'), value:attr.transition, options:[{label:'Fade',value:'fade'},{label:'Slide',value:'slide'}], onChange:v=>setAttributes({transition:v})}), |
| 81 |
el(ToggleControl, {label:__('Autoplay'), checked:attr.autoplay, onChange:v=>setAttributes({autoplay:v}), __nextHasNoMarginBottom:true}), |
| 82 |
attr.autoplay && el(RangeControl, {label:__('Speed (ms)'), value:attr.speed, min:1500, max:9000, step:500, onChange:v=>setAttributes({speed:v})}), |
| 83 |
el(ToggleControl, {label:__('Show Arrows'), checked:attr.showArrows, onChange:v=>setAttributes({showArrows:v}), __nextHasNoMarginBottom:true}), |
| 84 |
el(ToggleControl, {label:__('Show Dots'), checked:attr.showDots, onChange:v=>setAttributes({showDots:v}), __nextHasNoMarginBottom:true}), |
| 85 |
el(SelectControl, {label:__('Caption Alignment'), value:attr.captionAlign, options:[{label:'Left',value:'left'},{label:'Center',value:'center'},{label:'Right',value:'right'}], onChange:v=>setAttributes({captionAlign:v})}) |
| 86 |
), |
| 87 |
el(PanelBody, {title:__('Typography'), initialOpen:false}, |
| 88 |
(() => { |
| 89 |
const TC = getTypoControl(); |
| 90 |
if (!TC) return el('p', null, 'Loading…'); |
| 91 |
return el(Fragment, null, |
| 92 |
el(TC, { label: 'Title Typography', value: attr.titleTypo, onChange: v => setAttributes({ titleTypo: v }) }), |
| 93 |
el(TC, { label: 'Excerpt Typography', value: attr.excerptTypo, onChange: v => setAttributes({ excerptTypo: v }) }) |
| 94 |
); |
| 95 |
})(), |
| 96 |
el(RangeControl, {label:__('Border Radius (px)'), value:attr.borderRadius, min:0, max:32, onChange:v=>setAttributes({borderRadius:v})}) |
| 97 |
), |
| 98 |
el(PanelColorSettings, { |
| 99 |
title:__('Colors'), initialOpen:false, |
| 100 |
colorSettings:[ |
| 101 |
{label:__('Overlay Color'), value:attr.overlayBg, onChange:v=>setAttributes({overlayBg:v||'rgba(0,0,0,0.45)'})}, |
| 102 |
{label:__('Text Color'), value:attr.textColor, onChange:v=>setAttributes({textColor:v||'#ffffff'})}, |
| 103 |
{label:__('Accent / Button'), value:attr.accentColor, onChange:v=>setAttributes({accentColor:v||'#6c3fb5'})}, |
| 104 |
] |
| 105 |
}) |
| 106 |
), |
| 107 |
|
| 108 |
/* Editor preview */ |
| 109 |
el('div', {className:'bkps-slide bkps-active', style: slideStyle}, |
| 110 |
el('div', {className:'bkps-overlay'}), |
| 111 |
el('div', {className:'bkps-caption', style:{alignItems: boxAlign, textAlign: attr.captionAlign}}, |
| 112 |
el('h2', {className:'bkps-title'}, current.title), |
| 113 |
el('p', {className:'bkps-excerpt'}, current.excerpt), |
| 114 |
current.btnLabel && el('span', {className:'bkps-btn'}, current.btnLabel) |
| 115 |
) |
| 116 |
), |
| 117 |
|
| 118 |
attr.showArrows && el('div', {className:'bkps-arrows'}, |
| 119 |
el('button', {className:'bkps-arrow bkps-prev', onClick:()=>setActiveIdx((activeIdx-1+attr.slides.length)%attr.slides.length)}, '‹'), |
| 120 |
el('button', {className:'bkps-arrow bkps-next', onClick:()=>setActiveIdx((activeIdx+1)%attr.slides.length)}, '›') |
| 121 |
), |
| 122 |
attr.showDots && el('div', {className:'bkps-dots'}, |
| 123 |
attr.slides.map((_,i)=>el('button',{key:i, className:'bkps-dot'+(i===activeIdx?' bkps-dot-active':''), onClick:()=>setActiveIdx(i)})) |
| 124 |
) |
| 125 |
); |
| 126 |
}, |
| 127 |
|
| 128 |
deprecated: [{ |
| 129 |
attributes: { |
| 130 |
slides: { type: 'array', default: [{imageUrl:'',imageId:0,title:'Slide One Headline',excerpt:'A short caption describing this featured post or section.',btnLabel:'Read More',btnUrl:'#'},{imageUrl:'',imageId:0,title:'Slide Two Headline',excerpt:'A short caption describing this featured post or section.',btnLabel:'Read More',btnUrl:'#'}] }, |
| 131 |
height: { type: 'number', default: 500 }, |
| 132 |
heightUnit: { type: 'string', default: 'px' }, |
| 133 |
transition: { type: 'string', default: 'fade' }, |
| 134 |
autoplay: { type: 'boolean', default: true }, |
| 135 |
speed: { type: 'number', default: 4000 }, |
| 136 |
overlayBg: { type: 'string', default: 'rgba(0,0,0,0.45)' }, |
| 137 |
captionAlign: { type: 'string', default: 'left' }, |
| 138 |
textColor: { type: 'string', default: '#ffffff' }, |
| 139 |
accentColor: { type: 'string', default: '#6c3fb5' }, |
| 140 |
showArrows: { type: 'boolean', default: true }, |
| 141 |
showDots: { type: 'boolean', default: true }, |
| 142 |
titleSz: { type: 'number', default: 42 }, |
| 143 |
excerptSz: { type: 'number', default: 16 }, |
| 144 |
borderRadius: { type: 'number', default: 0 }, |
| 145 |
titleFontWeight: { type: 'string', default: '700' }, |
| 146 |
excerptFontWeight:{ type: 'string', default: '400' } |
| 147 |
}, |
| 148 |
save: function({ attributes: attr }) { |
| 149 |
const wrapStyle = { |
| 150 |
'--bkps-height': attr.height + attr.heightUnit, |
| 151 |
'--bkps-overlay': attr.overlayBg, |
| 152 |
'--bkps-text': attr.textColor, |
| 153 |
'--bkps-accent': attr.accentColor, |
| 154 |
'--bkps-title-sz': attr.titleSz + 'px', |
| 155 |
'--bkps-excerpt-sz': attr.excerptSz + 'px', |
| 156 |
'--bkps-radius': attr.borderRadius + 'px', |
| 157 |
}; |
| 158 |
return el('div', { |
| 159 |
className: 'bkps-wrap bkps-transition-' + attr.transition, |
| 160 |
style: wrapStyle, |
| 161 |
'data-autoplay': attr.autoplay ? '1' : '0', |
| 162 |
'data-speed': attr.speed, |
| 163 |
'data-arrows': attr.showArrows ? '1' : '0', |
| 164 |
'data-dots': attr.showDots ? '1' : '0', |
| 165 |
}, |
| 166 |
el('div', {className:'bkps-track'}, |
| 167 |
attr.slides.map((slide, i)=> |
| 168 |
el('div', {key:i, className:'bkps-slide'+(i===0?' bkps-active':''), |
| 169 |
style:{backgroundImage: slide.imageUrl ? `url(${slide.imageUrl})` : 'none', backgroundColor: slide.imageUrl ? 'transparent':'#1e0a3c'} |
| 170 |
}, |
| 171 |
el('div', {className:'bkps-overlay'}), |
| 172 |
el('div', {className:'bkps-caption', style:{textAlign:attr.captionAlign, alignItems:attr.captionAlign==='center'?'center':attr.captionAlign==='right'?'flex-end':'flex-start'}}, |
| 173 |
el('h2', {className:'bkps-title'}, slide.title), |
| 174 |
el('p', {className:'bkps-excerpt'}, slide.excerpt), |
| 175 |
slide.btnLabel && el('a', {href:slide.btnUrl, className:'bkps-btn'}, slide.btnLabel) |
| 176 |
) |
| 177 |
) |
| 178 |
) |
| 179 |
), |
| 180 |
attr.showArrows && el('div', {className:'bkps-arrows'}, |
| 181 |
el('button', {className:'bkps-arrow bkps-prev','aria-label':'Previous'}, '\u2039'), |
| 182 |
el('button', {className:'bkps-arrow bkps-next','aria-label':'Next'}, '\u203A') |
| 183 |
), |
| 184 |
attr.showDots && el('div', {className:'bkps-dots'}) |
| 185 |
); |
| 186 |
} |
| 187 |
}], |
| 188 |
|
| 189 |
save: function({ attributes: attr }) { |
| 190 |
const _tvFn = getTypoCssVars(); |
| 191 |
const wrapStyle = Object.assign({ |
| 192 |
'--bkps-height': attr.height + attr.heightUnit, |
| 193 |
'--bkps-overlay': attr.overlayBg, |
| 194 |
'--bkps-text': attr.textColor, |
| 195 |
'--bkps-accent': attr.accentColor, |
| 196 |
'--bkps-radius': attr.borderRadius + 'px', |
| 197 |
}, _tvFn(attr.titleTypo, '--bkps-tt-'), _tvFn(attr.excerptTypo, '--bkps-ex-')); |
| 198 |
return el('div', { |
| 199 |
className: 'bkps-wrap bkps-transition-' + attr.transition, |
| 200 |
style: wrapStyle, |
| 201 |
'data-autoplay': attr.autoplay ? '1' : '0', |
| 202 |
'data-speed': attr.speed, |
| 203 |
'data-arrows': attr.showArrows ? '1' : '0', |
| 204 |
'data-dots': attr.showDots ? '1' : '0', |
| 205 |
}, |
| 206 |
el('div', {className:'bkps-track'}, |
| 207 |
attr.slides.map((slide, i)=> |
| 208 |
el('div', {key:i, className:'bkps-slide'+(i===0?' bkps-active':''), |
| 209 |
style:{backgroundImage: slide.imageUrl ? `url(${slide.imageUrl})` : 'none', backgroundColor: slide.imageUrl ? 'transparent':'#1e0a3c'} |
| 210 |
}, |
| 211 |
el('div', {className:'bkps-overlay'}), |
| 212 |
el('div', {className:'bkps-caption', style:{textAlign:attr.captionAlign, alignItems:attr.captionAlign==='center'?'center':attr.captionAlign==='right'?'flex-end':'flex-start'}}, |
| 213 |
el('h2', {className:'bkps-title'}, slide.title), |
| 214 |
el('p', {className:'bkps-excerpt'}, slide.excerpt), |
| 215 |
slide.btnLabel && el('a', {href:slide.btnUrl, className:'bkps-btn'}, slide.btnLabel) |
| 216 |
) |
| 217 |
) |
| 218 |
) |
| 219 |
), |
| 220 |
attr.showArrows && el('div', {className:'bkps-arrows'}, |
| 221 |
el('button', {className:'bkps-arrow bkps-prev','aria-label':'Previous'}, '‹'), |
| 222 |
el('button', {className:'bkps-arrow bkps-next','aria-label':'Next'}, '›') |
| 223 |
), |
| 224 |
attr.showDots && el('div', {className:'bkps-dots'}) |
| 225 |
); |
| 226 |
} |
| 227 |
}); |
| 228 |
}() ); |
| 229 |
|