PluginProbe ʕ •ᴥ•ʔ
VK Blocks / trunk
VK Blocks vtrunk
1.123.0 1.122.0 1.121.0 1.120.0 1.119.2 1.119.1 1.119.0 1.118.7 1.82.0.0 1.82.0.1 1.83.0.0 1.83.0.1 1.84.0.0 1.84.0.1 1.85.0.2 1.85.0.3 1.85.1.0 1.85.1.1 1.86.0.0 1.86.0.1 1.86.1.0 1.87.0.0 1.87.0.1 1.88.0.1 1.88.0.2 1.89.0.0 1.9.2 1.90.0.0 1.90.0.1 1.90.1.1 1.91.0.0 1.91.1.1 1.92.0.0 1.92.0.1 1.92.1.0 1.92.1.1 1.93.0.0 trunk 1.93.0.1 0.1.1 1.93.1.0 0.10.3 1.93.1.1 0.11.0 1.94.0.0 0.12.6 1.94.0.1 0.15.1 1.94.1.0 0.16.2 1.94.2.1 0.17.6 1.94.2.2 0.2.2 1.95.0.3 0.22.4 1.95.0.4 0.26.7 1.96.2.0 0.3.2 1.96.2.1 0.31.0 1.97.0.1 0.35.5 1.97.0.2 0.37.5 1.99.0.0 0.38.8 1.99.0.1 0.39.4 0.4.7 0.41.0 0.42.0 0.44.13 0.45.2 0.46.1 0.47.0 0.48.0 0.49.8 0.5.2 0.50.3 0.51.0 0.52.2 0.53.2 0.54.0 0.55.0 0.56.2 0.56.3 0.57.6 0.58.10 0.59.0 0.6.0 0.60.1 0.61.2 0.7.1 0.8.2 1.0.16 1.10.0 1.100.0.0 1.100.0.1 1.102.0.0 1.102.0.1 1.103.0.0 1.104.0.0 1.104.0.1 1.105.1.0 1.105.1.1 1.106.0.0 1.106.0.1 1.107.0.0 1.107.0.1 1.107.0.2 1.108.0.0 1.108.0.1 1.109.0.0 1.109.0.1 1.11.4 1.110.0.0 1.110.0.1 1.111.0.0 1.111.0.1 1.111.0.2 1.112.0.0 1.112.0.1 1.113.0.0 1.113.0.1 1.114.0.0 1.114.0.1 1.114.2.0 1.114.2.1 1.115.0.0 1.115.0.1 1.115.1.0 1.115.1.1 1.115.2.0 1.115.2.1 1.116.0.0 1.116.0.1 1.116.1.0 1.116.1.1 1.116.2.0 1.117.0.0 1.117.0.1 1.117.1.0 1.118.2 1.118.5 1.12.0 1.13.2 1.14.1 1.15.1 1.16.11 1.17.0 1.18.6 1.19.0 1.19.1 1.2.3 1.20.7 1.21.0 1.22.4 1.23.0 1.24.5 1.25.1 1.26.2 1.27.7.2 1.28.0.1 1.29.2.0 1.3.9 1.30.0.1 1.31.0.1 1.32.0.2 1.33.2.1 1.36.1.5 1.37.0.0 1.39.2.1 1.4.6 1.40.0.1 1.40.1.0 1.40.1.1 1.41.0.0 1.41.0.1 1.41.2.2 1.41.2.3 1.43.0.0 1.43.0.1 1.43.0.2 1.44.0.0 1.44.0.1 1.45.0.0 1.45.0.1 1.46.0.0 1.46.0.1 1.47.0.0 1.47.0.1 1.47.1.0 1.48.0.0 1.48.0.1 1.48.0.2 1.48.1.0 1.48.1.1 1.5.0 1.50.0.0 1.50.0.1 1.51.0.0 1.51.0.1 1.52.0.0 1.52.0.1 1.53.0.0 1.53.0.1 1.54.0.0 1.54.0.1 1.55.0.0 1.55.0.1 1.56.0.0 1.56.0.1 1.57.0.0 1.57.0.2 1.57.0.3 1.57.0.4 1.57.0.5 1.57.1.0 1.57.1.1 1.57.1.2 1.58.0.0 1.58.0.1 1.59.0.0 1.59.0.1 1.6.0 1.60.0.0 1.60.0.1 1.63.0.0 1.63.0.1 1.64.0.0 1.64.0.1 1.64.1.0 1.64.1.2 1.67.0.0 1.67.0.1 1.68.0.0 1.68.0.1 1.69.0.0 1.69.0.1 1.69.1.1 1.69.1.2 1.7.1 1.70.0.0 1.70.0.1 1.71.0.0 1.71.0.1 1.72.0.0 1.72.1.0 1.72.1.1 1.73.0.0 1.73.0.1 1.74.0.0 1.74.0.1 1.75.0.0 1.75.1.0 1.75.1.1 1.76.0.0 1.76.0.1 1.76.1.0 1.76.1.1 1.76.2.0 1.76.2.1 1.77.0.0 1.77.0.1 1.78.0.0 1.78.0.1 1.79.0.0 1.79.0.1 1.79.0.2 1.79.0.3 1.79.1.0 1.79.1.1 1.8.2 1.80.1.0 1.80.1.1 1.80.1.2 1.81.0.1 1.81.0.2
vk-blocks / src / blocks / heading / edit.js
vk-blocks / src / blocks / heading Last commit date
deprecated 2 months ago block.json 1 day ago edit.js 2 months ago heading-level-dropdown.js 2 months ago heading-level-icon.js 2 months ago icon.svg 2 months ago index.js 2 months ago index.php 2 months ago save.js 2 months ago style.scss 2 months ago transforms.js 2 months ago
edit.js
428 lines
1 import { FontAwesome } from '@vkblocks/utils/font-awesome-new';
2
3 import HeadingLevelDropdown from './heading-level-dropdown';
4 import { __ } from '@wordpress/i18n';
5 import {
6 RangeControl,
7 PanelBody,
8 RadioControl,
9 SelectControl,
10 BaseControl,
11 ToolbarGroup,
12 } from '@wordpress/components';
13 import {
14 InspectorControls,
15 BlockControls,
16 AlignmentToolbar,
17 RichText,
18 useBlockProps,
19 } from '@wordpress/block-editor';
20 import { isHexColor } from '@vkblocks/utils/is-hex-color';
21 import { AdvancedColorPalette } from '@vkblocks/components/advanced-color-palette';
22 import parse from 'html-react-parser';
23 import classnames from 'classnames';
24 import { sanitizeSlug } from '@vkblocks/utils/sanitizeSlug';
25 import { iconLabel } from '@vkblocks/utils/icon-label';
26 import { useEffect } from '@wordpress/element';
27 import { fixBrokenUnicode } from '@vkblocks/utils/fixBrokenUnicode';
28
29 const renderTitle = (level, contents, tStyle, headingStyle) => {
30 switch (level) {
31 case 1:
32 return (
33 <h1 style={tStyle} className={headingStyle}>
34 {contents}
35 </h1>
36 );
37 case 2:
38 return (
39 <h2 style={tStyle} className={headingStyle}>
40 {contents}
41 </h2>
42 );
43 case 3:
44 return (
45 <h3 style={tStyle} className={headingStyle}>
46 {contents}
47 </h3>
48 );
49 case 4:
50 return (
51 <h4 style={tStyle} className={headingStyle}>
52 {contents}
53 </h4>
54 );
55 case 5:
56 return (
57 <h5 style={tStyle} className={headingStyle}>
58 {contents}
59 </h5>
60 );
61 case 6:
62 return (
63 <h6 style={tStyle} className={headingStyle}>
64 {contents}
65 </h6>
66 );
67 }
68 };
69
70 export default function HeaddingEdit(props) {
71 const { attributes, setAttributes } = props;
72 const {
73 level,
74 align,
75 title,
76 titleColor,
77 titleSize,
78 subText,
79 subTextFlag,
80 subTextColor,
81 subTextSize,
82 titleStyle,
83 titleMarginBottom,
84 outerMarginBottom,
85 fontAwesomeIconBefore,
86 fontAwesomeIconAfter,
87 fontAwesomeIconColor,
88 } = attributes;
89
90 const setTitleFontSize = (newLevel) => {
91 setAttributes({ level: newLevel });
92 };
93
94 const containerClass = `vk_heading vk_heading-style-${titleStyle}`;
95
96 const cStyle = {
97 marginBottom:
98 outerMarginBottom !== null && outerMarginBottom !== undefined
99 ? outerMarginBottom + `rem`
100 : undefined,
101 };
102
103 let headingColorClassName = '';
104 if (titleColor !== undefined) {
105 headingColorClassName += `has-text-color`;
106 if (!isHexColor(titleColor)) {
107 headingColorClassName += ` has-${sanitizeSlug(titleColor)}-color`;
108 }
109 }
110
111 const headingStyle = classnames('vk_heading_title', {
112 [`vk_heading_title-style-${titleStyle}`]: !!titleStyle,
113 [`${headingColorClassName}`]: !!headingColorClassName,
114 });
115
116 const tStyle = {
117 color:
118 titleColor !== null &&
119 titleColor !== undefined &&
120 isHexColor(titleColor)
121 ? titleColor
122 : undefined,
123 fontSize:
124 titleSize !== null && titleSize !== undefined
125 ? titleSize + 'rem'
126 : undefined,
127 marginBottom:
128 titleMarginBottom !== null && titleMarginBottom !== undefined
129 ? titleMarginBottom + 'rem'
130 : undefined,
131 textAlign: align !== null && align !== undefined ? align : undefined,
132 };
133
134 let subTextColorClassName = '';
135 if (subTextColor !== undefined) {
136 subTextColorClassName += `has-text-color`;
137 if (!isHexColor(subTextColor)) {
138 subTextColorClassName += ` has-${sanitizeSlug(subTextColor)}-color`;
139 }
140 }
141
142 const subTextClass = classnames('vk_heading_subtext', {
143 [`vk_heading_subtext-style-${titleStyle}`]: !!titleStyle,
144 [`${subTextColorClassName}`]: !!subTextColorClassName,
145 });
146
147 const subTextStyle = {
148 color:
149 subTextColor !== null &&
150 subTextColor !== undefined &&
151 isHexColor(subTextColor)
152 ? subTextColor
153 : undefined,
154 fontSize:
155 subTextSize !== null && subTextSize !== undefined
156 ? subTextSize + 'rem'
157 : undefined,
158 textAlign: align !== null && align !== undefined ? align : undefined,
159 };
160
161 let iconColorClassName = '';
162 if (fontAwesomeIconColor !== undefined) {
163 iconColorClassName += `has-text-color`;
164 if (!isHexColor(fontAwesomeIconColor)) {
165 iconColorClassName += ` has-${sanitizeSlug(fontAwesomeIconColor)}-color`;
166 }
167 }
168
169 const fontAwesomeIconStyle =
170 fontAwesomeIconColor && isHexColor(fontAwesomeIconColor)
171 ? `style="color:${fontAwesomeIconColor};"`
172 : '';
173
174 let iconBefore = fontAwesomeIconBefore
175 ? fixBrokenUnicode(fontAwesomeIconBefore)
176 : fontAwesomeIconBefore;
177 let iconAfter = fontAwesomeIconAfter
178 ? fixBrokenUnicode(fontAwesomeIconAfter)
179 : fontAwesomeIconAfter;
180 //add class
181 if (iconBefore && iconColorClassName) {
182 const faIconFragmentBefore = iconBefore.split('<i class="');
183 faIconFragmentBefore[0] =
184 faIconFragmentBefore[0] + `<i class="${iconColorClassName} `;
185 iconBefore = faIconFragmentBefore.join('');
186 }
187
188 if (iconAfter && iconColorClassName) {
189 const faIconFragmentAfter = iconAfter.split('<i class="');
190 faIconFragmentAfter[0] =
191 faIconFragmentAfter[0] + `<i class="${iconColorClassName} `;
192 iconAfter = faIconFragmentAfter.join('');
193 }
194
195 //add inline css
196 if (iconBefore && fontAwesomeIconStyle) {
197 const faIconFragmentBefore = iconBefore.split('<i');
198 faIconFragmentBefore[0] =
199 faIconFragmentBefore[0] + `<i ${fontAwesomeIconStyle} `;
200 iconBefore = faIconFragmentBefore.join('');
201 }
202
203 if (iconAfter && fontAwesomeIconStyle) {
204 const faIconFragmentAfter = iconAfter.split('<i');
205 faIconFragmentAfter[0] =
206 faIconFragmentAfter[0] + `<i ${fontAwesomeIconStyle} `;
207 iconAfter = faIconFragmentAfter.join('');
208 }
209
210 useEffect(() => {
211 const fixes = {};
212 if (fontAwesomeIconBefore) {
213 const fixed = fixBrokenUnicode(fontAwesomeIconBefore);
214 if (fixed !== fontAwesomeIconBefore) {
215 fixes.fontAwesomeIconBefore = fixed;
216 }
217 }
218 if (fontAwesomeIconAfter) {
219 const fixed = fixBrokenUnicode(fontAwesomeIconAfter);
220 if (fixed !== fontAwesomeIconAfter) {
221 fixes.fontAwesomeIconAfter = fixed;
222 }
223 }
224 if (Object.keys(fixes).length > 0) {
225 setAttributes(fixes);
226 }
227 }, [fontAwesomeIconBefore, fontAwesomeIconAfter]);
228
229 const titleContent = (
230 <>
231 {parse(iconBefore)}
232 <RichText
233 tagName={'span'}
234 value={title}
235 onChange={(value) => {
236 setAttributes({ title: value });
237 }}
238 placeholder={__('Input title…', 'vk-blocks')}
239 />
240 {parse(iconAfter)}
241 </>
242 );
243
244 let subtextContent;
245 if (subTextFlag === 'on') {
246 subtextContent = (
247 <RichText
248 tagName={'p'}
249 value={subText}
250 onChange={(value) => setAttributes({ subText: value })}
251 style={subTextStyle}
252 className={subTextClass}
253 placeholder={__('Input sub text…', 'vk-blocks')}
254 />
255 );
256 }
257
258 const blockProps = useBlockProps({
259 className: ``,
260 });
261
262 return (
263 <>
264 <BlockControls group="block">
265 <ToolbarGroup>
266 <HeadingLevelDropdown
267 selectedLevel={level}
268 onChange={setTitleFontSize}
269 />
270 </ToolbarGroup>
271 <AlignmentToolbar
272 value={align}
273 onChange={(value) => {
274 setAttributes({ align: value });
275 }}
276 />
277 </BlockControls>
278 <InspectorControls>
279 <PanelBody title={__('Style Settings', 'vk-blocks')}>
280 <SelectControl
281 label={__('Heading style', 'vk-blocks')}
282 value={titleStyle}
283 onChange={(value) =>
284 setAttributes({ titleStyle: value })
285 }
286 options={[
287 {
288 label: __('Default', 'vk-blocks'),
289 value: 'default',
290 },
291 {
292 label: __('Plain', 'vk-blocks'),
293 value: 'plain',
294 },
295 ]}
296 />
297 </PanelBody>
298 <PanelBody title={__('Margin Setting', 'vk-blocks')}>
299 <p>
300 {__(
301 'Margin between Heading and sub text (rem)',
302 'vk-blocks'
303 )}
304 </p>
305 <RangeControl
306 value={titleMarginBottom}
307 onChange={(value) => {
308 setAttributes({ titleMarginBottom: value });
309 }}
310 min={-1}
311 max={3}
312 step={0.1}
313 allowReset={true}
314 resetFallbackValue={null}
315 />
316 <p>
317 {__(
318 'Margin bottom size of after this block (rem)',
319 'vk-blocks'
320 )}
321 </p>
322 <RangeControl
323 value={outerMarginBottom}
324 onChange={(value) => {
325 setAttributes({ outerMarginBottom: value });
326 }}
327 min={-1}
328 max={8}
329 step={0.1}
330 allowReset={true}
331 resetFallbackValue={null}
332 />
333 </PanelBody>
334 <PanelBody title={__('Heading Settings', 'vk-blocks')}>
335 <RangeControl
336 label={__('Text size (rem)', 'vk-blocks')}
337 value={titleSize}
338 onChange={(value) => {
339 setAttributes({ titleSize: value });
340 }}
341 min={0.5}
342 max={4}
343 step={0.1}
344 allowReset={true}
345 resetFallbackValue={null}
346 />
347 <BaseControl
348 label={__('Text Color', 'vk-blocks')}
349 id={`vk_heading_textColor`}
350 >
351 <AdvancedColorPalette
352 schema={'titleColor'}
353 {...props}
354 />
355 </BaseControl>
356 </PanelBody>
357 <PanelBody title={iconLabel(__('Icon', 'vk-blocks'))}>
358 <BaseControl
359 label={__('Before text', 'vk-blocks')}
360 id={`vk_heading_beforeText`}
361 >
362 <FontAwesome
363 attributeName={'fontAwesomeIconBefore'}
364 {...props}
365 />
366 </BaseControl>
367 <BaseControl
368 label={__('After text', 'vk-blocks')}
369 id={`vk_heading_afterText`}
370 >
371 <FontAwesome
372 attributeName={'fontAwesomeIconAfter'}
373 {...props}
374 />
375 </BaseControl>
376 <BaseControl
377 label={__('Icon Color', 'vk-blocks')}
378 id={`vk_heading_iconColor`}
379 >
380 <AdvancedColorPalette
381 schema={'fontAwesomeIconColor'}
382 {...props}
383 />
384 </BaseControl>
385 </PanelBody>
386 <PanelBody title={__('Sub Text Settings', 'vk-blocks')}>
387 <RadioControl
388 label={__('Position', 'vk-blocks')}
389 selected={subTextFlag}
390 options={[
391 {
392 label: __('Display', 'vk-blocks'),
393 value: 'on',
394 },
395 {
396 label: __('Hide', 'vk-blocks'),
397 value: 'off',
398 },
399 ]}
400 onChange={(value) =>
401 setAttributes({ subTextFlag: value })
402 }
403 />
404 <p>{__('Text size (rem)', 'vk-blocks')}</p>
405 <RangeControl
406 value={subTextSize}
407 onChange={(value) => {
408 setAttributes({ subTextSize: value });
409 }}
410 min={0.5}
411 max={3}
412 step={0.1}
413 allowReset={true}
414 resetFallbackValue={null}
415 />
416 <AdvancedColorPalette schema={'subTextColor'} {...props} />
417 </PanelBody>
418 </InspectorControls>
419 <div {...blockProps}>
420 <div className={containerClass} style={cStyle}>
421 {renderTitle(level, titleContent, tStyle, headingStyle)}
422 {subtextContent}
423 </div>
424 </div>
425 </>
426 );
427 }
428