@juo/blocks 1.8.0 → 1.8.2

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.
@@ -6,7 +6,6 @@ export declare class BlockWrapper extends HTMLElement {
6
6
  private menuElement;
7
7
  private isMenuOpen;
8
8
  private closeMenuOnOutsideClick;
9
- private emptyObserver;
10
9
  private addButtons;
11
10
  private addRail;
12
11
  static get observedAttributes(): string[];
@@ -18,11 +17,23 @@ export declare class BlockWrapper extends HTMLElement {
18
17
  private clearAddButtonMenuState;
19
18
  connectedCallback(): void;
20
19
  /**
21
- * Mirror `data-empty` from the slotted block wrapper onto this editor
22
- * wrapper so page-level divider CSS (and live-data preview) treat empty
23
- * blocks the same as in view mode.
20
+ * Resolve the slotted block's first painted descendant — the
21
+ * card-like surface we paint the hover outline on. We can't use
22
+ * ::slotted() (CE blocks' own :host rules win the cascade) and we
23
+ * can't put outline on .block-wrapper directly (it has no radius and
24
+ * adopting one is more code than this), so we apply outline as an
25
+ * inline style on the visible element. Skips:
26
+ * - <style> nodes (Vue's defineCustomElement injects styles into
27
+ * the CE shadow root next to the rendered tree).
28
+ * - display:contents wrappers (Vue's <ContextProvider> sits between
29
+ * the slotted div and the actual UiCard for createVueRenderer).
30
+ * Crosses one shadow-root boundary for createVueCeRenderer blocks
31
+ * whose slotted element is itself a CE host.
24
32
  */
25
- private observeSlotEmptyState;
33
+ private static resolveOutlineTarget;
34
+ private hoverOutlineTarget;
35
+ private handleHoverEnter;
36
+ private handleHoverLeave;
26
37
  disconnectedCallback(): void;
27
38
  private toggleMenu;
28
39
  private openMenu;
@@ -1 +1 @@
1
- {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../src/editor/components.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AA2gB9C,qBAAa,YAAa,SAAQ,WAAW;IAC3C,OAAO,CAAC,KAAK,CAA8B;IAC3C,OAAO,CAAC,YAAY,CAAwB;IAC5C,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,uBAAuB,CAA0C;IACzE,OAAO,CAAC,aAAa,CAAiC;IACtD,OAAO,CAAC,UAAU,CAA2B;IAC7C,OAAO,CAAC,OAAO,CAA4B;IAE3C,MAAM,KAAK,kBAAkB,aAE5B;;IASD,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,aAAa;IA8GrB,OAAO,CAAC,eAAe;IAsCvB,OAAO,CAAC,cAAc;IAgCtB,OAAO,CAAC,uBAAuB;IAO/B,iBAAiB;IAsCjB;;;;OAIG;IACH,OAAO,CAAC,qBAAqB;IAqC7B,oBAAoB;IAYpB,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,QAAQ;IAahB,OAAO,CAAC,SAAS;IAWjB,QAAQ,CAAC,KAAK,EAAE,aAAa;IAQ7B,OAAO,CAAC,iBAAiB;IASzB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAaxB,OAAO,CAAC,iBAAiB;CAmD1B;AAMD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,0BAA0B,EAAE,YAAY,CAAC;KAC1C;CACF"}
1
+ {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../src/editor/components.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAygB9C,qBAAa,YAAa,SAAQ,WAAW;IAC3C,OAAO,CAAC,KAAK,CAA8B;IAC3C,OAAO,CAAC,YAAY,CAAwB;IAC5C,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,uBAAuB,CAA0C;IACzE,OAAO,CAAC,UAAU,CAA2B;IAC7C,OAAO,CAAC,OAAO,CAA4B;IAE3C,MAAM,KAAK,kBAAkB,aAE5B;;IASD,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,aAAa;IA8GrB,OAAO,CAAC,eAAe;IAsCvB,OAAO,CAAC,cAAc;IAgCtB,OAAO,CAAC,uBAAuB;IAO/B,iBAAiB;IAuCjB;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAuBnC,OAAO,CAAC,kBAAkB,CAA4B;IAEtD,OAAO,CAAC,gBAAgB,CAUtB;IAEF,OAAO,CAAC,gBAAgB,CAKtB;IAEF,oBAAoB;IAUpB,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,QAAQ;IAahB,OAAO,CAAC,SAAS;IAWjB,QAAQ,CAAC,KAAK,EAAE,aAAa;IAQ7B,OAAO,CAAC,iBAAiB;IAazB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAaxB,OAAO,CAAC,iBAAiB;CAmD1B;AAMD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,0BAA0B,EAAE,YAAY,CAAC;KAC1C;CACF"}
package/dist/editor.js CHANGED
@@ -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
@@ -725,7 +717,7 @@ const styles = `
725
717
  :host(.active:hover) .block-wrapper__add-btn:hover .block-wrapper__add-btn-surface,
726
718
  :host(.active) .block-wrapper__add-btn--menu-open .block-wrapper__add-btn-surface {
727
719
  width: 60px;
728
- border-radius: 32px;
720
+ border-radius: 2px;
729
721
  padding: 0 6px;
730
722
  }
731
723
 
@@ -777,8 +769,14 @@ const styles = `
777
769
  </style>
778
770
  `;
779
771
  const blockIconSvg = `
780
- <svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
781
- <path d="M4.36328 6.5459C4.96626 6.5459 5.4541 7.03374 5.4541 7.63672V10.9092C5.45405 11.5121 4.96623 12 4.36328 12H1.09082C0.96088 12 0.834934 11.9772 0.717773 11.9346C0.626296 11.9016 0.540642 11.8561 0.461914 11.8008C0.182984 11.6037 3.23667e-05 11.2776 0 10.9092V7.63672C0 7.03377 0.487878 6.54595 1.09082 6.5459H4.36328ZM10.9092 6.5459C11.5122 6.5459 12 7.03374 12 7.63672V10.9092C11.9999 11.5121 11.5121 12 10.9092 12H7.63672C7.50675 12 7.38086 11.9772 7.26367 11.9346C7.17215 11.9016 7.08658 11.8561 7.00781 11.8008C6.72883 11.6037 6.54593 11.2777 6.5459 10.9092V7.63672C6.5459 7.03374 7.03374 6.5459 7.63672 6.5459H10.9092ZM1.09082 7.63672V10.9092H4.36328V7.63672H1.09082ZM7.63672 10.9092H10.9092V7.63672H7.63672V10.9092ZM4.36328 0C4.96623 0 5.45405 0.487878 5.4541 1.09082V4.36328C5.4541 4.96626 4.96626 5.4541 4.36328 5.4541H1.09082C0.96088 5.45409 0.834934 5.43225 0.717773 5.38965C0.626233 5.35663 0.54069 5.31024 0.461914 5.25488C0.183079 5.05776 0 4.73167 0 4.36328V1.09082C4.77994e-05 0.487908 0.487908 4.79046e-05 1.09082 0H4.36328ZM10.9092 0C11.5121 0 12 0.487878 12 1.09082V4.36328C12 4.96626 11.5122 5.4541 10.9092 5.4541H7.63672C7.50675 5.4541 7.38086 5.43226 7.26367 5.38965C7.17208 5.35663 7.08662 5.31026 7.00781 5.25488C6.72893 5.05777 6.5459 4.73171 6.5459 4.36328V1.09082C6.54595 0.487878 7.03377 0 7.63672 0H10.9092ZM1.09082 4.36328H4.36328V1.09082H1.09082V4.36328ZM7.63672 4.36328H10.9092V1.09082H7.63672V4.36328Z" fill="currentColor"/>
772
+ <svg width="14" height="12" viewBox="0 0 14 13" fill="none" xmlns="http://www.w3.org/2000/svg">
773
+ <path d="M2 9.34521H1V10.3452C1 11.4497 1.89453 12.3452 3 12.3452H4V11.3452H3C2.44727 11.3452 2 10.8979 2 10.3452V9.34521Z" fill="currentColor"/>
774
+ <path d="M2 3.34521H1V2.34521C1 1.24072 1.89453 0.345215 3 0.345215H4V1.34521H3C2.44727 1.34521 2 1.79248 2 2.34521V3.34521Z" fill="currentColor"/>
775
+ <path d="M10 1.34521V0.345215H11C12.1055 0.345215 13 1.24072 13 2.34521V3.34521H12V2.34521C12 2.24072 11.9844 2.14014 11.9551 2.04541C11.9023 1.87842 11.8066 1.72998 11.6816 1.61377C11.5039 1.44775 11.2637 1.34521 11 1.34521H10Z" fill="currentColor"/>
776
+ <path d="M12 9.34521H13V10.3452C13 11.4497 12.1055 12.3452 11 12.3452H10V11.3452H11C11.5527 11.3452 12 10.8979 12 10.3452V9.34521Z" fill="currentColor"/>
777
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M0 5.34521C0 4.79248 0.447266 4.34521 1 4.34521H13C13.5527 4.34521 14 4.79248 14 5.34521V7.34521C14 7.89795 13.5527 8.34521 13 8.34521H1C0.880859 8.34521 0.765625 8.32471 0.658203 8.28564C0.574219 8.25537 0.496094 8.21338 0.423828 8.1626C0.167969 7.98193 0 7.68311 0 7.34521V5.34521ZM1 5.34521H13V7.34521H1V5.34521Z" fill="currentColor"/>
778
+ <path d="M5.5 0.345215H8.5V1.34521H5.5V0.345215Z" fill="currentColor"/>
779
+ <path d="M8.5 11.3452H5.5V12.3452H8.5V11.3452Z" fill="currentColor"/>
782
780
  </svg>
783
781
 
784
782
  `;
@@ -812,9 +810,25 @@ class BlockWrapper extends HTMLElement {
812
810
  __publicField(this, "menuElement", null);
813
811
  __publicField(this, "isMenuOpen", false);
814
812
  __publicField(this, "closeMenuOnOutsideClick", null);
815
- __publicField(this, "emptyObserver", null);
816
813
  __publicField(this, "addButtons", []);
817
814
  __publicField(this, "addRail", null);
815
+ __publicField(this, "hoverOutlineTarget", null);
816
+ __publicField(this, "handleHoverEnter", () => {
817
+ if (this.classList.contains("active")) return;
818
+ const slotted = this.firstElementChild;
819
+ if (!slotted || slotted.hasAttribute("data-empty")) return;
820
+ const target = BlockWrapper.resolveOutlineTarget(slotted);
821
+ if (!target) return;
822
+ this.hoverOutlineTarget = target;
823
+ target.style.outline = "1px solid #060606";
824
+ target.style.outlineOffset = "0";
825
+ });
826
+ __publicField(this, "handleHoverLeave", () => {
827
+ if (!this.hoverOutlineTarget) return;
828
+ this.hoverOutlineTarget.style.outline = "";
829
+ this.hoverOutlineTarget.style.outlineOffset = "";
830
+ this.hoverOutlineTarget = null;
831
+ });
818
832
  this.attachShadow({ mode: "open" });
819
833
  this.setupStyles();
820
834
  this.setupTemplate();
@@ -992,50 +1006,40 @@ class BlockWrapper extends HTMLElement {
992
1006
  if (isWorkflowPreview && !isInOverlay) {
993
1007
  this.style.pointerEvents = "none";
994
1008
  }
995
- this.observeSlotEmptyState();
1009
+ this.addEventListener("mouseenter", this.handleHoverEnter);
1010
+ this.addEventListener("mouseleave", this.handleHoverLeave);
996
1011
  }
997
1012
  /**
998
- * Mirror `data-empty` from the slotted block wrapper onto this editor
999
- * wrapper so page-level divider CSS (and live-data preview) treat empty
1000
- * blocks the same as in view mode.
1013
+ * Resolve the slotted block's first painted descendant — the
1014
+ * card-like surface we paint the hover outline on. We can't use
1015
+ * ::slotted() (CE blocks' own :host rules win the cascade) and we
1016
+ * can't put outline on .block-wrapper directly (it has no radius and
1017
+ * adopting one is more code than this), so we apply outline as an
1018
+ * inline style on the visible element. Skips:
1019
+ * - <style> nodes (Vue's defineCustomElement injects styles into
1020
+ * the CE shadow root next to the rendered tree).
1021
+ * - display:contents wrappers (Vue's <ContextProvider> sits between
1022
+ * the slotted div and the actual UiCard for createVueRenderer).
1023
+ * Crosses one shadow-root boundary for createVueCeRenderer blocks
1024
+ * whose slotted element is itself a CE host.
1001
1025
  */
1002
- observeSlotEmptyState() {
1003
- var _a;
1004
- (_a = this.emptyObserver) == null ? void 0 : _a.disconnect();
1005
- const sync = () => {
1006
- const slotted = this.firstElementChild;
1007
- const empty = slotted == null || slotted.hasAttribute("data-empty");
1008
- this.toggleAttribute("data-empty", empty);
1009
- };
1010
- const bindObservers = () => {
1011
- this.emptyObserver.observe(this, { childList: true });
1012
- const slotted = this.firstElementChild;
1013
- if (slotted) {
1014
- this.emptyObserver.observe(slotted, {
1015
- attributes: true,
1016
- attributeFilter: ["data-empty"]
1017
- });
1026
+ static resolveOutlineTarget(slotted) {
1027
+ const root = slotted.shadowRoot ?? slotted;
1028
+ let el = root.firstElementChild;
1029
+ while (el) {
1030
+ if (el.tagName === "STYLE") {
1031
+ el = el.nextElementSibling;
1032
+ continue;
1018
1033
  }
1019
- };
1020
- sync();
1021
- this.emptyObserver = new MutationObserver((records) => {
1022
- const slottedChildChanged = records.some(
1023
- (record) => record.type === "childList" && record.target === this
1024
- );
1025
- if (slottedChildChanged) {
1026
- this.emptyObserver.disconnect();
1027
- sync();
1028
- bindObservers();
1029
- return;
1034
+ if (getComputedStyle(el).display === "contents") {
1035
+ el = el.firstElementChild;
1036
+ continue;
1030
1037
  }
1031
- sync();
1032
- });
1033
- bindObservers();
1038
+ return el;
1039
+ }
1040
+ return slotted.shadowRoot ? null : slotted;
1034
1041
  }
1035
1042
  disconnectedCallback() {
1036
- var _a;
1037
- (_a = this.emptyObserver) == null ? void 0 : _a.disconnect();
1038
- this.emptyObserver = null;
1039
1043
  this.closeMenu();
1040
1044
  }
1041
1045
  toggleMenu() {
@@ -1075,6 +1079,7 @@ class BlockWrapper extends HTMLElement {
1075
1079
  updateActiveState(isActive) {
1076
1080
  if (isActive) {
1077
1081
  this.classList.add("active");
1082
+ this.handleHoverLeave();
1078
1083
  } else {
1079
1084
  this.classList.remove("active");
1080
1085
  this.closeMenu();
@@ -1168,7 +1173,7 @@ async function serializeBlock(block) {
1168
1173
  locales
1169
1174
  };
1170
1175
  }
1171
- const EDITOR_BODY_TOP_PADDING_PX = 32;
1176
+ const EDITOR_BODY_TOP_PADDING_PX = 48;
1172
1177
  async function setupEditorMode(deps) {
1173
1178
  const { routerService, themeState } = deps;
1174
1179
  const padStyle = document.createElement("style");
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@juo/blocks",
3
3
  "private": false,
4
- "version": "1.8.0",
4
+ "version": "1.8.2",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist"