itmar-block-packages 1.9.0 → 1.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "itmar-block-packages",
3
- "version": "1.9.0",
3
+ "version": "1.10.1",
4
4
  "description": "We have put together a package of common React components used for WordPress custom blocks.",
5
5
  "main": "build/index.js",
6
6
  "scripts": {
@@ -0,0 +1,247 @@
1
+ import {
2
+ serializeBlockTree,
3
+ createBlockTree,
4
+ flattenBlocks,
5
+ } from "./blockStore";
6
+ import { createBlock, getBlockType } from "@wordpress/blocks";
7
+ import { useEffect } from "@wordpress/element";
8
+ import { useSelect, useDispatch } from "@wordpress/data";
9
+
10
+ //フィールド生成用関数
11
+ const createBlockAttr = (selectedField) => {
12
+ let blockAttributes = {};
13
+
14
+ switch (selectedField.block) {
15
+ case "itmar/design-title":
16
+ const block_class = selectedField.key.startsWith("tax_")
17
+ ? selectedField.key
18
+ : `sp_field_${selectedField.key}`;
19
+ blockAttributes = {
20
+ className: block_class,
21
+ headingContent: `[${selectedField.label}]`,
22
+ };
23
+
24
+ break;
25
+ case "core/paragraph":
26
+ blockAttributes = {
27
+ className: `itmar_ex_block sp_field_${selectedField.key}`,
28
+ content: `[${selectedField.label}]`,
29
+ };
30
+ break;
31
+ case "core/image":
32
+ blockAttributes = {
33
+ className: `itmar_ex_block sp_field_${selectedField.key}`,
34
+ url: `${ec_relate_blocks.plugin_url}/assets/image/main_sample.png`,
35
+ };
36
+ break;
37
+ case "itmar/slide-mv":
38
+ const spaceAttributes = {
39
+ margin_val: {
40
+ type: "object",
41
+ default: {
42
+ top: "0em",
43
+ left: "0em",
44
+ bottom: "0em",
45
+ right: "0em",
46
+ },
47
+ },
48
+ padding_val: {
49
+ type: "object",
50
+ default: {
51
+ top: "0em",
52
+ left: "0em",
53
+ bottom: "0em",
54
+ right: "0em",
55
+ },
56
+ },
57
+ };
58
+
59
+ const imageBlock = createBlock("core/image", {
60
+ className: "itmar_ex_block",
61
+ url: `${ec_relate_blocks.plugin_url}/assets/image/slide_sample.png`,
62
+ ...spaceAttributes,
63
+ });
64
+ //Design Blockの初期設定を取得
65
+ const blockType = getBlockType("itmar/design-group");
66
+ const defaultValBase = blockType?.attributes?.default_val?.default ?? {};
67
+ const mobileValBase = blockType?.attributes?.mobile_val?.default ?? {};
68
+ const slideBlock = createBlock(
69
+ "itmar/design-group",
70
+ {
71
+ default_val: {
72
+ ...defaultValBase,
73
+ width_val: "fit",
74
+ },
75
+ mobile_val: {
76
+ ...mobileValBase,
77
+ width_val: "fit",
78
+ },
79
+ },
80
+ [imageBlock]
81
+ );
82
+ //slideBlock をシリアライズ
83
+ const serializedSlide = serializeBlockTree(slideBlock);
84
+ // 同じスライドブロックを5つ複製(独立したブロックとして)
85
+ const slideBlocks = Array.from({ length: 5 }, () =>
86
+ createBlockTree(serializedSlide)
87
+ );
88
+ //子ブロック付きで返す
89
+ blockAttributes = {
90
+ attributes: { className: `sp_field_${selectedField.key}` },
91
+ slideBlocks: slideBlocks,
92
+ };
93
+ break;
94
+ default:
95
+ blockAttributes = {
96
+ className: `sp_field_${selectedField.key}`,
97
+ headingContent: `[${selectedField.label}]`,
98
+ };
99
+ }
100
+ return blockAttributes;
101
+ };
102
+
103
+ //表示フィールド変更によるインナーブロックの再構成
104
+ export const useRebuildChangeField = (
105
+ dispAttributeArray,
106
+ selectedFields,
107
+ pickupType,
108
+ dispTaxonomies,
109
+ sectionCount,
110
+ domType,
111
+ clientId,
112
+ insertId
113
+ ) => {
114
+ // dispatch関数を取得
115
+ const { replaceInnerBlocks } = useDispatch("core/block-editor");
116
+ const pickupBlock = useSelect(
117
+ (select) => select("core/block-editor").getBlock(clientId),
118
+ [clientId]
119
+ );
120
+
121
+ useEffect(() => {
122
+ //dispAttributeArray の個数調整
123
+ const blocksLength = dispAttributeArray.length;
124
+
125
+ if (blocksLength < sectionCount) {
126
+ // dispAttributeArrayの長さが短い場合、{}を追加する
127
+ const diff = sectionCount - blocksLength;
128
+ for (let i = 0; i < diff; i++) {
129
+ dispAttributeArray.push({});
130
+ }
131
+ } else {
132
+ // dispAttributeArrayの長さが長い場合、余分な要素を削除する
133
+ dispAttributeArray.splice(sectionCount);
134
+ }
135
+
136
+ // インナーブロックに差し込むブロック配列を生成
137
+ const blocksArray = dispAttributeArray.map((dispAttribute, unit_index) => {
138
+ // blocksAttributesArray属性で登録されたブロックのclassName一覧(sp_field_xxx を拾う)
139
+ const allBlocks = Array.isArray(dispAttribute.innerBlocks)
140
+ ? flattenBlocks(dispAttribute.innerBlocks) //階層になったブロックを平坦化
141
+ : [];
142
+
143
+ const existingKeys = allBlocks
144
+ .map((block) => block.attributes?.className)
145
+ .filter(Boolean)
146
+ .map((cls) => {
147
+ // sp_field_◯◯ か tax_◯◯ のどちらかにマッチ
148
+ const match = cls.match(/sp_field_([\w-]+)|(tax_[\w-]+)/);
149
+ if (!match) return null;
150
+
151
+ // match[1] があれば sp_field_ のほう → プレフィックス除去
152
+ // match[2] があれば tax_ のほう → そのまま返す
153
+ return match[1] ?? match[2];
154
+ })
155
+ .filter(Boolean);
156
+
157
+ // dispTaxonomies からオブジェクトを作って selectedFieldsに加えてnewSelectedFieldsを生成
158
+ const newSelectedFields = [
159
+ ...selectedFields,
160
+ ...dispTaxonomies.map((tax) => ({
161
+ key: `tax_${tax}`, // 例: "tax_category"
162
+ label: tax, // 例: "category"
163
+ block: "itmar/design-title",
164
+ })),
165
+ ];
166
+
167
+ // newSelectedFieldsのうち未挿入のものだけ追加
168
+ const autoGeneratedBlocks = newSelectedFields
169
+ .filter((field) => !existingKeys.includes(field.key))
170
+ .map((field) => {
171
+ const attr = createBlockAttr(field);
172
+ const blockName = field.block;
173
+ const blockAttributes = attr?.attributes ?? attr;
174
+ const innerBlocks = Array.isArray(attr?.slideBlocks)
175
+ ? attr.slideBlocks
176
+ : [];
177
+
178
+ return createBlock(blockName, blockAttributes, innerBlocks);
179
+ });
180
+ // blocksAttributesArray属性で登録されたブロックの再構築
181
+ const selectedKeys = selectedFields.map((f) => f.key);
182
+
183
+ const filterBlocksRecursively = (blocks) => {
184
+ return blocks
185
+ .map((block) => {
186
+ const className = block.attributes?.className || "";
187
+ // 1. まず sp_field_ のパターンを探す
188
+ let match = className.match(/sp_field_([a-zA-Z0-9_]+)/);
189
+ // 2. 見つからなければ tax_○○ をチェック
190
+ if (className.startsWith("tax_")) {
191
+ const name = className.slice("tax_".length); // "tax_category" → "category"
192
+
193
+ // dispTaxonomies に含まれないものだけ有効とする
194
+ if (!dispTaxonomies.includes(name)) {
195
+ // 正規表現の match 結果っぽい形の配列を自分で作る
196
+ // [0] に全体一致, [1] にグループ1 というイメージ
197
+ match = [`tax_${name}`, name];
198
+ }
199
+ }
200
+
201
+ // 再帰的に innerBlocks をフィルタ
202
+ const filteredInner = block.innerBlocks
203
+ ? filterBlocksRecursively(block.innerBlocks)
204
+ : [];
205
+
206
+ const isAutoGenerated = !!match;
207
+ const keep = !isAutoGenerated || selectedKeys.includes(match[1]);
208
+
209
+ if (!keep) return null;
210
+
211
+ // 構造を復元して返す
212
+ return {
213
+ ...block,
214
+ innerBlocks: filteredInner,
215
+ };
216
+ })
217
+ .filter(Boolean); // null を除去
218
+ };
219
+
220
+ const userBlocks = Array.isArray(dispAttribute.innerBlocks)
221
+ ? filterBlocksRecursively(dispAttribute.innerBlocks).map(
222
+ createBlockTree
223
+ )
224
+ : [];
225
+
226
+ // autoGenerated(selectedFields) + userBlocks を合成
227
+ const innerBlocks = [...userBlocks, ...autoGeneratedBlocks];
228
+
229
+ const ret = createBlock(
230
+ "itmar/design-group",
231
+ {
232
+ ...dispAttribute.attributes,
233
+ className: `unit_design_${unit_index}`,
234
+ domType: domType,
235
+ },
236
+ innerBlocks
237
+ );
238
+ return ret;
239
+ });
240
+ //挿入するブロックと自身のブロックが異なる場合(slide-mvにデータを入れる場合)
241
+ if (insertId !== clientId) {
242
+ blocksArray.push(pickupBlock);
243
+ }
244
+ // 既存のインナーブロックを一括置換
245
+ replaceInnerBlocks(insertId, blocksArray, false);
246
+ }, [selectedFields, pickupType, dispTaxonomies]);
247
+ };
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Masonry グリッドを初期化する共通関数
3
+ *
4
+ * @param {HTMLElement} gridEl - `.itmar-masonry-grid` のコンテナ要素
5
+ * @param {Array<{ url: string, alt?: string }>} images - 描画する画像リスト
6
+ * @param {Object} options
7
+ * @param {number} options.columns - カラム数
8
+ * @param {boolean} [options.renderItems=true]
9
+ * true: この関数内で gridEl をクリアして <figure><img> を追加する
10
+ * false: 既にある .itmar-masonry-item をそのまま使い、幅だけ更新する
11
+ *
12
+ * @returns {any|null} Masonry インスタンス(なければ null)
13
+ */
14
+
15
+ export default function MasonryControl(
16
+ gridEl,
17
+ images = [],
18
+ { columns = 1, renderItems = true } = {}
19
+ ) {
20
+ if (!gridEl) return null;
21
+ const columnWidthPercent = 100 / (columns || 1);
22
+
23
+ // 既存インスタンスがあれば破棄(再初期化に対応)
24
+ if (gridEl.__masonryInstance) {
25
+ try {
26
+ gridEl.__masonryInstance.destroy();
27
+ } catch (e) {
28
+ console.warn("Failed to destroy previous Masonry instance", e);
29
+ }
30
+ gridEl.__masonryInstance = null;
31
+ }
32
+
33
+ // ---------------------------
34
+ // 1) アイテムの DOM を構築 or 更新
35
+ // ---------------------------
36
+ if (renderItems) {
37
+ // ★ コンテナ全部は消さない。マソンリー用の要素だけを削除する
38
+ gridEl
39
+ .querySelectorAll(".itmar-masonry-sizer, .itmar-masonry-item")
40
+ .forEach((node) => node.remove());
41
+
42
+ // sizer 追加
43
+ const sizer = document.createElement("div");
44
+ sizer.className = "itmar-masonry-sizer";
45
+ sizer.style.width = `${columnWidthPercent}%`;
46
+ gridEl.appendChild(sizer);
47
+
48
+ // 画像アイテム追加
49
+ images.forEach((item, index) => {
50
+ const fig = document.createElement("figure");
51
+ fig.className = "itmar-masonry-item";
52
+ fig.style.width = `${columnWidthPercent}%`;
53
+
54
+ // クリック検知用の a タグ
55
+ const link = document.createElement("a");
56
+ link.href = "#";
57
+ link.className = "itmar-masonry-link";
58
+ link.dataset.masonryIndex = String(index);
59
+ //img要素
60
+ const img = document.createElement("img");
61
+ img.src = item.url;
62
+ img.alt = item.alt || "";
63
+ img.style.display = "block";
64
+ img.style.width = "100%";
65
+ img.style.height = "auto";
66
+
67
+ link.appendChild(img);
68
+ fig.appendChild(link);
69
+ gridEl.appendChild(fig);
70
+ });
71
+ } else {
72
+ // React 側(edit.js)みたいに、すでに <figure> が描画されている場合
73
+ // sizer がなければ作る
74
+ let sizer = gridEl.querySelector(".itmar-masonry-sizer");
75
+ if (!sizer) {
76
+ sizer = document.createElement("div");
77
+ sizer.className = "itmar-masonry-sizer";
78
+ gridEl.insertBefore(sizer, gridEl.firstChild || null);
79
+ }
80
+ sizer.style.width = `${columnWidthPercent}%`;
81
+
82
+ // 既存 item の幅だけ更新
83
+ gridEl.querySelectorAll(".itmar-masonry-item").forEach((fig) => {
84
+ fig.style.width = `${columnWidthPercent}%`;
85
+ });
86
+ }
87
+
88
+ // ---------------------------
89
+ // 2) Masonry / imagesLoaded を iframe-aware に取得
90
+ // ---------------------------
91
+ let win = null;
92
+
93
+ if (gridEl.ownerDocument && gridEl.ownerDocument.defaultView) {
94
+ // サイトエディタ・ブロックエディタの iframe 内ならこっち
95
+ win = gridEl.ownerDocument.defaultView;
96
+ } else if (typeof window !== "undefined") {
97
+ // フロントなら普通に window
98
+ win = window;
99
+ }
100
+
101
+ if (!win || !win.Masonry || !win.imagesLoaded) {
102
+ // ライブラリが読み込まれていない場合は、
103
+ // DOM だけ作って終了(レイアウトはブラウザ任せ)
104
+ return null;
105
+ }
106
+
107
+ const MasonryCtor = win.Masonry;
108
+ const imagesLoadedFn = win.imagesLoaded;
109
+
110
+ const msnry = new MasonryCtor(gridEl, {
111
+ itemSelector: ".itmar-masonry-item",
112
+ columnWidth: ".itmar-masonry-sizer",
113
+ percentPosition: true,
114
+ });
115
+
116
+ const imgLoad = imagesLoadedFn(gridEl);
117
+ imgLoad.on("progress", () => {
118
+ msnry.layout();
119
+ });
120
+
121
+ // 後から破棄できるように要素に紐付けておく
122
+ gridEl.__masonryInstance = msnry;
123
+
124
+ return msnry;
125
+ }
@@ -0,0 +1,265 @@
1
+ //Swiper初期化関数
2
+ // jQueryの $.data() 相当をざっくり再現(文字列→boolean/number/JSON を変換)
3
+ function coerceDataValue(val) {
4
+ if (val == null) return null;
5
+ if (typeof val !== "string") return val;
6
+
7
+ const t = val.trim();
8
+ if (t === "") return "";
9
+
10
+ if (t === "true") return true;
11
+ if (t === "false") return false;
12
+ if (t === "null") return null;
13
+
14
+ // JSONっぽければJSONとして読む(swiper-info など)
15
+ const looksJson =
16
+ (t.startsWith("{") && t.endsWith("}")) ||
17
+ (t.startsWith("[") && t.endsWith("]"));
18
+ if (looksJson) {
19
+ try {
20
+ return JSON.parse(t);
21
+ } catch {
22
+ // JSONとして壊れてたら文字列のまま
23
+ return val;
24
+ }
25
+ }
26
+
27
+ // 数値
28
+ const n = Number(t);
29
+ if (!Number.isNaN(n) && t !== "") return n;
30
+
31
+ return val;
32
+ }
33
+
34
+ function toDatasetKey(key) {
35
+ // "swiper-id" -> "swiperId" のように変換
36
+ return key.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
37
+ }
38
+
39
+ function getData(el, key) {
40
+ const dsKey = toDatasetKey(key);
41
+
42
+ // dataset優先
43
+ if (el?.dataset && Object.prototype.hasOwnProperty.call(el.dataset, dsKey)) {
44
+ return coerceDataValue(el.dataset[dsKey]);
45
+ }
46
+
47
+ // 念のため attribute も見ておく
48
+ const attr = el.getAttribute?.(`data-${key}`);
49
+ if (attr != null) return coerceDataValue(attr);
50
+
51
+ return null;
52
+ }
53
+
54
+ // (任意)複数回呼ばれても関連付けできるように、モジュール内で保持
55
+ const swiperRegistry = new Map();
56
+ // 二重にイベントを張らないための印
57
+ const linkedPairs = new Set();
58
+
59
+ function linkSwipers(a, b) {
60
+ if (!a || !b) return;
61
+
62
+ const pairKey = `${a.swiper_id}__${b.swiper_id}`;
63
+ if (linkedPairs.has(pairKey)) return;
64
+ linkedPairs.add(pairKey);
65
+
66
+ // bがサムネならthumbs連携
67
+ if (b.is_thumbnail) {
68
+ a.instance.thumbs.swiper = b.instance;
69
+ a.instance.thumbs.init();
70
+ a.instance.thumbs.update(true);
71
+ return;
72
+ }
73
+
74
+ // どちらもサムネじゃなければ相互同期
75
+ if (!a.is_thumbnail) {
76
+ a.instance.on("slideChangeTransitionStart", (slider) => {
77
+ b.instance.slideToLoop(slider.realIndex, undefined, false);
78
+ });
79
+ b.instance.on("slideChangeTransitionStart", (slider) => {
80
+ a.instance.slideToLoop(slider.realIndex, undefined, false);
81
+ });
82
+ }
83
+ }
84
+
85
+ function tryLink(swiperObj) {
86
+ // 自分が relate_id を持っていて、相手が既にいればリンク
87
+ if (swiperObj.relate_id && swiperRegistry.has(swiperObj.relate_id)) {
88
+ linkSwipers(swiperObj, swiperRegistry.get(swiperObj.relate_id));
89
+ }
90
+
91
+ // 逆に「相手が自分を relate_id に指定していた」ケースも拾う
92
+ for (const other of swiperRegistry.values()) {
93
+ if (other.relate_id === swiperObj.swiper_id) {
94
+ linkSwipers(other, swiperObj);
95
+ }
96
+ }
97
+ }
98
+
99
+ export function slideBlockSwiperInit(swiperElement) {
100
+ // 文字列セレクタでも渡せるようにしておく(好みで削除OK)
101
+ const el =
102
+ typeof swiperElement === "string"
103
+ ? document.querySelector(swiperElement)
104
+ : swiperElement;
105
+
106
+ if (!el) return null;
107
+
108
+ const swiper_id = getData(el, "swiper-id");
109
+ const relate_id = getData(el, "relate-id");
110
+ const is_thumbnail = !!getData(el, "thumb-flg");
111
+ const swiper_info = getData(el, "swiper-info");
112
+ const parallax_obj = getData(el, "parallax-option");
113
+
114
+ if (!swiper_info || typeof swiper_info !== "object") {
115
+ throw new Error(
116
+ "data-swiper-info が見つからないか、JSONとして解釈できません。"
117
+ );
118
+ }
119
+
120
+ const parallax_option = parallax_obj != null ? { parallax: true } : {};
121
+
122
+ const autoplayOption = swiper_info.is_autoplay
123
+ ? {
124
+ freeMode: { enabled: true, momentum: false },
125
+ autoplay: {
126
+ delay: swiper_info.autoplay,
127
+ stopOnLastSlide: false,
128
+ disableOnInteraction: false,
129
+ },
130
+ }
131
+ : {};
132
+
133
+ const effectOption = {
134
+ none: {
135
+ centeredSlides: swiper_info.isActiveCenter,
136
+ direction: swiper_info.singleDirection,
137
+ speed: swiper_info.slideSpeed,
138
+ slidesPerView: swiper_info.mobilePerView,
139
+ spaceBetween: swiper_info.mobileBetween,
140
+ breakpoints: {
141
+ 768: {
142
+ slidesPerView: swiper_info.defaultPerView,
143
+ spaceBetween: swiper_info.defaultBetween,
144
+ },
145
+ },
146
+ },
147
+ slide_single_view: {
148
+ direction: swiper_info.singleDirection,
149
+ loopAdditionalSlides: 1,
150
+ speed: swiper_info.slideSpeed,
151
+ allowTouchMove: false,
152
+ ...parallax_option,
153
+ },
154
+ fade_single_view: {
155
+ speed: swiper_info.slideSpeed,
156
+ effect: "fade",
157
+ fadeEffect: { crossFade: true },
158
+ ...parallax_option,
159
+ },
160
+ coverflow: {
161
+ centeredSlides: true,
162
+ slidesPerView: 3,
163
+ spaceBetween: swiper_info.mobileBetween,
164
+ effect: "coverflow",
165
+ coverflowEffect: {
166
+ rotate: 50,
167
+ depth: 100,
168
+ stretch: 0,
169
+ modifier: 1,
170
+ scale: 0.9,
171
+ slideShadows: true,
172
+ },
173
+ breakpoints: {
174
+ 768: {
175
+ spaceBetween: swiper_info.defaultBetween,
176
+ coverflowEffect: { stretch: 0 },
177
+ },
178
+ },
179
+ },
180
+ coverflow_2: {
181
+ centeredSlides: true,
182
+ slidesPerView: "auto",
183
+ effect: "coverflow",
184
+ coverflowEffect: { rotate: 0, slideShadows: false, stretch: 100 },
185
+ breakpoints: { 768: { coverflowEffect: { stretch: 100 } } },
186
+ },
187
+ cube: {
188
+ speed: 800,
189
+ effect: "cube",
190
+ cubeEffect: {
191
+ slideShadows: true,
192
+ shadow: true,
193
+ shadowOffset: 40,
194
+ shadowScale: 0.94,
195
+ },
196
+ on: {
197
+ slideChangeTransitionStart: function () {
198
+ this.el.classList.remove("scale-in");
199
+ this.el.classList.add("scale-out");
200
+ },
201
+ slideChangeTransitionEnd: function () {
202
+ this.el.classList.remove("scale-out");
203
+ this.el.classList.add("scale-in");
204
+ },
205
+ },
206
+ },
207
+ flip: {
208
+ effect: "flip",
209
+ flipEffect: { limitRotation: true, slideShadows: true },
210
+ },
211
+ cards: {
212
+ effect: "cards",
213
+ cardsEffect: {
214
+ perSlideOffset: 8,
215
+ perSlideRotate: 2,
216
+ rotate: true,
217
+ slideShadows: true,
218
+ },
219
+ },
220
+ };
221
+
222
+ let swiperOptions = {
223
+ loop: swiper_info.loop,
224
+ ...autoplayOption,
225
+ };
226
+
227
+ if (is_thumbnail) {
228
+ swiperOptions = {
229
+ ...swiperOptions,
230
+ watchSlidesProgress: true,
231
+ watchSlidesVisibility: true,
232
+ freeMode: true,
233
+ slideToClickedSlide: true,
234
+ };
235
+ }
236
+
237
+ if (swiper_info.navigation?.disp) {
238
+ swiperOptions.navigation = {
239
+ nextEl: `.${swiper_id}-next`,
240
+ prevEl: `.${swiper_id}-prev`,
241
+ };
242
+ }
243
+
244
+ if (swiper_info.pagination?.disp) {
245
+ swiperOptions.pagination = { el: `.${swiper_id}-pagination` };
246
+ }
247
+
248
+ if (swiper_info.scrollbar?.disp) {
249
+ swiperOptions.scrollbar = { el: `.${swiper_id}-scrollbar` };
250
+ }
251
+
252
+ if (swiper_info.effect && effectOption[swiper_info.effect]) {
253
+ swiperOptions = { ...swiperOptions, ...effectOption[swiper_info.effect] };
254
+ }
255
+
256
+ // ここが $swiperElement[0] -> el に変わる
257
+ const instance = new Swiper(el, swiperOptions);
258
+
259
+ const swiperObj = { instance, swiper_id, relate_id, is_thumbnail };
260
+ if (swiper_id) swiperRegistry.set(swiper_id, swiperObj);
261
+
262
+ tryLink(swiperObj);
263
+
264
+ return swiperObj;
265
+ }
@@ -249,6 +249,7 @@ export function useBlockAttributeChanges(
249
249
  // setIdleFlg(false);
250
250
  // }
251
251
  //呼び出し元に返すための更新後の属性オブジェクトを格納
252
+
252
253
  setLatestAttributes(JSON.stringify(filteredCurrentAttributes));
253
254
  }
254
255
  }
package/src/index.js CHANGED
@@ -120,3 +120,12 @@ export {
120
120
  redirectCustomerAuthorize,
121
121
  sendRegistrationRequest,
122
122
  } from "./shopfiApi";
123
+
124
+ //インナーブロック挿入のカスタムフック
125
+ export { useRebuildChangeField } from "./BrockInserter";
126
+
127
+ //Masonry グリッドを初期化する共通関数
128
+ export { default as MasonryControl } from "./MasonryControl";
129
+
130
+ //インナーブロック挿入のカスタムフック
131
+ export { slideBlockSwiperInit } from "./SwiperControl";