| 1 |
(function () { |
| 2 |
var el = wp.element.createElement; |
| 3 |
var Fragment = wp.element.Fragment; |
| 4 |
var registerBlockType = wp.blocks.registerBlockType; |
| 5 |
var __ = wp.i18n.__; |
| 6 |
var InspectorControls = wp.blockEditor.InspectorControls; |
| 7 |
var PanelColorSettings = wp.blockEditor.PanelColorSettings; |
| 8 |
var useBlockProps = wp.blockEditor.useBlockProps; |
| 9 |
var MediaUpload = wp.blockEditor.MediaUpload; |
| 10 |
var MediaUploadCheck = wp.blockEditor.MediaUploadCheck; |
| 11 |
var PanelBody = wp.components.PanelBody; |
| 12 |
var RangeControl = wp.components.RangeControl; |
| 13 |
var ToggleControl = wp.components.ToggleControl; |
| 14 |
var TextControl = wp.components.TextControl; |
| 15 |
var SelectControl = wp.components.SelectControl; |
| 16 |
var Button = wp.components.Button; |
| 17 |
|
| 18 |
var _tc, _tvf; |
| 19 |
Object.defineProperty(window, '_tc', { get: function () { return _tc || (_tc = window.bkbgTypographyControl); } }); |
| 20 |
Object.defineProperty(window, '_tvf', { get: function () { return _tvf || (_tvf = window.bkbgTypoCssVars); } }); |
| 21 |
function getTypoControl(p, key, label) { return _tc ? _tc(p, key, label) : null; } |
| 22 |
function getTypoCssVars(a) { |
| 23 |
if (!_tvf) return {}; |
| 24 |
var v = {}; |
| 25 |
Object.assign(v, _tvf(a.labelTypo || {}, '--bktb-lb-')); |
| 26 |
Object.assign(v, _tvf(a.sublabelTypo || {}, '--bktb-sl-')); |
| 27 |
return v; |
| 28 |
} |
| 29 |
|
| 30 |
var LAYOUT_OPTIONS = [ |
| 31 |
{ label: 'Single row', value: 'row' }, |
| 32 |
{ label: '2-column grid', value: 'grid-2' }, |
| 33 |
{ label: '3-column grid', value: 'grid-3' }, |
| 34 |
]; |
| 35 |
var CARD_STYLE_OPTIONS = [ |
| 36 |
{ label: 'Plain', value: 'plain' }, |
| 37 |
{ label: 'Card', value: 'card' }, |
| 38 |
{ label: 'Bordered', value: 'bordered' }, |
| 39 |
]; |
| 40 |
var TEXT_ALIGN_OPTIONS = [ |
| 41 |
{ label: 'Left', value: 'left' }, |
| 42 |
{ label: 'Center', value: 'center' }, |
| 43 |
{ label: 'Right', value: 'right' }, |
| 44 |
]; |
| 45 |
|
| 46 |
/* Inline SVG icons */ |
| 47 |
var ICONS = { |
| 48 |
shield: 'M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z', |
| 49 |
lock: 'M19 11H5a2 2 0 00-2 2v7a2 2 0 002 2h14a2 2 0 002-2v-7a2 2 0 00-2-2zM12 7a3 3 0 016 0v4H6V7a3 3 0 016 0z', |
| 50 |
check: 'M22 11.08V12a10 10 0 11-5.93-9.14M22 4L12 14.01l-3-3', |
| 51 |
bolt: 'M13 2L3 14h9l-1 8 10-12h-9l1-8z', |
| 52 |
headphones: 'M3 18v-6a9 9 0 0118 0v6M3 18a2 2 0 002 2h1a2 2 0 002-2v-3a2 2 0 00-2-2H3v5zM21 18a2 2 0 01-2 2h-1a2 2 0 01-2-2v-3a2 2 0 012-2h3v5z', |
| 53 |
star: 'M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z', |
| 54 |
award: 'M12 15a7 7 0 100-14 7 7 0 000 14zM8.21 13.89L7 23l5-3 5 3-1.21-9.12', |
| 55 |
users: 'M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2M9 11a4 4 0 100-8 4 4 0 000 8zM23 21v-2a4 4 0 00-3-3.87M16 3.13a4 4 0 010 7.75', |
| 56 |
cloud: 'M18 10h-1.26A8 8 0 109 20h9a5 5 0 000-10z', |
| 57 |
eye: 'M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8zM12 9a3 3 0 100 6 3 3 0 000-6z', |
| 58 |
}; |
| 59 |
var ICON_OPTIONS = [ |
| 60 |
{ label: 'Shield', value: 'shield' }, |
| 61 |
{ label: 'Lock', value: 'lock' }, |
| 62 |
{ label: 'Checkmark', value: 'check' }, |
| 63 |
{ label: 'Lightning', value: 'bolt' }, |
| 64 |
{ label: 'Headphones', value: 'headphones' }, |
| 65 |
{ label: 'Star', value: 'star' }, |
| 66 |
{ label: 'Award', value: 'award' }, |
| 67 |
{ label: 'Users', value: 'users' }, |
| 68 |
{ label: 'Cloud', value: 'cloud' }, |
| 69 |
{ label: 'Eye', value: 'eye' }, |
| 70 |
{ label: 'Custom image',value: 'image' }, |
| 71 |
]; |
| 72 |
|
| 73 |
function makeId() { return 'tb' + Math.random().toString(36).substr(2, 6); } |
| 74 |
|
| 75 |
function renderIcon(item, a) { |
| 76 |
if (item.icon === 'image' && item.imageUrl) { |
| 77 |
return el('img', { src: item.imageUrl, alt: item.label, style: { width: a.iconSize + 'px', height: a.iconSize + 'px', objectFit: 'contain', display: 'block' } }); |
| 78 |
} |
| 79 |
var path = ICONS[item.icon] || ICONS.shield; |
| 80 |
var iconEl = el('svg', { |
| 81 |
viewBox: '0 0 24 24', width: a.iconSize, height: a.iconSize, |
| 82 |
fill: 'none', stroke: a.iconColor || '#6c3fb5', strokeWidth: 2, |
| 83 |
strokeLinecap: 'round', strokeLinejoin: 'round', |
| 84 |
style: { display: 'block', flexShrink: 0 } |
| 85 |
}, el('path', { d: path })); |
| 86 |
if (a.iconBgSize > 0) { |
| 87 |
return el('div', { style: { width: a.iconBgSize + 'px', height: a.iconBgSize + 'px', borderRadius: a.iconBgRadius + 'px', background: a.iconBg || 'rgba(108,63,181,0.1)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 } }, iconEl); |
| 88 |
} |
| 89 |
return iconEl; |
| 90 |
} |
| 91 |
|
| 92 |
function gridStyle(layout, gap) { |
| 93 |
if (layout === 'row') return { display: 'flex', flexWrap: 'wrap', alignItems: 'center', justifyContent: 'center', gap: gap + 'px' }; |
| 94 |
var cols = layout === 'grid-2' ? 2 : 3; |
| 95 |
return { display: 'grid', gridTemplateColumns: 'repeat(' + cols + ', 1fr)', gap: gap + 'px' }; |
| 96 |
} |
| 97 |
|
| 98 |
function itemBoxStyle(a) { |
| 99 |
var base = { display: 'flex', flexDirection: 'column', alignItems: a.textAlign === 'center' ? 'center' : (a.textAlign === 'right' ? 'flex-end' : 'flex-start'), textAlign: a.textAlign, padding: a.cardPadding + 'px', gap: '8px', borderRadius: a.cardRadius + 'px' }; |
| 100 |
if (a.cardStyle === 'card') return Object.assign({}, base, { background: a.cardBg || '#fff', boxShadow: '0 2px 12px rgba(0,0,0,0.08)' }); |
| 101 |
if (a.cardStyle === 'bordered') return Object.assign({}, base, { background: a.cardBg || 'transparent', border: '1.5px solid rgba(108,63,181,0.15)' }); |
| 102 |
return base; |
| 103 |
} |
| 104 |
|
| 105 |
registerBlockType('blockenberg/trust-bar', { |
| 106 |
edit: function (props) { |
| 107 |
var attributes = props.attributes; |
| 108 |
var setAttributes = props.setAttributes; |
| 109 |
var items = attributes.items; |
| 110 |
var blockProps = useBlockProps((function () { |
| 111 |
var _tv = getTypoCssVars(attributes); |
| 112 |
var s = { paddingTop: attributes.paddingTop + 'px', paddingBottom: attributes.paddingBottom + 'px', backgroundColor: attributes.bgColor || undefined }; |
| 113 |
Object.assign(s, _tv); |
| 114 |
return { className: 'bkbg-trust-bar-wrap', style: s }; |
| 115 |
})()); |
| 116 |
|
| 117 |
function setItem(id, patch) { setAttributes({ items: items.map(function (it) { return it.id === id ? Object.assign({}, it, patch) : it; }) }); } |
| 118 |
function addItem() { setAttributes({ items: items.concat([{ id: makeId(), icon: 'shield', label: 'Security', sublabel: 'Grade A', imageUrl: '', imageId: 0 }]) }); } |
| 119 |
function removeItem(id) { if (items.length <= 1) return; setAttributes({ items: items.filter(function (it) { return it.id !== id; }) }); } |
| 120 |
|
| 121 |
return el(Fragment, null, |
| 122 |
el(InspectorControls, null, |
| 123 |
el(PanelBody, { title: __('Layout', 'blockenberg'), initialOpen: true }, |
| 124 |
el(SelectControl, { label: __('Layout', 'blockenberg'), value: attributes.layout, options: LAYOUT_OPTIONS, onChange: function (v) { setAttributes({ layout: v }); } }), |
| 125 |
el(SelectControl, { label: __('Card style', 'blockenberg'), value: attributes.cardStyle, options: CARD_STYLE_OPTIONS, onChange: function (v) { setAttributes({ cardStyle: v }); } }), |
| 126 |
el(SelectControl, { label: __('Text alignment', 'blockenberg'), value: attributes.textAlign, options: TEXT_ALIGN_OPTIONS, onChange: function (v) { setAttributes({ textAlign: v }); } }), |
| 127 |
el(ToggleControl, { label: __('Show sublabel', 'blockenberg'), checked: attributes.showSublabel, onChange: function (v) { setAttributes({ showSublabel: v }); }, __nextHasNoMarginBottom: true }), |
| 128 |
el(ToggleControl, { label: __('Show divider between items', 'blockenberg'), checked: attributes.showDivider, onChange: function (v) { setAttributes({ showDivider: v }); }, __nextHasNoMarginBottom: true }), |
| 129 |
el(RangeControl, { label: __('Gap (px)', 'blockenberg'), value: attributes.gap, min: 0, max: 80, onChange: function (v) { setAttributes({ gap: v }); } }) |
| 130 |
), |
| 131 |
el(PanelBody, { title: __('Icon', 'blockenberg'), initialOpen: false }, |
| 132 |
el(RangeControl, { label: __('Icon size (px)', 'blockenberg'), value: attributes.iconSize, min: 16, max: 64, onChange: function (v) { setAttributes({ iconSize: v }); } }), |
| 133 |
el(RangeControl, { label: __('Icon bg size (px, 0 = none)', 'blockenberg'), value: attributes.iconBgSize, min: 0, max: 120, onChange: function (v) { setAttributes({ iconBgSize: v }); } }), |
| 134 |
el(RangeControl, { label: __('Icon bg radius (px)', 'blockenberg'), value: attributes.iconBgRadius, min: 0, max: 60, onChange: function (v) { setAttributes({ iconBgRadius: v }); } }) |
| 135 |
), |
| 136 |
el(PanelBody, { title: __('Typography', 'blockenberg'), initialOpen: false }, |
| 137 |
getTypoControl(props, 'labelTypo', __('Label', 'blockenberg')), |
| 138 |
getTypoControl(props, 'sublabelTypo', __('Sublabel', 'blockenberg')) |
| 139 |
), |
| 140 |
el(PanelBody, { title: __('Appearance', 'blockenberg'), initialOpen: false }, |
| 141 |
el(RangeControl, { label: __('Card radius (px)', 'blockenberg'), value: attributes.cardRadius, min: 0, max: 32, onChange: function (v) { setAttributes({ cardRadius: v }); } }), |
| 142 |
el(RangeControl, { label: __('Card padding (px)', 'blockenberg'), value: attributes.cardPadding, min: 4, max: 48, onChange: function (v) { setAttributes({ cardPadding: v }); } }) |
| 143 |
), |
| 144 |
el(PanelColorSettings, { |
| 145 |
title: __('Colors', 'blockenberg'), initialOpen: false, |
| 146 |
colorSettings: [ |
| 147 |
{ value: attributes.iconColor, onChange: function (v) { setAttributes({ iconColor: v || '' }); }, label: __('Icon', 'blockenberg') }, |
| 148 |
{ value: attributes.iconBg, onChange: function (v) { setAttributes({ iconBg: v || '' }); }, label: __('Icon background', 'blockenberg') }, |
| 149 |
{ value: attributes.labelColor, onChange: function (v) { setAttributes({ labelColor: v || '' }); }, label: __('Label', 'blockenberg') }, |
| 150 |
{ value: attributes.sublabelColor,onChange: function (v) { setAttributes({ sublabelColor: v || '' }); },label: __('Sublabel', 'blockenberg') }, |
| 151 |
{ value: attributes.dividerColor, onChange: function (v) { setAttributes({ dividerColor: v || '' }); }, label: __('Divider', 'blockenberg') }, |
| 152 |
{ value: attributes.cardBg, onChange: function (v) { setAttributes({ cardBg: v || '' }); }, label: __('Card background', 'blockenberg') }, |
| 153 |
{ value: attributes.bgColor, onChange: function (v) { setAttributes({ bgColor: v || '' }); }, label: __('Section background', 'blockenberg') }, |
| 154 |
] |
| 155 |
}), |
| 156 |
el(PanelBody, { title: __('Spacing', 'blockenberg'), initialOpen: false }, |
| 157 |
el(RangeControl, { label: __('Padding top (px)', 'blockenberg'), value: attributes.paddingTop, min: 0, max: 200, onChange: function (v) { setAttributes({ paddingTop: v }); } }), |
| 158 |
el(RangeControl, { label: __('Padding bottom (px)', 'blockenberg'), value: attributes.paddingBottom, min: 0, max: 200, onChange: function (v) { setAttributes({ paddingBottom: v }); } }) |
| 159 |
), |
| 160 |
el(PanelBody, { title: __('Items', 'blockenberg'), initialOpen: false }, |
| 161 |
items.map(function (item, idx) { |
| 162 |
return el(PanelBody, { key: item.id, title: (item.label || 'Item') + ' #' + (idx + 1), initialOpen: false }, |
| 163 |
el(SelectControl, { label: __('Icon', 'blockenberg'), value: item.icon, options: ICON_OPTIONS, onChange: function (v) { setItem(item.id, { icon: v }); } }), |
| 164 |
item.icon === 'image' && el(Fragment, null, |
| 165 |
el(MediaUploadCheck, null, |
| 166 |
el(MediaUpload, { |
| 167 |
onSelect: function (media) { setItem(item.id, { imageUrl: media.url, imageId: media.id }); }, |
| 168 |
allowedTypes: ['image'], |
| 169 |
value: item.imageId, |
| 170 |
render: function (ref) { return el(Button, { onClick: ref.open, variant: 'secondary', size: 'compact', style: { marginBottom: '6px' } }, item.imageUrl ? __('Change image', 'blockenberg') : __('Upload image', 'blockenberg')); } |
| 171 |
}) |
| 172 |
), |
| 173 |
item.imageUrl && el(Button, { onClick: function () { setItem(item.id, { imageUrl: '', imageId: 0 }); }, variant: 'tertiary', size: 'compact', isDestructive: true, style: { display: 'block', marginBottom: '6px' } }, __('Remove image', 'blockenberg')) |
| 174 |
), |
| 175 |
el(TextControl, { label: __('Label', 'blockenberg'), value: item.label, onChange: function (v) { setItem(item.id, { label: v }); } }), |
| 176 |
el(TextControl, { label: __('Sublabel', 'blockenberg'), value: item.sublabel, onChange: function (v) { setItem(item.id, { sublabel: v }); } }), |
| 177 |
items.length > 1 && el(Button, { onClick: function () { removeItem(item.id); }, variant: 'tertiary', size: 'compact', isDestructive: true }, __('Remove item', 'blockenberg')) |
| 178 |
); |
| 179 |
}), |
| 180 |
el(Button, { onClick: addItem, variant: 'primary', style: { marginTop: '8px' } }, __('+ Add Item', 'blockenberg')) |
| 181 |
) |
| 182 |
), |
| 183 |
|
| 184 |
el('div', blockProps, |
| 185 |
el('div', { className: 'bkbg-trust-bar', style: gridStyle(attributes.layout, attributes.gap) }, |
| 186 |
items.map(function (item, idx) { |
| 187 |
return el(Fragment, { key: item.id }, |
| 188 |
attributes.showDivider && idx > 0 && attributes.layout === 'row' && el('div', { style: { width: '1px', height: '40px', background: attributes.dividerColor || '#e5e7eb', flexShrink: 0 } }), |
| 189 |
el('div', { className: 'bkbg-trust-bar-item', style: itemBoxStyle(attributes) }, |
| 190 |
renderIcon(item, attributes), |
| 191 |
el('div', null, |
| 192 |
el('p', { className: 'bkbg-tb-label', style: { margin: 0, color: attributes.labelColor || undefined } }, item.label), |
| 193 |
attributes.showSublabel && item.sublabel && el('p', { className: 'bkbg-tb-sublabel', style: { margin: 0, color: attributes.sublabelColor || undefined, opacity: 0.7 } }, item.sublabel) |
| 194 |
) |
| 195 |
) |
| 196 |
); |
| 197 |
}) |
| 198 |
) |
| 199 |
) |
| 200 |
); |
| 201 |
}, |
| 202 |
|
| 203 |
save: function (props) { |
| 204 |
var a = props.attributes; |
| 205 |
var blockProps = wp.blockEditor.useBlockProps.save((function () { |
| 206 |
var _tv = getTypoCssVars(a); |
| 207 |
var s = { paddingTop: a.paddingTop + 'px', paddingBottom: a.paddingBottom + 'px', backgroundColor: a.bgColor || undefined }; |
| 208 |
Object.assign(s, _tv); |
| 209 |
return { className: 'bkbg-trust-bar-wrap', style: s }; |
| 210 |
})()); |
| 211 |
|
| 212 |
function iconSVG(item) { |
| 213 |
if (item.icon === 'image' && item.imageUrl) { |
| 214 |
return el('img', { src: item.imageUrl, alt: item.label, style: { width: a.iconSize + 'px', height: a.iconSize + 'px', objectFit: 'contain', display: 'block' } }); |
| 215 |
} |
| 216 |
var path = ICONS[item.icon] || ICONS.shield; |
| 217 |
var iconEl = el('svg', { viewBox: '0 0 24 24', width: a.iconSize, height: a.iconSize, fill: 'none', stroke: a.iconColor || '#6c3fb5', strokeWidth: 2, strokeLinecap: 'round', strokeLinejoin: 'round', 'aria-hidden': 'true', style: { display: 'block', flexShrink: 0 } }, el('path', { d: path })); |
| 218 |
if (a.iconBgSize > 0) { |
| 219 |
return el('div', { style: { width: a.iconBgSize + 'px', height: a.iconBgSize + 'px', borderRadius: a.iconBgRadius + 'px', background: a.iconBg || 'rgba(108,63,181,0.1)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 } }, iconEl); |
| 220 |
} |
| 221 |
return iconEl; |
| 222 |
} |
| 223 |
|
| 224 |
return el('div', blockProps, |
| 225 |
el('div', { className: 'bkbg-trust-bar', style: gridStyle(a.layout, a.gap) }, |
| 226 |
a.items.map(function (item, idx) { |
| 227 |
return el(Fragment, { key: item.id }, |
| 228 |
a.showDivider && idx > 0 && a.layout === 'row' && el('div', { className: 'bkbg-trust-bar-divider', style: { width: '1px', height: '40px', background: a.dividerColor || '#e5e7eb', flexShrink: 0 } }), |
| 229 |
el('div', { className: 'bkbg-trust-bar-item', style: itemBoxStyle(a) }, |
| 230 |
iconSVG(item), |
| 231 |
el('div', null, |
| 232 |
el('p', { className: 'bkbg-tb-label', style: { margin: 0, color: a.labelColor || undefined } }, item.label), |
| 233 |
a.showSublabel && item.sublabel && el('p', { className: 'bkbg-tb-sublabel', style: { margin: 0, color: a.sublabelColor || undefined, opacity: 0.7 } }, item.sublabel) |
| 234 |
) |
| 235 |
) |
| 236 |
); |
| 237 |
}) |
| 238 |
) |
| 239 |
); |
| 240 |
} |
| 241 |
}); |
| 242 |
}()); |
| 243 |
|