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 / extensions / common / margin-extension / index.js
vk-blocks / src / extensions / common / margin-extension Last commit date
icons.js 2 months ago index.js 2 months ago
index.js
352 lines
1 /**
2 * WordPress dependencies
3 */
4 import { __ } from '@wordpress/i18n';
5 import { addFilter } from '@wordpress/hooks';
6 import { BlockControls } from '@wordpress/block-editor';
7 import { createHigherOrderComponent } from '@wordpress/compose';
8 import { ToolbarDropdownMenu } from '@wordpress/components';
9 import { useEffect } from '@wordpress/element';
10
11 /**
12 * External dependencies
13 */
14 import classnames from 'classnames';
15
16 /**
17 * Internal dependencies
18 */
19 import { marginIcon, marginTopIcon, marginBottomIcon } from './icons';
20 import { isExcludesBlocks } from '@vkblocks/utils/is-excludes-blocks';
21 import { emptyStringToUndefined } from '@vkblocks/utils/empty-string-to-undefined';
22
23 const DEFAULT_MARGIN_TOP_CONTROLS = [
24 {
25 title: __('Top XXL', 'vk-blocks'),
26 marginClass: 'vk_block-margin-xxl--margin-top',
27 flag: 'top',
28 },
29 {
30 title: __('Top XL', 'vk-blocks'),
31 marginClass: 'vk_block-margin-xl--margin-top',
32 flag: 'top',
33 },
34 {
35 title: __('Top L', 'vk-blocks'),
36 marginClass: 'vk_block-margin-lg--margin-top',
37 flag: 'top',
38 },
39 {
40 title: __('Top M', 'vk-blocks'),
41 marginClass: 'vk_block-margin-md--margin-top',
42 flag: 'top',
43 },
44 {
45 title: __('Top S', 'vk-blocks'),
46 marginClass: 'vk_block-margin-sm--margin-top',
47 flag: 'top',
48 },
49 {
50 title: __('Top XS', 'vk-blocks'),
51 marginClass: 'vk_block-margin-xs--margin-top',
52 flag: 'top',
53 },
54 {
55 title: __('Top XXS', 'vk-blocks'),
56 marginClass: 'vk_block-margin-xxs--margin-top',
57 flag: 'top',
58 },
59 {
60 title: __('Top 0', 'vk-blocks'),
61 marginClass: 'vk_block-margin-0--margin-top',
62 flag: 'top',
63 },
64 ];
65
66 const DEFAULT_MARGIN_BOTTOM_CONTROLS = [
67 {
68 title: __('Bottom 0', 'vk-blocks'),
69 marginClass: 'vk_block-margin-0--margin-bottom',
70 flag: 'bottom',
71 },
72 {
73 title: __('Bottom XXS', 'vk-blocks'),
74 marginClass: 'vk_block-margin-xxs--margin-bottom',
75 flag: 'bottom',
76 },
77 {
78 title: __('Bottom XS', 'vk-blocks'),
79 marginClass: 'vk_block-margin-xs--margin-bottom',
80 flag: 'bottom',
81 },
82 {
83 title: __('Bottom S', 'vk-blocks'),
84 marginClass: 'vk_block-margin-sm--margin-bottom',
85 flag: 'bottom',
86 },
87 {
88 title: __('Bottom M', 'vk-blocks'),
89 marginClass: 'vk_block-margin-md--margin-bottom',
90 flag: 'bottom',
91 },
92 {
93 title: __('Bottom L', 'vk-blocks'),
94 marginClass: 'vk_block-margin-lg--margin-bottom',
95 flag: 'bottom',
96 },
97 {
98 title: __('Bottom XL', 'vk-blocks'),
99 marginClass: 'vk_block-margin-xl--margin-bottom',
100 flag: 'bottom',
101 },
102 {
103 title: __('Bottom XXL', 'vk-blocks'),
104 marginClass: 'vk_block-margin-xxl--margin-bottom',
105 flag: 'bottom',
106 },
107 ];
108
109 const DEFAULT_MARGIN_CONTROLS = [
110 ...DEFAULT_MARGIN_TOP_CONTROLS,
111 ...DEFAULT_MARGIN_BOTTOM_CONTROLS,
112 ];
113
114 // deprecated用 �
115 �通余白使用している可能性があるdynamic block
116 const MAY_USED_DYNAMIC_BLOCK = [
117 'vk-blocks/breadcrumb',
118 'vk-blocks/child-page',
119 'vk-blocks/post-list',
120 'vk-blocks/page-content',
121 // ExUnitに�
122 �っているvk blocksブロック,
123 'vk-blocks/share-button',
124 'vk-blocks/child-page-index',
125 'vk-blocks/contact-section',
126 'vk-blocks/page-list-ancestor',
127 'vk-blocks/sitemap',
128 ];
129
130 export const isAddMargin = (blockName) => {
131 const addMarginCoreBlocks = [
132 'core/post-excerpt',
133 'core/post-title',
134 'core/query-title',
135 'core/post-featured-image',
136 'core/post-date',
137 'core/post-terms',
138 'core/post-content',
139 ];
140
141 if (addMarginCoreBlocks.includes(blockName)) {
142 return true; // 抜粋ブロックとタイトルブロックは強制的に許可
143 }
144
145 const addExclude = [
146 'vk-blocks/slider-item',
147 'vk-blocks/card-item',
148 'vk-blocks/icon-card-item',
149 'vk-blocks/select-post-list-item',
150 ];
151 return isExcludesBlocks({ blockName, addExclude });
152 };
153
154 /* Filter of blocks.registerBlockType
155 /*-----------------------------------*/
156 addFilter(
157 'blocks.registerBlockType',
158 'vk-blocks/margin-extension',
159 (settings) => {
160 // deprecated用 dynamic blockは自動的に追加CSSクラスに追加されないのでattributeを残す
161 const mayUsedDynamicBlock = MAY_USED_DYNAMIC_BLOCK;
162 if (mayUsedDynamicBlock.includes(settings.name)) {
163 settings.attributes = {
164 // Deploy original settings.attributes to array and...
165 ...settings.attributes,
166 // Add margin attributes
167 ...{
168 marginTop: {
169 type: 'string',
170 },
171 marginBottom: {
172 type: 'string',
173 },
174 },
175 };
176 }
177 return settings;
178 }
179 );
180
181 /* Filter of editor.BlockEdit
182 /*-----------------------------------*/
183 addFilter(
184 'editor.BlockEdit',
185 'vk-blocks/margin-extension',
186 createHigherOrderComponent((BlockEdit) => {
187 return (props) => {
188 const { name, attributes, setAttributes } = props;
189 const { marginTop, marginBottom, className } = attributes;
190 const marginTopControls = DEFAULT_MARGIN_TOP_CONTROLS;
191 const marginBottomControls = DEFAULT_MARGIN_BOTTOM_CONTROLS;
192 const marginControls = DEFAULT_MARGIN_CONTROLS;
193 // attributeの変数名がわかりにくいので別の変数にする
194 const nowClass = className || '';
195 const marginTopRegex =
196 /vk_block-margin-(0|xxs|xs|sm|md|lg|xl|xxl)--margin-top/;
197 const marginBottomRegex =
198 /vk_block-margin-(0|xxs|xs|sm|md|lg|xl|xxl)--margin-bottom/;
199
200 // deprecated
201 /**
202 * �
203 �通余白のattribute:marginTop,marginBottomが使用されている可能性があるdynamic blockは過去に使用していたmarginTop,marginBottomをclassNameに�
204 �れ,過去のmarginTopやmarginBottomはundefinedにする
205 *
206 * dynamic block以外はコアの仕様で追加 CSS クラスに自動的に追加される
207 */
208 const mayUsedDynamicBlock = MAY_USED_DYNAMIC_BLOCK;
209 const isMatchTop = marginTopRegex.test(marginTop);
210 const isMatchBottom = marginBottomRegex.test(marginBottom);
211 useEffect(() => {
212 if (mayUsedDynamicBlock.includes(name)) {
213 if (isMatchTop || isMatchBottom) {
214 setAttributes({
215 className: classnames({
216 [nowClass]: nowClass,
217 [marginTop]: isMatchTop,
218 [marginBottom]: isMatchBottom,
219 }),
220 });
221 setAttributes({ marginTop: undefined });
222 setAttributes({ marginBottom: undefined });
223 }
224 }
225 }, []);
226
227 // 追加CSSクラスを半角文字列で分けて�
228 �列化
229 const nowClassArray = nowClass ? nowClass.split(' ') : [];
230 // 現在カスタムcssに�
231 �っているvk_block-margin-(0|sm|md|lg)--margin-top,bottomクラス名を取得
232 const activeMarginTopClassArray = nowClassArray.filter((item) => {
233 return item.match(marginTopRegex);
234 });
235 const activeMarginBottomClassArray = nowClassArray.filter(
236 (item) => {
237 return item.match(marginBottomRegex);
238 }
239 );
240
241 // 複数のクラス名が�
242 �っていた場合は最後のcssが当たるので最後のクラス名を取得する
243 const activeMarginTopClass = activeMarginTopClassArray.slice(-1)[0];
244 const activeMarginBottomClass =
245 activeMarginBottomClassArray.slice(-1)[0];
246
247 // アクティブマージンのObjectを作る
248 const activeMarginTop = marginTopControls.find(
249 (control) => control.marginClass === activeMarginTopClass
250 );
251 const activeMarginBottom = marginBottomControls.find(
252 (control) => control.marginClass === activeMarginBottomClass
253 );
254
255 // 追加CSSに保存するクラスを作る関数
256 const getNewClasses = (
257 classArray, // 現在のクラス �
258 �列
259 clickedClass, // クリックされたクラス名 文字列
260 spliceMarginClassName // アクティブなクラス名,削除するクラス名 文字列
261 ) => {
262 // アクティブなクラスがなければ新規に新しいクラスを追加する
263 if (spliceMarginClassName === undefined) {
264 classArray.push(clickedClass);
265 return classArray;
266 }
267 // 選択されているクラスがクリックされたらそのクラス名を削除する
268 if (classArray.includes(clickedClass)) {
269 const clickIndex = classArray.indexOf(clickedClass);
270 classArray.splice(clickIndex, 1);
271 return classArray;
272 }
273 // アクティブなクラス名を削除
274 const spliceIndex = classArray.indexOf(spliceMarginClassName);
275 classArray.splice(spliceIndex, 1);
276 // 新しいクラスを追加する
277 classArray.push(clickedClass);
278 return classArray;
279 };
280
281 if (!isAddMargin(name)) {
282 return <BlockEdit {...props} />;
283 }
284 return (
285 <>
286 <BlockEdit {...props} />
287 <BlockControls group="block">
288 <ToolbarDropdownMenu
289 icon={
290 <>
291 {activeMarginTop &&
292 !activeMarginBottom &&
293 marginTopIcon}
294 {!activeMarginTop &&
295 activeMarginBottom &&
296 marginBottomIcon}
297 {activeMarginTop &&
298 activeMarginBottom &&
299 marginIcon}
300 {!activeMarginTop &&
301 !activeMarginBottom &&
302 marginIcon}
303 {activeMarginTop || activeMarginBottom ? (
304 <span style={{ marginLeft: '8px' }}>
305 {activeMarginTop &&
306 activeMarginTop.title}
307 {activeMarginTop &&
308 activeMarginBottom && <br />}
309 {activeMarginBottom &&
310 activeMarginBottom.title}
311 </span>
312 ) : null}
313 </>
314 }
315 label={__('Margin the block', 'vk-blocks')}
316 controls={marginControls.map((control) => {
317 const { marginClass, flag } = control;
318 const isActive =
319 activeMarginTopClass === marginClass ||
320 activeMarginBottomClass === marginClass;
321 return {
322 ...control,
323 isActive,
324 icon:
325 flag === 'top'
326 ? marginTopIcon
327 : marginBottomIcon,
328 onClick: () => {
329 // 現在のクラス,クリックされたクラス,アクティブなクラス名をgetNewClassesに渡してクラス名を作り直す
330 const newClasses = getNewClasses(
331 nowClassArray,
332 marginClass,
333 flag === 'top'
334 ? activeMarginTopClass
335 : activeMarginBottomClass
336 );
337 setAttributes({
338 className: emptyStringToUndefined(
339 newClasses.join(' ')
340 ),
341 });
342 },
343 };
344 })}
345 />
346 </BlockControls>
347 </>
348 );
349 };
350 }, 'addMarginSection')
351 );
352