@ohhwells/bridge 0.1.117-next.323 → 0.1.117-next.324

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
@@ -10155,6 +10155,14 @@ function setMediaStripItemAsset(tree, index, assetId) {
10155
10155
  return true;
10156
10156
  });
10157
10157
  }
10158
+ function setMediaStripItemAlt(tree, index, alt) {
10159
+ return withMediaStrip(tree, (block) => {
10160
+ const items = block.items;
10161
+ if (index < 0 || index >= items.length) return false;
10162
+ items[index] = { ...items[index], alt };
10163
+ return true;
10164
+ });
10165
+ }
10158
10166
 
10159
10167
  // src/ui/ai-section/AiMediaStripOverlay.tsx
10160
10168
  var import_jsx_runtime18 = require("react/jsx-runtime");
@@ -10273,6 +10281,74 @@ function Pill({
10273
10281
  }
10274
10282
  );
10275
10283
  }
10284
+ function AltInput({ value, onCommit }) {
10285
+ const [draft, setDraft] = (0, import_react9.useState)(value);
10286
+ (0, import_react9.useEffect)(() => setDraft(value), [value]);
10287
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
10288
+ "div",
10289
+ {
10290
+ style: {
10291
+ display: "flex",
10292
+ alignItems: "center",
10293
+ gap: 6,
10294
+ height: 28,
10295
+ padding: "0 12px",
10296
+ borderRadius: 999,
10297
+ background: "#ffffff",
10298
+ width: "100%",
10299
+ maxWidth: 260,
10300
+ boxSizing: "border-box"
10301
+ },
10302
+ children: [
10303
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
10304
+ "span",
10305
+ {
10306
+ style: {
10307
+ flex: "0 0 auto",
10308
+ color: OHW_BLUE_DARK,
10309
+ fontSize: 10,
10310
+ fontWeight: 700,
10311
+ textTransform: "uppercase",
10312
+ letterSpacing: 0.4
10313
+ },
10314
+ children: "Alt"
10315
+ }
10316
+ ),
10317
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
10318
+ "input",
10319
+ {
10320
+ type: "text",
10321
+ value: draft,
10322
+ onChange: (e) => setDraft(e.target.value),
10323
+ onBlur: () => {
10324
+ if (draft !== value) onCommit(draft);
10325
+ },
10326
+ onKeyDown: (e) => {
10327
+ if (e.key === "Enter") e.currentTarget.blur();
10328
+ if (e.key === "Escape") {
10329
+ setDraft(value);
10330
+ e.currentTarget.blur();
10331
+ }
10332
+ },
10333
+ placeholder: "Describe this image",
10334
+ "aria-label": "Image alt text",
10335
+ style: {
10336
+ flex: 1,
10337
+ minWidth: 0,
10338
+ border: "none",
10339
+ outline: "none",
10340
+ background: "transparent",
10341
+ fontSize: 12,
10342
+ lineHeight: "16px",
10343
+ fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
10344
+ color: "#1f2937"
10345
+ }
10346
+ }
10347
+ )
10348
+ ]
10349
+ }
10350
+ );
10351
+ }
10276
10352
  var VARIANTS = [
10277
10353
  { value: "logos", label: "Logos" },
10278
10354
  { value: "reel", label: "Reel" }
@@ -10302,6 +10378,7 @@ function MediaStripToolbar({
10302
10378
  onSetHover,
10303
10379
  onSetTreatment,
10304
10380
  onResize,
10381
+ onSetAlt,
10305
10382
  onAddItem,
10306
10383
  onRemoveItem,
10307
10384
  onChangeImage,
@@ -10310,13 +10387,24 @@ function MediaStripToolbar({
10310
10387
  }) {
10311
10388
  const items = mediaStripItems(entry.tree);
10312
10389
  const itemCount = items.length;
10390
+ const currentAlt = items[index]?.alt ?? "";
10313
10391
  const slots = findMediaStripSlots(entry.tree);
10314
10392
  const variant = slots?.variant === "reel" ? "reel" : "logos";
10315
10393
  const align = slots?.align === "left" || slots?.align === "right" ? slots.align : "center";
10316
10394
  const hover = slots?.hover === "none" || slots?.hover === "lift" || slots?.hover === "zoom" || slots?.hover === "fade" ? slots.hover : "none";
10317
10395
  const treatment = slots?.treatment === "color" || slots?.treatment === "grayscale" ? slots.treatment : variant === "logos" ? "grayscale" : "color";
10318
10396
  const sizeValue = variant === "logos" ? typeof slots?.logoMaxHeight === "number" ? slots.logoMaxHeight : 48 : typeof slots?.cardWidth === "number" ? slots.cardWidth : 240;
10319
- const pillWrap = window.innerWidth <= 480 ? "wrap" : "nowrap";
10397
+ const isMobile = window.innerWidth <= 480;
10398
+ const rowStyle = isMobile ? {
10399
+ display: "flex",
10400
+ gap: 6,
10401
+ flexWrap: "nowrap",
10402
+ justifyContent: "center",
10403
+ overflowX: "auto",
10404
+ WebkitOverflowScrolling: "touch",
10405
+ width: "100%",
10406
+ scrollbarWidth: "none"
10407
+ } : { display: "flex", gap: 6, flexWrap: "nowrap", justifyContent: "center" };
10320
10408
  return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
10321
10409
  "div",
10322
10410
  {
@@ -10334,14 +10422,14 @@ function MediaStripToolbar({
10334
10422
  boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
10335
10423
  pointerEvents: pending ? "none" : "auto",
10336
10424
  opacity: pending ? 0.6 : 1,
10337
- maxWidth: pillWrap === "wrap" ? "calc(100vw - 24px)" : "none"
10425
+ maxWidth: isMobile ? "calc(100vw - 24px)" : "none"
10338
10426
  },
10339
10427
  children: [
10340
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { display: "flex", gap: 6, flexWrap: pillWrap, justifyContent: "center" }, children: [
10428
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: rowStyle, children: [
10341
10429
  VARIANTS.map((v) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Pill, { label: v.label, active: variant === v.value, onClick: () => onSetVariant(v.value) }, v.value)),
10342
10430
  ALIGNS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Pill, { label: a.label, active: align === a.value, onClick: () => onSetAlign(a.value) }, a.value))
10343
10431
  ] }),
10344
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { display: "flex", gap: 6, flexWrap: pillWrap, justifyContent: "center" }, children: [
10432
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: rowStyle, children: [
10345
10433
  HOVERS.map((h) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Pill, { label: h.label, active: hover === h.value, onClick: () => onSetHover(h.value) }, h.value)),
10346
10434
  TREATMENTS.map((t) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Pill, { label: t.label, active: treatment === t.value, onClick: () => onSetTreatment(t.value) }, t.value))
10347
10435
  ] }),
