PluginProbe ʕ •ᴥ•ʔ
FrontBlocks for Gutenberg/GeneratePress / trunk
FrontBlocks for Gutenberg/GeneratePress vtrunk
trunk 0.2.0 0.2.1 0.2.2 0.2.3 0.2.4 0.2.5 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.1.0 1.2.0 1.2.1 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 ci-artifacts
frontblocks / assets / user-text / frontblocks-user-text.js
frontblocks / assets / user-text Last commit date
frontblocks-user-text-option.jsx 1 month ago frontblocks-user-text.css 1 month ago frontblocks-user-text.js 1 month ago
frontblocks-user-text.js
368 lines
1 "use strict";
2
3 function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
4 function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
5 function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
6 function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
7 function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
8 function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
9 function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
10 function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
11 function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
12 function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
13 function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
14 function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
15 function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
16 var registerBlockType = wp.blocks.registerBlockType;
17 var _wp$element = wp.element,
18 Fragment = _wp$element.Fragment,
19 useState = _wp$element.useState,
20 useEffect = _wp$element.useEffect;
21 var useSelect = wp.data.useSelect;
22 var _wp$blockEditor = wp.blockEditor,
23 InspectorControls = _wp$blockEditor.InspectorControls,
24 useBlockProps = _wp$blockEditor.useBlockProps,
25 PanelColorSettings = _wp$blockEditor.PanelColorSettings;
26 var _wp$components = wp.components,
27 PanelBody = _wp$components.PanelBody,
28 SelectControl = _wp$components.SelectControl,
29 TextControl = _wp$components.TextControl,
30 TextareaControl = _wp$components.TextareaControl;
31 var __ = wp.i18n.__;
32 var HEADING_TAGS = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
33 var TAG_OPTIONS = [{
34 label: 'p',
35 value: 'p'
36 }, {
37 label: 'h1',
38 value: 'h1'
39 }, {
40 label: 'h2',
41 value: 'h2'
42 }, {
43 label: 'h3',
44 value: 'h3'
45 }, {
46 label: 'h4',
47 value: 'h4'
48 }, {
49 label: 'h5',
50 value: 'h5'
51 }, {
52 label: 'h6',
53 value: 'h6'
54 }, {
55 label: 'span',
56 value: 'span'
57 }, {
58 label: 'div',
59 value: 'div'
60 }];
61 var FONT_WEIGHT_OPTIONS = [{
62 label: __('Default', 'frontblocks'),
63 value: ''
64 }, {
65 label: __('Thin (100)', 'frontblocks'),
66 value: '100'
67 }, {
68 label: __('Extra Light (200)', 'frontblocks'),
69 value: '200'
70 }, {
71 label: __('Light (300)', 'frontblocks'),
72 value: '300'
73 }, {
74 label: __('Normal (400)', 'frontblocks'),
75 value: '400'
76 }, {
77 label: __('Medium (500)', 'frontblocks'),
78 value: '500'
79 }, {
80 label: __('Semi Bold (600)', 'frontblocks'),
81 value: '600'
82 }, {
83 label: __('Bold (700)', 'frontblocks'),
84 value: '700'
85 }, {
86 label: __('Extra Bold (800)', 'frontblocks'),
87 value: '800'
88 }, {
89 label: __('Black (900)', 'frontblocks'),
90 value: '900'
91 }];
92 var TEXT_ALIGN_OPTIONS = [{
93 label: __('Default', 'frontblocks'),
94 value: ''
95 }, {
96 label: __('Left', 'frontblocks'),
97 value: 'left'
98 }, {
99 label: __('Center', 'frontblocks'),
100 value: 'center'
101 }, {
102 label: __('Right', 'frontblocks'),
103 value: 'right'
104 }, {
105 label: __('Justify', 'frontblocks'),
106 value: 'justify'
107 }];
108
109 /**
110 * Resolve a CSS var like "var(--wp--preset--font-size--large)" to a real value
111 * using computed styles on the document root.
112 */
113 function resolveCssVar(value) {
114 if (!value || !value.startsWith('var(')) return value;
115 var match = value.match(/var\(\s*(--[^,)]+)/);
116 if (!match) return value;
117 var resolved = getComputedStyle(document.documentElement).getPropertyValue(match[1]).trim();
118 return resolved || value;
119 }
120 registerBlockType('frontblocks/user-text', {
121 title: __('User Text', 'frontblocks'),
122 description: __('Text pattern with logged-in user data placeholders.', 'frontblocks'),
123 category: 'text',
124 icon: 'admin-users',
125 supports: {
126 html: false
127 },
128 attributes: {
129 textPattern: {
130 type: 'string',
131 default: __('Hello, {nombre}!', 'frontblocks')
132 },
133 htmlTag: {
134 type: 'string',
135 default: 'p'
136 },
137 textColor: {
138 type: 'string',
139 default: ''
140 },
141 hoverTextColor: {
142 type: 'string',
143 default: ''
144 },
145 fontSize: {
146 type: 'string',
147 default: ''
148 },
149 fontFamily: {
150 type: 'string',
151 default: ''
152 },
153 fontWeight: {
154 type: 'string',
155 default: ''
156 },
157 textAlign: {
158 type: 'string',
159 default: ''
160 },
161 loggedOutText: {
162 type: 'string',
163 default: ''
164 }
165 },
166 edit: function edit(_ref) {
167 var attributes = _ref.attributes,
168 setAttributes = _ref.setAttributes;
169 var textPattern = attributes.textPattern,
170 htmlTag = attributes.htmlTag,
171 textColor = attributes.textColor,
172 hoverTextColor = attributes.hoverTextColor,
173 fontSize = attributes.fontSize,
174 fontFamily = attributes.fontFamily,
175 fontWeight = attributes.fontWeight,
176 textAlign = attributes.textAlign,
177 loggedOutText = attributes.loggedOutText;
178
179 // ── Current user (with email, needs context=edit) ──────────────────
180 var _useState = useState(null),
181 _useState2 = _slicedToArray(_useState, 2),
182 currentUser = _useState2[0],
183 setCurrentUser = _useState2[1];
184 useEffect(function () {
185 wp.apiFetch({
186 path: '/wp/v2/users/me?context=edit'
187 }).then(function (u) {
188 return setCurrentUser(u);
189 }).catch(function () {});
190 }, []);
191
192 // ── Theme global styles ─────────────────────────────────────────────
193 var _useState3 = useState({}),
194 _useState4 = _slicedToArray(_useState3, 2),
195 themeTypo = _useState4[0],
196 setThemeTypo = _useState4[1];
197 var themeSlug = useSelect(function (select) {
198 var _select$getCurrentThe;
199 return (_select$getCurrentThe = select('core').getCurrentTheme()) === null || _select$getCurrentThe === void 0 ? void 0 : _select$getCurrentThe.stylesheet;
200 });
201 useEffect(function () {
202 if (!themeSlug) return;
203 wp.apiFetch({
204 path: '/wp/v2/global-styles/themes/' + themeSlug
205 }).then(function (data) {
206 var elements = data && data.styles && data.styles.elements ? data.styles.elements : {};
207 // Merge heading base + specific tag (specific wins)
208 var base = HEADING_TAGS.includes(htmlTag) ? elements.heading && elements.heading.typography ? elements.heading.typography : {} : {};
209 var tagTypo = elements[htmlTag] && elements[htmlTag].typography ? elements[htmlTag].typography : {};
210 var merged = Object.assign({}, base, tagTypo);
211 // Resolve CSS vars to real values for display
212 var resolved = {};
213 Object.keys(merged).forEach(function (k) {
214 resolved[k] = resolveCssVar(merged[k]);
215 });
216 setThemeTypo(resolved);
217 }).catch(function () {});
218 }, [themeSlug, htmlTag]);
219
220 // ── Preview: replace placeholders with real user data ───────────────
221 var previewText = function previewText(pattern) {
222 if (!currentUser) return pattern;
223 var nombre = currentUser.first_name || currentUser.name || '';
224 var map = {
225 '{nombre}': nombre,
226 '{apellido}': currentUser.last_name || '',
227 '{display_name}': currentUser.name || '',
228 '{email}': currentUser.email || '',
229 '{username}': currentUser.slug || '',
230 '{bio}': currentUser.description || '',
231 '{web}': currentUser.url || ''
232 };
233 return Object.entries(map).reduce(function (str, _ref2) {
234 var _ref3 = _slicedToArray(_ref2, 2),
235 key = _ref3[0],
236 val = _ref3[1];
237 return str.split(key).join(val);
238 }, pattern);
239 };
240
241 // ── Inline styles: only explicit overrides ──────────────────────────
242 var inlineStyle = {
243 color: textColor || undefined,
244 fontSize: fontSize || undefined,
245 fontFamily: fontFamily || undefined,
246 fontWeight: fontWeight || undefined,
247 textAlign: textAlign || undefined
248 };
249 var blockProps = useBlockProps();
250 var Tag = htmlTag || 'p';
251
252 // Helper: placeholder showing theme default when field is empty
253 var themePlaceholder = function themePlaceholder(key, fallback) {
254 if (!themeTypo[key]) return fallback;
255 return themeTypo[key] + ' (' + __('tema', 'frontblocks') + ')';
256 };
257
258 // For SelectControl (fontWeight): inject theme default into label
259 var weightOptions = FONT_WEIGHT_OPTIONS.map(function (opt) {
260 if (opt.value !== '') return opt;
261 var tw = themeTypo.fontWeight;
262 return _objectSpread(_objectSpread({}, opt), {}, {
263 label: tw ? __('Default', 'frontblocks') + '' + tw : __('Default', 'frontblocks')
264 });
265 });
266 return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(InspectorControls, null, /*#__PURE__*/React.createElement(PanelBody, {
267 title: __('Pattern & Data', 'frontblocks'),
268 initialOpen: true
269 }, /*#__PURE__*/React.createElement(TextareaControl, {
270 label: __('Text Pattern', 'frontblocks'),
271 value: textPattern,
272 onChange: function onChange(val) {
273 return setAttributes({
274 textPattern: val
275 });
276 },
277 rows: 4,
278 help: __('Placeholders: {nombre}, {apellido}, {display_name}, {email}, {username}, {bio}, {web}', 'frontblocks')
279 }), /*#__PURE__*/React.createElement(TextControl, {
280 label: __('Logged-out Fallback', 'frontblocks'),
281 value: loggedOutText,
282 onChange: function onChange(val) {
283 return setAttributes({
284 loggedOutText: val
285 });
286 },
287 help: __('Shown when no user is logged in. Leave empty to hide.', 'frontblocks')
288 })), /*#__PURE__*/React.createElement(PanelBody, {
289 title: __('Typography', 'frontblocks'),
290 initialOpen: false
291 }, /*#__PURE__*/React.createElement(SelectControl, {
292 label: __('HTML Tag', 'frontblocks'),
293 value: htmlTag,
294 options: TAG_OPTIONS,
295 onChange: function onChange(val) {
296 return setAttributes({
297 htmlTag: val
298 });
299 }
300 }), /*#__PURE__*/React.createElement(TextControl, {
301 label: __('Font Size', 'frontblocks'),
302 value: fontSize,
303 onChange: function onChange(val) {
304 return setAttributes({
305 fontSize: val
306 });
307 },
308 placeholder: themePlaceholder('fontSize', '16px, 1.5rem…'),
309 help: fontSize ? __('Custom override active. Clear to use theme default.', 'frontblocks') : __('Empty = theme default.', 'frontblocks')
310 }), /*#__PURE__*/React.createElement(SelectControl, {
311 label: __('Font Weight', 'frontblocks'),
312 value: fontWeight,
313 options: weightOptions,
314 onChange: function onChange(val) {
315 return setAttributes({
316 fontWeight: val
317 });
318 }
319 }), /*#__PURE__*/React.createElement(TextControl, {
320 label: __('Font Family', 'frontblocks'),
321 value: fontFamily,
322 onChange: function onChange(val) {
323 return setAttributes({
324 fontFamily: val
325 });
326 },
327 placeholder: themePlaceholder('fontFamily', 'Inter, sans-serif…'),
328 help: fontFamily ? __('Custom override active. Clear to use theme default.', 'frontblocks') : __('Empty = theme default.', 'frontblocks')
329 }), /*#__PURE__*/React.createElement(SelectControl, {
330 label: __('Text Align', 'frontblocks'),
331 value: textAlign,
332 options: TEXT_ALIGN_OPTIONS,
333 onChange: function onChange(val) {
334 return setAttributes({
335 textAlign: val
336 });
337 }
338 })), /*#__PURE__*/React.createElement(PanelColorSettings, {
339 title: __('Color', 'frontblocks'),
340 initialOpen: false,
341 colorSettings: [{
342 value: textColor,
343 onChange: function onChange(val) {
344 return setAttributes({
345 textColor: val || ''
346 });
347 },
348 label: __('Text Color', 'frontblocks')
349 }, {
350 value: hoverTextColor,
351 onChange: function onChange(val) {
352 return setAttributes({
353 hoverTextColor: val || ''
354 });
355 },
356 label: __('Text Color on Hover', 'frontblocks')
357 }]
358 })), /*#__PURE__*/React.createElement(Tag, _extends({}, blockProps, {
359 style: _objectSpread(_objectSpread({}, inlineStyle), {}, {
360 margin: 0
361 })
362 }), previewText(textPattern) || __('Enter a text pattern in the sidebar…', 'frontblocks')));
363 },
364 save: function save() {
365 return null;
366 }
367 });
368