@juo/blocks 1.8.0 → 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.
@@ -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;AAmgB9C,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
@@ -812,9 +804,25 @@ class BlockWrapper extends HTMLElement {
812
804
  __publicField(this, "menuElement", null);
813
805
  __publicField(this, "isMenuOpen", false);
814
806
  __publicField(this, "closeMenuOnOutsideClick", null);
815
- __publicField(this, "emptyObserver", null);
816
807
  __publicField(this, "addButtons", []);
817
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
+ });
818
826
  this.attachShadow({ mode: "open" });
819
827
  this.setupStyles();
820
828
  this.setupTemplate();
@@ -992,50 +1000,40 @@ class BlockWrapper extends HTMLElement {
992
1000
  if (isWorkflowPreview && !isInOverlay) {
993
1001
  this.style.pointerEvents = "none";
994
1002
  }
995
- this.observeSlotEmptyState();
1003
+ this.addEventListener("mouseenter", this.handleHoverEnter);
1004
+ this.addEventListener("mouseleave", this.handleHoverLeave);
996
1005
  }
997
1006
  /**
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.
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.
1001
1019
  */
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
- });
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;
1018
1027
  }
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;
1028
+ if (getComputedStyle(el).display === "contents") {
1029
+ el = el.firstElementChild;
1030
+ continue;
1030
1031
  }
1031
- sync();
1032
- });
1033
- bindObservers();
1032
+ return el;
1033
+ }
1034
+ return slotted.shadowRoot ? null : slotted;
1034
1035
  }
1035
1036
  disconnectedCallback() {
1036
- var _a;
1037
- (_a = this.emptyObserver) == null ? void 0 : _a.disconnect();
1038
- this.emptyObserver = null;
1039
1037
  this.closeMenu();
1040
1038
  }
1041
1039
  toggleMenu() {
@@ -1075,6 +1073,7 @@ class BlockWrapper extends HTMLElement {
1075
1073
  updateActiveState(isActive) {
1076
1074
  if (isActive) {
1077
1075
  this.classList.add("active");
1076
+ this.handleHoverLeave();
1078
1077
  } else {
1079
1078
  this.classList.remove("active");
1080
1079
  this.closeMenu();
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.1",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist"