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

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

237 lines 15.0 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 Fragment = wp.element.Fragment;
4 var __ = wp.i18n.__;
5 var registerBlockType = wp.blocks.registerBlockType;
6 var InspectorControls = wp.blockEditor.InspectorControls;
7 var useBlockProps = wp.blockEditor.useBlockProps;
8 var PanelColorSettings = wp.blockEditor.PanelColorSettings;
9 var PanelBody = wp.components.PanelBody;
10 var TextControl = wp.components.TextControl;
11 var ToggleControl = wp.components.ToggleControl;
12 var RangeControl = wp.components.RangeControl;
13 var SelectControl = wp.components.SelectControl;
14
15 var _tc, _tvf;
16 Object.defineProperty(window, '_tc', { get: function () { return _tc || (_tc = window.bkbgTypographyControl); } });
17 Object.defineProperty(window, '_tvf', { get: function () { return _tvf || (_tvf = window.bkbgTypoCssVars); } });
18 function getTypoControl(label, key, attrs, setA) { return _tc(label, key, attrs, setA); }
19 function getTypoCssVars(attrs) {
20 var v = {};
21 _tvf(v, 'tempTypo', attrs, '--bkww-tp-');
22 _tvf(v, 'cityTypo', attrs, '--bkww-ct-');
23 _tvf(v, 'metaTypo', attrs, '--bkww-mt-');
24 return v;
25 }
26
27 var UNITS = [
28 { label: 'Celsius (°C)', value: 'metric' },
29 { label: 'Fahrenheit (°F)', value: 'imperial' },
30 { label: 'Kelvin (K)', value: 'standard' },
31 ];
32
33 var LAYOUTS = [
34 { label: 'Card (centered)', value: 'card' },
35 { label: 'Wide (full-width)', value: 'wide' },
36 { label: 'Minimal (compact)', value: 'minimal' },
37 ];
38
39 var BG_STYLES = [
40 { label: 'Gradient (auto by weather)', value: 'gradient' },
41 { label: 'Custom color', value: 'custom' },
42 { label: 'Transparent', value: 'transparent' },
43 ];
44
45 var LANGS = [
46 { label: 'English', value: 'en' },
47 { label: 'Russian', value: 'ru' },
48 { label: 'German', value: 'de' },
49 { label: 'French', value: 'fr' },
50 { label: 'Spanish', value: 'es' },
51 { label: 'Japanese', value: 'ja' },
52 ];
53
54 /* weather icon emoji map for editor preview */
55 function weatherIcon(code) {
56 if (!code) return '🌤';
57 var c = String(code);
58 if (c.startsWith('01')) return '☀️';
59 if (c.startsWith('02')) return '�
60 ';
61 if (c.startsWith('03') || c.startsWith('04')) return '☁️';
62 if (c.startsWith('09') || c.startsWith('10')) return '🌧';
63 if (c.startsWith('11')) return '';
64 if (c.startsWith('13')) return '❄️';
65 if (c.startsWith('50')) return '🌫';
66 return '🌤';
67 }
68
69 function unitLabel(units) {
70 if (units === 'imperial') return '°F';
71 if (units === 'standard') return 'K';
72 return '°C';
73 }
74
75 /* demo forecast data for editor preview */
76 var DEMO_FORECAST = [
77 { day: 'Mon', icon: '☀️', hi: 22, lo: 14 },
78 { day: 'Tue', icon: '�
79 ', hi: 19, lo: 12 },
80 { day: 'Wed', icon: '🌧', hi: 15, lo: 10 },
81 { day: 'Thu', icon: '☁️', hi: 17, lo: 11 },
82 { day: 'Fri', icon: '☀️', hi: 24, lo: 16 },
83 ];
84
85 function WeatherPreview(props) {
86 var a = props.attributes;
87 var deg = unitLabel(a.units);
88 var wrapStyle = {
89 background: a.backgroundStyle === 'gradient'
90 ? 'linear-gradient(135deg, #1e3a5f 0%, #2563eb 50%, #0f172a 100%)'
91 : a.backgroundStyle === 'custom' ? a.customBg : 'transparent',
92 borderRadius: a.borderRadius + 'px',
93 padding: a.padding + 'px',
94 maxWidth: a.layout === 'card' ? a.maxWidth + 'px' : '100%',
95 margin: a.layout === 'card' ? '0 auto' : '0',
96 color: a.textColor,
97 fontFamily: 'inherit',
98 };
99 var cardStyle = {
100 background: a.cardBg,
101 backdropFilter: 'blur(16px)',
102 borderRadius: a.cardRadius + 'px',
103 padding: '24px',
104 border: '1px solid rgba(255,255,255,0.2)',
105 };
106
107 return el('div', { style: wrapStyle },
108 el('div', { style: cardStyle },
109 /* top row: city + icon */
110 el('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: '12px' } },
111 el('div', null,
112 el('div', { className: 'bkbg-ww-city-label', style: { opacity: 0.75, marginBottom: '4px' } },
113 '📍 ' + (a.city || 'Your City')),
114 el('div', { className: 'bkbg-ww-temp' }, '22' + deg),
115 el('div', { style: { fontSize: '15px', opacity: 0.85, marginTop: '4px' } }, 'Partly Cloudy'),
116 ),
117 el('div', { style: { fontSize: '72px', lineHeight: 1 } }, '�
118 ')
119 ),
120 /* feels like / hi-lo */
121 a.showFeelsLike && el('div', { style: { fontSize: '13px', opacity: 0.7, marginBottom: '16px' } },
122 'Feels like 20' + deg + ' · H: 25' + deg + ' L: 14' + deg),
123 /* stats row */
124 el('div', { style: { display: 'flex', gap: '16px', flexWrap: 'wrap', marginBottom: a.showForecast ? '24px' : '0' } },
125 a.showHumidity && el('div', { style: { background: 'rgba(255,255,255,0.1)', borderRadius: '10px', padding: '10px 14px', flex: '1', minWidth: '80px', textAlign: 'center' } },
126 el('div', { style: { fontSize: '18px' } }, '💧'),
127 el('div', { style: { fontSize: '14px', fontWeight: 600 } }, '68%'),
128 el('div', { className: 'bkbg-ww-stat-lbl', style: { opacity: 0.7 } }, 'Humidity'),
129 ),
130 a.showWind && el('div', { style: { background: 'rgba(255,255,255,0.1)', borderRadius: '10px', padding: '10px 14px', flex: '1', minWidth: '80px', textAlign: 'center' } },
131 el('div', { style: { fontSize: '18px' } }, '💨'),
132 el('div', { style: { fontSize: '14px', fontWeight: 600 } }, '14 km/h'),
133 el('div', { className: 'bkbg-ww-stat-lbl', style: { opacity: 0.7 } }, 'Wind'),
134 ),
135 a.showPressure && el('div', { style: { background: 'rgba(255,255,255,0.1)', borderRadius: '10px', padding: '10px 14px', flex: '1', minWidth: '80px', textAlign: 'center' } },
136 el('div', { style: { fontSize: '18px' } }, '🌡'),
137 el('div', { style: { fontSize: '14px', fontWeight: 600 } }, '1013 hPa'),
138 el('div', { className: 'bkbg-ww-stat-lbl', style: { opacity: 0.7 } }, 'Pressure'),
139 ),
140 ),
141 /* forecast */
142 a.showForecast && el('div', null,
143 el('div', { style: { fontSize: '12px', fontWeight: 600, opacity: 0.7, textTransform: 'uppercase', letterSpacing: '1px', marginBottom: '10px' } }, '5-Day Forecast'),
144 el('div', { style: { display: 'flex', gap: '8px' } },
145 DEMO_FORECAST.slice(0, a.forecastDays).map(function (f) {
146 return el('div', {
147 key: f.day,
148 style: { background: a.forecastBg, borderRadius: '10px', padding: '10px 8px', flex: 1, textAlign: 'center' },
149 },
150 el('div', { style: { fontSize: '11px', opacity: 0.7, marginBottom: '4px' } }, f.day),
151 el('div', { style: { fontSize: '20px', marginBottom: '4px' } }, f.icon),
152 el('div', { style: { fontSize: '12px', fontWeight: 600 } }, f.hi + deg),
153 el('div', { style: { fontSize: '11px', opacity: 0.6 } }, f.lo + deg),
154 );
155 })
156 )
157 )
158 ),
159 !a.apiKey && el('div', { style: { marginTop: '10px', padding: '8px 12px', background: 'rgba(255,165,0,0.2)', borderRadius: '8px', fontSize: '12px', color: '#fbbf24', border: '1px solid rgba(251,191,36,0.4)' } },
160 '⚠️ Add your OpenWeatherMap API key in the block settings to fetch live data.')
161 );
162 }
163
164 registerBlockType('blockenberg/weather-widget', {
165 edit: function (props) {
166 var a = props.attributes;
167 var set = props.setAttributes;
168
169 return el(Fragment, null,
170 el(InspectorControls, null,
171 /* API */
172 el(PanelBody, { title: 'API & Location', initialOpen: true },
173 el(TextControl, { __nextHasNoMarginBottom: true, label: 'OpenWeatherMap API Key', value: a.apiKey, onChange: function (v) { set({ apiKey: v }); }, help: 'Free key from openweathermap.org' }),
174 el(TextControl, { __nextHasNoMarginBottom: true, label: 'Default City', value: a.city, onChange: function (v) { set({ city: v }); }, help: 'e.g. London, New York, Tokyo' }),
175 el(ToggleControl, { __nextHasNoMarginBottom: true, label: 'Auto-detect visitor location (Geolocation)', checked: a.autoLocation, onChange: function (v) { set({ autoLocation: v }); } }),
176 el(SelectControl, { __nextHasNoMarginBottom: true, label: 'Units', value: a.units, options: UNITS, onChange: function (v) { set({ units: v }); } }),
177 el(SelectControl, { __nextHasNoMarginBottom: true, label: 'Language', value: a.lang, options: LANGS, onChange: function (v) { set({ lang: v }); } }),
178 el(RangeControl, { __nextHasNoMarginBottom: true, label: 'Auto-refresh interval (minutes)', value: a.refreshInterval, min: 0, max: 60, step: 5, onChange: function (v) { set({ refreshInterval: v }); }, help: '0 = no refresh' }),
179 ),
180 /* Display */
181 el(PanelBody, { title: 'Display Options', initialOpen: false },
182 el(ToggleControl, { __nextHasNoMarginBottom: true, label: 'Show feels-like temperature', checked: a.showFeelsLike, onChange: function (v) { set({ showFeelsLike: v }); } }),
183 el(ToggleControl, { __nextHasNoMarginBottom: true, label: 'Show humidity', checked: a.showHumidity, onChange: function (v) { set({ showHumidity: v }); } }),
184 el(ToggleControl, { __nextHasNoMarginBottom: true, label: 'Show wind speed', checked: a.showWind, onChange: function (v) { set({ showWind: v }); } }),
185 el(ToggleControl, { __nextHasNoMarginBottom: true, label: 'Show pressure', checked: a.showPressure, onChange: function (v) { set({ showPressure: v }); } }),
186 el(ToggleControl, { __nextHasNoMarginBottom: true, label: 'Show visibility', checked: a.showVisibility, onChange: function (v) { set({ showVisibility: v }); } }),
187 el(ToggleControl, { __nextHasNoMarginBottom: true, label: 'Show animated weather icon', checked: a.showAnimatedIcon, onChange: function (v) { set({ showAnimatedIcon: v }); } }),
188 el(ToggleControl, { __nextHasNoMarginBottom: true, label: 'Show 5-day forecast', checked: a.showForecast, onChange: function (v) { set({ showForecast: v }); } }),
189 a.showForecast && el(RangeControl, { __nextHasNoMarginBottom: true, label: 'Forecast days', value: a.forecastDays, min: 2, max: 5, onChange: function (v) { set({ forecastDays: v }); } }),
190 ),
191 /* Layout */
192 el(PanelBody, { title: 'Layout', initialOpen: false },
193 el(SelectControl, { __nextHasNoMarginBottom: true, label: 'Layout', value: a.layout, options: LAYOUTS, onChange: function (v) { set({ layout: v }); } }),
194 a.layout === 'card' && el(RangeControl, { __nextHasNoMarginBottom: true, label: 'Max width (px)', value: a.maxWidth, min: 280, max: 800, step: 10, onChange: function (v) { set({ maxWidth: v }); } }),
195 el(RangeControl, { __nextHasNoMarginBottom: true, label: 'Padding (px)', value: a.padding, min: 8, max: 64, onChange: function (v) { set({ padding: v }); } }),
196 el(RangeControl, { __nextHasNoMarginBottom: true, label: 'Outer radius (px)', value: a.borderRadius, min: 0, max: 48, onChange: function (v) { set({ borderRadius: v }); } }),
197 el(RangeControl, { __nextHasNoMarginBottom: true, label: 'Card radius (px)', value: a.cardRadius, min: 0, max: 32, onChange: function (v) { set({ cardRadius: v }); } }),
198 ),
199 /* Typography */
200 el(PanelBody, { title: 'Typography', initialOpen: false },
201 getTypoControl( __( 'Temperature', 'blockenberg' ), 'tempTypo', a, set ),
202 getTypoControl( __( 'City Label', 'blockenberg' ), 'cityTypo', a, set ),
203 getTypoControl( __( 'Stat Labels', 'blockenberg' ), 'metaTypo', a, set ),
204 ),
205 /* Colors */
206 el(PanelBody, { title: 'Background', initialOpen: false },
207 el(SelectControl, { __nextHasNoMarginBottom: true, label: 'Background style', value: a.backgroundStyle, options: BG_STYLES, onChange: function (v) { set({ backgroundStyle: v }); } }),
208 a.backgroundStyle === 'custom' && el('div', { style: { marginTop: '8px' } },
209 el('label', { style: { display: 'block', fontSize: '12px', marginBottom: '4px' } }, 'Background color'),
210 el('input', { type: 'color', value: a.customBg, onChange: function (e) { set({ customBg: e.target.value }); }, style: { width: '100%', height: '36px', border: 'none', borderRadius: '4px', cursor: 'pointer' } })
211 ),
212 ),
213 el(PanelColorSettings, {
214 title: 'Colors',
215 initialOpen: false,
216 colorSettings: [
217 { value: a.textColor, onChange: function (v) { set({ textColor: v || '#ffffff' }); }, label: 'Text color' },
218 { value: a.accentColor, onChange: function (v) { set({ accentColor: v || '#60a5fa' }); }, label: 'Accent color' },
219 { value: a.cardBg, onChange: function (v) { set({ cardBg: v || 'rgba(255,255,255,0.12)' }); }, label: 'Card background' },
220 { value: a.forecastBg, onChange: function (v) { set({ forecastBg: v || 'rgba(255,255,255,0.08)' }); }, label: 'Forecast day background' },
221 ],
222 }),
223 ),
224 el('div', useBlockProps({ style: getTypoCssVars(a) }),
225 el(WeatherPreview, { attributes: a })
226 )
227 );
228 },
229 save: function (props) {
230 var a = props.attributes;
231 return el('div', useBlockProps.save({ style: getTypoCssVars(a) }),
232 el('div', { className: 'bkbg-ww-app', 'data-opts': JSON.stringify(a) })
233 );
234 },
235 });
236 }() );
237