@burger-editor/client 4.0.0-alpha.52 → 4.0.0-alpha.53

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/README.md CHANGED
@@ -219,6 +219,52 @@ await createBurgerEditorClient({
219
219
  });
220
220
  ```
221
221
 
222
+ ## ブロックのコピー&ペースト
223
+
224
+ BurgerEditorは、ブロック単位でのコピー&ペースト機能を提供します。
225
+
226
+ ### 使用方法
227
+
228
+ 1. **ブロックのコピー**
229
+ - コピーしたいブロックを選択
230
+ - ブロックメニューから「ブロックをコピー」をクリック
231
+ - ブロックのデータがクリップボード(sessionStorage)に保存されます
232
+
233
+ 2. **ブロックのペースト**
234
+ - ブロック追加ダイアログを開く
235
+ - クリップボードにデータがある場合、「クリップボードから貼り付け」ボタンが表示されます
236
+ - ボタンをクリックすると、コピーしたブロックが挿入されます
237
+
238
+ ### 仕様
239
+
240
+ - **保存形式**: JSON形式(BlockData)
241
+ - **保存先**: sessionStorage
242
+ - **有効期限**: ブラウザセッション内のみ(タブを閉じると消去)
243
+ - **保存キー**: `engine.storageKey.blockClipboard`(デフォルト: `'bge-copied-block'`)
244
+ - **動作**: ペースト後、クリップボードは自動的にクリアされます
245
+
246
+ ### ストレージキーのカスタマイズ
247
+
248
+ ```typescript
249
+ await createBurgerEditorClient({
250
+ root: '.editor',
251
+ config: {
252
+ classList: [],
253
+ stylesheets: [],
254
+ sampleImagePath: '/images/sample.jpg',
255
+ sampleFilePath: '/files/sample.pdf',
256
+ googleMapsApiKey: null,
257
+ },
258
+ items,
259
+ catalog: defaultCatalog,
260
+ generalCSS,
261
+ initialContents: '<div></div>',
262
+ storageKey: {
263
+ blockClipboard: 'my-custom-clipboard-key', // カスタムキー
264
+ },
265
+ });
266
+ ```
267
+
222
268
  ## 詳細なAPI仕様
223
269
 
224
270
  ブロックの構造やアイテムの作成方法など、より詳細な技術仕様については [@burger-editor/core のREADME](../core/README.md) を参照してください。
package/dist/client.css CHANGED
@@ -55,6 +55,47 @@
55
55
  text-align: center;
56
56
  }
57
57
 
58
+ /* ペーストセクション */
59
+ .paste-section.svelte-1hna6ki {
60
+ padding-block-end: 1em;
61
+ margin-block-end: 1em;
62
+ border-block-end: 2px solid var(--bge-ui-primary-color, #4a90e2);
63
+ }
64
+
65
+ .paste-button.svelte-1hna6ki {
66
+ display: flex;
67
+ gap: 0.5em;
68
+ align-items: center;
69
+ justify-content: center;
70
+ inline-size: 100%;
71
+ padding-block: 0.8em;
72
+ padding-inline: 1em;
73
+ font-size: 1em;
74
+ font-weight: bold;
75
+ color: var(--bge-lightest-color, #fff);
76
+ cursor: pointer;
77
+ background-color: var(--bge-ui-primary-color, #4a90e2);
78
+ border: none;
79
+ border-radius: 4px;
80
+ transition: background-color 0.2s ease;
81
+ }
82
+
83
+ .paste-button.svelte-1hna6ki:hover {
84
+ background-color: color-mix(
85
+ in srgb,
86
+ var(--bge-ui-primary-color, #4a90e2) 80%,
87
+ var(--bge-darkest-color, #000) 20%
88
+ );
89
+ }
90
+
91
+ .paste-button.svelte-1hna6ki:active {
92
+ translate: 0 1px;
93
+ }
94
+
95
+ .paste-button.svelte-1hna6ki span:where(.svelte-1hna6ki) {
96
+ font-size: 0.95em;
97
+ }
98
+
58
99
  button.svelte-4wfsd1 {
59
100
  anchor-name: var(--name);
60
101
  display: block;
package/dist/client.js CHANGED
@@ -41403,16 +41403,140 @@ function prop(props, key, flags, fallback) {
41403
41403
  );
41404
41404
  }
41405
41405
 
41406
- var root_4$3 = from_html(`<img alt="" loading="lazy" class="svelte-1hna6ki"/>`);
41407
- var root_3$5 = from_html(`<figure class="svelte-1hna6ki"><div class="img svelte-1hna6ki"><!></div> <figcaption class="svelte-1hna6ki"> </figcaption></figure>`);
41408
- var root_2$3 = from_html(`<dd class="svelte-1hna6ki"><button type="button" class="svelte-1hna6ki"><!></button></dd>`);
41409
- var root_1$6 = from_html(`<dt class="svelte-1hna6ki"> </dt> <div class="svelte-1hna6ki"></div>`, 1);
41410
- var root$b = from_html(`<div class="block-catalog"><dl class="svelte-1hna6ki"></dl></div>`);
41406
+ const defaultAttributes = {
41407
+ outline: {
41408
+ xmlns: 'http://www.w3.org/2000/svg',
41409
+ width: 24,
41410
+ height: 24,
41411
+ viewBox: '0 0 24 24',
41412
+ fill: 'none',
41413
+ stroke: 'currentColor',
41414
+ 'stroke-width': 2,
41415
+ 'stroke-linecap': 'round',
41416
+ 'stroke-linejoin': 'round',
41417
+ },
41418
+ filled: {
41419
+ xmlns: 'http://www.w3.org/2000/svg',
41420
+ width: 24,
41421
+ height: 24,
41422
+ viewBox: '0 0 24 24',
41423
+ fill: 'currentColor',
41424
+ stroke: 'none'
41425
+ },
41426
+ };
41427
+
41428
+ var root$b = from_svg(`<svg><!><!></svg>`);
41429
+
41430
+ function Icon($$anchor, $$props) {
41431
+ const $$sanitized_props = legacy_rest_props($$props, ['children', '$$slots', '$$events', '$$legacy']);
41432
+ const $$restProps = legacy_rest_props($$sanitized_props, ['type', 'name', 'color', 'size', 'stroke', 'iconNode']);
41433
+
41434
+ push($$props, false);
41435
+
41436
+ let type = prop($$props, 'type', 8);
41437
+ let name = prop($$props, 'name', 8);
41438
+ let color = prop($$props, 'color', 8, 'currentColor');
41439
+ let size = prop($$props, 'size', 8, 24);
41440
+ let stroke = prop($$props, 'stroke', 8, 2);
41441
+ let iconNode = prop($$props, 'iconNode', 8);
41442
+
41443
+ init();
41444
+
41445
+ var svg = root$b();
41446
+
41447
+ attribute_effect(svg, () => ({
41448
+ ...defaultAttributes[type()],
41449
+ ...$$restProps,
41450
+ width: size(),
41451
+ height: size(),
41452
+
41453
+ class: (
41454
+ deep_read_state(name()),
41455
+ deep_read_state($$sanitized_props),
41456
+ untrack(() => `tabler-icon tabler-icon-${name()} ${$$sanitized_props.class ?? ''}`)
41457
+ ),
41458
+
41459
+ ...type() === 'filled'
41460
+ ? { fill: color() }
41461
+ : { 'stroke-width': stroke(), stroke: color() }
41462
+ }));
41463
+
41464
+ var node = child(svg);
41465
+
41466
+ each(node, 1, iconNode, index, ($$anchor, $$item) => {
41467
+ var $$array = user_derived(() => to_array(get($$item), 2));
41468
+ let tag = () => get($$array)[0];
41469
+ let attrs = () => get($$array)[1];
41470
+ var fragment = comment();
41471
+ var node_1 = first_child(fragment);
41472
+
41473
+ element(node_1, tag, true, ($$element, $$anchor) => {
41474
+ attribute_effect($$element, () => ({ ...attrs() }));
41475
+ });
41476
+
41477
+ append($$anchor, fragment);
41478
+ });
41479
+
41480
+ var node_2 = sibling(node);
41481
+
41482
+ slot(node_2, $$props, 'default', {});
41483
+ append($$anchor, svg);
41484
+ pop();
41485
+ }
41486
+
41487
+ function Clipboard($$anchor, $$props) {
41488
+ const $$sanitized_props = legacy_rest_props($$props, ['children', '$$slots', '$$events', '$$legacy']);
41489
+
41490
+ const iconNode = [
41491
+ [
41492
+ "path",
41493
+
41494
+ {
41495
+ "d": "M9 5h-2a2 2 0 0 0 -2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-12a2 2 0 0 0 -2 -2h-2"
41496
+ }
41497
+ ],
41498
+
41499
+ [
41500
+ "path",
41501
+
41502
+ {
41503
+ "d": "M9 5a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2a2 2 0 0 1 -2 2h-2a2 2 0 0 1 -2 -2"
41504
+ }
41505
+ ]
41506
+ ];
41507
+
41508
+ Icon($$anchor, spread_props({ type: 'outline', name: 'clipboard' }, () => $$sanitized_props, {
41509
+ get iconNode() {
41510
+ return iconNode;
41511
+ },
41512
+
41513
+ children: ($$anchor, $$slotProps) => {
41514
+ var fragment_1 = comment();
41515
+ var node = first_child(fragment_1);
41516
+
41517
+ slot(node, $$props, 'default', {});
41518
+ append($$anchor, fragment_1);
41519
+ },
41520
+
41521
+ $$slots: { default: true }
41522
+ }));
41523
+ }
41524
+
41525
+ var root_1$6 = from_html(`<div class="paste-section svelte-1hna6ki"><button type="button" class="paste-button svelte-1hna6ki"><!> <span class="svelte-1hna6ki">クリップボードから貼り付け</span></button></div>`);
41526
+ var root_5$4 = from_html(`<img alt="" loading="lazy" class="svelte-1hna6ki"/>`);
41527
+ var root_4$3 = from_html(`<figure class="svelte-1hna6ki"><div class="img svelte-1hna6ki"><!></div> <figcaption class="svelte-1hna6ki"> </figcaption></figure>`);
41528
+ var root_3$5 = from_html(`<dd class="svelte-1hna6ki"><button type="button" class="svelte-1hna6ki"><!></button></dd>`);
41529
+ var root_2$3 = from_html(`<dt class="svelte-1hna6ki"> </dt> <div class="svelte-1hna6ki"></div>`, 1);
41530
+ var root$a = from_html(`<div class="block-catalog"><!> <dl class="svelte-1hna6ki"></dl></div>`);
41411
41531
 
41412
41532
  function Block_catalog($$anchor, $$props) {
41413
41533
  push($$props, false);
41414
41534
 
41415
41535
  let engine = prop($$props, 'engine', 8);
41536
+ let hasCopiedBlock = mutable_source(false);
41537
+
41538
+ // コンポーネント初期化時にsessionStorageをチェック
41539
+ set(hasCopiedBlock, !!sessionStorage.getItem(engine().storageKey.blockClipboard));
41416
41540
 
41417
41541
  /**
41418
41542
  *
@@ -41423,10 +41547,65 @@ function Block_catalog($$anchor, $$props) {
41423
41547
  engine().addBlock(blockData);
41424
41548
  }
41425
41549
 
41550
+ /**
41551
+ * クリップボードからブロックをペースト
41552
+ */
41553
+ async function pasteBlock() {
41554
+ // 1. sessionStorageから取得
41555
+ const jsonString = sessionStorage.getItem(engine().storageKey.blockClipboard);
41556
+
41557
+ if (!jsonString) {
41558
+ alert('クリップボードにブロックデータがありません。');
41559
+
41560
+ return;
41561
+ }
41562
+
41563
+ // 2. JSONをBlockDataにパース
41564
+ let blockData;
41565
+
41566
+ try {
41567
+ blockData = JSON.parse(jsonString);
41568
+ } catch(error) {
41569
+ // eslint-disable-next-line no-console
41570
+ console.error('Invalid JSON in clipboard:', error);
41571
+
41572
+ alert('ブロックの貼り付けに失敗しました。\n' + 'クリップボードのデータが破損している可能性があります。\n' + 'もう一度ブロックをコピーしてください。');
41573
+
41574
+ return;
41575
+ }
41576
+
41577
+ // 3. ダイアログを閉じる
41578
+ engine().blockCatalogDialog.close();
41579
+
41580
+ // 4. ブロックを追加(既存のaddBlock関数と同じ)
41581
+ await engine().addBlock(blockData);
41582
+
41583
+ // 5. sessionStorageをクリア
41584
+ sessionStorage.removeItem(engine().storageKey.blockClipboard);
41585
+ }
41586
+
41426
41587
  init();
41427
41588
 
41428
- var div = root$b();
41429
- var dl = child(div);
41589
+ var div = root$a();
41590
+ var node = child(div);
41591
+
41592
+ {
41593
+ var consequent = ($$anchor) => {
41594
+ var div_1 = root_1$6();
41595
+ var button = child(div_1);
41596
+ var node_1 = child(button);
41597
+
41598
+ Clipboard(node_1, {});
41599
+ event('click', button, pasteBlock);
41600
+ append($$anchor, div_1);
41601
+ };
41602
+
41603
+ if_block(node, ($$render) => {
41604
+ if (get(hasCopiedBlock)) $$render(consequent);
41605
+ });
41606
+ }
41607
+
41608
+ var dl = sibling(node, 2);
41430
41609
 
41431
41610
  each(
41432
41611
  dl,
@@ -41440,26 +41619,26 @@ function Block_catalog($$anchor, $$props) {
41440
41619
  var $$array = user_derived(() => to_array(get($$item), 2));
41441
41620
  let category = () => get($$array)[0];
41442
41621
  let blocks = () => get($$array)[1];
41443
- var fragment = root_1$6();
41622
+ var fragment = root_2$3();
41444
41623
  var dt = first_child(fragment);
41445
41624
  var text$1 = child(dt);
41446
41625
 
41447
- var div_1 = sibling(dt, 2);
41626
+ var div_2 = sibling(dt, 2);
41448
41627
 
41449
- each(div_1, 5, blocks, (blockInfo) => category() + blockInfo.label + blockInfo.definition.name, ($$anchor, blockInfo) => {
41450
- var dd = root_2$3();
41451
- var button = child(dd);
41452
- var node = child(button);
41628
+ each(div_2, 5, blocks, (blockInfo) => category() + blockInfo.label + blockInfo.definition.name, ($$anchor, blockInfo) => {
41629
+ var dd = root_3$5();
41630
+ var button_1 = child(dd);
41631
+ var node_2 = child(button_1);
41453
41632
 
41454
41633
  {
41455
- var consequent_2 = ($$anchor) => {
41456
- var figure = root_3$5();
41457
- var div_2 = child(figure);
41458
- var node_1 = child(div_2);
41634
+ var consequent_3 = ($$anchor) => {
41635
+ var figure = root_4$3();
41636
+ var div_3 = child(figure);
41637
+ var node_3 = child(div_3);
41459
41638
 
41460
41639
  {
41461
- var consequent = ($$anchor) => {
41462
- var img = root_4$3();
41640
+ var consequent_1 = ($$anchor) => {
41641
+ var img = root_5$4();
41463
41642
 
41464
41643
  template_effect(() => set_attribute(img, 'src', (
41465
41644
  get(blockInfo),
@@ -41471,14 +41650,14 @@ function Block_catalog($$anchor, $$props) {
41471
41650
 
41472
41651
  var alternate = ($$anchor) => {
41473
41652
  var fragment_1 = comment();
41474
- var node_2 = first_child(fragment_1);
41653
+ var node_4 = first_child(fragment_1);
41475
41654
 
41476
41655
  {
41477
- var consequent_1 = ($$anchor) => {
41656
+ var consequent_2 = ($$anchor) => {
41478
41657
  var fragment_2 = comment();
41479
- var node_3 = first_child(fragment_2);
41658
+ var node_5 = first_child(fragment_2);
41480
41659
 
41481
- html(node_3, () => (
41660
+ html(node_5, () => (
41482
41661
  get(blockInfo),
41483
41662
  untrack(() => get(blockInfo).definition.svg)
41484
41663
  ));
@@ -41487,12 +41666,12 @@ function Block_catalog($$anchor, $$props) {
41487
41666
  };
41488
41667
 
41489
41668
  if_block(
41490
- node_2,
41669
+ node_4,
41491
41670
  ($$render) => {
41492
41671
  if ((
41493
41672
  get(blockInfo),
41494
41673
  untrack(() => get(blockInfo).definition.svg)
41495
- )) $$render(consequent_1);
41674
+ )) $$render(consequent_2);
41496
41675
  },
41497
41676
  true
41498
41677
  );
@@ -41501,15 +41680,15 @@ function Block_catalog($$anchor, $$props) {
41501
41680
  append($$anchor, fragment_1);
41502
41681
  };
41503
41682
 
41504
- if_block(node_1, ($$render) => {
41683
+ if_block(node_3, ($$render) => {
41505
41684
  if ((
41506
41685
  get(blockInfo),
41507
41686
  untrack(() => get(blockInfo).definition.img)
41508
- )) $$render(consequent); else $$render(alternate, false);
41687
+ )) $$render(consequent_1); else $$render(alternate, false);
41509
41688
  });
41510
41689
  }
41511
41690
 
41512
- var figcaption = sibling(div_2, 2);
41691
+ var figcaption = sibling(div_3, 2);
41513
41692
  var text_1 = child(figcaption);
41514
41693
  template_effect(() => set_text(text_1, (get(blockInfo), untrack(() => get(blockInfo).label))));
41515
41694
  append($$anchor, figure);
@@ -41522,14 +41701,14 @@ function Block_catalog($$anchor, $$props) {
41522
41701
  append($$anchor, text_2);
41523
41702
  };
41524
41703
 
41525
- if_block(node, ($$render) => {
41704
+ if_block(node_2, ($$render) => {
41526
41705
  if ((
41527
41706
  get(blockInfo),
41528
41707
  untrack(() => get(blockInfo).definition.img || get(blockInfo).definition.svg)
41529
- )) $$render(consequent_2); else $$render(alternate_1, false);
41708
+ )) $$render(consequent_3); else $$render(alternate_1, false);
41530
41709
  });
41531
41710
  }
41532
- event('click', button, () => addBlock(get(blockInfo).definition));
41711
+ event('click', button_1, () => addBlock(get(blockInfo).definition));
41533
41712
  append($$anchor, dd);
41534
41713
  });
41535
41714
  template_effect(() => set_text(text$1, category()));
@@ -41540,87 +41719,6 @@ function Block_catalog($$anchor, $$props) {
41540
41719
  pop();
41541
41720
  }
41542
41721
 
41543
- const defaultAttributes = {
41544
- outline: {
41545
- xmlns: 'http://www.w3.org/2000/svg',
41546
- width: 24,
41547
- height: 24,
41548
- viewBox: '0 0 24 24',
41549
- fill: 'none',
41550
- stroke: 'currentColor',
41551
- 'stroke-width': 2,
41552
- 'stroke-linecap': 'round',
41553
- 'stroke-linejoin': 'round',
41554
- },
41555
- filled: {
41556
- xmlns: 'http://www.w3.org/2000/svg',
41557
- width: 24,
41558
- height: 24,
41559
- viewBox: '0 0 24 24',
41560
- fill: 'currentColor',
41561
- stroke: 'none'
41562
- },
41563
- };
41564
-
41565
- var root$a = from_svg(`<svg><!><!></svg>`);
41566
-
41567
- function Icon($$anchor, $$props) {
41568
- const $$sanitized_props = legacy_rest_props($$props, ['children', '$$slots', '$$events', '$$legacy']);
41569
- const $$restProps = legacy_rest_props($$sanitized_props, ['type', 'name', 'color', 'size', 'stroke', 'iconNode']);
41570
-
41571
- push($$props, false);
41572
-
41573
- let type = prop($$props, 'type', 8);
41574
- let name = prop($$props, 'name', 8);
41575
- let color = prop($$props, 'color', 8, 'currentColor');
41576
- let size = prop($$props, 'size', 8, 24);
41577
- let stroke = prop($$props, 'stroke', 8, 2);
41578
- let iconNode = prop($$props, 'iconNode', 8);
41579
-
41580
- init();
41581
-
41582
- var svg = root$a();
41583
-
41584
- attribute_effect(svg, () => ({
41585
- ...defaultAttributes[type()],
41586
- ...$$restProps,
41587
- width: size(),
41588
- height: size(),
41589
-
41590
- class: (
41591
- deep_read_state(name()),
41592
- deep_read_state($$sanitized_props),
41593
- untrack(() => `tabler-icon tabler-icon-${name()} ${$$sanitized_props.class ?? ''}`)
41594
- ),
41595
-
41596
- ...type() === 'filled'
41597
- ? { fill: color() }
41598
- : { 'stroke-width': stroke(), stroke: color() }
41599
- }));
41600
-
41601
- var node = child(svg);
41602
-
41603
- each(node, 1, iconNode, index, ($$anchor, $$item) => {
41604
- var $$array = user_derived(() => to_array(get($$item), 2));
41605
- let tag = () => get($$array)[0];
41606
- let attrs = () => get($$array)[1];
41607
- var fragment = comment();
41608
- var node_1 = first_child(fragment);
41609
-
41610
- element(node_1, tag, true, ($$element, $$anchor) => {
41611
- attribute_effect($$element, () => ({ ...attrs() }));
41612
- });
41613
-
41614
- append($$anchor, fragment);
41615
- });
41616
-
41617
- var node_2 = sibling(node);
41618
-
41619
- slot(node_2, $$props, 'default', {});
41620
- append($$anchor, svg);
41621
- pop();
41622
- }
41623
-
41624
41722
  function Arrow_big_down_line($$anchor, $$props) {
41625
41723
  const $$sanitized_props = legacy_rest_props($$props, ['children', '$$slots', '$$events', '$$legacy']);
41626
41724
 
@@ -42184,9 +42282,9 @@ function Block_menu($$anchor, $$props) {
42184
42282
  // );
42185
42283
  // return;
42186
42284
  // }
42187
- const html = get(currentBlock).getHTMLStringify();
42285
+ const json = get(currentBlock).toJSONStringify();
42188
42286
 
42189
- sessionStorage.setItem(engine().storageKey.blockClipboard, html);
42287
+ sessionStorage.setItem(engine().storageKey.blockClipboard, json);
42190
42288
  alert('ブロックをコピーしました。\nブロックの追加ボタンからペースト(貼り付け)することができます。');
42191
42289
  }
42192
42290
 
@@ -44324,7 +44422,7 @@ function parseConfig(config) {
44324
44422
  }
44325
44423
  }
44326
44424
 
44327
- const version = "4.0.0-alpha.51";
44425
+ const version = "4.0.0-alpha.52";
44328
44426
  function attachDraftSwitcher(engine) {
44329
44427
  if (engine.hasDraft()) {
44330
44428
  const container = document.createElement("div");