@juo/blocks 1.7.1 → 1.8.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/dist/{ExtensionRoot-CY2JksJh.js → ExtensionRoot-BmfKKpcU.js} +1 -1
- package/dist/{bridge-DAUIcGuq.js → bridge-BOcO9toS.js} +48 -25
- package/dist/core.js +81 -13
- package/dist/editor/bridge.d.ts.map +1 -1
- package/dist/editor/components.d.ts +21 -5
- package/dist/editor/components.d.ts.map +1 -1
- package/dist/editor/messages.d.ts +35 -3
- package/dist/editor/messages.d.ts.map +1 -1
- package/dist/editor.js +424 -81
- package/dist/{juo-workflow-Dqr1lB1k.js → juo-workflow-B3OHYsp-.js} +1 -1
- package/dist/preact.js +1 -1
- package/dist/react.js +1 -1
- package/dist/services/subscription/adapter.d.ts +21 -3
- package/dist/services/subscription/adapter.d.ts.map +1 -1
- package/dist/services/subscription/discountErrors.d.ts +27 -0
- package/dist/services/subscription/discountErrors.d.ts.map +1 -0
- package/dist/services/subscription/index.d.ts +2 -1
- package/dist/services/subscription/index.d.ts.map +1 -1
- package/dist/services/subscription/subscriptionService.d.ts.map +1 -1
- package/dist/services/subscription/subscriptionService.test.d.ts +2 -0
- package/dist/services/subscription/subscriptionService.test.d.ts.map +1 -0
- package/dist/services/subscription/types.d.ts +11 -3
- package/dist/services/subscription/types.d.ts.map +1 -1
- package/dist/vue.js +1 -1
- package/dist/web-components-editor.js +3 -3
- package/dist/web-components-runtime.js +2 -2
- package/package.json +1 -1
package/dist/editor.js
CHANGED
|
@@ -2,8 +2,8 @@ var __defProp = Object.defineProperty;
|
|
|
2
2
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
4
|
import { onRegisterBlock, getDefinedBlocks } from "@juo/blocks";
|
|
5
|
-
import { a as createEditorBridge, f as
|
|
6
|
-
import {
|
|
5
|
+
import { a as createEditorBridge, f as createOpenAddBlockMenuMessage, g as createRemoveBlockMessage, h as createRegisterBlocksMessage, i as createRegisterRoutesMessage } from "./bridge-BOcO9toS.js";
|
|
6
|
+
import { j, k, b, l, m, n, o, p, c, q, r, s, t, u, e, v, w, x, y, d, z, A, B, C } from "./bridge-BOcO9toS.js";
|
|
7
7
|
import { h as createBlockInstanceFromObject } from "./block-C8lPBCF8.js";
|
|
8
8
|
import { i as indexOverrides } from "./theme-state-LZS5T-Xb.js";
|
|
9
9
|
function createEditorHandler(options) {
|
|
@@ -128,17 +128,17 @@ function createEditorHandler(options) {
|
|
|
128
128
|
if (location.type === "before" || location.type === "after") {
|
|
129
129
|
let findAndInsertBlock = function(blocks, targetId, newBlock2, position) {
|
|
130
130
|
var _a2;
|
|
131
|
-
for (let
|
|
132
|
-
if (blocks[
|
|
131
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
132
|
+
if (blocks[i].id === targetId) {
|
|
133
133
|
if (position === "before") {
|
|
134
|
-
blocks.splice(
|
|
134
|
+
blocks.splice(i, 0, newBlock2);
|
|
135
135
|
} else {
|
|
136
|
-
blocks.splice(
|
|
136
|
+
blocks.splice(i + 1, 0, newBlock2);
|
|
137
137
|
}
|
|
138
138
|
return true;
|
|
139
139
|
}
|
|
140
|
-
for (const slotKey of Object.keys(blocks[
|
|
141
|
-
const slotBlocks = blocks[
|
|
140
|
+
for (const slotKey of Object.keys(blocks[i].slots || {})) {
|
|
141
|
+
const slotBlocks = blocks[i].slots[slotKey];
|
|
142
142
|
const slotArray = Array.isArray(slotBlocks) ? slotBlocks : [slotBlocks];
|
|
143
143
|
for (let j2 = 0; j2 < slotArray.length; j2++) {
|
|
144
144
|
if (typeof slotArray[j2] !== "string" && ((_a2 = slotArray[j2]) == null ? void 0 : _a2.id) === targetId) {
|
|
@@ -147,7 +147,7 @@ function createEditorHandler(options) {
|
|
|
147
147
|
} else {
|
|
148
148
|
slotArray.splice(j2 + 1, 0, newBlock2);
|
|
149
149
|
}
|
|
150
|
-
blocks[
|
|
150
|
+
blocks[i].slots[slotKey] = slotArray;
|
|
151
151
|
return true;
|
|
152
152
|
}
|
|
153
153
|
}
|
|
@@ -201,21 +201,21 @@ function createEditorHandler(options) {
|
|
|
201
201
|
} else if (message.type === "REMOVE_BLOCK") {
|
|
202
202
|
let findAndRemoveBlock = function(blocks, blockId, slot, parentId) {
|
|
203
203
|
var _a2;
|
|
204
|
-
for (let
|
|
205
|
-
if (blocks[
|
|
206
|
-
const slotBlocks = blocks[
|
|
204
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
205
|
+
if (blocks[i].id === parentId && ((_a2 = blocks[i].slots) == null ? void 0 : _a2[slot])) {
|
|
206
|
+
const slotBlocks = blocks[i].slots[slot];
|
|
207
207
|
const slotArray = Array.isArray(slotBlocks) ? slotBlocks : [slotBlocks];
|
|
208
208
|
const index = slotArray.findIndex(
|
|
209
209
|
(b2) => typeof b2 !== "string" && (b2 == null ? void 0 : b2.id) === blockId
|
|
210
210
|
);
|
|
211
211
|
if (index !== -1) {
|
|
212
212
|
slotArray.splice(index, 1);
|
|
213
|
-
blocks[
|
|
213
|
+
blocks[i].slots[slot] = slotArray;
|
|
214
214
|
return true;
|
|
215
215
|
}
|
|
216
216
|
}
|
|
217
|
-
for (const slotKey of Object.keys(blocks[
|
|
218
|
-
const slotBlocks = blocks[
|
|
217
|
+
for (const slotKey of Object.keys(blocks[i].slots || {})) {
|
|
218
|
+
const slotBlocks = blocks[i].slots[slotKey];
|
|
219
219
|
const slotArray = Array.isArray(slotBlocks) ? slotBlocks : [slotBlocks];
|
|
220
220
|
for (const child of slotArray) {
|
|
221
221
|
if (typeof child !== "string" && (child == null ? void 0 : child.id)) {
|
|
@@ -309,14 +309,6 @@ const styles = `
|
|
|
309
309
|
box-sizing: border-box;
|
|
310
310
|
}
|
|
311
311
|
|
|
312
|
-
:host(:hover:not(.active)) .block-wrapper {
|
|
313
|
-
outline: 1px dashed #060606;
|
|
314
|
-
/* 4px gap between the block content and the dashed outline so the
|
|
315
|
-
* outline reads as a hover affordance rather than a touching border.
|
|
316
|
-
* Outline doesn't participate in layout, so this stays layout-neutral. */
|
|
317
|
-
outline-offset: 4px;
|
|
318
|
-
}
|
|
319
|
-
|
|
320
312
|
/*
|
|
321
313
|
* Stacking model for the active state (no negative z-index, no isolation):
|
|
322
314
|
* - .block-wrapper__chrome z-index: 100 → visual frame above neighbours
|
|
@@ -518,6 +510,262 @@ const styles = `
|
|
|
518
510
|
background: #e9e9e9;
|
|
519
511
|
flex-shrink: 0;
|
|
520
512
|
}
|
|
513
|
+
|
|
514
|
+
/*
|
|
515
|
+
* Add-block UI — full-width rail (absolute, inset of .block-wrapper) so
|
|
516
|
+
* spill line widths use 50% of the block without container-type / cqw
|
|
517
|
+
* (which breaks flex layout in workflow overlays). Each chrome edge is an
|
|
518
|
+
* .add-edge row; the button and ::before/::after spills live on that edge.
|
|
519
|
+
*
|
|
520
|
+
* Chrome extends 44px above and 12px below the block content:
|
|
521
|
+
* .add-edge--top → top: -44px
|
|
522
|
+
* .add-edge--bottom → bottom: -12px
|
|
523
|
+
*/
|
|
524
|
+
.block-wrapper__add-rail {
|
|
525
|
+
position: absolute;
|
|
526
|
+
left: 0;
|
|
527
|
+
right: 0;
|
|
528
|
+
top: 0;
|
|
529
|
+
bottom: 0;
|
|
530
|
+
pointer-events: none;
|
|
531
|
+
z-index: 103;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
.block-wrapper__add-edge {
|
|
535
|
+
position: absolute;
|
|
536
|
+
left: 0;
|
|
537
|
+
right: 0;
|
|
538
|
+
height: 0;
|
|
539
|
+
pointer-events: none;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
.block-wrapper__add-edge--top {
|
|
543
|
+
top: -44px;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
.block-wrapper__add-edge--bottom {
|
|
547
|
+
bottom: -12px;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
.block-wrapper__add-btn {
|
|
551
|
+
position: absolute;
|
|
552
|
+
left: 50%;
|
|
553
|
+
display: inline-flex;
|
|
554
|
+
align-items: center;
|
|
555
|
+
justify-content: center;
|
|
556
|
+
/* Above ::before/::after spills on the same .add-edge */
|
|
557
|
+
z-index: 1;
|
|
558
|
+
pointer-events: none;
|
|
559
|
+
appearance: none;
|
|
560
|
+
border: none;
|
|
561
|
+
background: none;
|
|
562
|
+
padding: 0;
|
|
563
|
+
margin: 0;
|
|
564
|
+
cursor: pointer;
|
|
565
|
+
/* Larger hit target than the 14×14 icon (lines are pointer-events: none). */
|
|
566
|
+
min-width: 28px;
|
|
567
|
+
min-height: 28px;
|
|
568
|
+
overflow: visible;
|
|
569
|
+
line-height: 1;
|
|
570
|
+
font-family: inherit;
|
|
571
|
+
opacity: 0;
|
|
572
|
+
transition: opacity 180ms ease;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
.block-wrapper__add-btn--top {
|
|
576
|
+
top: 0;
|
|
577
|
+
transform: translate(-50%, -50%);
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
.block-wrapper__add-btn--bottom {
|
|
581
|
+
bottom: 0;
|
|
582
|
+
top: auto;
|
|
583
|
+
transform: translate(-50%, 50%);
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/* B — active chrome hovered: fade buttons in (opacity only). */
|
|
587
|
+
:host(.active:hover) .block-wrapper__add-btn {
|
|
588
|
+
opacity: 1;
|
|
589
|
+
pointer-events: auto;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
/*
|
|
593
|
+
* Entering the chrome from outside often lands on the button at once — skip
|
|
594
|
+
* the fade so only the + → pill morph runs (avoids end-of-animation snap).
|
|
595
|
+
*/
|
|
596
|
+
:host(.active:hover)
|
|
597
|
+
.block-wrapper__add-edge:has(.block-wrapper__add-btn:hover)
|
|
598
|
+
.block-wrapper__add-btn,
|
|
599
|
+
:host(.active)
|
|
600
|
+
.block-wrapper__add-edge:has(.block-wrapper__add-btn--menu-open)
|
|
601
|
+
.block-wrapper__add-btn {
|
|
602
|
+
transition: opacity 0s;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
.block-wrapper__add-btn-inner {
|
|
606
|
+
position: relative;
|
|
607
|
+
z-index: 1;
|
|
608
|
+
display: inline-flex;
|
|
609
|
+
align-items: center;
|
|
610
|
+
justify-content: center;
|
|
611
|
+
height: 14px;
|
|
612
|
+
overflow: visible;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
/*
|
|
616
|
+
* Single surface morphs 14×14 circle → 60×14 pill (plus scales away, text
|
|
617
|
+
* fades in). No overlapping icon + label layers.
|
|
618
|
+
*/
|
|
619
|
+
.block-wrapper__add-btn-surface {
|
|
620
|
+
position: relative;
|
|
621
|
+
display: inline-flex;
|
|
622
|
+
align-items: center;
|
|
623
|
+
justify-content: center;
|
|
624
|
+
box-sizing: border-box;
|
|
625
|
+
width: 14px;
|
|
626
|
+
height: 14px;
|
|
627
|
+
padding: 0;
|
|
628
|
+
background: #121212;
|
|
629
|
+
border: 0.5px solid #121212;
|
|
630
|
+
border-radius: 50%;
|
|
631
|
+
overflow: visible;
|
|
632
|
+
isolation: isolate;
|
|
633
|
+
transition:
|
|
634
|
+
width 200ms cubic-bezier(0.34, 1.12, 0.64, 1),
|
|
635
|
+
border-radius 200ms cubic-bezier(0.34, 1.12, 0.64, 1),
|
|
636
|
+
padding 200ms cubic-bezier(0.34, 1.12, 0.64, 1);
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
.block-wrapper__add-btn-plus {
|
|
640
|
+
display: inline-flex;
|
|
641
|
+
flex-shrink: 0;
|
|
642
|
+
align-items: center;
|
|
643
|
+
justify-content: center;
|
|
644
|
+
width: 14px;
|
|
645
|
+
height: 14px;
|
|
646
|
+
transition:
|
|
647
|
+
opacity 160ms ease,
|
|
648
|
+
transform 200ms cubic-bezier(0.34, 1.12, 0.64, 1),
|
|
649
|
+
width 200ms cubic-bezier(0.34, 1.12, 0.64, 1);
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
.block-wrapper__add-btn-plus svg {
|
|
653
|
+
display: block;
|
|
654
|
+
filter: drop-shadow(0 0 7px rgba(0, 0, 0, 0.1));
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
.block-wrapper__add-btn-text {
|
|
658
|
+
max-width: 0;
|
|
659
|
+
opacity: 0;
|
|
660
|
+
overflow: hidden;
|
|
661
|
+
color: #ffffff;
|
|
662
|
+
font-size: 9px;
|
|
663
|
+
font-weight: 600;
|
|
664
|
+
letter-spacing: -0.036px;
|
|
665
|
+
line-height: 1;
|
|
666
|
+
white-space: nowrap;
|
|
667
|
+
transition:
|
|
668
|
+
max-width 200ms cubic-bezier(0.34, 1.12, 0.64, 1) 35ms,
|
|
669
|
+
opacity 140ms ease 70ms;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
/*
|
|
673
|
+
* 0.5px spill on the chrome border — ::before/::after meet at 50% (no gap
|
|
674
|
+
* for the pill) so the line stays continuous when the button fades out.
|
|
675
|
+
* The button paints above (z-index). Vertical: fixed translateY (never
|
|
676
|
+
* transitioned). Horizontal: width 0 → full (not scale — Safari thickens /
|
|
677
|
+
* shifts 0.5px lines when scale is composited with translateY on transform).
|
|
678
|
+
*/
|
|
679
|
+
.block-wrapper__add-edge::before,
|
|
680
|
+
.block-wrapper__add-edge::after {
|
|
681
|
+
content: "";
|
|
682
|
+
position: absolute;
|
|
683
|
+
top: 50%;
|
|
684
|
+
width: 0;
|
|
685
|
+
min-width: 0;
|
|
686
|
+
height: 0.5px;
|
|
687
|
+
pointer-events: none;
|
|
688
|
+
z-index: 0;
|
|
689
|
+
overflow: hidden;
|
|
690
|
+
transition-property: width;
|
|
691
|
+
transition-duration: 260ms;
|
|
692
|
+
transition-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
|
|
693
|
+
transition-delay: 50ms;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
.block-wrapper__add-edge::before {
|
|
697
|
+
right: 50%;
|
|
698
|
+
background: linear-gradient(to left, #121212 0%, #b5b5b5 100%);
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
.block-wrapper__add-edge::after {
|
|
702
|
+
left: 50%;
|
|
703
|
+
background: linear-gradient(to right, #121212 0%, #b5b5b5 100%);
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
.block-wrapper__add-edge--top::before,
|
|
707
|
+
.block-wrapper__add-edge--top::after {
|
|
708
|
+
transform: translateY(calc(-50% + 0.25px));
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
.block-wrapper__add-edge--bottom::before,
|
|
712
|
+
.block-wrapper__add-edge--bottom::after {
|
|
713
|
+
transform: translateY(calc(-50% - 0.25px));
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
/* C — hover / menu-open: morph + spill extend */
|
|
717
|
+
:host(.active:hover) .block-wrapper__add-btn:hover .block-wrapper__add-btn-surface,
|
|
718
|
+
:host(.active) .block-wrapper__add-btn--menu-open .block-wrapper__add-btn-surface {
|
|
719
|
+
width: 60px;
|
|
720
|
+
border-radius: 32px;
|
|
721
|
+
padding: 0 6px;
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
:host(.active:hover) .block-wrapper__add-btn:hover .block-wrapper__add-btn-plus,
|
|
725
|
+
:host(.active) .block-wrapper__add-btn--menu-open .block-wrapper__add-btn-plus {
|
|
726
|
+
width: 0;
|
|
727
|
+
opacity: 0;
|
|
728
|
+
transform: scale(0.35);
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
:host(.active:hover) .block-wrapper__add-btn:hover .block-wrapper__add-btn-text,
|
|
732
|
+
:host(.active) .block-wrapper__add-btn--menu-open .block-wrapper__add-btn-text {
|
|
733
|
+
max-width: 52px;
|
|
734
|
+
opacity: 1;
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
:host(.active:hover) .block-wrapper__add-edge:has(.block-wrapper__add-btn:hover)::before,
|
|
738
|
+
:host(.active:hover) .block-wrapper__add-edge:has(.block-wrapper__add-btn:hover)::after,
|
|
739
|
+
:host(.active) .block-wrapper__add-edge:has(.block-wrapper__add-btn--menu-open)::before,
|
|
740
|
+
:host(.active) .block-wrapper__add-edge:has(.block-wrapper__add-btn--menu-open)::after {
|
|
741
|
+
width: calc(50% - 24px);
|
|
742
|
+
min-width: 40px;
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
/*
|
|
746
|
+
* --menu-open keeps the button in pill state while the editor's AddMenu
|
|
747
|
+
* is open against this button — so the user has a visual anchor of
|
|
748
|
+
* where the menu was triggered from. Note: we explicitly do NOT require
|
|
749
|
+
* :host(:hover) here because the user's pointer is over the menu (which
|
|
750
|
+
* lives outside the iframe) once the menu opens, so :host(:hover) has
|
|
751
|
+
* dropped.
|
|
752
|
+
*/
|
|
753
|
+
:host(.active) .block-wrapper__add-btn--menu-open {
|
|
754
|
+
opacity: 1;
|
|
755
|
+
pointer-events: auto;
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
@media (prefers-reduced-motion: reduce) {
|
|
759
|
+
.block-wrapper__add-btn,
|
|
760
|
+
.block-wrapper__add-btn-inner,
|
|
761
|
+
.block-wrapper__add-btn-surface,
|
|
762
|
+
.block-wrapper__add-edge::before,
|
|
763
|
+
.block-wrapper__add-edge::after,
|
|
764
|
+
.block-wrapper__add-btn-plus,
|
|
765
|
+
.block-wrapper__add-btn-text {
|
|
766
|
+
transition: none;
|
|
767
|
+
}
|
|
768
|
+
}
|
|
521
769
|
</style>
|
|
522
770
|
`;
|
|
523
771
|
const blockIconSvg = `
|
|
@@ -531,6 +779,12 @@ const moreIconSvg = `
|
|
|
531
779
|
<path d="M1.5 0C2.32843 2.0934e-07 3 0.671573 3 1.5C3 2.32843 2.32843 3 1.5 3C0.671573 3 3.62117e-08 2.32843 0 1.5C6.04266e-08 0.671573 0.671573 3.62117e-08 1.5 0ZM6.5 0C7.32843 2.0934e-07 8 0.671573 8 1.5C8 2.32843 7.32843 3 6.5 3C5.67157 3 5 2.32843 5 1.5C5 0.671573 5.67157 3.62117e-08 6.5 0ZM11.5 0C12.3284 2.0934e-07 13 0.671573 13 1.5C13 2.32843 12.3284 3 11.5 3C10.6716 3 10 2.32843 10 1.5C10 0.671573 10.6716 3.62117e-08 11.5 0Z" fill="currentColor"/>
|
|
532
780
|
</svg>
|
|
533
781
|
`;
|
|
782
|
+
const addBlockIconSvg = `
|
|
783
|
+
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
784
|
+
<circle cx="7" cy="7" r="7" fill="#121212"/>
|
|
785
|
+
<path d="M7 4.77V9.23M4.77 7H9.23" stroke="white" stroke-width="1.14" stroke-linecap="round"/>
|
|
786
|
+
</svg>
|
|
787
|
+
`;
|
|
534
788
|
const trashIconSvg = `
|
|
535
789
|
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
536
790
|
<path d="M2 4H12" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/>
|
|
@@ -550,7 +804,25 @@ class BlockWrapper extends HTMLElement {
|
|
|
550
804
|
__publicField(this, "menuElement", null);
|
|
551
805
|
__publicField(this, "isMenuOpen", false);
|
|
552
806
|
__publicField(this, "closeMenuOnOutsideClick", null);
|
|
553
|
-
__publicField(this, "
|
|
807
|
+
__publicField(this, "addButtons", []);
|
|
808
|
+
__publicField(this, "addRail", null);
|
|
809
|
+
__publicField(this, "hoverOutlineTarget", null);
|
|
810
|
+
__publicField(this, "handleHoverEnter", () => {
|
|
811
|
+
if (this.classList.contains("active")) return;
|
|
812
|
+
const slotted = this.firstElementChild;
|
|
813
|
+
if (!slotted || slotted.hasAttribute("data-empty")) return;
|
|
814
|
+
const target = BlockWrapper.resolveOutlineTarget(slotted);
|
|
815
|
+
if (!target) return;
|
|
816
|
+
this.hoverOutlineTarget = target;
|
|
817
|
+
target.style.outline = "1px solid #060606";
|
|
818
|
+
target.style.outlineOffset = "0";
|
|
819
|
+
});
|
|
820
|
+
__publicField(this, "handleHoverLeave", () => {
|
|
821
|
+
if (!this.hoverOutlineTarget) return;
|
|
822
|
+
this.hoverOutlineTarget.style.outline = "";
|
|
823
|
+
this.hoverOutlineTarget.style.outlineOffset = "";
|
|
824
|
+
this.hoverOutlineTarget = null;
|
|
825
|
+
});
|
|
554
826
|
this.attachShadow({ mode: "open" });
|
|
555
827
|
this.setupStyles();
|
|
556
828
|
this.setupTemplate();
|
|
@@ -617,16 +889,91 @@ class BlockWrapper extends HTMLElement {
|
|
|
617
889
|
const slot = document.createElement("slot");
|
|
618
890
|
slotHost.appendChild(slot);
|
|
619
891
|
wrapper.appendChild(slotHost);
|
|
892
|
+
const addRail = document.createElement("div");
|
|
893
|
+
addRail.className = "block-wrapper__add-rail";
|
|
894
|
+
this.addRail = addRail;
|
|
895
|
+
const topEdge = document.createElement("div");
|
|
896
|
+
topEdge.className = "block-wrapper__add-edge block-wrapper__add-edge--top";
|
|
897
|
+
const topAddBtn = this.createAddButton("before");
|
|
898
|
+
topAddBtn.classList.add("block-wrapper__add-btn--top");
|
|
899
|
+
topEdge.appendChild(topAddBtn);
|
|
900
|
+
addRail.appendChild(topEdge);
|
|
901
|
+
const bottomEdge = document.createElement("div");
|
|
902
|
+
bottomEdge.className = "block-wrapper__add-edge block-wrapper__add-edge--bottom";
|
|
903
|
+
const bottomAddBtn = this.createAddButton("after");
|
|
904
|
+
bottomAddBtn.classList.add("block-wrapper__add-btn--bottom");
|
|
905
|
+
bottomEdge.appendChild(bottomAddBtn);
|
|
906
|
+
addRail.appendChild(bottomEdge);
|
|
907
|
+
wrapper.appendChild(addRail);
|
|
908
|
+
this.addButtons = [topAddBtn, bottomAddBtn];
|
|
620
909
|
this.shadowRoot.appendChild(wrapper);
|
|
621
910
|
this.nameElement = nameSpan;
|
|
622
911
|
this.menuElement = menuEl;
|
|
623
912
|
this.editorBridge.onMessage((message) => {
|
|
624
|
-
var _a;
|
|
913
|
+
var _a, _b;
|
|
625
914
|
if (message.type === "SELECT_BLOCK") {
|
|
626
915
|
this.updateActiveState(message.payload.blockId === ((_a = this.block) == null ? void 0 : _a.id));
|
|
916
|
+
} else if (message.type === "ADD_BLOCK_MENU_CLOSED" && message.payload.targetBlockId === ((_b = this.block) == null ? void 0 : _b.id)) {
|
|
917
|
+
this.clearAddButtonMenuState(message.payload.position);
|
|
627
918
|
}
|
|
628
919
|
});
|
|
629
920
|
}
|
|
921
|
+
createAddButton(position) {
|
|
922
|
+
const btn = document.createElement("button");
|
|
923
|
+
btn.type = "button";
|
|
924
|
+
btn.className = "block-wrapper__add-btn";
|
|
925
|
+
btn.setAttribute("aria-label", "Add block");
|
|
926
|
+
btn.dataset.position = position;
|
|
927
|
+
const inner = document.createElement("span");
|
|
928
|
+
inner.className = "block-wrapper__add-btn-inner";
|
|
929
|
+
const surface = document.createElement("span");
|
|
930
|
+
surface.className = "block-wrapper__add-btn-surface";
|
|
931
|
+
const plus = document.createElement("span");
|
|
932
|
+
plus.className = "block-wrapper__add-btn-plus";
|
|
933
|
+
plus.setAttribute("aria-hidden", "true");
|
|
934
|
+
plus.innerHTML = addBlockIconSvg;
|
|
935
|
+
const text = document.createElement("span");
|
|
936
|
+
text.className = "block-wrapper__add-btn-text";
|
|
937
|
+
text.textContent = "Add block";
|
|
938
|
+
surface.appendChild(plus);
|
|
939
|
+
surface.appendChild(text);
|
|
940
|
+
inner.appendChild(surface);
|
|
941
|
+
btn.appendChild(inner);
|
|
942
|
+
btn.addEventListener("click", (e2) => {
|
|
943
|
+
e2.stopPropagation();
|
|
944
|
+
e2.preventDefault();
|
|
945
|
+
this.handleAddBlock(position, btn);
|
|
946
|
+
});
|
|
947
|
+
return btn;
|
|
948
|
+
}
|
|
949
|
+
handleAddBlock(position, button) {
|
|
950
|
+
if (!this.block) return;
|
|
951
|
+
const rect = button.getBoundingClientRect();
|
|
952
|
+
const anchor = {
|
|
953
|
+
x: rect.right,
|
|
954
|
+
// Top edge of the button — menu opens to the right with align=start.
|
|
955
|
+
y: rect.top
|
|
956
|
+
};
|
|
957
|
+
for (const btn of this.addButtons) {
|
|
958
|
+
btn.classList.toggle(
|
|
959
|
+
"block-wrapper__add-btn--menu-open",
|
|
960
|
+
btn === button
|
|
961
|
+
);
|
|
962
|
+
}
|
|
963
|
+
this.editorBridge.sendMessage(
|
|
964
|
+
createOpenAddBlockMenuMessage({
|
|
965
|
+
targetBlockId: this.block.id,
|
|
966
|
+
position,
|
|
967
|
+
anchor
|
|
968
|
+
})
|
|
969
|
+
);
|
|
970
|
+
}
|
|
971
|
+
clearAddButtonMenuState(position) {
|
|
972
|
+
for (const btn of this.addButtons) {
|
|
973
|
+
if (position != null && btn.dataset.position !== position) continue;
|
|
974
|
+
btn.classList.remove("block-wrapper__add-btn--menu-open");
|
|
975
|
+
}
|
|
976
|
+
}
|
|
630
977
|
connectedCallback() {
|
|
631
978
|
const isInOverlay = this.closest('juo-extension-root[surface="overlay"]') !== null;
|
|
632
979
|
if (isInOverlay) {
|
|
@@ -638,6 +985,9 @@ class BlockWrapper extends HTMLElement {
|
|
|
638
985
|
".block-wrapper__menu-item--danger"
|
|
639
986
|
);
|
|
640
987
|
if (deleteBtn) deleteBtn.style.display = "none";
|
|
988
|
+
if (this.addRail) {
|
|
989
|
+
this.addRail.style.display = "none";
|
|
990
|
+
}
|
|
641
991
|
}
|
|
642
992
|
const isWorkflowPreview = (() => {
|
|
643
993
|
try {
|
|
@@ -650,50 +1000,40 @@ class BlockWrapper extends HTMLElement {
|
|
|
650
1000
|
if (isWorkflowPreview && !isInOverlay) {
|
|
651
1001
|
this.style.pointerEvents = "none";
|
|
652
1002
|
}
|
|
653
|
-
this.
|
|
1003
|
+
this.addEventListener("mouseenter", this.handleHoverEnter);
|
|
1004
|
+
this.addEventListener("mouseleave", this.handleHoverLeave);
|
|
654
1005
|
}
|
|
655
1006
|
/**
|
|
656
|
-
*
|
|
657
|
-
*
|
|
658
|
-
* blocks
|
|
1007
|
+
* Resolve the slotted block's first painted descendant — the
|
|
1008
|
+
* card-like surface we paint the hover outline on. We can't use
|
|
1009
|
+
* ::slotted() (CE blocks' own :host rules win the cascade) and we
|
|
1010
|
+
* can't put outline on .block-wrapper directly (it has no radius and
|
|
1011
|
+
* adopting one is more code than this), so we apply outline as an
|
|
1012
|
+
* inline style on the visible element. Skips:
|
|
1013
|
+
* - <style> nodes (Vue's defineCustomElement injects styles into
|
|
1014
|
+
* the CE shadow root next to the rendered tree).
|
|
1015
|
+
* - display:contents wrappers (Vue's <ContextProvider> sits between
|
|
1016
|
+
* the slotted div and the actual UiCard for createVueRenderer).
|
|
1017
|
+
* Crosses one shadow-root boundary for createVueCeRenderer blocks
|
|
1018
|
+
* whose slotted element is itself a CE host.
|
|
659
1019
|
*/
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
};
|
|
668
|
-
const bindObservers = () => {
|
|
669
|
-
this.emptyObserver.observe(this, { childList: true });
|
|
670
|
-
const slotted = this.firstElementChild;
|
|
671
|
-
if (slotted) {
|
|
672
|
-
this.emptyObserver.observe(slotted, {
|
|
673
|
-
attributes: true,
|
|
674
|
-
attributeFilter: ["data-empty"]
|
|
675
|
-
});
|
|
1020
|
+
static resolveOutlineTarget(slotted) {
|
|
1021
|
+
const root = slotted.shadowRoot ?? slotted;
|
|
1022
|
+
let el = root.firstElementChild;
|
|
1023
|
+
while (el) {
|
|
1024
|
+
if (el.tagName === "STYLE") {
|
|
1025
|
+
el = el.nextElementSibling;
|
|
1026
|
+
continue;
|
|
676
1027
|
}
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
const slottedChildChanged = records.some(
|
|
681
|
-
(record) => record.type === "childList" && record.target === this
|
|
682
|
-
);
|
|
683
|
-
if (slottedChildChanged) {
|
|
684
|
-
this.emptyObserver.disconnect();
|
|
685
|
-
sync();
|
|
686
|
-
bindObservers();
|
|
687
|
-
return;
|
|
1028
|
+
if (getComputedStyle(el).display === "contents") {
|
|
1029
|
+
el = el.firstElementChild;
|
|
1030
|
+
continue;
|
|
688
1031
|
}
|
|
689
|
-
|
|
690
|
-
}
|
|
691
|
-
|
|
1032
|
+
return el;
|
|
1033
|
+
}
|
|
1034
|
+
return slotted.shadowRoot ? null : slotted;
|
|
692
1035
|
}
|
|
693
1036
|
disconnectedCallback() {
|
|
694
|
-
var _a;
|
|
695
|
-
(_a = this.emptyObserver) == null ? void 0 : _a.disconnect();
|
|
696
|
-
this.emptyObserver = null;
|
|
697
1037
|
this.closeMenu();
|
|
698
1038
|
}
|
|
699
1039
|
toggleMenu() {
|
|
@@ -733,6 +1073,7 @@ class BlockWrapper extends HTMLElement {
|
|
|
733
1073
|
updateActiveState(isActive) {
|
|
734
1074
|
if (isActive) {
|
|
735
1075
|
this.classList.add("active");
|
|
1076
|
+
this.handleHoverLeave();
|
|
736
1077
|
} else {
|
|
737
1078
|
this.classList.remove("active");
|
|
738
1079
|
this.closeMenu();
|
|
@@ -863,33 +1204,35 @@ async function setupEditorMode(deps) {
|
|
|
863
1204
|
}
|
|
864
1205
|
export {
|
|
865
1206
|
BlockWrapper,
|
|
866
|
-
|
|
1207
|
+
j as createAddBlockMenuClosedMessage,
|
|
1208
|
+
k as createAddBlockMessage,
|
|
867
1209
|
createEditorBridge,
|
|
868
1210
|
createEditorHandler,
|
|
869
1211
|
b as createFocusInlineTextMessage,
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
1212
|
+
l as createMoveBlockMessage,
|
|
1213
|
+
createOpenAddBlockMenuMessage,
|
|
1214
|
+
m as createProvideGlobalStylesMessage,
|
|
1215
|
+
n as createProvideInitialGlobalStylesMessage,
|
|
1216
|
+
o as createProvideThemeStateMessage,
|
|
1217
|
+
p as createProvideTranslationOverridesMessage,
|
|
875
1218
|
c as createRegisterBlockTranslationKeysMessage,
|
|
876
1219
|
createRegisterBlocksMessage,
|
|
877
1220
|
createRegisterRoutesMessage,
|
|
878
1221
|
createRemoveBlockMessage,
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
1222
|
+
q as createReportContentHeightMessage,
|
|
1223
|
+
r as createRequestGlobalStylesMessage,
|
|
1224
|
+
s as createRequestThemeStateMessage,
|
|
1225
|
+
t as createRequestTranslationOverridesMessage,
|
|
1226
|
+
u as createScrollSyncMessage,
|
|
884
1227
|
e as createSelectBlockMessage,
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
1228
|
+
v as createSetBlockPresetMessage,
|
|
1229
|
+
w as createSetGlobalStylesMessage,
|
|
1230
|
+
x as createSetLocaleMessage,
|
|
1231
|
+
y as createUpdateBlockPropsMessage,
|
|
889
1232
|
d as createUpdateBlockTranslationMessage,
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
1233
|
+
z as createUpsertThemeStateMessage,
|
|
1234
|
+
A as getEditorBridge,
|
|
1235
|
+
B as isEditorMessage,
|
|
1236
|
+
C as isIframeMessage,
|
|
894
1237
|
setupEditorMode
|
|
895
1238
|
};
|
|
@@ -2,7 +2,7 @@ var __defProp = Object.defineProperty;
|
|
|
2
2
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
4
|
import { c as createContext, d, E, m as getDefinedBlocks, f as createBlockInstance, w, r as registerBlock, k as defineBlock, v as subscribeContext } from "./block-C8lPBCF8.js";
|
|
5
|
-
import { a as createEditorBridge, e as createSelectBlockMessage } from "./bridge-
|
|
5
|
+
import { a as createEditorBridge, e as createSelectBlockMessage } from "./bridge-BOcO9toS.js";
|
|
6
6
|
const TranslationContext = createContext("translation");
|
|
7
7
|
function toStringRecord(input) {
|
|
8
8
|
if (input == null) return {};
|
package/dist/preact.js
CHANGED
|
@@ -6,7 +6,7 @@ import { useState, useRef, useEffect, useContext as useContext$1, useMemo } from
|
|
|
6
6
|
import { g as getSignalValue, s as setSignalValue, w as wrapContext, c as createSlotChildren } from "./block-VhmfGB3N.js";
|
|
7
7
|
import { t } from "./block-VhmfGB3N.js";
|
|
8
8
|
import { createContext, h, render } from "preact";
|
|
9
|
-
import { a as createEditorBridge } from "./bridge-
|
|
9
|
+
import { a as createEditorBridge } from "./bridge-BOcO9toS.js";
|
|
10
10
|
function toState(signal) {
|
|
11
11
|
const [value, setValue] = useState(() => getSignalValue(signal));
|
|
12
12
|
const disposeRef = useRef(null);
|
package/dist/react.js
CHANGED
|
@@ -6,7 +6,7 @@ import React, { useSyncExternalStore, createContext, useState, useContext as use
|
|
|
6
6
|
import { g as getSignalValue, s as setSignalValue, w as wrapContext, c as createSlotChildren } from "./block-VhmfGB3N.js";
|
|
7
7
|
import { t } from "./block-VhmfGB3N.js";
|
|
8
8
|
import { createRoot } from "react-dom/client";
|
|
9
|
-
import { a as createEditorBridge } from "./bridge-
|
|
9
|
+
import { a as createEditorBridge } from "./bridge-BOcO9toS.js";
|
|
10
10
|
function toState(signal) {
|
|
11
11
|
const subscribe = (callback) => {
|
|
12
12
|
const dispose = effect(() => {
|