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

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

255 lines 16.1 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 __ = wp.i18n.__;
4 var useBlockProps = wp.blockEditor.useBlockProps;
5 var InspectorControls = wp.blockEditor.InspectorControls;
6 var PanelColorSettings = wp.blockEditor.PanelColorSettings;
7 var PanelBody = wp.components.PanelBody;
8 var TextControl = wp.components.TextControl;
9 var ToggleControl = wp.components.ToggleControl;
10 var SelectControl = wp.components.SelectControl;
11 var RangeControl = wp.components.RangeControl;
12
13 var _tc, _tv;
14 function getTypoControl() { return _tc || (_tc = window.bkbgTypographyControl); }
15 function getTypoCssVars() { return _tv || (_tv = window.bkbgTypoCssVars); }
16
17 var LAYOUTS = [
18 { label: 'Scrolling Ticker', value: 'ticker' },
19 { label: 'Cards Grid', value: 'cards' },
20 { label: 'Table', value: 'table' }
21 ];
22
23 var CURRENCIES = [
24 { label: 'USD ($)', value: 'usd' },
25 { label: 'EUR (€)', value: 'eur' },
26 { label: 'GBP (£)', value: 'gbp' },
27 { label: 'JPY (¥)', value: 'jpy' },
28 { label: 'BTC (₿)', value: 'btc' },
29 { label: 'ETH (Ξ)', value: 'eth' }
30 ];
31
32 var DUMMY_COINS = [
33 { id: 'bitcoin', symbol: 'BTC', name: 'Bitcoin', price: 67245.32, change: 2.34, mcap: '1.33T', vol: '38.2B', icon: '' },
34 { id: 'ethereum', symbol: 'ETH', name: 'Ethereum', price: 3512.18, change: -1.22, mcap: '422.1B', vol: '18.5B', icon: 'Ξ' },
35 { id: 'solana', symbol: 'SOL', name: 'Solana', price: 178.44, change: 5.61, mcap: '82.3B', vol: '4.1B', icon: '' },
36 { id: 'cardano', symbol: 'ADA', name: 'Cardano', price: 0.4823, change: -0.88, mcap: '17.1B', vol: '520M', icon: '' },
37 { id: 'dogecoin', symbol: 'DOGE',name: 'Dogecoin', price: 0.1624, change: 3.14, mcap: '23.5B', vol: '1.2B', icon: 'Ð' },
38 { id: 'polkadot', symbol: 'DOT', name: 'Polkadot', price: 8.24, change: -2.07, mcap: '12.9B', vol: '350M', icon: '' }
39 ];
40
41 function formatPrice(p, sym) {
42 if (p >= 1000) return sym + p.toLocaleString('en-US', { minimumFractionDigits: 0, maximumFractionDigits: 0 });
43 if (p >= 1) return sym + p.toFixed(2);
44 return sym + p.toFixed(4);
45 }
46
47 function TickerPreview(props) {
48 var attr = props.attr;
49 var sym = attr.currencySymbol || '$';
50
51 if (attr.layout === 'ticker') {
52 return el('div', {
53 style: {
54 backgroundColor: attr.bgColor,
55 borderRadius: attr.borderRadius + 'px',
56 overflow: 'hidden',
57 padding: '0',
58 display: 'flex',
59 alignItems: 'center'
60 }
61 },
62 attr.showLabel && el('div', {
63 style: {
64 background: attr.accentColor, color: '#fff',
65 padding: '8px 14px', fontSize: '11px', fontWeight: 700,
66 letterSpacing: '0.1em', flexShrink: 0,
67 whiteSpace: 'nowrap'
68 }
69 }, '' + (attr.labelText || 'LIVE')),
70 el('div', {
71 style: {
72 display: 'flex', gap: '32px', padding: '10px 24px',
73 overflow: 'hidden', whiteSpace: 'nowrap',
74 fontSize: attr.fontSize + 'px', fontWeight: attr.fontWeight,
75 color: attr.textColor
76 }
77 },
78 DUMMY_COINS.slice(0, 6).map(function (c) {
79 return el('span', { key: c.id, style: { display: 'inline-flex', alignItems: 'center', gap: '6px' } },
80 attr.showIcons && el('span', { style: { color: attr.accentColor } }, c.icon),
81 attr.showSymbol && el('span', { style: { fontWeight: 700 } }, c.symbol),
82 el('span', {}, formatPrice(c.price, sym)),
83 attr.showChange && el('span', {
84 style: { color: c.change >= 0 ? attr.upColor : attr.downColor, fontSize: '12px' }
85 }, (c.change >= 0 ? '+' : '') + c.change.toFixed(2) + '%')
86 );
87 })
88 )
89 );
90 }
91
92 if (attr.layout === 'cards') {
93 return el('div', {
94 style: {
95 display: 'grid',
96 gridTemplateColumns: 'repeat(' + Math.min(attr.cardColumns, 4) + ', 1fr)',
97 gap: '12px'
98 }
99 },
100 DUMMY_COINS.slice(0, attr.cardColumns * 2).map(function (c) {
101 return el('div', {
102 key: c.id,
103 style: {
104 backgroundColor: attr.cardBg,
105 borderRadius: attr.borderRadius + 'px',
106 padding: '16px',
107 border: '1px solid ' + attr.borderColor
108 }
109 },
110 el('div', { style: { display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '10px' } },
111 attr.showIcons && el('span', { style: { fontSize: '20px', color: attr.accentColor } }, c.icon),
112 el('div', {},
113 el('div', { style: { fontWeight: 700, color: attr.textColor, fontSize: attr.fontSize + 'px' } }, c.name),
114 attr.showSymbol && el('div', { style: { fontSize: '11px', color: attr.textColor, opacity: 0.5 } }, c.symbol)
115 )
116 ),
117 el('div', { style: { fontSize: (attr.fontSize + 2) + 'px', fontWeight: 700, color: attr.textColor } }, formatPrice(c.price, sym)),
118 attr.showChange && el('div', {
119 style: { color: c.change >= 0 ? attr.upColor : attr.downColor, fontSize: '13px', marginTop: '4px' }
120 }, (c.change >= 0 ? '▲ +' : '') + c.change.toFixed(2) + '%')
121 );
122 })
123 );
124 }
125
126 // Table
127 return el('table', {
128 style: {
129 width: '100%', borderCollapse: 'collapse',
130 backgroundColor: attr.bgColor, borderRadius: attr.borderRadius + 'px',
131 overflow: 'hidden', fontSize: attr.fontSize + 'px', color: attr.textColor
132 }
133 },
134 el('thead', {},
135 el('tr', { style: { borderBottom: '1px solid ' + attr.borderColor, opacity: 0.7 } },
136 el('th', { style: { padding: '10px 14px', textAlign: 'left', fontWeight: 600 } }, 'Asset'),
137 el('th', { style: { padding: '10px 14px', textAlign: 'right', fontWeight: 600 } }, 'Price'),
138 attr.showChange && el('th', { style: { padding: '10px 14px', textAlign: 'right', fontWeight: 600 } }, '24h'),
139 attr.showMarketCap && el('th', { style: { padding: '10px 14px', textAlign: 'right', fontWeight: 600 } }, 'Mkt Cap'),
140 attr.showVolume && el('th', { style: { padding: '10px 14px', textAlign: 'right', fontWeight: 600 } }, 'Volume')
141 )
142 ),
143 el('tbody', {},
144 DUMMY_COINS.map(function (c, i) {
145 return el('tr', {
146 key: c.id,
147 style: { borderBottom: '1px solid ' + attr.borderColor, backgroundColor: i % 2 ? 'rgba(255,255,255,0.02)' : '' }
148 },
149 el('td', { style: { padding: '10px 14px' } },
150 el('div', { style: { display: 'flex', alignItems: 'center', gap: '8px' } },
151 attr.showIcons && el('span', { style: { color: attr.accentColor } }, c.icon),
152 el('strong', {}, c.name),
153 attr.showSymbol && el('span', { style: { opacity: 0.5, fontSize: '12px' } }, c.symbol)
154 )
155 ),
156 el('td', { style: { padding: '10px 14px', textAlign: 'right', fontWeight: 700 } }, formatPrice(c.price, sym)),
157 attr.showChange && el('td', {
158 style: { padding: '10px 14px', textAlign: 'right', color: c.change >= 0 ? attr.upColor : attr.downColor }
159 }, (c.change >= 0 ? '▲ +' : '') + c.change.toFixed(2) + '%'),
160 attr.showMarketCap && el('td', { style: { padding: '10px 14px', textAlign: 'right', opacity: 0.7 } }, c.mcap),
161 attr.showVolume && el('td', { style: { padding: '10px 14px', textAlign: 'right', opacity: 0.7 } }, c.vol)
162 );
163 })
164 )
165 );
166 }
167
168 wp.blocks.registerBlockType('blockenberg/stock-ticker', {
169 title: 'Crypto Price Ticker',
170 icon: 'chart-line',
171 category: 'bkbg-effects',
172 edit: function (props) {
173 var attr = props.attributes;
174 var setAttr = props.setAttributes;
175 var blockProps = useBlockProps((function() {
176 var _tvf = getTypoCssVars();
177 var s = { fontFamily: 'inherit' };
178 if (_tvf) {
179 Object.assign(s, _tvf(attr.textTypo, '--bkstk-tx-'));
180 }
181 s['--bkstk-tx-fw'] = attr.fontWeight || 600;
182 s['--bkstk-tx-lh'] = attr.lineHeight || 1.4;
183 return { style: s };
184 })());
185
186 return el('div', blockProps,
187 el(InspectorControls, {},
188 el(PanelBody, { title: __('Coins & Currency', 'blockenberg'), initialOpen: true },
189 el(TextControl, {
190 __nextHasNoMarginBottom: true,
191 label: __('Coin IDs (CoinGecko, comma-separated)', 'blockenberg'),
192 help: __('e.g. bitcoin,ethereum,solana,dogecoin', 'blockenberg'),
193 value: attr.coins,
194 onChange: function (v) { setAttr({ coins: v }); }
195 }),
196 el(SelectControl, { __nextHasNoMarginBottom: true, label: __('Currency', 'blockenberg'), value: attr.currency, options: CURRENCIES, onChange: function (v) { setAttr({ currency: v }); } }),
197 el(TextControl, { __nextHasNoMarginBottom: true, label: __('Currency Symbol', 'blockenberg'), value: attr.currencySymbol, onChange: function (v) { setAttr({ currencySymbol: v }); } }),
198 el(RangeControl, { __nextHasNoMarginBottom: true, label: __('Refresh Interval (seconds)', 'blockenberg'), value: attr.refreshInterval, min: 10, max: 3600, step: 10, onChange: function (v) { setAttr({ refreshInterval: v }); } })
199 ),
200 el(PanelBody, { title: __('Layout', 'blockenberg'), initialOpen: false },
201 el(SelectControl, { __nextHasNoMarginBottom: true, label: __('Display Layout', 'blockenberg'), value: attr.layout, options: LAYOUTS, onChange: function (v) { setAttr({ layout: v }); } }),
202 attr.layout === 'ticker' && el(RangeControl, { __nextHasNoMarginBottom: true, label: __('Scroll Speed (seconds/loop)', 'blockenberg'), value: attr.tickerSpeed, min: 10, max: 120, onChange: function (v) { setAttr({ tickerSpeed: v }); } }),
203 attr.layout === 'ticker' && el(ToggleControl, { __nextHasNoMarginBottom: true, label: __('Pause on Hover', 'blockenberg'), checked: attr.pauseOnHover, onChange: function (v) { setAttr({ pauseOnHover: v }); } }),
204 attr.layout === 'cards' && el(RangeControl, { __nextHasNoMarginBottom: true, label: __('Card Columns', 'blockenberg'), value: attr.cardColumns, min: 1, max: 6, onChange: function (v) { setAttr({ cardColumns: v }); } })
205 ),
206 el(PanelBody, { title: __('Data Fields', 'blockenberg'), initialOpen: false },
207 el(ToggleControl, { __nextHasNoMarginBottom: true, label: __('Show 24h Price Change', 'blockenberg'), checked: attr.showChange, onChange: function (v) { setAttr({ showChange: v }); } }),
208 el(ToggleControl, { __nextHasNoMarginBottom: true, label: __('Show Volume', 'blockenberg'), checked: attr.showVolume, onChange: function (v) { setAttr({ showVolume: v }); } }),
209 el(ToggleControl, { __nextHasNoMarginBottom: true, label: __('Show Market Cap', 'blockenberg'), checked: attr.showMarketCap, onChange: function (v) { setAttr({ showMarketCap: v }); } }),
210 el(ToggleControl, { __nextHasNoMarginBottom: true, label: __('Show Coin Icons', 'blockenberg'), checked: attr.showIcons, onChange: function (v) { setAttr({ showIcons: v }); } }),
211 el(ToggleControl, { __nextHasNoMarginBottom: true, label: __('Show Ticker Symbol', 'blockenberg'), checked: attr.showSymbol, onChange: function (v) { setAttr({ showSymbol: v }); } })
212 ),
213 el(PanelBody, { title: __('Label', 'blockenberg'), initialOpen: false },
214 el(ToggleControl, { __nextHasNoMarginBottom: true, label: __('Show LIVE Label', 'blockenberg'), checked: attr.showLabel, onChange: function (v) { setAttr({ showLabel: v }); } }),
215 attr.showLabel && el(TextControl, { __nextHasNoMarginBottom: true, label: __('Label Text', 'blockenberg'), value: attr.labelText, onChange: function (v) { setAttr({ labelText: v }); } })
216 ),
217 el(PanelBody, { title: __('Typography', 'blockenberg'), initialOpen: false },
218 getTypoControl() && getTypoControl()({ label: __('Text', 'blockenberg'), value: attr.textTypo, onChange: function (v) { setAttr({ textTypo: v }); } }),
219 el(RangeControl, { __nextHasNoMarginBottom: true, label: __('Border Radius (px)', 'blockenberg'), value: attr.borderRadius, min: 0, max: 30, onChange: function (v) { setAttr({ borderRadius: v }); } })
220 ),
221 el(PanelColorSettings, {
222 title: __('Colors', 'blockenberg'),
223 initialOpen: false,
224 colorSettings: [
225 { label: __('Background', 'blockenberg'), value: attr.bgColor, onChange: function (v) { setAttr({ bgColor: v || '' }); } },
226 { label: __('Card Background','blockenberg'), value: attr.cardBg, onChange: function (v) { setAttr({ cardBg: v || '' }); } },
227 { label: __('Text Color', 'blockenberg'), value: attr.textColor, onChange: function (v) { setAttr({ textColor: v || '' }); } },
228 { label: __('Accent / Label', 'blockenberg'), value: attr.accentColor, onChange: function (v) { setAttr({ accentColor: v || '' }); } },
229 { label: __('Price Up (▲)', 'blockenberg'), value: attr.upColor, onChange: function (v) { setAttr({ upColor: v || '' }); } },
230 { label: __('Price Down (▼)','blockenberg'), value: attr.downColor, onChange: function (v) { setAttr({ downColor: v || '' }); } },
231 { label: __('Border Color', 'blockenberg'), value: attr.borderColor, onChange: function (v) { setAttr({ borderColor: v || '' }); } }
232 ]
233 })
234 ),
235 el('p', {
236 style: {
237 background: '#fff3cd', color: '#856404', padding: '8px 12px',
238 borderRadius: '6px', fontSize: '12px', marginBottom: '12px'
239 }
240 }, '⚠️ Editor shows dummy data. Live prices load on the front end via the CoinGecko API.'),
241 el(TickerPreview, { attr: attr })
242 );
243 },
244 save: function (props) {
245 var attr = props.attributes;
246 return el('div', useBlockProps.save(),
247 el('div', {
248 className: 'bkbg-st-app',
249 'data-opts': JSON.stringify(attr)
250 })
251 );
252 }
253 });
254 }() );
255