| 1 |
( function () { |
| 2 |
var el = React.createElement; |
| 3 |
var registerBlockType = wp.blocks.registerBlockType; |
| 4 |
var useBlockProps = wp.blockEditor.useBlockProps; |
| 5 |
var InspectorControls = wp.blockEditor.InspectorControls; |
| 6 |
var PanelBody = wp.components.PanelBody; |
| 7 |
var RangeControl = wp.components.RangeControl; |
| 8 |
var SelectControl = wp.components.SelectControl; |
| 9 |
var TextControl = wp.components.TextControl; |
| 10 |
var TextareaControl = wp.components.TextareaControl; |
| 11 |
var ToggleControl = wp.components.ToggleControl; |
| 12 |
var Button = wp.components.Button; |
| 13 |
var PanelColorSettings = wp.blockEditor.PanelColorSettings; |
| 14 |
|
| 15 |
var _tc, _tv; |
| 16 |
function getTypoControl() { return _tc || (_tc = window.bkbgTypographyControl); } |
| 17 |
function getTypoCssVars() { return _tv || (_tv = window.bkbgTypoCssVars); } |
| 18 |
var IP = function () { return window.bkbgIconPicker; }; |
| 19 |
|
| 20 |
var LAYOUT_OPTS = [ |
| 21 |
{ value: 'left-sticky', label: 'Sticky panel — Left' }, |
| 22 |
{ value: 'right-sticky', label: 'Sticky panel — Right' } |
| 23 |
]; |
| 24 |
|
| 25 |
function FeatureCard(props) { |
| 26 |
var f = props.feature; var a = props.attr; var active = props.active; |
| 27 |
return el('div', { |
| 28 |
style: { |
| 29 |
display:'flex', gap:20, padding:'28px 28px', borderRadius:16, |
| 30 |
border: '1px solid ' + (active ? a.accentColor : (a.cardBorder||'#1f2937')), |
| 31 |
background: active ? (a.activeCardBg||'#1e1b4b') : (a.cardBg||'#111827'), |
| 32 |
transition:'all 0.35s ease', marginBottom:16, |
| 33 |
boxShadow: active ? '0 0 0 1px '+(a.accentColor||'#7c3aed')+'33' : 'none', |
| 34 |
opacity: active ? 1 : 0.65 |
| 35 |
} |
| 36 |
}, |
| 37 |
el('div', { style: { fontSize:(a.cardIconSize||36)+'px', lineHeight:1, flexShrink:0, marginTop:2, color:a.accentColor||'#7c3aed' } }, IP().buildEditorIcon(f.iconType || 'custom-char', f.icon, f.iconDashicon, f.iconImageUrl, f.iconDashiconColor)), |
| 38 |
el('div', null, |
| 39 |
el('div', { className:'bkbg-ssc-card-title', style: { color:a.headingColor||'#fff', marginBottom:6 } }, f.title), |
| 40 |
el('div', { className:'bkbg-ssc-card-desc', style: { color:a.textColor||'#e2e8f0' } }, f.desc) |
| 41 |
) |
| 42 |
); |
| 43 |
} |
| 44 |
|
| 45 |
function StickyPanel(props) { |
| 46 |
var a = props.attr; |
| 47 |
return el('div', { |
| 48 |
style: { background: a.panelBg||'transparent', padding:'0 0 40px' } |
| 49 |
}, |
| 50 |
el('div', { className:'bkbg-ssc-heading', style: { color:a.headingColor||'#fff', marginBottom:20 } }, a.sectionTitle), |
| 51 |
el('div', { className:'bkbg-ssc-subtitle', style: { color:a.textColor||'#e2e8f0', marginBottom:32, maxWidth:380 } }, a.sectionSubtitle), |
| 52 |
a.showCta && el('a', { href:a.ctaUrl||'#', style: { display:'inline-block', background:a.ctaBg||'#7c3aed', color:a.ctaColor||'#fff', padding:'12px 28px', borderRadius:8, fontWeight:700, fontSize:15, textDecoration:'none' } }, a.ctaLabel||'Get Started') |
| 53 |
); |
| 54 |
} |
| 55 |
|
| 56 |
function EditorPreview(props) { |
| 57 |
var a = props.attr; |
| 58 |
var activeIdx = props.activeIdx; |
| 59 |
var features = a.features || []; |
| 60 |
var isLeft = a.layout !== 'right-sticky'; |
| 61 |
|
| 62 |
var stickyPanel = el(StickyPanel, {attr:a}); |
| 63 |
var cardsPanel = el('div', {style:{flex:1}}, features.map(function(f,i){ return el(FeatureCard,{key:i,feature:f,attr:a,active:i===activeIdx}); })); |
| 64 |
|
| 65 |
return el('div', { |
| 66 |
style: { display:'flex', gap:64, flexDirection: isLeft ? 'row' : 'row-reverse', background:a.sectionBg||'#0a0a0f', borderRadius:12, padding:'48px', color:a.textColor||'#e2e8f0' } |
| 67 |
}, |
| 68 |
el('div', { style: { flex:'0 0 340px' } }, stickyPanel), |
| 69 |
cardsPanel |
| 70 |
); |
| 71 |
} |
| 72 |
|
| 73 |
registerBlockType('blockenberg/scroll-sticky-content', { |
| 74 |
title: 'Scroll Sticky Content', |
| 75 |
icon: 'columns', |
| 76 |
category: 'bkbg-effects', |
| 77 |
|
| 78 |
edit: function (props) { |
| 79 |
var attr = props.attributes; var setAttr = props.setAttributes; |
| 80 |
var activeIdx = 0; |
| 81 |
|
| 82 |
function updateFeature(i, key, val) { |
| 83 |
var f = attr.features.map(function(x){return Object.assign({},x);}); |
| 84 |
f[i][key] = val; setAttr({features:f}); |
| 85 |
} |
| 86 |
function addFeature() { |
| 87 |
setAttr({features:attr.features.concat([{icon:'💡',iconType:'custom-char',iconDashicon:'',iconImageUrl:'',title:'New Feature',desc:'Describe this feature.'}])}); |
| 88 |
} |
| 89 |
function removeFeature(i) { |
| 90 |
var f = attr.features.filter(function(_,j){return j!==i;}); |
| 91 |
setAttr({features:f}); |
| 92 |
} |
| 93 |
|
| 94 |
var featurePanels = (attr.features||[]).map(function(f,i){ |
| 95 |
return el(PanelBody, { key:i, title:'Item '+(i+1)+': '+f.title, initialOpen:false }, |
| 96 |
el(IP().IconPickerControl, IP().iconPickerProps(f, function (key, val) { updateFeature(i, key, val); }, { label: 'Icon', typeAttr: 'iconType', dashiconAttr: 'iconDashicon', imageUrlAttr: 'iconImageUrl' })), |
| 97 |
el(TextControl,{__nextHasNoMarginBottom:true,label:'Title',value:f.title,onChange:function(v){updateFeature(i,'title',v);}}), |
| 98 |
el(TextareaControl,{__nextHasNoMarginBottom:true,label:'Description',value:f.desc,onChange:function(v){updateFeature(i,'desc',v);}}), |
| 99 |
el(Button,{variant:'tertiary',isDestructive:true,isSmall:true,onClick:function(){removeFeature(i);}},'Remove Item') |
| 100 |
); |
| 101 |
}); |
| 102 |
|
| 103 |
return el(React.Fragment, null, |
| 104 |
el(InspectorControls, null, |
| 105 |
el(PanelBody, {title:'Panel Content', initialOpen:true}, |
| 106 |
el(TextControl,{__nextHasNoMarginBottom:true,label:'Heading',value:attr.sectionTitle,onChange:function(v){setAttr({sectionTitle:v});}}), |
| 107 |
el(TextareaControl,{__nextHasNoMarginBottom:true,label:'Subtext',value:attr.sectionSubtitle,onChange:function(v){setAttr({sectionSubtitle:v});}}), |
| 108 |
el(ToggleControl,{__nextHasNoMarginBottom:true,label:'Show CTA Button',checked:attr.showCta,onChange:function(v){setAttr({showCta:v});}}), |
| 109 |
attr.showCta && el(TextControl,{__nextHasNoMarginBottom:true,label:'CTA Label',value:attr.ctaLabel,onChange:function(v){setAttr({ctaLabel:v});}}), |
| 110 |
attr.showCta && el(TextControl,{__nextHasNoMarginBottom:true,label:'CTA URL',value:attr.ctaUrl,onChange:function(v){setAttr({ctaUrl:v});}}) |
| 111 |
), |
| 112 |
el(PanelBody, {title:'Layout & Scroll',initialOpen:false}, |
| 113 |
el(SelectControl,{__nextHasNoMarginBottom:true,label:'Sticky Panel Position',value:attr.layout,options:LAYOUT_OPTS,onChange:function(v){setAttr({layout:v});}}), |
| 114 |
el(RangeControl,{__nextHasNoMarginBottom:true,label:'Sticky Top Offset (px)',value:attr.stickyOffset,min:0,max:200,onChange:function(v){setAttr({stickyOffset:v});}}), |
| 115 |
el(ToggleControl,{__nextHasNoMarginBottom:true,label:'Line Connector',checked:attr.lineConnector,onChange:function(v){setAttr({lineConnector:v});}}), |
| 116 |
el(ToggleControl,{__nextHasNoMarginBottom:true,label:'Animate Cards on Scroll',checked:attr.animateCards,onChange:function(v){setAttr({animateCards:v});}}), |
| 117 |
el(RangeControl,{__nextHasNoMarginBottom:true,label:'Intersection Threshold',value:attr.threshold,min:0.1,max:0.9,step:0.05,onChange:function(v){setAttr({threshold:v});}}) |
| 118 |
), |
| 119 |
el(PanelBody, {title:'Spacing & Sizes',initialOpen:false}, |
| 120 |
el(RangeControl,{__nextHasNoMarginBottom:true,label:'Padding Top (px)',value:attr.paddingTop,min:0,max:200,onChange:function(v){setAttr({paddingTop:v});}}), |
| 121 |
el(RangeControl,{__nextHasNoMarginBottom:true,label:'Padding Bottom (px)',value:attr.paddingBottom,min:0,max:200,onChange:function(v){setAttr({paddingBottom:v});}}), |
| 122 |
el(RangeControl,{__nextHasNoMarginBottom:true,label:'Card Icon Size (px)',value:attr.cardIconSize,min:16,max:80,onChange:function(v){setAttr({cardIconSize:v});}}), |
| 123 |
), |
| 124 |
|
| 125 |
el( PanelBody, { title: 'Typography', initialOpen: false }, |
| 126 |
getTypoControl() && el(getTypoControl(), { label: 'Heading Typography', value: attr.headingTypo||{}, onChange: function(v){ setAttr({headingTypo:v}); } }), |
| 127 |
getTypoControl() && el(getTypoControl(), { label: 'Subtitle Typography', value: attr.subtitleTypo||{}, onChange: function(v){ setAttr({subtitleTypo:v}); } }), |
| 128 |
getTypoControl() && el(getTypoControl(), { label: 'Card Title Typography', value: attr.cardTitleTypo||{}, onChange: function(v){ setAttr({cardTitleTypo:v}); } }), |
| 129 |
getTypoControl() && el(getTypoControl(), { label: 'Card Desc Typography', value: attr.cardDescTypo||{}, onChange: function(v){ setAttr({cardDescTypo:v}); } }) |
| 130 |
), |
| 131 |
el(PanelColorSettings, { |
| 132 |
title:'Colors', initialOpen:false, |
| 133 |
colorSettings:[ |
| 134 |
{value:attr.sectionBg, onChange:function(v){setAttr({sectionBg: v||'#0a0a0f'});},label:'Section Background'}, |
| 135 |
{value:attr.headingColor, onChange:function(v){setAttr({headingColor: v||'#ffffff'});},label:'Heading'}, |
| 136 |
{value:attr.textColor, onChange:function(v){setAttr({textColor: v||'#e2e8f0'});},label:'Body Text'}, |
| 137 |
{value:attr.accentColor, onChange:function(v){setAttr({accentColor: v||'#7c3aed'});},label:'Accent'}, |
| 138 |
{value:attr.cardBg, onChange:function(v){setAttr({cardBg: v||'#111827'});},label:'Card Background'}, |
| 139 |
{value:attr.activeCardBg, onChange:function(v){setAttr({activeCardBg: v||'#1e1b4b'});},label:'Active Card Bg'}, |
| 140 |
{value:attr.cardBorder, onChange:function(v){setAttr({cardBorder: v||'#1f2937'});},label:'Card Border'}, |
| 141 |
attr.showCta && {value:attr.ctaBg, onChange:function(v){setAttr({ctaBg: v||'#7c3aed'});},label:'CTA Background'}, |
| 142 |
attr.showCta && {value:attr.ctaColor,onChange:function(v){setAttr({ctaColor: v||'#ffffff'});},label:'CTA Text'} |
| 143 |
].filter(Boolean) |
| 144 |
}), |
| 145 |
el(PanelBody, {title:'Features', initialOpen:false}, |
| 146 |
featurePanels, |
| 147 |
el(Button,{variant:'secondary',isSmall:true,style:{marginTop:8},onClick:addFeature},'+ Add Feature') |
| 148 |
) |
| 149 |
), |
| 150 |
el('div', useBlockProps((function(){ |
| 151 |
var _tv = getTypoCssVars(); |
| 152 |
var s = {}; |
| 153 |
if(_tv) Object.assign(s, _tv(attr.headingTypo||{}, '--bkssc-ht-')); |
| 154 |
if(_tv) Object.assign(s, _tv(attr.subtitleTypo||{}, '--bkssc-st-')); |
| 155 |
if(_tv) Object.assign(s, _tv(attr.cardTitleTypo||{}, '--bkssc-ct-')); |
| 156 |
if(_tv) Object.assign(s, _tv(attr.cardDescTypo||{}, '--bkssc-cd-')); |
| 157 |
return { style: s }; |
| 158 |
})()), el(EditorPreview, {attr:attr, activeIdx:activeIdx})) |
| 159 |
); |
| 160 |
}, |
| 161 |
|
| 162 |
save: function (props) { |
| 163 |
return el('div', useBlockProps.save(), |
| 164 |
el('div', { className:'bkbg-ssc-app', 'data-opts':JSON.stringify(props.attributes) }) |
| 165 |
); |
| 166 |
} |
| 167 |
}); |
| 168 |
}() ); |
| 169 |
|