@@ -10353,10 +10441,13 @@ function MediaStripToolbar({
10353
10441
  ] }),
10354
10442
  /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Pill, { label: "+", onClick: () => onResize(8) })
10355
10443
  ] }),
10356
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { display: "flex", gap: 6, flexWrap: pillWrap, justifyContent: "center" }, children: [
10444
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { display: "flex", justifyContent: "center", width: "100%" }, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(AltInput, { value: currentAlt, onCommit: onSetAlt }) }),
10445
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: rowStyle, children: [
10357
10446
  /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Pill, { label: "Change Image", onClick: onChangeImage }),
10358
10447
  /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Pill, { label: "+ Item", onClick: onAddItem }),
10359
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Pill, { label: "\u2212 Item", onClick: onRemoveItem, disabled: itemCount <= 1 }),
10448
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Pill, { label: "\u2212 Item", onClick: onRemoveItem, disabled: itemCount <= 1 })
10449
+ ] }),
10450
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: rowStyle, children: [
10360
10451
  /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Pill, { label: "\u2190 Move", onClick: onMoveLeft, disabled: index <= 0 }),
10361
10452
  /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Pill, { label: "\u2192 Move", onClick: onMoveRight, disabled: index >= itemCount - 1 })
10362
10453
  ] }),
@@ -10377,7 +10468,8 @@ function findMediaStripSlots(tree) {
10377
10468
  function AiMediaStripOverlay({
10378
10469
  postToParent: postToParent2,
10379
10470
  aiSectionsRef,
10380
- applyTreeLocalRef
10471
+ applyTreeLocalRef,
10472
+ clearInteractionChromeRef
10381
10473
  }) {
10382
10474
  const [hover, setHover] = (0, import_react9.useState)(null);
10383
10475
  const [active, setActive] = (0, import_react9.useState)(null);
@@ -10494,7 +10586,10 @@ function AiMediaStripOverlay({
10494
10586
  {
10495
10587
  type: "button",
10496
10588
  "data-ohw-toolbar": "",
10497
- onClick: () => setActive(hover),
10589
+ onClick: () => {
10590
+ clearInteractionChromeRef.current();
10591
+ setActive(hover);
10592
+ },
10498
10593
  "aria-label": "Configure media item",
10499
10594
  style: {
10500
10595
  position: "fixed",
@@ -10539,6 +10634,9 @@ function AiMediaStripOverlay({
10539
10634
  const current = variant === "logos" ? typeof slots?.logoMaxHeight === "number" ? slots.logoMaxHeight : 48 : typeof slots?.cardWidth === "number" ? slots.cardWidth : 240;
10540
10635
  void runMutation(active.sectionId, (tree) => setMediaStripSizing(tree, current + delta));
10541
10636
  },
10637
+ onSetAlt: (alt) => {
10638
+ void runMutation(active.sectionId, (tree) => setMediaStripItemAlt(tree, active.index, alt));
10639
+ },
10542
10640
  onAddItem: () => {
10543
10641
  void requestAssetPick(postToParent2).then((picked) => {
10544
10642
  if (!picked) return;
@@ -20547,6 +20645,8 @@ function OhhwellsBridge() {
20547
20645
  const addNavAfterAnchorRef = (0, import_react18.useRef)(null);
20548
20646
  const editContentRef = (0, import_react18.useRef)({});
20549
20647
  const aiSectionsRef = (0, import_react18.useRef)("");
20648
+ const clearInteractionChromeRef = (0, import_react18.useRef)(() => {
20649
+ });
20550
20650
  const brandKitRef = (0, import_react18.useRef)("");
20551
20651
  const stylesRef = (0, import_react18.useRef)("");
20552
20652
  const appliedDrawerRef = (0, import_react18.useRef)(null);
@@ -24660,6 +24760,7 @@ function OhhwellsBridge() {
24660
24760
  deselectRef.current();
24661
24761
  clearMediaSelectionRef.current();
24662
24762
  };
24763
+ clearInteractionChromeRef.current = clearInteractionChrome;
24663
24764
  const applyTreeToLocalState = (payload) => {
24664
24765
  clearInteractionChrome();
24665
24766
  const previous = aiSectionsRef.current;
@@ -26550,7 +26651,8 @@ function OhhwellsBridge() {
26550
26651
  {
26551
26652
  postToParent: postToParent2,
26552
26653
  aiSectionsRef,
26553
- applyTreeLocalRef
26654
+ applyTreeLocalRef,
26655
+ clearInteractionChromeRef
26554
26656
  }
26555
26657
  ),
26556
26658
  isSectionDragging && sectionDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(