PluginProbe ʕ •ᴥ•ʔ
VK Blocks / 1.124.0
VK Blocks v1.124.0
1.124.0 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 / slider / edit.js
vk-blocks / src / blocks / slider Last commit date
deprecated 1 month ago _swiper._scss 2 months ago block.json 1 month ago edit-multiItem.js 1 month ago edit-slider.js 1 month ago edit.js 2 days ago icon.svg 2 months ago index.js 2 months ago index.php 2 months ago loop-min-slides.js 2 months ago pause-button.js 2 weeks ago save.js 2 weeks ago style.scss 2 months ago view.js 2 weeks ago
edit.js
849 lines
1 import { AdvancedToggleControl } from '@vkblocks/components/advanced-toggle-control';
2 import { __ } from '@wordpress/i18n';
3 import { useEffect, useRef } from '@wordpress/element';
4 import {
5 InspectorControls,
6 BlockControls,
7 BlockAlignmentToolbar,
8 InnerBlocks,
9 useBlockProps,
10 } from '@wordpress/block-editor';
11 import {
12 PanelBody,
13 BaseControl,
14 TextControl,
15 __experimentalToggleGroupControl as ToggleGroupControl,
16 __experimentalToggleGroupControlOption as ToggleGroupControlOption,
17 SelectControl,
18 ToolbarGroup,
19 ToolbarDropdownMenu,
20 Dashicon,
21 ToggleControl,
22 RangeControl,
23 } from '@wordpress/components';
24 import {
25 isParentReusableBlock,
26 hasBlockIdCollision,
27 shouldUpdateBlockId,
28 } from '@vkblocks/utils/is-parent-reusable-block';
29 import { editSliderLaunch } from './edit-slider';
30 import { MultiItemSetting } from './edit-multiItem';
31 import { PauseButton } from './pause-button';
32 import ResponsiveSizeControl, {
33 getMaxByUnit,
34 } from '@vkblocks/components/responsive-size-control';
35 import { useSelect } from '@wordpress/data';
36
37 // eslint-disable no-shadow
38 export default function SliderEdit(props) {
39 const { attributes, setAttributes, clientId } = props;
40 const {
41 editorMode,
42 pc,
43 tablet,
44 mobile,
45 autoPlay,
46 autoPlayStop,
47 autoPlayDelay,
48 pauseButton,
49 pagination,
50 width,
51 loop,
52 effect,
53 speed,
54 slidesPerView,
55 slidesPerViewMobile,
56 slidesPerViewTablet,
57 slidesPerViewPC,
58 slidesPerGroup,
59 centeredSlides,
60 navigationPosition,
61 direction,
62 unit,
63 zoomAnimation,
64 zoomInitialScale,
65 zoomFinalScale,
66 blockId,
67 } = attributes;
68
69 // インナーブロックを取得
70 const innerBlocks = useSelect((select) =>
71 select('core/block-editor').getBlocks(clientId)
72 );
73
74 // editorMode と innerBlocks の順序をログ出力
75 useEffect(() => {
76 // 編集モード(default)に戻す時に DOM 要素を正しい順序に復�
77
78 if (editorMode === 'default') {
79 const sliderElement = blockRef.current;
80
81 if (sliderElement) {
82 const wrapper = sliderElement.querySelector(
83 '.block-editor-block-list__layout'
84 );
85
86 if (wrapper && innerBlocks && innerBlocks.length > 0) {
87 // 現在の DOM 順序を取得
88 const currentOrder = Array.from(
89 wrapper.querySelectorAll('.vk_slider_item')
90 )
91 .map((el) => {
92 const classMatch = el.className.match(
93 /vk_slider_item-([a-f0-9\-]+)/
94 );
95 return classMatch ? classMatch[1] : null;
96 })
97 .filter((id) => id !== null);
98
99 // 期�
100 される順序
101 const expectedOrder = innerBlocks.map(
102 (b) => b.attributes.blockId || b.clientId
103 );
104
105 // 順序が同じなら何もしない(不要な DOM 操作を避ける)
106 if (
107 JSON.stringify(currentOrder) ===
108 JSON.stringify(expectedOrder)
109 ) {
110 return;
111 }
112
113 // 順序が異なる場合のみ並べ替え
114 // innerBlocks の順序に従って slider-item を並べ替え
115 let previousElement = null;
116 innerBlocks.forEach((block) => {
117 const blockIdToUse =
118 block.attributes.blockId || block.clientId;
119 const element = wrapper.querySelector(
120 `.vk_slider_item-${blockIdToUse}`
121 );
122 if (!element) {
123 return;
124 }
125
126 if (previousElement) {
127 // 前の要素の次に挿�
128
129 if (previousElement.nextSibling) {
130 wrapper.insertBefore(
131 element,
132 previousElement.nextSibling
133 );
134 } else {
135 wrapper.appendChild(element);
136 }
137 } else if (element !== wrapper.firstChild) {
138 // 最初の要素が�
139 �頭にない場合のみ移動
140 wrapper.insertBefore(element, wrapper.firstChild);
141 }
142
143 previousElement = element;
144 });
145 }
146 }
147 }
148 }, [editorMode, innerBlocks, clientId]);
149
150 // プレビューモードに戻す時に、Swiper インスタンスをリセットして確実に再初期化
151 useEffect(() => {
152 if (editorMode === 'slide') {
153 // requestAnimationFrame で React のレンダリングが完了するのを�
154 ってから初期化
155 let timerId;
156 const rafId = requestAnimationFrame(() => {
157 timerId = setTimeout(() => {
158 editSliderLaunch();
159 }, 50);
160 });
161
162 return () => {
163 cancelAnimationFrame(rafId);
164 if (timerId) {
165 clearTimeout(timerId);
166 }
167 };
168 }
169 }, [editorMode]);
170
171 useEffect(() => {
172 // attributes の clientId は使わなくなったので削除
173 if (attributes.clientId !== undefined) {
174 setAttributes({ clientId: undefined });
175 }
176
177 // issue #2556: blockId を毎リロードで上書きすると dirty 化するため、
178 // 「未確定」または「再利用ブロック外での実衝突(複製)」のときだけ再採番する。
179 if (
180 shouldUpdateBlockId({
181 blockId,
182 isInReusableBlock: isParentReusableBlock(clientId),
183 hasCollision: hasBlockIdCollision(clientId, blockId),
184 })
185 ) {
186 setAttributes({ blockId: clientId });
187 }
188
189 // 1.49 以前では slidesPerViewMobile が定義されていないので互換設定を追加
190 if (slidesPerViewMobile === undefined) {
191 setAttributes({
192 slidesPerViewMobile: 1,
193 });
194 }
195
196 // 1.49 以前では slidesPerViewTablet が定義されていないので互換設定を追加
197 if (slidesPerViewTablet === undefined) {
198 setAttributes({
199 slidesPerViewTablet: 1,
200 });
201 }
202
203 // 1.49 以前では slidesPerViewPC が定義されていないので互換設定を追加
204 if (slidesPerViewPC === undefined) {
205 if (slidesPerView !== undefined) {
206 setAttributes({
207 slidesPerViewPC: slidesPerView,
208 });
209 } else {
210 setAttributes({
211 slidesPerViewPC: 1,
212 });
213 }
214 }
215
216 // 1.49 以前では slidesPerView が定義されていないので互換設定を追加
217 if (slidesPerView === undefined) {
218 setAttributes({
219 slidesPerView: 1,
220 });
221 }
222
223 // @since 1.50
224 // 1.49 までは slidesPerGroup は 数字での保存のみだったため、
225 // 1 の場合は one-by-one に、 1 以外の数字指定だった場合は slides-per-view になるように
226 if (
227 slidesPerGroup === undefined ||
228 slidesPerGroup === null ||
229 slidesPerGroup === '' ||
230 slidesPerGroup === 1 ||
231 slidesPerGroup === 'one-by-one'
232 ) {
233 setAttributes({
234 slidesPerGroup: 'one-by-one',
235 });
236 } else {
237 setAttributes({
238 slidesPerGroup: 'slides-per-view',
239 });
240 }
241
242 // 1.51 以前では centeredSlides が定義されていないので互換設定を追加
243 if (centeredSlides === undefined) {
244 setAttributes({ centeredSlides: false });
245 }
246
247 // 1.49 以前では pagination はブール型だったが文字列型になっための互換処理
248 if (pagination === false) {
249 setAttributes({ pagination: 'hide' });
250 }
251 if (pagination === true) {
252 setAttributes({ pagination: 'bullets' });
253 }
254
255 // 1.49 以前では autoPlayStop が定義されていないので互換設定を追加
256 if (autoPlayStop === undefined) {
257 setAttributes({ autoPlayStop: false });
258 }
259
260 // pauseButton 追加前のブロックでは未定義なので互換設定を追加
261 if (pauseButton === undefined) {
262 setAttributes({ pauseButton: false });
263 }
264
265 // 1.49 以前では navigationPosition が定義されていないので互換設定を追加
266 if (navigationPosition === undefined) {
267 setAttributes({ navigationPosition: 'mobile-bottom' });
268 }
269
270 // 1.67 以前では editorMode が定義されていないので互換設定を追加
271 if (editorMode === undefined) {
272 setAttributes({ editorMode: 'default' });
273 }
274
275 // ズームアニメーション設定の初期化
276 if (zoomAnimation === undefined) {
277 setAttributes({ zoomAnimation: false });
278 }
279 if (zoomInitialScale === undefined) {
280 setAttributes({ zoomInitialScale: 1 });
281 }
282 if (zoomFinalScale === undefined) {
283 setAttributes({ zoomFinalScale: 1.25 });
284 }
285
286 // 1.68 以前では direction が定義されていないので互換設定を追加
287 if (direction === undefined) {
288 setAttributes({ direction: 'rtl' });
289 }
290 }, [clientId]);
291
292 // 複数枚表示が設定されている場合に拡大機能を無効化
293 useEffect(() => {
294 if (
295 slidesPerViewPC > 1 ||
296 slidesPerViewTablet > 1 ||
297 slidesPerViewMobile > 1
298 ) {
299 if (zoomAnimation) {
300 setAttributes({ zoomAnimation: false });
301 }
302 }
303 }, [
304 slidesPerViewPC,
305 slidesPerViewTablet,
306 slidesPerViewMobile,
307 zoomAnimation,
308 ]);
309
310 // 拡大機能が有効になった場合に複数枚表示設定を1にリセット
311 useEffect(() => {
312 if (zoomAnimation) {
313 if (slidesPerViewPC > 1) {
314 setAttributes({ slidesPerViewPC: 1 });
315 }
316 if (slidesPerViewTablet > 1) {
317 setAttributes({ slidesPerViewTablet: 1 });
318 }
319 if (slidesPerViewMobile > 1) {
320 setAttributes({ slidesPerViewMobile: 1 });
321 }
322 }
323 }, [
324 zoomAnimation,
325 slidesPerViewPC,
326 slidesPerViewTablet,
327 slidesPerViewMobile,
328 ]);
329
330 // 複数枚動かすときに sliderPerView が小数だと微妙なので対処
331 useEffect(() => {
332 if (slidesPerGroup === 'slides-per-view') {
333 setAttributes({
334 slidesPerViewPC: parseInt(Number(slidesPerViewPC), 10),
335 });
336 setAttributes({
337 slidesPerViewTablet: parseInt(Number(slidesPerViewTablet), 10),
338 });
339 setAttributes({
340 slidesPerViewMobile: parseInt(Number(slidesPerViewMobile), 10),
341 });
342 }
343 }, [slidesPerGroup]);
344
345 const containerClass = ' vk_grid-column';
346 const ALLOWED_BLOCKS = ['vk-blocks/slider-item'];
347 const TEMPLATE = [['vk-blocks/slider-item']];
348
349 // �
350 のクラス名変更
351 let alignClass = '';
352 if ('full' === width) {
353 alignClass = ' alignfull';
354 } else if ('wide' === width) {
355 alignClass = ' alignwide';
356 }
357
358 // JS に渡す値の構造体
359 const sliderData = {
360 editorMode,
361 autoPlay,
362 autoPlayStop,
363 autoPlayDelay,
364 pauseButton,
365 pagination,
366 blockId,
367 width,
368 loop,
369 effect,
370 speed,
371 slidesPerViewMobile,
372 slidesPerViewTablet,
373 slidesPerViewPC,
374 slidesPerGroup,
375 centeredSlides,
376 zoomAnimation,
377 zoomInitialScale,
378 zoomFinalScale,
379 direction,
380 };
381
382 // ページネーションの HTML
383 let pagination_html = '';
384 if (pagination !== 'hide') {
385 pagination_html = (
386 <div
387 className={`swiper-pagination swiper-pagination-${pagination}`}
388 ></div>
389 );
390 }
391
392 // ナビゲーションの HTML
393 let navigation_next_html = '';
394 let navigation_prev_html = '';
395 if (navigationPosition !== 'hide') {
396 navigation_next_html = (
397 <div
398 className={`swiper-button-next swiper-button-${navigationPosition}`}
399 ></div>
400 );
401 navigation_prev_html = (
402 <div
403 className={`swiper-button-prev swiper-button-${navigationPosition}`}
404 ></div>
405 );
406 }
407
408 // 停止/再生ボタンの HTML(プレビュー(slide)モードで Swiper が初期化される時のみ意味を持つため、
409 // editorMode === 'slide' かつ自動再生が有効かつ表示設定が ON の時だけ出力)
410 const pause_button_html =
411 editorMode === 'slide' && autoPlay && pauseButton ? (
412 <PauseButton />
413 ) : (
414 ''
415 );
416
417 const blockRef = useRef(null);
418
419 // 高さ・ズーム用の CSS は blockId をキーに生成される(index.js / save.js と�
420 �通)。
421 // issue #2556 以降 blockId は編集時に clientId と一致しなくなったため、ラッパーの
422 // クラスも blockId で揃えないと編集画面だけ CSS が当たらず表示が崩れる。
423 // The height/zoom CSS is keyed on blockId (shared with index.js / save.js).
424 // Since issue #2556, blockId no longer equals clientId in the editor, so the
425 // wrapper class must also use blockId; otherwise the CSS misses only in the
426 // editor and the slider renders broken.
427 const blockProps = useBlockProps({
428 className: `vk_slider vk_swiper vk_slider_editorMode--${editorMode} vk_slider_${blockId}${alignClass}`,
429 ref: blockRef,
430 });
431
432 return (
433 <>
434 <BlockControls>
435 <BlockAlignmentToolbar
436 value={width}
437 onChange={(nextWidth) =>
438 setAttributes({ width: nextWidth })
439 }
440 controls={['wide', 'full']}
441 />
442 <ToolbarGroup>
443 <ToolbarDropdownMenu
444 icon={
445 editorMode === 'default' ? (
446 <Dashicon icon="edit" />
447 ) : (
448 <Dashicon icon="visibility" />
449 )
450 }
451 label={__('Change Slide Editor Mode', 'vk-blocks')}
452 controls={[
453 {
454 title: __(
455 'Edit ( Stacked Layout ) Mode',
456 'vk-blocks'
457 ),
458 icon: <Dashicon icon="edit" />,
459 isActive: editorMode === 'default',
460 onClick: () =>
461 setAttributes({ editorMode: 'default' }),
462 },
463 {
464 title: __(
465 'Preview ( Slide ) Mode',
466 'vk-blocks'
467 ),
468 icon: <Dashicon icon="visibility" />,
469 isActive: editorMode === 'slide',
470 onClick: () =>
471 setAttributes({ editorMode: 'slide' }),
472 },
473 ]}
474 />
475 </ToolbarGroup>
476 </BlockControls>
477 <InspectorControls>
478 <PanelBody
479 title={__('Editor Setting', 'vk-blocks')}
480 initialOpen={true}
481 >
482 <BaseControl
483 label={__('Editor Mode', 'vk-blocks')}
484 id={`vk_slider-effect`}
485 >
486 <ToggleGroupControl
487 value={editorMode}
488 onChange={(value) =>
489 setAttributes({ editorMode: value })
490 }
491 isBlock
492 help={__(
493 'In edit mode, the elements are stacked vertically. In preview mode, the slides actually animate.',
494 'vk-blocks'
495 )}
496 >
497 <ToggleGroupControlOption
498 value="default"
499 label={__('Edit', 'vk-blocks')}
500 />
501 <ToggleGroupControlOption
502 value="slide"
503 label={__('Preview', 'vk-blocks')}
504 />
505 </ToggleGroupControl>
506 </BaseControl>
507 </PanelBody>
508 <PanelBody
509 title={__('Slider Settings', 'vk-blocks')}
510 initialOpen={false}
511 >
512 <BaseControl
513 label={__('Effect', 'vk-blocks')}
514 id={`vk_slider-effect`}
515 >
516 <SelectControl
517 value={effect}
518 onChange={(value) =>
519 setAttributes({ effect: value })
520 }
521 options={[
522 {
523 label: __('Slide', 'vk-blocks'),
524 value: 'slide',
525 },
526 {
527 label: __('Fade', 'vk-blocks'),
528 value: 'fade',
529 },
530 ]}
531 />
532 </BaseControl>
533 <BaseControl
534 label={__('Loop', 'vk-blocks')}
535 id={`vk_slider-loop`}
536 >
537 <AdvancedToggleControl
538 initialFixedTable={loop}
539 schema={'loop'}
540 {...props}
541 />
542 </BaseControl>
543 <BaseControl
544 label={__('AutoPlay', 'vk-blocks')}
545 id={`vk_slider-autoPlay`}
546 >
547 <AdvancedToggleControl
548 initialFixedTable={autoPlay}
549 schema={'autoPlay'}
550 {...props}
551 />
552 </BaseControl>
553
554 {/* Slide Direction is only available when AutoPlay is enabled because reverseDirection is an autoplay-specific setting in Swiper.js */}
555 {autoPlay && (
556 <BaseControl
557 label={__('Slide Direction', 'vk-blocks')}
558 id={`vk_slider-direction`}
559 >
560 <SelectControl
561 value={direction}
562 options={[
563 {
564 label: __('Right to Left', 'vk-blocks'),
565 value: 'rtl',
566 },
567 {
568 label: __('Left to Right', 'vk-blocks'),
569 value: 'ltr',
570 },
571 ]}
572 onChange={(value) =>
573 setAttributes({ direction: value })
574 }
575 />
576 </BaseControl>
577 )}
578 <BaseControl
579 label={__('Stop AutoPlay when swipe', 'vk-blocks')}
580 id={`vk_slider-autoPlay`}
581 >
582 <AdvancedToggleControl
583 initialFixedTable={autoPlayStop}
584 schema={'autoPlayStop'}
585 {...props}
586 />
587 </BaseControl>
588 {/* 停止/再生ボタンは自動再生が有効な時のみ意味を持つため、autoPlay が ON の時だけ表示 */}
589 {autoPlay && (
590 <BaseControl
591 label={__(
592 'Display pause / play button',
593 'vk-blocks'
594 )}
595 id={`vk_slider-pauseButton`}
596 help={
597 <>
598 {__(
599 'Displays a button on the front end that lets visitors pause and resume the autoplay.',
600 'vk-blocks'
601 )}{' '}
602 {__(
603 'When this is off, autoplay keeps running even for visitors whose device requests reduced motion, since there is no button to pause it.',
604 'vk-blocks'
605 )}
606 </>
607 }
608 >
609 <AdvancedToggleControl
610 initialFixedTable={pauseButton}
611 schema={'pauseButton'}
612 {...props}
613 />
614 </BaseControl>
615 )}
616 <BaseControl
617 label={__('Display Time', 'vk-blocks')}
618 id={`vk_slider-autoPlay`}
619 >
620 <TextControl
621 type={'number'}
622 value={autoPlayDelay}
623 onChange={(value) => {
624 if (
625 Number.isNaN(Number(value)) ||
626 Number(value) < 0
627 ) {
628 setAttributes({
629 autoPlayDelay: 0,
630 });
631 } else {
632 setAttributes({
633 autoPlayDelay: parseInt(
634 Number(value),
635 10
636 ),
637 });
638 }
639 }}
640 min={0}
641 />
642 </BaseControl>
643 <BaseControl
644 label={__('Change Speed', 'vk-blocks')}
645 id={`vk_slider-changeSpeed`}
646 >
647 <TextControl
648 type={'number'}
649 value={speed}
650 onChange={(value) => {
651 if (
652 Number.isNaN(Number(value)) ||
653 Number(value) < 0
654 ) {
655 setAttributes({
656 speed: 0,
657 });
658 } else {
659 setAttributes({
660 speed: parseInt(Number(value), 10),
661 });
662 }
663 }}
664 min={0}
665 />
666 </BaseControl>
667 <BaseControl
668 label={__('Pagination Type', 'vk-blocks')}
669 id={`vk_slider-displayPagination`}
670 >
671 <SelectControl
672 value={pagination}
673 options={[
674 {
675 label: __('Hide', 'vk-blocks'),
676 value: 'hide',
677 },
678 {
679 label: __('Default', 'vk-blocks'),
680 value: 'bullets',
681 },
682 {
683 label: __('Number of slides', 'vk-blocks'),
684 value: 'fraction',
685 },
686 ]}
687 onChange={(value) =>
688 setAttributes({ pagination: value })
689 }
690 />
691 </BaseControl>
692 <BaseControl
693 label={__('Navigation Position', 'vk-blocks')}
694 id={`vk_slider-navigationPosition`}
695 >
696 <SelectControl
697 value={navigationPosition}
698 options={[
699 {
700 label: __('Hide', 'vk-blocks'),
701 value: 'hide',
702 },
703 {
704 label: __('Center', 'vk-blocks'),
705 value: 'center',
706 },
707 {
708 label: __(
709 'Bottom on Mobile device',
710 'vk-blocks'
711 ),
712 value: 'mobile-bottom',
713 },
714 {
715 label: __(
716 'Bottom on all devices',
717 'vk-blocks'
718 ),
719 value: 'always-bottom',
720 },
721 ]}
722 onChange={(value) =>
723 setAttributes({ navigationPosition: value })
724 }
725 />
726 </BaseControl>
727 </PanelBody>
728 <MultiItemSetting {...props} />
729 <PanelBody
730 title={__('Height', 'vk-blocks')}
731 initialOpen={false}
732 >
733 <ResponsiveSizeControl
734 label={__('Slide Height for each device', 'vk-blocks')}
735 valuePC={pc}
736 valueTablet={tablet}
737 valueMobile={mobile}
738 unit={unit}
739 onChangePC={(value) => setAttributes({ pc: value })}
740 onChangeTablet={(value) =>
741 setAttributes({ tablet: value })
742 }
743 onChangeMobile={(value) =>
744 setAttributes({ mobile: value })
745 }
746 onChangeUnit={(value) => setAttributes({ unit: value })}
747 maxPC={getMaxByUnit(unit)}
748 maxTablet={getMaxByUnit(unit)}
749 maxMobile={getMaxByUnit(unit)}
750 />
751 </PanelBody>
752 <PanelBody
753 title={__('Background Image Zoom Animation', 'vk-blocks')}
754 initialOpen={false}
755 >
756 {effect !== 'fade' &&
757 (slidesPerViewPC > 1 ||
758 slidesPerViewTablet > 1 ||
759 slidesPerViewMobile > 1) ? (
760 <div className="alert alert-warning font-size-11px">
761 {__(
762 'When multiple items are set in "Multi-item Display Setting", zoom settings here will be disabled. Please set all to "1".',
763 'vk-blocks'
764 )}
765 </div>
766 ) : (
767 <>
768 <ToggleControl
769 label={__('Enable', 'vk-blocks')}
770 checked={zoomAnimation}
771 onChange={(value) =>
772 setAttributes({ zoomAnimation: value })
773 }
774 help={__(
775 'Enabling this will apply a zoom animation to the slide background image.',
776 'vk-blocks'
777 )}
778 />
779 <div className="alert alert-info font-size-11px">
780 {__(
781 'We recommend using the Fade effect together with Background image Zoom Animation.',
782 'vk-blocks'
783 )}
784 </div>
785 {zoomAnimation && (
786 <>
787 <RangeControl
788 label={__(
789 'Initial Background Scale',
790 'vk-blocks'
791 )}
792 value={zoomInitialScale}
793 onChange={(value) =>
794 setAttributes({
795 zoomInitialScale: value,
796 })
797 }
798 min={1}
799 max={3}
800 step={0.05}
801 />
802 <RangeControl
803 label={__(
804 'Final Background Scale',
805 'vk-blocks'
806 )}
807 value={zoomFinalScale}
808 onChange={(value) =>
809 setAttributes({
810 zoomFinalScale: value,
811 })
812 }
813 min={1}
814 max={3}
815 step={0.05}
816 />
817 <p className="vk_slider_zoomAnimation_help">
818 {__(
819 '1 means original size. Larger values will zoom in the background image.',
820 'vk-blocks'
821 )}
822 </p>
823 </>
824 )}
825 </>
826 )}
827 </PanelBody>
828 </InspectorControls>
829 <div {...blockProps} data-vkb-slider={JSON.stringify(sliderData)}>
830 <div className={`vk_slider_wrapper`}>
831 <div>
832 <InnerBlocks
833 //編集画面の追加タグ用に2回目のClassを挿�
834
835 className={`${containerClass} row`}
836 template={TEMPLATE}
837 allowedBlocks={ALLOWED_BLOCKS}
838 />
839 </div>
840 </div>
841 {navigation_next_html}
842 {navigation_prev_html}
843 {pagination_html}
844 {pause_button_html}
845 </div>
846 </>
847 );
848 }
849