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

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

145 lines 7.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 ( function () {
2 var el = window.wp.element.createElement;
3 var { registerBlockType } = window.wp.blocks;
4 var { InspectorControls, PanelColorSettings, useBlockProps } = window.wp.blockEditor;
5 var { PanelBody, RangeControl, SelectControl, TextControl, ToggleControl } = window.wp.components;
6 var { __ } = window.wp.i18n;
7
8 var _tc; function getTypoControl() { return _tc || (_tc = window.bkbgTypographyControl); }
9 var _tv; function getTypoCssVars() { return _tv || (_tv = window.bkbgTypoCssVars); }
10
11 var DISPLAY_STYLES = [{label:'Badge (pill)',value:'badge'},{label:'Inline text',value:'inline'},{label:'Icon only + text',value:'icon'}];
12 var ALIGNS = [{label:'Left',value:'left'},{label:'Center',value:'center'},{label:'Right',value:'right'}];
13 var ICONS = ['clock','backup','visibility','media-text'].map(i=>({label:i,value:i}));
14
15 var v1Attributes = {
16 wpm: { type: 'number', default: 200 },
17 prefix: { type: 'string', default: '' },
18 suffix: { type: 'string', default: 'min read' },
19 showIcon: { type: 'boolean', default: true },
20 icon: { type: 'string', default: 'clock' },
21 displayStyle: { type: 'string', default: 'badge' },
22 textAlign: { type: 'string', default: 'left' },
23 fontSize: { type: 'number', default: 14 },
24 fontWeight: { type: 'number', default: 600 },
25 bgColor: { type: 'string', default: '#ede9fc' },
26 textColor: { type: 'string', default: '#6c3fb5' },
27 borderRadius: { type: 'number', default: 40 },
28 paddingX: { type: 'number', default: 14 },
29 paddingY: { type: 'number', default: 6 },
30 };
31
32 function BadgePreview(a, readTime) {
33 var badgeStyle = {
34 display:'inline-flex', alignItems:'center', gap:'5px',
35 background: a.displayStyle==='inline'?'transparent':a.bgColor,
36 color:a.textColor, padding:a.displayStyle==='inline'?'0':a.paddingY+'px '+a.paddingX+'px',
37 borderRadius:a.borderRadius+'px',
38 };
39 return el('div',{style:{textAlign:a.textAlign}},
40 el('span',{className:'bkrt-badge',style:badgeStyle},
41 a.showIcon&&el('span',{className:'dashicons dashicons-'+a.icon,style:{lineHeight:1}}),
42 el('span',null,(a.prefix?a.prefix+' ':'')+readTime+' '+(a.suffix||'')),
43 )
44 );
45 }
46
47 registerBlockType('blockenberg/reading-time', {
48 edit: function(props) {
49 var a = props.attributes;
50 var set = props.setAttributes;
51 var TC = getTypoControl();
52 var blockProps = useBlockProps((function() {
53 var _tvFn = getTypoCssVars();
54 var s = {};
55 if (_tvFn) Object.assign(s, _tvFn(a.badgeTypo || {}, '--bkrt-bt-'));
56 return { style: s };
57 })());
58 // Editor preview: estimate from the current post content
59 var postContent = (window.wp.data && window.wp.data.select('core/editor') ? window.wp.data.select('core/editor').getEditedPostContent() : '') || '';
60 var wordCount = postContent.replace(/<[^>]+>/g,' ').trim().split(/\s+/).filter(Boolean).length;
61 var readTime = Math.max(1, Math.ceil(wordCount / (a.wpm||200)));
62
63 return el('div',blockProps,
64 el(InspectorControls,null,
65 el(PanelBody,{title:__('Reading Time Settings'),initialOpen:true},
66 el(RangeControl,{label:__('Words Per Minute'),value:a.wpm,min:50,max:500,onChange:v=>set({wpm:v})}),
67 el(TextControl,{label:__('Prefix'),value:a.prefix,onChange:v=>set({prefix:v}),placeholder:'e.g.: About'}),
68 el(TextControl,{label:__('Suffix'),value:a.suffix,onChange:v=>set({suffix:v}),placeholder:'e.g.: min read'}),
69 el(SelectControl,{label:__('Display Style'),value:a.displayStyle,options:DISPLAY_STYLES,onChange:v=>set({displayStyle:v})}),
70 el(SelectControl,{label:__('Alignment'),value:a.textAlign,options:ALIGNS,onChange:v=>set({textAlign:v})}),
71 el(ToggleControl,{label:__('Show Icon'),checked:a.showIcon,onChange:v=>set({showIcon:v}),__nextHasNoMarginBottom:true}),
72 a.showIcon&&el(SelectControl,{label:__('Icon'),value:a.icon,options:ICONS,onChange:v=>set({icon:v})}),
73 ),
74 el(PanelBody,{title:__('Typography','blockenberg'),initialOpen:false},
75 TC && el(TC, { label: __('Badge Text','blockenberg'), value: a.badgeTypo || {}, onChange: function(v) { set({ badgeTypo: v }); } })
76 ),
77 el(PanelBody,{title:__('Badge Style','blockenberg'),initialOpen:false},
78 el(RangeControl,{label:__('Border Radius (px)'),value:a.borderRadius,min:0,max:50,onChange:v=>set({borderRadius:v})}),
79 el(RangeControl,{label:__('Padding X (px)'),value:a.paddingX,min:0,max:40,onChange:v=>set({paddingX:v})}),
80 el(RangeControl,{label:__('Padding Y (px)'),value:a.paddingY,min:0,max:20,onChange:v=>set({paddingY:v})}),
81 ),
82 el(PanelColorSettings,{title:__('Colors'),initialOpen:false,colorSettings:[
83 {label:__('Background'),value:a.bgColor,onChange:v=>set({bgColor:v||'#ede9fc'})},
84 {label:__('Text / Icon'),value:a.textColor,onChange:v=>set({textColor:v||'#6c3fb5'})},
85 ]}),
86 ),
87 el('div',{style:{padding:'4px 0'}},
88 BadgePreview(a, readTime),
89 el('div',{style:{marginTop:'6px',fontSize:'11px',color:'#9ca3af'}},__('Word count: ')+wordCount+''+readTime+' min (updates on frontend)')
90 )
91 );
92 },
93
94 save: function({attributes:a}) {
95 var _tvFn = getTypoCssVars();
96 var wrapStyle = { textAlign: a.textAlign };
97 if (_tvFn) Object.assign(wrapStyle, _tvFn(a.badgeTypo || {}, '--bkrt-bt-'));
98
99 return el('div',{
100 className:'bkrt-wrap',
101 style: wrapStyle,
102 'data-wpm':a.wpm,
103 'data-prefix':a.prefix,
104 'data-suffix':a.suffix,
105 },
106 el('span',{className:'bkrt-badge',style:{
107 display:'inline-flex',alignItems:'center',gap:'5px',
108 background:a.displayStyle==='inline'?'transparent':a.bgColor,
109 color:a.textColor,
110 padding:a.displayStyle==='inline'?'0':a.paddingY+'px '+a.paddingX+'px',
111 borderRadius:a.borderRadius+'px',
112 }},
113 a.showIcon&&el('span',{className:'dashicons dashicons-'+a.icon,style:{lineHeight:1}}),
114 el('span',{className:'bkrt-text'},(a.prefix ? a.prefix+' ' : '')+''+' '+(a.suffix||'')),
115 )
116 );
117 },
118
119 deprecated: [{
120 attributes: v1Attributes,
121 save: function({attributes:a}) {
122 return el('div',{
123 className:'bkrt-wrap',
124 style:{textAlign:a.textAlign},
125 'data-wpm':a.wpm,
126 'data-prefix':a.prefix,
127 'data-suffix':a.suffix,
128 },
129 el('span',{className:'bkrt-badge',style:{
130 display:'inline-flex',alignItems:'center',gap:'5px',
131 background:a.displayStyle==='inline'?'transparent':a.bgColor,
132 color:a.textColor,
133 padding:a.displayStyle==='inline'?'0':a.paddingY+'px '+a.paddingX+'px',
134 borderRadius:a.borderRadius+'px',
135 fontSize:a.fontSize+'px', fontWeight:a.fontWeight,
136 }},
137 a.showIcon&&el('span',{className:'dashicons dashicons-'+a.icon,style:{fontSize:a.fontSize+'px',width:a.fontSize+'px',height:a.fontSize+'px',lineHeight:1}}),
138 el('span',{className:'bkrt-text'},(a.prefix ? a.prefix+' ' : '')+''+' '+(a.suffix||'')),
139 )
140 );
141 }
142 }]
143 });
144 }() );
145