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

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

208 lines 12.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 ( function () {
2 var el = wp.element.createElement;
3 var useState = wp.element.useState;
4 var Fragment = wp.element.Fragment;
5 var registerBlockType = wp.blocks.registerBlockType;
6 var __ = wp.i18n.__;
7 var InspectorControls = wp.blockEditor.InspectorControls;
8 var PanelColorSettings = wp.blockEditor.PanelColorSettings;
9 var useBlockProps = wp.blockEditor.useBlockProps;
10 var RichText = wp.blockEditor.RichText;
11 var PanelBody = wp.components.PanelBody;
12 var RangeControl = wp.components.RangeControl;
13 var TextControl = wp.components.TextControl;
14 var ToggleControl = wp.components.ToggleControl;
15 var SelectControl = wp.components.SelectControl;
16 var Button = wp.components.Button;
17
18 var EMOJI_POOL = ['�
19 ','📌','🔖','','💡','🎯','📝','🔑','🏆','💎','🌟','🔥'];
20
21 function getTypographyControl() { return (window.bkbgTypographyControl || function () { return null; }); }
22 function getTypoCssVars() { return (window.bkbgTypoCssVars || function () { return {}; }); }
23 function _tv(typo, prefix) { var fn = getTypoCssVars(); return fn(typo || {}, prefix); }
24
25 function genId() { return Date.now().toString(36) + Math.random().toString(36).slice(2, 6); }
26
27 function EditorPreview(props) {
28 var a = props.attributes;
29 var set = props.setAttributes;
30 var items = a.items || [];
31 var total = items.length;
32 var done = items.filter(function (i) { return i.done; }).length;
33 var pct = total ? Math.round((done / total) * 100) : 0;
34
35 var wrapStyle = Object.assign({
36 background: a.sectionBg,
37 borderRadius:'16px',
38 padding: '32px 24px',
39 maxWidth: a.contentMaxWidth + 'px',
40 margin: '0 auto',
41 fontFamily: 'inherit',
42 boxSizing: 'border-box'
43 }, _tv(a.typoTitle, '--bkbg-cl-tt-'), _tv(a.typoItem, '--bkbg-cl-it-'));
44
45 function toggleItem(id) {
46 set({ items: items.map(function (i) { return i.id === id ? Object.assign({}, i, { done: !i.done }) : i; }) });
47 }
48 function removeItem(id) {
49 set({ items: items.filter(function (i) { return i.id !== id; }) });
50 }
51 function addItem() {
52 var next = { id:genId(), text:'New item', done:false, icon:EMOJI_POOL[items.length % EMOJI_POOL.length] };
53 set({ items: items.concat([next]) });
54 }
55 function updateText(id, txt) {
56 set({ items: items.map(function (i) { return i.id === id ? Object.assign({}, i, { text: txt }) : i; }) });
57 }
58
59 return el('div', { style: wrapStyle },
60 a.showTitle && el(RichText, {
61 tagName:'h3', value:a.title,
62 className:'bkbg-cl-title',
63 onChange:function(v){ set({title:v}); },
64 style: { color:a.titleColor, margin:'0 0 5px 0' },
65 placeholder:'Checklist title…'
66 }),
67 a.showSubtitle && el(RichText, {
68 tagName:'p', value:a.subtitle,
69 onChange:function(v){ set({subtitle:v}); },
70 style: { fontSize:'14px', color:a.subtitleColor, margin:'0 0 16px 0' },
71 placeholder:'Subtitle…'
72 }),
73
74 // Progress bar
75 a.showProgress && el('div', { style:{ marginBottom:'18px' } },
76 el('div', { style:{ display:'flex', justifyContent:'space-between', fontSize:'12px', fontWeight:'600', color:a.labelColor, marginBottom:'6px' } },
77 el('span', null, 'Progress'),
78 el('span', { style:{ color:a.accentColor } }, pct + '% (' + done + '/' + total + ')')
79 ),
80 el('div', { style:{ height:'8px', borderRadius:'10px', background:a.progressBg, overflow:'hidden' } },
81 el('div', { style:{ height:'100%', width:pct+'%', background:a.accentColor, borderRadius:'10px', transition:'width .3s' } })
82 )
83 ),
84
85 // Items
86 el('div', { style:{ display:'flex', flexDirection:'column', gap:'8px', marginBottom:'14px' } },
87 items.map(function (item) {
88 return el('div', { key:item.id, className:'bkbg-cl-item'+(item.done?' is-done':''),
89 style:{ display:'flex', alignItems:'center', gap:'10px', background:item.done?a.sectionBg:a.itemBg, borderRadius:'10px', padding:'10px 14px', border:'1.5px solid '+(item.done?a.accentColor:'#e5e7eb'), transition:'all .15s' } },
90 // Checkbox
91 el('button', {
92 onClick: function () { toggleItem(item.id); },
93 style:{ width:'22px', height:'22px', borderRadius:a.checkStyle==='square'?'5px':'50%', border:'2px solid '+(item.done?a.accentColor:'#d1d5db'), background:item.done?a.accentColor:'transparent', color:a.checkColor, fontSize:'13px', cursor:'pointer', flexShrink:'0', display:'flex', alignItems:'center', justifyContent:'center' }
94 }, item.done ? '' : ''),
95 el('span', { style:{ fontSize:'16px', flexShrink:'0' } }, item.icon),
96 el('input', {
97 type:'text', value:item.text,
98 className:'bkbg-cl-text',
99 onChange:function(e){ updateText(item.id, e.target.value); },
100 style:{ flex:'1', border:'none', background:'transparent', color:item.done?a.doneTextColor:a.labelColor, outline:'none' }
101 }),
102 a.allowDelete && el('button', {
103 onClick: function () { removeItem(item.id); },
104 style:{ background:'none', border:'none', color:'#d1d5db', cursor:'pointer', fontSize:'16px', padding:'0', lineHeight:'1', flexShrink:'0' }
105 }, '×')
106 );
107 })
108 ),
109
110 // Add item button
111 a.showAddItem && el('button', {
112 onClick: addItem,
113 style:{ width:'100%', padding:'10px', borderRadius:'10px', border:'2px dashed '+a.accentColor, background:'transparent', color:a.accentColor, fontWeight:'600', fontSize:'14px', cursor:'pointer' }
114 }, '+ Add item')
115 );
116 }
117
118 registerBlockType('blockenberg/checklist', {
119 edit: function (props) {
120 var a = props.attributes;
121 var set = props.setAttributes;
122
123 var colorSettings = [
124 { value:a.accentColor, onChange:function(v){set({accentColor: v||'#10b981'});}, label:'Accent / progress color' },
125 { value:a.checkColor, onChange:function(v){set({checkColor: v||'#ffffff'});}, label:'Checkmark color' },
126 { value:a.doneTextColor, onChange:function(v){set({doneTextColor: v||'#9ca3af'});}, label:'Done item text color' },
127 { value:a.progressBg, onChange:function(v){set({progressBg: v||'#d1fae5'});}, label:'Progress bar background' },
128 { value:a.sectionBg, onChange:function(v){set({sectionBg: v||'#f0fdf4'});}, label:'Section background' },
129 { value:a.cardBg, onChange:function(v){set({cardBg: v||'#ffffff'});}, label:'Card background' },
130 { value:a.itemBg, onChange:function(v){set({itemBg: v||'#f9fafb'});}, label:'Item background' },
131 { value:a.titleColor, onChange:function(v){set({titleColor: v||'#111827'});}, label:'Title color' },
132 { value:a.subtitleColor,onChange:function(v){set({subtitleColor: v||'#6b7280'});}, label:'Subtitle color' },
133 { value:a.labelColor, onChange:function(v){set({labelColor: v||'#374151'});}, label:'Label color' }
134 ];
135
136 return el(Fragment, null,
137 el(InspectorControls, null,
138 el(PanelBody, { title:'Checklist Settings', initialOpen:true },
139 el(ToggleControl, { __nextHasNoMarginBottom:true, label:'Show title', checked:a.showTitle, onChange:function(v){set({showTitle:v});} }),
140 el(ToggleControl, { __nextHasNoMarginBottom:true, label:'Show subtitle', checked:a.showSubtitle, onChange:function(v){set({showSubtitle:v});} }),
141 el(ToggleControl, { __nextHasNoMarginBottom:true, label:'Show progress bar',checked:a.showProgress, onChange:function(v){set({showProgress:v});} }),
142 el(ToggleControl, { __nextHasNoMarginBottom:true, label:'Allow adding items',checked:a.showAddItem, onChange:function(v){set({showAddItem:v});} }),
143 el(ToggleControl, { __nextHasNoMarginBottom:true, label:'Allow deleting items',checked:a.allowDelete,onChange:function(v){set({allowDelete:v});} }),
144 el(ToggleControl, { __nextHasNoMarginBottom:true, label:'Remember checked state (localStorage)',checked:a.rememberState,onChange:function(v){set({rememberState:v});} }),
145 el(SelectControl, {
146 label:'Checkbox style',
147 value:a.checkStyle,
148 options:[ {label:'Circle',value:'circle'}, {label:'Square',value:'square'} ],
149 onChange:function(v){set({checkStyle:v});}
150 })
151 ),
152 el(PanelBody, { title:'Sizing', initialOpen:false },
153 el(RangeControl, { label:'Max width (px)', value:a.contentMaxWidth, min:320, max:1000, step:20, onChange:function(v){set({contentMaxWidth:v});} })
154 ),
155
156 el( PanelBody, { title: __( 'Typography', 'blockenberg' ), initialOpen: false },
157 el(getTypographyControl(), { label: __('Title', 'blockenberg'), value: a.typoTitle, onChange: function (v) { set({ typoTitle: v }); } }),
158 el(getTypographyControl(), { label: __('Item', 'blockenberg'), value: a.typoItem, onChange: function (v) { set({ typoItem: v }); } })
159 ),
160 el(PanelColorSettings, { title:'Colors', initialOpen:false, disableCustomGradients:true, colorSettings:colorSettings })
161 ),
162 el('div', useBlockProps(),
163 el(EditorPreview, { attributes:a, setAttributes:set })
164 )
165 );
166 },
167
168 save: function (props) {
169 var a = props.attributes;
170 return el('div', useBlockProps.save(),
171 el('div', {
172 className: 'bkbg-cl-app',
173 'data-opts': JSON.stringify({
174 title: a.title,
175 subtitle: a.subtitle,
176 showTitle: a.showTitle,
177 showSubtitle: a.showSubtitle,
178 showProgress: a.showProgress,
179 showAddItem: a.showAddItem,
180 allowDelete: a.allowDelete,
181 rememberState: a.rememberState,
182 checkStyle: a.checkStyle,
183 items: a.items,
184 accentColor: a.accentColor,
185 checkColor: a.checkColor,
186 doneTextColor: a.doneTextColor,
187 progressBg: a.progressBg,
188 sectionBg: a.sectionBg,
189 cardBg: a.cardBg,
190 itemBg: a.itemBg,
191 titleColor: a.titleColor,
192 subtitleColor: a.subtitleColor,
193 labelColor: a.labelColor,
194 titleFontSize: a.titleFontSize,
195 titleFontWeight: a.titleFontWeight,
196 titleLineHeight: a.titleLineHeight,
197 itemFontSize: a.itemFontSize,
198 itemFontWeight: a.itemFontWeight,
199 typoTitle: a.typoTitle,
200 typoItem: a.typoItem,
201 contentMaxWidth:a.contentMaxWidth
202 })
203 })
204 );
205 }
206 });
207 }() );
208