@ohhwells/bridge 0.1.42-next.103 → 0.1.42-next.105

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/index.cjs CHANGED
@@ -4943,7 +4943,11 @@ function MediaOverlay({
4943
4943
  variant: "outline",
4944
4944
  size: "sm",
4945
4945
  className: "gap-1.5 cursor-pointer hover:bg-background",
4946
- style: OVERLAY_BUTTON_STYLE,
4946
+ style: {
4947
+ ...OVERLAY_BUTTON_STYLE,
4948
+ // Don't let Replace steal clicks when text (e.g. nav) sits on top of this media.
4949
+ pointerEvents: hover.hasTextOverlap ? "none" : "auto"
4950
+ },
4947
4951
  onMouseDown: (e) => e.preventDefault(),
4948
4952
  onClick: (e) => {
4949
4953
  e.stopPropagation();
@@ -7067,7 +7071,195 @@ function parseFooterOrder(content) {
7067
7071
  return null;
7068
7072
  }
7069
7073
  }
7074
+ var FOOTER_HEADING_RE = /^footer-(\d+)-heading$/;
7075
+ var FOOTER_LABEL_RE = /^footer-(\d+)-(\d+)-label$/;
7076
+ var DEFAULT_FOOTER_COLUMN_HEADING = "New";
7077
+ var DEFAULT_FOOTER_COLUMN_LINK_LABEL = "New link";
7078
+ var DEFAULT_FOOTER_COLUMN_LINK_HREF = "";
7079
+ function isFooterLinksContainer(el) {
7080
+ return el.hasAttribute("data-ohw-footer-links") || el.classList.contains("rb-footer-links");
7081
+ }
7082
+ function getFooterColumnIndicesInDom() {
7083
+ const indices = /* @__PURE__ */ new Set();
7084
+ for (const col of listFooterColumns()) {
7085
+ const attr = col.getAttribute("data-ohw-footer-col");
7086
+ if (attr != null) {
7087
+ const n = parseInt(attr, 10);
7088
+ if (Number.isFinite(n)) indices.add(n);
7089
+ }
7090
+ for (const link of listFooterLinksInColumn(col)) {
7091
+ const parsed = parseFooterHrefKey(link.getAttribute("data-ohw-href-key"));
7092
+ if (parsed) indices.add(parsed.col);
7093
+ }
7094
+ const heading = col.querySelector('[data-ohw-key^="footer-"][data-ohw-key$="-heading"]');
7095
+ const headingKey = heading?.getAttribute("data-ohw-key");
7096
+ if (headingKey) {
7097
+ const match = headingKey.match(FOOTER_HEADING_RE);
7098
+ if (match) indices.add(parseInt(match[1], 10));
7099
+ }
7100
+ }
7101
+ return [...indices].sort((a, b) => a - b);
7102
+ }
7103
+ function getNextFooterColumnIndex() {
7104
+ const indices = getFooterColumnIndicesInDom();
7105
+ if (indices.length === 0) return 0;
7106
+ return Math.max(...indices) + 1;
7107
+ }
7108
+ function cloneFooterLinkShell(template) {
7109
+ const anchor = document.createElement("a");
7110
+ if (template) {
7111
+ anchor.style.cssText = template.style.cssText;
7112
+ if (template.className) anchor.className = template.className;
7113
+ }
7114
+ anchor.style.cursor = "pointer";
7115
+ anchor.style.textDecoration = "none";
7116
+ return anchor;
7117
+ }
7118
+ function buildFooterHeading(colIndex, text) {
7119
+ const heading = document.createElement("p");
7120
+ heading.setAttribute("data-ohw-editable", "text");
7121
+ heading.setAttribute("data-ohw-key", `footer-${colIndex}-heading`);
7122
+ heading.textContent = text;
7123
+ heading.style.cssText = [
7124
+ "color: var(--espresso, #3d312b)",
7125
+ "font-size: 14px",
7126
+ "font-weight: 800",
7127
+ "opacity: 0.82",
7128
+ "margin: 0 0 6px",
7129
+ "padding: 0",
7130
+ "line-height: 1.2"
7131
+ ].join(";");
7132
+ return heading;
7133
+ }
7134
+ function buildFooterLink(colIndex, itemIndex, href, label, template) {
7135
+ const anchor = cloneFooterLinkShell(template);
7136
+ anchor.setAttribute("href", href);
7137
+ anchor.setAttribute("data-ohw-href-key", `footer-${colIndex}-${itemIndex}-href`);
7138
+ const span = document.createElement("span");
7139
+ span.setAttribute("data-ohw-editable", "text");
7140
+ span.setAttribute("data-ohw-key", `footer-${colIndex}-${itemIndex}-label`);
7141
+ span.textContent = label;
7142
+ anchor.appendChild(span);
7143
+ return anchor;
7144
+ }
7145
+ function footerColumnExistsInDom(colIndex) {
7146
+ return document.querySelector(`[data-ohw-footer-col="${colIndex}"]`) !== null || document.querySelector(`[data-ohw-href-key^="footer-${colIndex}-"]`) !== null || document.querySelector(`[data-ohw-key="footer-${colIndex}-heading"]`) !== null;
7147
+ }
7148
+ function getFooterLinkTemplate() {
7149
+ for (const col of listFooterColumns()) {
7150
+ const link = listFooterLinksInColumn(col)[0];
7151
+ if (link) return link;
7152
+ }
7153
+ return null;
7154
+ }
7155
+ function getFooterColumnTemplate() {
7156
+ return listFooterColumns()[0] ?? null;
7157
+ }
7158
+ function insertFooterColumnDom(colIndex, heading, items) {
7159
+ const container = getFooterLinksContainer();
7160
+ if (!container) return null;
7161
+ const colTemplate = getFooterColumnTemplate();
7162
+ const linkTemplate = getFooterLinkTemplate();
7163
+ const column = document.createElement("div");
7164
+ if (colTemplate?.className) column.className = colTemplate.className;
7165
+ else column.className = "rb-footer-link-col";
7166
+ column.setAttribute("data-ohw-footer-col", String(colIndex));
7167
+ if (colTemplate) {
7168
+ const gap = getComputedStyle(colTemplate).gap;
7169
+ if (gap && gap !== "normal") column.style.gap = gap;
7170
+ column.style.display = getComputedStyle(colTemplate).display || "flex";
7171
+ column.style.flexDirection = "column";
7172
+ }
7173
+ column.appendChild(buildFooterHeading(colIndex, heading));
7174
+ let firstLink = null;
7175
+ items.forEach((item, itemIndex) => {
7176
+ const link = buildFooterLink(colIndex, itemIndex, item.href, item.label, linkTemplate);
7177
+ column.appendChild(link);
7178
+ if (!firstLink) firstLink = link;
7179
+ });
7180
+ container.appendChild(column);
7181
+ return { column, firstLink };
7182
+ }
7183
+ function insertFooterColumn(heading = DEFAULT_FOOTER_COLUMN_HEADING, linkLabel = DEFAULT_FOOTER_COLUMN_LINK_LABEL, linkHref = DEFAULT_FOOTER_COLUMN_LINK_HREF) {
7184
+ const colIndex = getNextFooterColumnIndex();
7185
+ const inserted = insertFooterColumnDom(colIndex, heading, [{ href: linkHref, label: linkLabel }]);
7186
+ if (!inserted?.firstLink) throw new Error("Failed to insert footer column");
7187
+ syncFooterColumnIndices(listFooterColumns());
7188
+ return {
7189
+ column: inserted.column,
7190
+ firstLink: inserted.firstLink,
7191
+ colIndex,
7192
+ headingKey: `footer-${colIndex}-heading`,
7193
+ hrefKey: `footer-${colIndex}-0-href`,
7194
+ labelKey: `footer-${colIndex}-0-label`,
7195
+ heading,
7196
+ label: linkLabel,
7197
+ href: linkHref,
7198
+ order: getFooterOrderFromDom()
7199
+ };
7200
+ }
7201
+ function collectFooterColumnIndicesFromContent(content) {
7202
+ const indices = /* @__PURE__ */ new Set();
7203
+ for (const key of Object.keys(content)) {
7204
+ const href = parseFooterHrefKey(key);
7205
+ if (href) indices.add(href.col);
7206
+ const heading = key.match(FOOTER_HEADING_RE);
7207
+ if (heading) indices.add(parseInt(heading[1], 10));
7208
+ const label = key.match(FOOTER_LABEL_RE);
7209
+ if (label) indices.add(parseInt(label[1], 10));
7210
+ }
7211
+ const order = parseFooterOrder(content);
7212
+ if (order) {
7213
+ for (const col of order) {
7214
+ for (const hrefKey of col) {
7215
+ const parsed = parseFooterHrefKey(hrefKey);
7216
+ if (parsed) indices.add(parsed.col);
7217
+ }
7218
+ }
7219
+ }
7220
+ return [...indices].sort((a, b) => a - b);
7221
+ }
7222
+ function collectFooterItemsForColumn(content, colIndex) {
7223
+ const itemIndices = /* @__PURE__ */ new Set();
7224
+ for (const key of Object.keys(content)) {
7225
+ const href = parseFooterHrefKey(key);
7226
+ if (href?.col === colIndex) itemIndices.add(href.item);
7227
+ const label = key.match(FOOTER_LABEL_RE);
7228
+ if (label && parseInt(label[1], 10) === colIndex) {
7229
+ itemIndices.add(parseInt(label[2], 10));
7230
+ }
7231
+ }
7232
+ const sorted = [...itemIndices].sort((a, b) => a - b);
7233
+ if (sorted.length === 0) {
7234
+ return [
7235
+ {
7236
+ href: content[`footer-${colIndex}-0-href`] ?? DEFAULT_FOOTER_COLUMN_LINK_HREF,
7237
+ label: content[`footer-${colIndex}-0-label`] ?? DEFAULT_FOOTER_COLUMN_LINK_LABEL
7238
+ }
7239
+ ];
7240
+ }
7241
+ return sorted.map((itemIndex) => ({
7242
+ href: content[`footer-${colIndex}-${itemIndex}-href`] ?? DEFAULT_FOOTER_COLUMN_LINK_HREF,
7243
+ label: content[`footer-${colIndex}-${itemIndex}-label`] ?? DEFAULT_FOOTER_COLUMN_LINK_LABEL
7244
+ }));
7245
+ }
7246
+ function reconcileFooterColumnsFromContent(content) {
7247
+ const indices = collectFooterColumnIndicesFromContent(content);
7248
+ for (const colIndex of indices) {
7249
+ if (footerColumnExistsInDom(colIndex)) continue;
7250
+ const heading = content[`footer-${colIndex}-heading`] ?? DEFAULT_FOOTER_COLUMN_HEADING;
7251
+ const items = collectFooterItemsForColumn(content, colIndex);
7252
+ const hasPayload = Boolean(content[`footer-${colIndex}-heading`]) || items.some(
7253
+ (_, i) => content[`footer-${colIndex}-${i}-href`] !== void 0 || content[`footer-${colIndex}-${i}-label`] !== void 0
7254
+ ) || (parseFooterOrder(content)?.some(
7255
+ (col) => col.some((k) => parseFooterHrefKey(k)?.col === colIndex)
7256
+ ) ?? false);
7257
+ if (!hasPayload) continue;
7258
+ insertFooterColumnDom(colIndex, heading, items);
7259
+ }
7260
+ }
7070
7261
  function reconcileFooterOrderFromContent(content) {
7262
+ reconcileFooterColumnsFromContent(content);
7071
7263
  const order = parseFooterOrder(content);
7072
7264
  if (!order?.length) return;
7073
7265
  const current = getFooterOrderFromDom();
@@ -7077,6 +7269,26 @@ function reconcileFooterOrderFromContent(content) {
7077
7269
  }
7078
7270
  applyFooterOrder(order);
7079
7271
  }
7272
+ function resolveFooterLinksContainerSelectionTarget(target, clientX, clientY, isPointOverItem) {
7273
+ const container = getFooterLinksContainer();
7274
+ if (!container) return null;
7275
+ const inContainer = target === container || container.contains(target) && Boolean(target.closest("[data-ohw-footer-links], .rb-footer-links"));
7276
+ if (!inContainer && target !== container) {
7277
+ const r2 = container.getBoundingClientRect();
7278
+ const over = clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom;
7279
+ if (!over) return null;
7280
+ }
7281
+ if (isPointOverItem(container, clientX, clientY)) return null;
7282
+ const column = target.closest("[data-ohw-footer-col], [data-ohw-footer-column]") ?? null;
7283
+ if (column && container.contains(column)) {
7284
+ if (target === column || column.contains(target)) return null;
7285
+ }
7286
+ if (target === container || container.contains(target) || inContainer) {
7287
+ if (target === container || isFooterLinksContainer(target)) return container;
7288
+ if (!column) return container;
7289
+ }
7290
+ return null;
7291
+ }
7080
7292
  function isRowLayoutColumn(links) {
7081
7293
  if (links.length < 2) return false;
7082
7294
  const firstTop = links[0].getBoundingClientRect().top;
@@ -7232,6 +7444,30 @@ function hitTestColumnDropSlot(clientX, _clientY) {
7232
7444
  return best?.slot ?? null;
7233
7445
  }
7234
7446
 
7447
+ // src/lib/add-footer-column.ts
7448
+ function buildFooterColumnEditContentPatch(result) {
7449
+ return {
7450
+ [result.headingKey]: result.heading,
7451
+ [result.hrefKey]: result.href,
7452
+ [result.labelKey]: result.label,
7453
+ [FOOTER_ORDER_KEY]: JSON.stringify(result.order)
7454
+ };
7455
+ }
7456
+ function addFooterColumnWithPersist({
7457
+ postToParent: postToParent2
7458
+ }) {
7459
+ const result = insertFooterColumn();
7460
+ const patch = buildFooterColumnEditContentPatch(result);
7461
+ setStoredLinkHref(result.hrefKey, result.href);
7462
+ postToParent2({
7463
+ type: "ow:change",
7464
+ nodes: Object.entries(patch).map(([key, text]) => ({ key, text }))
7465
+ });
7466
+ postToParent2({ type: "ow:toast", title: "Item added", toastType: "success" });
7467
+ enforceLinkHrefs();
7468
+ return result;
7469
+ }
7470
+
7235
7471
  // src/lib/item-drag-interaction.ts
7236
7472
  function disableNativeHrefDrag(el) {
7237
7473
  if (el.draggable) el.draggable = false;
@@ -7306,18 +7542,28 @@ function buildRootNavDropSlots() {
7306
7542
  });
7307
7543
  return slots;
7308
7544
  }
7545
+ const edgeGap = (() => {
7546
+ if (items.length < 2) return 32;
7547
+ const a = items[0].getBoundingClientRect();
7548
+ const b = items[1].getBoundingClientRect();
7549
+ return Math.max(0, b.left - a.right);
7550
+ })();
7309
7551
  for (let i = 0; i <= items.length; i++) {
7310
7552
  let left;
7311
7553
  let top;
7312
7554
  let height;
7313
7555
  if (i === 0) {
7314
7556
  const first = items[0].getBoundingClientRect();
7315
- left = first.left - barThickness / 2;
7557
+ left = first.left - edgeGap / 2 - barThickness / 2;
7316
7558
  top = first.top;
7317
7559
  height = first.height;
7318
7560
  } else if (i === items.length) {
7319
7561
  const last = items[items.length - 1].getBoundingClientRect();
7320
- left = last.right - barThickness / 2;
7562
+ const lastGap = items.length >= 2 ? Math.max(
7563
+ 0,
7564
+ last.left - items[items.length - 2].getBoundingClientRect().right
7565
+ ) : edgeGap;
7566
+ left = last.right + lastGap / 2 - barThickness / 2;
7321
7567
  top = last.top;
7322
7568
  height = last.height;
7323
7569
  } else {
@@ -7344,18 +7590,28 @@ function buildChildNavDropSlots(parentHrefKey) {
7344
7590
  const slots = [];
7345
7591
  const barThickness = 3;
7346
7592
  if (children.length === 0) return slots;
7593
+ const edgeGap = (() => {
7594
+ if (children.length < 2) return 16;
7595
+ const a = children[0].getBoundingClientRect();
7596
+ const b = children[1].getBoundingClientRect();
7597
+ return Math.max(0, b.top - a.bottom);
7598
+ })();
7347
7599
  for (let i = 0; i <= children.length; i++) {
7348
7600
  let top;
7349
7601
  let width;
7350
7602
  let left;
7351
7603
  if (i === 0) {
7352
7604
  const first = children[0].getBoundingClientRect();
7353
- top = first.top - barThickness / 2;
7605
+ top = first.top - edgeGap / 2 - barThickness / 2;
7354
7606
  left = first.left;
7355
7607
  width = first.width;
7356
7608
  } else if (i === children.length) {
7357
7609
  const last = children[children.length - 1].getBoundingClientRect();
7358
- top = last.bottom - barThickness / 2;
7610
+ const lastGap = children.length >= 2 ? Math.max(
7611
+ 0,
7612
+ last.top - children[children.length - 2].getBoundingClientRect().bottom
7613
+ ) : edgeGap;
7614
+ top = last.bottom + lastGap / 2 - barThickness / 2;
7359
7615
  left = last.left;
7360
7616
  width = last.width;
7361
7617
  } else {
@@ -7744,15 +8000,60 @@ function useNavItemDrag({
7744
8000
  };
7745
8001
  }
7746
8002
 
7747
- // src/ui/navbar-container-chrome.tsx
8003
+ // src/ui/footer-container-chrome.tsx
7748
8004
  var import_lucide_react10 = require("lucide-react");
7749
8005
  var import_jsx_runtime21 = require("react/jsx-runtime");
8006
+ function FooterContainerChrome({ rect, onAdd }) {
8007
+ const chromeGap = 6;
8008
+ const buttonMargin = 7;
8009
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
8010
+ "div",
8011
+ {
8012
+ "data-ohw-footer-container-chrome": "",
8013
+ "data-ohw-bridge": "",
8014
+ className: "pointer-events-none fixed z-[2147483647]",
8015
+ style: {
8016
+ top: rect.top - chromeGap,
8017
+ left: rect.left - chromeGap,
8018
+ width: rect.width + chromeGap * 2,
8019
+ height: rect.height + chromeGap * 2
8020
+ },
8021
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Tooltip, { children: [
8022
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
8023
+ "button",
8024
+ {
8025
+ type: "button",
8026
+ "data-ohw-footer-add-button": "",
8027
+ className: "pointer-events-auto absolute left-1/2 flex size-7 -translate-x-1/2 -translate-y-full items-center justify-center rounded-[10px] border border-border bg-background p-0.5 shadow-sm transition-colors hover:bg-muted/80",
8028
+ style: { top: chromeGap - buttonMargin },
8029
+ "aria-label": "Add item",
8030
+ onMouseDown: (e) => {
8031
+ e.preventDefault();
8032
+ e.stopPropagation();
8033
+ },
8034
+ onClick: (e) => {
8035
+ e.preventDefault();
8036
+ e.stopPropagation();
8037
+ onAdd();
8038
+ },
8039
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react10.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
8040
+ }
8041
+ ) }),
8042
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipContent, { side: "bottom", sideOffset: 9, children: "Add item" })
8043
+ ] })
8044
+ }
8045
+ ) });
8046
+ }
8047
+
8048
+ // src/ui/navbar-container-chrome.tsx
8049
+ var import_lucide_react11 = require("lucide-react");
8050
+ var import_jsx_runtime22 = require("react/jsx-runtime");
7750
8051
  function NavbarContainerChrome({
7751
8052
  rect,
7752
8053
  onAdd
7753
8054
  }) {
7754
8055
  const chromeGap = 6;
7755
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
8056
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
7756
8057
  "div",
7757
8058
  {
7758
8059
  "data-ohw-navbar-container-chrome": "",
@@ -7764,7 +8065,7 @@ function NavbarContainerChrome({
7764
8065
  width: rect.width + chromeGap * 2,
7765
8066
  height: rect.height + chromeGap * 2
7766
8067
  },
7767
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
8068
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
7768
8069
  "button",
7769
8070
  {
7770
8071
  type: "button",
@@ -7781,7 +8082,7 @@ function NavbarContainerChrome({
7781
8082
  e.stopPropagation();
7782
8083
  onAdd();
7783
8084
  },
7784
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react10.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
8085
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react11.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
7785
8086
  }
7786
8087
  )
7787
8088
  }
@@ -7790,7 +8091,7 @@ function NavbarContainerChrome({
7790
8091
 
7791
8092
  // src/ui/drop-indicator.tsx
7792
8093
  var React10 = __toESM(require("react"), 1);
7793
- var import_jsx_runtime22 = require("react/jsx-runtime");
8094
+ var import_jsx_runtime23 = require("react/jsx-runtime");
7794
8095
  var dropIndicatorVariants = cva(
7795
8096
  "ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
7796
8097
  {
@@ -7814,7 +8115,7 @@ var dropIndicatorVariants = cva(
7814
8115
  );
7815
8116
  var DropIndicator = React10.forwardRef(
7816
8117
  ({ className, direction, state, ...props }, ref) => {
7817
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
8118
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
7818
8119
  "div",
7819
8120
  {
7820
8121
  ref,
@@ -7831,7 +8132,7 @@ var DropIndicator = React10.forwardRef(
7831
8132
  DropIndicator.displayName = "DropIndicator";
7832
8133
 
7833
8134
  // src/ui/badge.tsx
7834
- var import_jsx_runtime23 = require("react/jsx-runtime");
8135
+ var import_jsx_runtime24 = require("react/jsx-runtime");
7835
8136
  var badgeVariants = cva(
7836
8137
  "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
7837
8138
  {
@@ -7849,12 +8150,12 @@ var badgeVariants = cva(
7849
8150
  }
7850
8151
  );
7851
8152
  function Badge({ className, variant, ...props }) {
7852
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
8153
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
7853
8154
  }
7854
8155
 
7855
8156
  // src/OhhwellsBridge.tsx
7856
- var import_lucide_react11 = require("lucide-react");
7857
- var import_jsx_runtime24 = require("react/jsx-runtime");
8157
+ var import_lucide_react12 = require("lucide-react");
8158
+ var import_jsx_runtime25 = require("react/jsx-runtime");
7858
8159
  var PRIMARY2 = "#0885FE";
7859
8160
  var IMAGE_FADE_MS = 300;
7860
8161
  function runOpacityFade(el, onDone) {
@@ -8033,7 +8334,7 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
8033
8334
  const root = (0, import_client.createRoot)(container);
8034
8335
  (0, import_react_dom2.flushSync)(() => {
8035
8336
  root.render(
8036
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
8337
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
8037
8338
  SchedulingWidget,
8038
8339
  {
8039
8340
  notifyOnConnect,
@@ -8234,7 +8535,7 @@ function applyLinkByKey(key, val) {
8234
8535
  }
8235
8536
  function isInsideLinkEditor(target) {
8236
8537
  return Boolean(
8237
- target.closest("[data-ohw-link-popover-root]") || target.closest("[data-ohw-link-modal-root]") || target.closest("[data-ohw-link-page-dropdown]") || target.closest("[data-ohw-section-picker]") || target.closest("[data-ohw-navbar-container-chrome]") || target.closest("[data-ohw-navbar-add-button]") || target.closest('[data-slot="popover-content"]') || target.closest('[data-slot="dialog-content"]') || target.closest('[data-slot="dialog-overlay"]')
8538
+ target.closest("[data-ohw-link-popover-root]") || target.closest("[data-ohw-link-modal-root]") || target.closest("[data-ohw-link-page-dropdown]") || target.closest("[data-ohw-section-picker]") || target.closest("[data-ohw-navbar-container-chrome]") || target.closest("[data-ohw-navbar-add-button]") || target.closest("[data-ohw-footer-container-chrome]") || target.closest("[data-ohw-footer-add-button]") || target.closest('[data-slot="popover-content"]') || target.closest('[data-slot="dialog-content"]') || target.closest('[data-slot="dialog-overlay"]')
8238
8539
  );
8239
8540
  }
8240
8541
  function getHrefKeyFromElement(el) {
@@ -8315,7 +8616,7 @@ function isInferredFooterGroup(el) {
8315
8616
  return countFooterNavItems(el) >= 2;
8316
8617
  }
8317
8618
  function isNavigationContainer(el) {
8318
- return el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isNavigationRoot(el) || isInferredFooterGroup(el);
8619
+ return el.hasAttribute("data-ohw-nav-container") || isFooterLinksContainer(el) || el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isNavigationRoot(el) || isInferredFooterGroup(el);
8319
8620
  }
8320
8621
  function isNavbarLinksContainer(el) {
8321
8622
  return el.hasAttribute("data-ohw-nav-container");
@@ -8334,6 +8635,9 @@ function isPointOverNavigation(x, y) {
8334
8635
  const roots = /* @__PURE__ */ new Set();
8335
8636
  const navRoot = document.querySelector("[data-ohw-nav-root]") ?? document.querySelector("nav");
8336
8637
  if (navRoot) roots.add(navRoot);
8638
+ document.querySelectorAll("[data-ohw-nav-drawer], [data-ohw-nav-container]").forEach((el) => {
8639
+ roots.add(el);
8640
+ });
8337
8641
  const footer = document.querySelector("footer");
8338
8642
  if (footer) roots.add(footer);
8339
8643
  for (const root of roots) {
@@ -8362,6 +8666,12 @@ function isPointOverNavItem(container, x, y) {
8362
8666
  return x >= itemRect.left && x <= itemRect.right && y >= itemRect.top && y <= itemRect.bottom;
8363
8667
  });
8364
8668
  }
8669
+ function isPointOverFooterColumn(x, y) {
8670
+ return listFooterColumns().some((col) => {
8671
+ const r2 = col.getBoundingClientRect();
8672
+ return x >= r2.left && x <= r2.right && y >= r2.top && y <= r2.bottom;
8673
+ });
8674
+ }
8365
8675
  function resolveNavContainerSelectionTarget(target, clientX, clientY) {
8366
8676
  if (getNavigationItemAnchor(target)) return null;
8367
8677
  if (target.closest('[data-ohw-role="navbar-button"]')) return null;
@@ -8392,7 +8702,10 @@ function getNavigationSelectionParent(el) {
8392
8702
  if (footerGroup) return footerGroup;
8393
8703
  return getNavigationRoot(el);
8394
8704
  }
8395
- if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup(el)) {
8705
+ if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup(el))) {
8706
+ return getFooterLinksContainer();
8707
+ }
8708
+ if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isFooterLinksContainer(el) || isInferredFooterGroup(el)) {
8396
8709
  return getNavigationRoot(el);
8397
8710
  }
8398
8711
  return null;
@@ -8619,7 +8932,7 @@ function EditGlowChrome({
8619
8932
  hideHandle = false
8620
8933
  }) {
8621
8934
  const GAP = SELECTION_CHROME_GAP2;
8622
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
8935
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
8623
8936
  "div",
8624
8937
  {
8625
8938
  ref: elRef,
@@ -8634,7 +8947,7 @@ function EditGlowChrome({
8634
8947
  zIndex: 2147483646
8635
8948
  },
8636
8949
  children: [
8637
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
8950
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
8638
8951
  "div",
8639
8952
  {
8640
8953
  style: {
@@ -8647,7 +8960,7 @@ function EditGlowChrome({
8647
8960
  }
8648
8961
  }
8649
8962
  ),
8650
- reorderHrefKey && !hideHandle && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
8963
+ reorderHrefKey && !hideHandle && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
8651
8964
  "div",
8652
8965
  {
8653
8966
  "data-ohw-drag-handle-container": "",
@@ -8659,7 +8972,7 @@ function EditGlowChrome({
8659
8972
  transform: "translate(calc(-100% - 7px), -50%)",
8660
8973
  pointerEvents: dragDisabled ? "none" : "auto"
8661
8974
  },
8662
- children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
8975
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
8663
8976
  DragHandle,
8664
8977
  {
8665
8978
  "aria-label": `Reorder ${reorderHrefKey}`,
@@ -8869,7 +9182,7 @@ function FloatingToolbar({
8869
9182
  return () => ro.disconnect();
8870
9183
  }, [showEditLink, activeCommands]);
8871
9184
  const { top, left, transform } = calcToolbarPos(rect, parentScroll, measuredW);
8872
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
9185
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
8873
9186
  "div",
8874
9187
  {
8875
9188
  ref: setRefs,
@@ -8881,12 +9194,12 @@ function FloatingToolbar({
8881
9194
  zIndex: 2147483647,
8882
9195
  pointerEvents: "auto"
8883
9196
  },
8884
- children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(CustomToolbar, { children: [
8885
- TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_react9.default.Fragment, { children: [
8886
- gi > 0 && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(CustomToolbarDivider, {}),
9197
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(CustomToolbar, { children: [
9198
+ TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_react9.default.Fragment, { children: [
9199
+ gi > 0 && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CustomToolbarDivider, {}),
8887
9200
  btns.map((btn) => {
8888
9201
  const isActive = activeCommands.has(btn.cmd);
8889
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
9202
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
8890
9203
  CustomToolbarButton,
8891
9204
  {
8892
9205
  title: btn.title,
@@ -8895,7 +9208,7 @@ function FloatingToolbar({
8895
9208
  e.preventDefault();
8896
9209
  onCommand(btn.cmd);
8897
9210
  },
8898
- children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
9211
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
8899
9212
  "svg",
8900
9213
  {
8901
9214
  width: "16",
@@ -8916,7 +9229,7 @@ function FloatingToolbar({
8916
9229
  );
8917
9230
  })
8918
9231
  ] }, gi)),
8919
- showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
9232
+ showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
8920
9233
  CustomToolbarButton,
8921
9234
  {
8922
9235
  type: "button",
@@ -8930,7 +9243,7 @@ function FloatingToolbar({
8930
9243
  e.preventDefault();
8931
9244
  e.stopPropagation();
8932
9245
  },
8933
- children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Link, { className: "size-4 shrink-0", "aria-hidden": true })
9246
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Link, { className: "size-4 shrink-0", "aria-hidden": true })
8934
9247
  }
8935
9248
  ) : null
8936
9249
  ] })
@@ -8947,7 +9260,7 @@ function StateToggle({
8947
9260
  states,
8948
9261
  onStateChange
8949
9262
  }) {
8950
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
9263
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
8951
9264
  ToggleGroup,
8952
9265
  {
8953
9266
  "data-ohw-state-toggle": "",
@@ -8961,7 +9274,7 @@ function StateToggle({
8961
9274
  left: rect.right - 8,
8962
9275
  transform: "translateX(-100%)"
8963
9276
  },
8964
- children: states.map((state) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
9277
+ children: states.map((state) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
8965
9278
  }
8966
9279
  );
8967
9280
  }
@@ -9456,6 +9769,18 @@ function OhhwellsBridge() {
9456
9769
  intent: "add-nav"
9457
9770
  });
9458
9771
  }, []);
9772
+ const handleAddFooterColumn = (0, import_react9.useCallback)(() => {
9773
+ deselectRef.current();
9774
+ deactivateRef.current();
9775
+ const result = addFooterColumnWithPersist({ postToParent: postToParent2 });
9776
+ editContentRef.current = {
9777
+ ...editContentRef.current,
9778
+ ...buildFooterColumnEditContentPatch(result)
9779
+ };
9780
+ requestAnimationFrame(() => {
9781
+ selectRef.current(result.firstLink);
9782
+ });
9783
+ }, [postToParent2]);
9459
9784
  const clearFooterDragVisuals = (0, import_react9.useCallback)(() => {
9460
9785
  footerDragRef.current = null;
9461
9786
  setSiblingHintRects([]);
@@ -9780,7 +10105,7 @@ function OhhwellsBridge() {
9780
10105
  const selectFrame = (0, import_react9.useCallback)((el) => {
9781
10106
  if (!isNavigationContainer(el)) return;
9782
10107
  if (activeElRef.current) deactivate();
9783
- const isFooterColumn = el.hasAttribute("data-ohw-footer-col") || Boolean(el.closest("footer") && isInferredFooterGroup(el));
10108
+ const isFooterColumn = !isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || Boolean(el.closest("footer") && isInferredFooterGroup(el)));
9784
10109
  selectedElRef.current = el;
9785
10110
  selectedHrefKeyRef.current = null;
9786
10111
  selectedFooterColAttrRef.current = isFooterColumn ? el.getAttribute("data-ohw-footer-col") ?? String(listFooterColumns().indexOf(el)) : null;
@@ -10335,7 +10660,7 @@ function OhhwellsBridge() {
10335
10660
  }
10336
10661
  e.preventDefault();
10337
10662
  e.stopPropagation();
10338
- activateRef.current(editable);
10663
+ activateRef.current(editable, { caretX: e.clientX, caretY: e.clientY });
10339
10664
  return;
10340
10665
  }
10341
10666
  const hrefAnchor = getNavigationItemAnchor(target);
@@ -10362,6 +10687,18 @@ function OhhwellsBridge() {
10362
10687
  selectFrameRef.current(footerColClick);
10363
10688
  return;
10364
10689
  }
10690
+ const footerLinksToSelect = resolveFooterLinksContainerSelectionTarget(
10691
+ target,
10692
+ e.clientX,
10693
+ e.clientY,
10694
+ isPointOverNavItem
10695
+ );
10696
+ if (footerLinksToSelect) {
10697
+ e.preventDefault();
10698
+ e.stopPropagation();
10699
+ selectFrameRef.current(footerLinksToSelect);
10700
+ return;
10701
+ }
10365
10702
  const navContainerToSelect = resolveNavContainerSelectionTarget(target, e.clientX, e.clientY);
10366
10703
  if (navContainerToSelect) {
10367
10704
  e.preventDefault();
@@ -10420,8 +10757,8 @@ function OhhwellsBridge() {
10420
10757
  return;
10421
10758
  }
10422
10759
  const navLabel = getNavigationLabelEditable(target);
10423
- if (!navLabel) return;
10424
- const { editable } = navLabel;
10760
+ const editable = navLabel?.editable ?? target.closest('[data-ohw-editable="text"], [data-ohw-editable="plain"]');
10761
+ if (!editable || isMediaEditable(editable) || editable.dataset.ohwEditable === "link") return;
10425
10762
  e.preventDefault();
10426
10763
  e.stopPropagation();
10427
10764
  if (activeElRef.current !== editable) {
@@ -10442,16 +10779,38 @@ function OhhwellsBridge() {
10442
10779
  setHoveredNavContainerRect(null);
10443
10780
  return;
10444
10781
  }
10445
- if (toolbarVariantRef.current !== "select-frame") {
10446
- const navContainer = target.closest("[data-ohw-nav-container]");
10447
- if (navContainer && !getNavigationItemAnchor(target)) {
10448
- hoveredNavContainerRef.current = navContainer;
10449
- setHoveredNavContainerRect(navContainer.getBoundingClientRect());
10450
- hoveredItemElRef.current = null;
10451
- setHoveredItemRect(null);
10452
- return;
10782
+ {
10783
+ const selected2 = selectedElRef.current;
10784
+ const selectedIsFooterColumn = Boolean(selected2) && !isFooterLinksContainer(selected2) && (selected2.hasAttribute("data-ohw-footer-col") || selected2.hasAttribute("data-ohw-footer-column") || Boolean(selected2.closest("footer") && isInferredFooterGroup(selected2)));
10785
+ const allowNavContainerHover = toolbarVariantRef.current !== "select-frame";
10786
+ const allowFooterLinksHover = toolbarVariantRef.current !== "select-frame" || selectedIsFooterColumn;
10787
+ if (allowNavContainerHover) {
10788
+ const navContainer = target.closest("[data-ohw-nav-container]");
10789
+ if (navContainer && !getNavigationItemAnchor(target)) {
10790
+ hoveredNavContainerRef.current = navContainer;
10791
+ setHoveredNavContainerRect(navContainer.getBoundingClientRect());
10792
+ hoveredItemElRef.current = null;
10793
+ setHoveredItemRect(null);
10794
+ return;
10795
+ }
10453
10796
  }
10454
- if (!target.closest("[data-ohw-nav-container]")) {
10797
+ if (allowFooterLinksHover) {
10798
+ const navContainer = target.closest("[data-ohw-nav-container]");
10799
+ if (!navContainer) {
10800
+ const footerLinks = target.closest("[data-ohw-footer-links], .rb-footer-links") ?? null;
10801
+ if (footerLinks && selected2 !== footerLinks && !getNavigationItemAnchor(target) && !target.closest("[data-ohw-footer-col], [data-ohw-footer-column]")) {
10802
+ hoveredNavContainerRef.current = footerLinks;
10803
+ setHoveredNavContainerRect(footerLinks.getBoundingClientRect());
10804
+ hoveredItemElRef.current = null;
10805
+ setHoveredItemRect(null);
10806
+ return;
10807
+ }
10808
+ if (!footerLinks) {
10809
+ hoveredNavContainerRef.current = null;
10810
+ setHoveredNavContainerRect(null);
10811
+ }
10812
+ }
10813
+ } else if (toolbarVariantRef.current === "select-frame") {
10455
10814
  hoveredNavContainerRef.current = null;
10456
10815
  setHoveredNavContainerRect(null);
10457
10816
  }
@@ -10493,9 +10852,9 @@ function OhhwellsBridge() {
10493
10852
  };
10494
10853
  const handleMouseOut = (e) => {
10495
10854
  const target = e.target;
10496
- if (target.closest("[data-ohw-nav-container], [data-ohw-footer-col], [data-ohw-footer-column]")) {
10855
+ if (target.closest("[data-ohw-nav-container], [data-ohw-footer-col], [data-ohw-footer-column], [data-ohw-footer-links], .rb-footer-links")) {
10497
10856
  const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
10498
- if (related2?.closest("[data-ohw-nav-container], [data-ohw-footer-col], [data-ohw-footer-column], [data-ohw-navbar-container-chrome], [data-ohw-navbar-add-button]")) {
10857
+ if (related2?.closest("[data-ohw-nav-container], [data-ohw-footer-col], [data-ohw-footer-column], [data-ohw-footer-links], .rb-footer-links, [data-ohw-navbar-container-chrome], [data-ohw-navbar-add-button], [data-ohw-footer-container-chrome], [data-ohw-footer-add-button]")) {
10499
10858
  return;
10500
10859
  }
10501
10860
  hoveredNavContainerRef.current = null;
@@ -10590,6 +10949,15 @@ function OhhwellsBridge() {
10590
10949
  if (track) track.setAttribute("data-ohw-hover-paused", "");
10591
10950
  };
10592
10951
  const clearImageHover = () => setMediaHover(null);
10952
+ const dismissImageHover = () => {
10953
+ if (hoveredImageRef.current) {
10954
+ hoveredImageRef.current = null;
10955
+ hoveredImageHasTextOverlapRef.current = false;
10956
+ resumeAnimTracks();
10957
+ postToParentRef.current({ type: "ow:image-unhover" });
10958
+ }
10959
+ clearImageHover();
10960
+ };
10593
10961
  const findImageAtPoint = (clientX, clientY, fromParentViewport) => {
10594
10962
  const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
10595
10963
  const images = Array.from(document.querySelectorAll(MEDIA_SELECTOR));
@@ -10633,16 +11001,13 @@ function OhhwellsBridge() {
10633
11001
  }
10634
11002
  return smallest;
10635
11003
  };
10636
- const dismissImageHover = () => {
10637
- if (hoveredImageRef.current) {
10638
- hoveredImageRef.current = null;
10639
- hoveredImageHasTextOverlapRef.current = false;
10640
- resumeAnimTracks();
10641
- postToParentRef.current({ type: "ow:image-unhover" });
10642
- }
10643
- };
10644
11004
  const probeNavigationHoverAt = (x, y) => {
10645
- if (toolbarVariantRef.current === "select-frame") {
11005
+ const selected = selectedElRef.current;
11006
+ const selectedIsFooterColumn = Boolean(selected) && !isFooterLinksContainer(selected) && (selected.hasAttribute("data-ohw-footer-col") || selected.hasAttribute("data-ohw-footer-column") || Boolean(selected.closest("footer") && isInferredFooterGroup(selected)));
11007
+ const selectedIsFooterLinks = Boolean(selected && isFooterLinksContainer(selected));
11008
+ const allowNavContainerHover = toolbarVariantRef.current !== "select-frame";
11009
+ const allowFooterLinksHover = (toolbarVariantRef.current !== "select-frame" || selectedIsFooterColumn) && !selectedIsFooterLinks;
11010
+ if (toolbarVariantRef.current === "select-frame" && !allowFooterLinksHover) {
10646
11011
  hoveredNavContainerRef.current = null;
10647
11012
  setHoveredNavContainerRect(null);
10648
11013
  }
@@ -10664,7 +11029,6 @@ function OhhwellsBridge() {
10664
11029
  if (navItemHit) {
10665
11030
  hoveredNavContainerRef.current = null;
10666
11031
  setHoveredNavContainerRect(null);
10667
- const selected = selectedElRef.current;
10668
11032
  if (selected !== navItemHit) {
10669
11033
  clearHrefKeyHover(navItemHit);
10670
11034
  hoveredItemElRef.current = navItemHit;
@@ -10676,7 +11040,7 @@ function OhhwellsBridge() {
10676
11040
  return;
10677
11041
  }
10678
11042
  }
10679
- if (toolbarVariantRef.current !== "select-frame") {
11043
+ if (allowNavContainerHover) {
10680
11044
  for (const container of navContainers) {
10681
11045
  const containerRect = container.getBoundingClientRect();
10682
11046
  const overContainer = x >= containerRect.left && x <= containerRect.right && y >= containerRect.top && y <= containerRect.bottom;
@@ -10688,12 +11052,23 @@ function OhhwellsBridge() {
10688
11052
  setHoveredItemRect(null);
10689
11053
  return;
10690
11054
  }
10691
- hoveredNavContainerRef.current = null;
10692
- setHoveredNavContainerRect(null);
10693
- } else {
10694
- hoveredNavContainerRef.current = null;
10695
- setHoveredNavContainerRect(null);
10696
11055
  }
11056
+ if (allowFooterLinksHover) {
11057
+ const footerLinks = getFooterLinksContainer();
11058
+ if (footerLinks) {
11059
+ const containerRect = footerLinks.getBoundingClientRect();
11060
+ const overContainer = x >= containerRect.left && x <= containerRect.right && y >= containerRect.top && y <= containerRect.bottom;
11061
+ if (overContainer && !isPointOverNavItem(footerLinks, x, y) && !isPointOverFooterColumn(x, y)) {
11062
+ hoveredNavContainerRef.current = footerLinks;
11063
+ setHoveredNavContainerRect(footerLinks.getBoundingClientRect());
11064
+ hoveredItemElRef.current = null;
11065
+ setHoveredItemRect(null);
11066
+ return;
11067
+ }
11068
+ }
11069
+ }
11070
+ hoveredNavContainerRef.current = null;
11071
+ setHoveredNavContainerRect(null);
10697
11072
  for (const column of footerColumns) {
10698
11073
  const containerRect = column.getBoundingClientRect();
10699
11074
  const overContainer = x >= containerRect.left && x <= containerRect.right && y >= containerRect.top && y <= containerRect.bottom;
@@ -11200,6 +11575,7 @@ function OhhwellsBridge() {
11200
11575
  }
11201
11576
  editContentRef.current = { ...editContentRef.current, ...content };
11202
11577
  reconcileNavbarItemsFromContent(editContentRef.current);
11578
+ reconcileFooterOrderFromContent(editContentRef.current);
11203
11579
  syncNavigationDragCursorAttrs();
11204
11580
  enforceLinkHrefs();
11205
11581
  postToParentRef.current({ type: "ow:hydrate-done" });
@@ -11254,6 +11630,11 @@ function OhhwellsBridge() {
11254
11630
  }
11255
11631
  if (selectedElRef.current) {
11256
11632
  if (toolbarVariantRef.current === "select-frame") {
11633
+ const parent2 = getNavigationSelectionParent(selectedElRef.current);
11634
+ if (parent2 && isNavigationContainer(parent2) && isFooterLinksContainer(parent2) && !isFooterLinksContainer(selectedElRef.current)) {
11635
+ selectFrameRef.current(parent2);
11636
+ return;
11637
+ }
11257
11638
  deselectRef.current();
11258
11639
  return;
11259
11640
  }
@@ -11269,13 +11650,10 @@ function OhhwellsBridge() {
11269
11650
  const handleKeyDown = (e) => {
11270
11651
  if (e.key === "Escape" && document.querySelector("[data-ohw-section-picker]")) return;
11271
11652
  if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "a" && activeElRef.current) {
11272
- const navAnchor = getNavigationItemAnchor(activeElRef.current);
11273
- if (navAnchor) {
11274
- e.preventDefault();
11275
- selectAllTextInEditable(activeElRef.current);
11276
- refreshActiveCommandsRef.current();
11277
- return;
11278
- }
11653
+ e.preventDefault();
11654
+ selectAllTextInEditable(activeElRef.current);
11655
+ refreshActiveCommandsRef.current();
11656
+ return;
11279
11657
  }
11280
11658
  if (e.key === "Escape" && linkPopoverOpenRef.current) {
11281
11659
  setLinkPopoverRef.current(null);
@@ -11283,6 +11661,12 @@ function OhhwellsBridge() {
11283
11661
  }
11284
11662
  if (e.key === "Escape" && selectedElRef.current && !activeElRef.current) {
11285
11663
  if (toolbarVariantRef.current === "select-frame") {
11664
+ const parent2 = getNavigationSelectionParent(selectedElRef.current);
11665
+ if (parent2 && isNavigationContainer(parent2) && isFooterLinksContainer(parent2) && !isFooterLinksContainer(selectedElRef.current)) {
11666
+ e.preventDefault();
11667
+ selectFrameRef.current(parent2);
11668
+ return;
11669
+ }
11286
11670
  deselectRef.current();
11287
11671
  return;
11288
11672
  }
@@ -12069,9 +12453,9 @@ function OhhwellsBridge() {
12069
12453
  [postToParent2]
12070
12454
  );
12071
12455
  return bridgeRoot ? (0, import_react_dom3.createPortal)(
12072
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
12073
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
12074
- Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
12456
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
12457
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
12458
+ Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
12075
12459
  MediaOverlay,
12076
12460
  {
12077
12461
  hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
@@ -12082,7 +12466,7 @@ function OhhwellsBridge() {
12082
12466
  },
12083
12467
  `uploading-${key}`
12084
12468
  )),
12085
- mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
12469
+ mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
12086
12470
  MediaOverlay,
12087
12471
  {
12088
12472
  hover: mediaHover,
@@ -12091,10 +12475,10 @@ function OhhwellsBridge() {
12091
12475
  onVideoSettingsChange: handleVideoSettingsChange
12092
12476
  }
12093
12477
  ),
12094
- siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
12095
- siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
12096
- isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
12097
- isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
12478
+ siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
12479
+ siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
12480
+ isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
12481
+ isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
12098
12482
  "div",
12099
12483
  {
12100
12484
  className: "pointer-events-none fixed z-2147483646",
@@ -12104,7 +12488,7 @@ function OhhwellsBridge() {
12104
12488
  width: slot.width,
12105
12489
  height: slot.height
12106
12490
  },
12107
- children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
12491
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
12108
12492
  DropIndicator,
12109
12493
  {
12110
12494
  direction: slot.direction,
@@ -12115,7 +12499,7 @@ function OhhwellsBridge() {
12115
12499
  },
12116
12500
  `footer-drop-${slot.direction}-${slot.columnIndex}-${slot.insertIndex}-${i}`
12117
12501
  )),
12118
- isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
12502
+ isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
12119
12503
  "div",
12120
12504
  {
12121
12505
  className: "pointer-events-none fixed z-2147483646",
@@ -12125,7 +12509,7 @@ function OhhwellsBridge() {
12125
12509
  width: slot.width,
12126
12510
  height: slot.height
12127
12511
  },
12128
- children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
12512
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
12129
12513
  DropIndicator,
12130
12514
  {
12131
12515
  direction: slot.direction,
@@ -12136,10 +12520,11 @@ function OhhwellsBridge() {
12136
12520
  },
12137
12521
  `nav-drop-${slot.direction}-${slot.parentId ?? "root"}-${slot.insertIndex}-${i}`
12138
12522
  )),
12139
- hoveredNavContainerRect && toolbarVariant !== "select-frame" && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
12140
- hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
12141
- toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
12142
- toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame") && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
12523
+ hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
12524
+ hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
12525
+ toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
12526
+ toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(FooterContainerChrome, { rect: toolbarRect, onAdd: handleAddFooterColumn }),
12527
+ toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame") && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
12143
12528
  ItemInteractionLayer,
12144
12529
  {
12145
12530
  rect: isItemDragging && draggedItemRect && (footerDragRef.current?.wasSelected || navDragRef.current?.wasSelected) ? draggedItemRect : toolbarRect,
@@ -12153,7 +12538,7 @@ function OhhwellsBridge() {
12153
12538
  onItemPointerDown: handleItemChromePointerDown,
12154
12539
  onItemClick: handleItemChromeClick,
12155
12540
  itemDragSurface: !isFooterFrameSelection,
12156
- toolbar: toolbarVariant === "link-action" && !isItemDragging ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
12541
+ toolbar: toolbarVariant === "link-action" && !isItemDragging ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
12157
12542
  ItemActionToolbar,
12158
12543
  {
12159
12544
  onEditLink: openLinkPopoverForSelected,
@@ -12166,8 +12551,8 @@ function OhhwellsBridge() {
12166
12551
  ) : void 0
12167
12552
  }
12168
12553
  ),
12169
- toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
12170
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
12554
+ toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
12555
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
12171
12556
  EditGlowChrome,
12172
12557
  {
12173
12558
  rect: toolbarRect,
@@ -12177,7 +12562,7 @@ function OhhwellsBridge() {
12177
12562
  hideHandle: isItemDragging
12178
12563
  }
12179
12564
  ),
12180
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
12565
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
12181
12566
  FloatingToolbar,
12182
12567
  {
12183
12568
  rect: toolbarRect,
@@ -12190,7 +12575,7 @@ function OhhwellsBridge() {
12190
12575
  }
12191
12576
  )
12192
12577
  ] }),
12193
- maxBadge && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
12578
+ maxBadge && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
12194
12579
  "div",
12195
12580
  {
12196
12581
  "data-ohw-max-badge": "",
@@ -12216,7 +12601,7 @@ function OhhwellsBridge() {
12216
12601
  ]
12217
12602
  }
12218
12603
  ),
12219
- toggleState && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
12604
+ toggleState && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
12220
12605
  StateToggle,
12221
12606
  {
12222
12607
  rect: toggleState.rect,
@@ -12225,15 +12610,15 @@ function OhhwellsBridge() {
12225
12610
  onStateChange: handleStateChange
12226
12611
  }
12227
12612
  ),
12228
- sectionGap && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
12613
+ sectionGap && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
12229
12614
  "div",
12230
12615
  {
12231
12616
  "data-ohw-section-insert-line": "",
12232
12617
  className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
12233
12618
  style: { top: sectionGap.y, transform: "translateY(-50%)" },
12234
12619
  children: [
12235
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
12236
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
12620
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
12621
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
12237
12622
  Badge,
12238
12623
  {
12239
12624
  className: "px-8 py-1 bg-primary hover:bg-primary text-primary-foreground text-xs font-medium shrink-0 rounded-full cursor-pointer pointer-events-auto",
@@ -12250,11 +12635,11 @@ function OhhwellsBridge() {
12250
12635
  children: "Add Section"
12251
12636
  }
12252
12637
  ),
12253
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
12638
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
12254
12639
  ]
12255
12640
  }
12256
12641
  ),
12257
- linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
12642
+ linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
12258
12643
  LinkPopover,
12259
12644
  {
12260
12645
  panelRef: linkPopoverPanelRef,