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 / badge-wall / index.js

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

174 lines 13.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, useBlockProps, PanelColorSettings } = window.wp.blockEditor;
5 const { PanelBody, RangeControl, ToggleControl, TextControl, Button } = window.wp.components;
6 const { __ } = window.wp.i18n;
7 var IP = function () { return window.bkbgIconPicker; };
8
9 function getTypographyControl() {
10 return (typeof window.bkbgTypographyControl !== 'undefined') ? window.bkbgTypographyControl : null;
11 }
12 function getTypoCssVars() {
13 return (typeof window.bkbgTypoCssVars !== 'undefined') ? window.bkbgTypoCssVars : function() { return {}; };
14 }
15
16 function buildWrapStyle( a ) {
17 var _tv = getTypoCssVars();
18 var s = { background: a.bgColor || undefined, boxSizing: 'border-box' };
19 Object.assign( s, _tv( a.headingTypo || {}, '--bkbg-bw-heading-' ) );
20 Object.assign( s, _tv( a.subtitleTypo || {}, '--bkbg-bw-sub-' ) );
21 Object.assign( s, _tv( a.labelTypo || {}, '--bkbg-bw-label-' ) );
22 Object.assign( s, _tv( a.issuerTypo || {}, '--bkbg-bw-issuer-' ) );
23 return s;
24 }
25
26 // ── Badge card ────────────────────────────────────────────────────────────
27 function BadgeCard( props ) {
28 const { badge, a, forSave } = props;
29 const accentClr = badge.accentColor || '#6366f1';
30 return el( 'div', {
31 className: 'bkbg-bw-card',
32 style: {
33 background: a.cardBg,
34 border: `1px solid ${ a.borderColor }`,
35 borderRadius: a.borderRadius + 'px',
36 padding: a.cardPadding + 'px',
37 boxSizing: 'border-box',
38 display: 'flex',
39 flexDirection: 'column',
40 alignItems: 'center',
41 textAlign: 'center',
42 gap: 8,
43 position: 'relative',
44 overflow: 'hidden',
45 }
46 },
47 // Soft accent glow in top-right
48 el( 'div', { style: { position: 'absolute', top: -20, right: -20, width: 70, height: 70, borderRadius: '50%', background: accentClr, opacity: 0.12 } } ),
49
50 // Icon
51 a.showIcon && badge.icon && el( 'div', { className: 'bkbg-bw-icon', style: { fontSize: a.iconSize + 'px', lineHeight: 1 } }, (badge.iconType || 'custom-char') !== 'custom-char' ? (forSave ? IP().buildSaveIcon(badge.iconType, badge.icon, badge.iconDashicon, badge.iconImageUrl, badge.iconDashiconColor) : IP().buildEditorIcon(badge.iconType, badge.icon, badge.iconDashicon, badge.iconImageUrl, badge.iconDashiconColor)) : badge.icon ),
52
53 // Label
54 a.showLabel && badge.label && el( 'div', { className: 'bkbg-bw-label', style: { color: a.labelColor } }, badge.label ),
55
56 // Issuer
57 a.showIssuer && badge.issuer && el( 'div', { className: 'bkbg-bw-issuer', style: { color: a.issuerColor } }, badge.issuer ),
58
59 // Year pill
60 a.showYear && badge.year && el( 'span', { className: 'bkbg-bw-year', style: { color: accentClr, background: accentClr + '1a' } }, badge.year ),
61 );
62 }
63
64 function renderBadgeWall( a, forSave ) {
65 return el( 'div', { className: 'bkbg-bw-grid', style: { display: 'grid', gridTemplateColumns: `repeat(${ a.columns }, 1fr)`, gap: 16 } },
66 ( a.badges || [] ).map( ( badge, i ) => el( BadgeCard, { key: i, badge, a, forSave } ) )
67 );
68 }
69
70 function updBadge( setAttributes, badges, bi, field, val ) {
71 setAttributes( { badges: badges.map( ( b, i ) => i === bi ? { ...b, [field]: val } : b ) } );
72 }
73
74 // ── Block ─────────────────────────────────────────────────────────────────
75 registerBlockType( 'blockenberg/badge-wall', {
76 edit: function ( props ) {
77 const { attributes: a, setAttributes } = props;
78 const blockProps = useBlockProps( { className: 'bkbg-bw-wrap', style: buildWrapStyle( a ) } );
79
80 return el( 'div', blockProps,
81 el( InspectorControls, {},
82
83 el( PanelBody, { title: __( 'Settings', 'blockenberg' ), initialOpen: true },
84 el( TextControl, { label: __( 'Title', 'blockenberg' ), value: a.title, onChange: v => setAttributes( { title: v } ) } ),
85 el( ToggleControl, { label: __( 'Show Title', 'blockenberg' ), checked: a.showTitle, onChange: v => setAttributes( { showTitle: v } ) } ),
86 el( TextControl, { label: __( 'Subtitle', 'blockenberg' ), value: a.subtitle, onChange: v => setAttributes( { subtitle: v } ) } ),
87 el( ToggleControl, { label: __( 'Show Subtitle', 'blockenberg' ), checked: a.showSubtitle, onChange: v => setAttributes( { showSubtitle: v } ) } ),
88 el( RangeControl, { label: __( 'Columns', 'blockenberg' ), value: a.columns, onChange: v => setAttributes( { columns: v } ), min: 1, max: 8 } ),
89 el( ToggleControl, { label: __( 'Show Icons', 'blockenberg' ), checked: a.showIcon, onChange: v => setAttributes( { showIcon: v } ) } ),
90 el( ToggleControl, { label: __( 'Show Labels', 'blockenberg' ), checked: a.showLabel, onChange: v => setAttributes( { showLabel: v } ) } ),
91 el( ToggleControl, { label: __( 'Show Issuers', 'blockenberg' ), checked: a.showIssuer, onChange: v => setAttributes( { showIssuer: v } ) } ),
92 el( ToggleControl, { label: __( 'Show Years', 'blockenberg' ), checked: a.showYear, onChange: v => setAttributes( { showYear: v } ) } ),
93 ),
94
95 el( PanelBody, { title: __( 'Style', 'blockenberg' ), initialOpen: false },
96 el( RangeControl, { label: __( 'Icon Size', 'blockenberg' ), value: a.iconSize, onChange: v => setAttributes( { iconSize: v } ), min: 20, max: 80 } ),
97 el( RangeControl, { label: __( 'Border Radius', 'blockenberg' ), value: a.borderRadius, onChange: v => setAttributes( { borderRadius: v } ), min: 0, max: 32 } ),
98 el( RangeControl, { label: __( 'Card Padding', 'blockenberg' ), value: a.cardPadding, onChange: v => setAttributes( { cardPadding: v } ), min: 8, max: 48 } ),
99 ),
100
101
102 el( PanelBody, { title: __( 'Typography', 'blockenberg' ), initialOpen: false },
103 (function () {
104 var TC = getTypographyControl();
105 if (!TC) return el('p', { style: { color: '#999', fontSize: '12px', padding: '8px 0' } }, __('Typography control loading…', 'blockenberg'));
106 return el(window.wp.element.Fragment, {},
107 el(TC, { label: __('Heading', 'blockenberg'), value: a.headingTypo || {}, onChange: function (v) { setAttributes({ headingTypo: v }); } }),
108 el(TC, { label: __('Subtitle', 'blockenberg'), value: a.subtitleTypo || {}, onChange: function (v) { setAttributes({ subtitleTypo: v }); } }),
109 el(TC, { label: __('Label', 'blockenberg'), value: a.labelTypo || {}, onChange: function (v) { setAttributes({ labelTypo: v }); } }),
110 el(TC, { label: __('Issuer', 'blockenberg'), value: a.issuerTypo || {}, onChange: function (v) { setAttributes({ issuerTypo: v }); } })
111 );
112 })()
113 ),
114 el( PanelColorSettings, {
115 title: __( 'Colors', 'blockenberg' ), initialOpen: false,
116 colorSettings: [
117 { label: __( 'Wrapper BG', 'blockenberg' ), value: a.bgColor, onChange: v => setAttributes( { bgColor: v || '#ffffff' } ) },
118 { label: __( 'Card BG', 'blockenberg' ), value: a.cardBg, onChange: v => setAttributes( { cardBg: v || '#f9fafb' } ) },
119 { label: __( 'Border', 'blockenberg' ), value: a.borderColor, onChange: v => setAttributes( { borderColor: v || '#e5e7eb' } ) },
120 { label: __( 'Heading', 'blockenberg' ), value: a.headingColor, onChange: v => setAttributes( { headingColor: v || '#111827' } ) },
121 { label: __( 'Subtitle', 'blockenberg' ), value: a.subtitleColor,onChange: v => setAttributes( { subtitleColor:v || '#6b7280' } ) },
122 { label: __( 'Label', 'blockenberg' ), value: a.labelColor, onChange: v => setAttributes( { labelColor: v || '#111827' } ) },
123 { label: __( 'Issuer', 'blockenberg' ), value: a.issuerColor, onChange: v => setAttributes( { issuerColor: v || '#6b7280' } ) },
124 { label: __( 'Year', 'blockenberg' ), value: a.yearColor, onChange: v => setAttributes( { yearColor: v || '#9ca3af' } ) },
125 ]
126 } ),
127
128 el( PanelBody, { title: __( 'Badges', 'blockenberg' ), initialOpen: false },
129 el( Button, { variant: 'secondary', style: { marginBottom: 10 }, onClick: () => setAttributes( { badges: [ ...( a.badges || [] ), { icon: '', iconType: 'custom-char', iconDashicon: '', iconImageUrl: '', accentColor: '#6366f1', label: 'New Badge', issuer: 'Issuer', year: '2024' } ] } ) }, __( '+ Add Badge', 'blockenberg' ) ),
130 a.badges.map( ( badge, bi ) =>
131 el( PanelBody, { key: bi, title: badge.label || `Badge ${ bi + 1 }`, initialOpen: false },
132 el(IP().IconPickerControl, {
133 iconType: badge.iconType, customChar: badge.icon, dashicon: badge.iconDashicon, imageUrl: badge.iconImageUrl,
134 onChangeType: function(v) { updBadge(setAttributes, a.badges, bi, 'iconType', v); },
135 onChangeChar: function(v) { updBadge(setAttributes, a.badges, bi, 'icon', v); },
136 onChangeDashicon: function(v) { updBadge(setAttributes, a.badges, bi, 'iconDashicon', v); },
137 onChangeImageUrl: function(v) { updBadge(setAttributes, a.badges, bi, 'iconImageUrl', v); }
138 }),
139 el( TextControl, { label: __( 'Label', 'blockenberg' ), value: badge.label, onChange: v => updBadge( setAttributes, a.badges, bi, 'label', v ) } ),
140 el( TextControl, { label: __( 'Issuer', 'blockenberg' ), value: badge.issuer, onChange: v => updBadge( setAttributes, a.badges, bi, 'issuer', v ) } ),
141 el( TextControl, { label: __( 'Year', 'blockenberg' ), value: badge.year, onChange: v => updBadge( setAttributes, a.badges, bi, 'year', v ) } ),
142 el( 'div', { style: { display: 'flex', alignItems: 'center', gap: 8, marginBottom: 8 } },
143 el( 'label', { style: { fontSize: 12 } }, __( 'Accent Color', 'blockenberg' ) ),
144 el( 'input', { type: 'color', value: badge.accentColor || '#6366f1', style: { width: 40, height: 28, border: 'none', borderRadius: 4, cursor: 'pointer' }, onChange: e => updBadge( setAttributes, a.badges, bi, 'accentColor', e.target.value ) } ),
145 ),
146 el( Button, { isDestructive: true, isSmall: true, onClick: () => setAttributes( { badges: a.badges.filter( ( _, x ) => x !== bi ) } ) }, __( 'Remove', 'blockenberg' ) ),
147 )
148 ),
149 ),
150 ),
151
152 // Header
153 el( 'div', { style: { marginBottom: 24 } },
154 a.showTitle && a.title && el( 'h2', { className: 'bkbg-bw-heading', style: { color: a.headingColor, margin: '0 0 6px' } }, a.title ),
155 a.showSubtitle && a.subtitle && el( 'p', { className: 'bkbg-bw-sub', style: { color: a.subtitleColor, margin: 0 } }, a.subtitle ),
156 ),
157
158 renderBadgeWall( a ),
159 );
160 },
161
162 save: function ( { attributes: a } ) {
163 const blockProps = useBlockProps.save( { className: 'bkbg-bw-wrap', style: buildWrapStyle( a ) } );
164 return el( 'div', blockProps,
165 el( 'div', { style: { marginBottom: 24 } },
166 a.showTitle && a.title ? el( 'h2', { className: 'bkbg-bw-heading', style: { color: a.headingColor, margin: '0 0 6px' } }, a.title ) : null,
167 a.showSubtitle && a.subtitle ? el( 'p', { className: 'bkbg-bw-sub', style: { color: a.subtitleColor, margin: 0 } }, a.subtitle ) : null,
168 ),
169 renderBadgeWall( a, true ),
170 );
171 },
172 } );
173 }() );
174