@ohhwells/bridge 0.1.38-next.58 → 0.1.38-next.59

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
@@ -57,12 +57,13 @@ __export(index_exports, {
57
57
  isValidUrl: () => isValidUrl,
58
58
  parseTarget: () => parseTarget,
59
59
  toggleVariants: () => toggleVariants,
60
+ useOhwCarousel: () => useOhwCarousel,
60
61
  validateUrlInput: () => validateUrlInput
61
62
  });
62
63
  module.exports = __toCommonJS(index_exports);
63
64
 
64
65
  // src/OhhwellsBridge.tsx
65
- var import_react8 = __toESM(require("react"), 1);
66
+ var import_react9 = __toESM(require("react"), 1);
66
67
  var import_client = require("react-dom/client");
67
68
  var import_react_dom2 = require("react-dom");
68
69
 
@@ -4861,6 +4862,61 @@ function MediaOverlay({
4861
4862
  ] });
4862
4863
  }
4863
4864
 
4865
+ // src/ui/CarouselOverlay.tsx
4866
+ var import_lucide_react4 = require("lucide-react");
4867
+ var import_jsx_runtime12 = require("react/jsx-runtime");
4868
+ var OVERLAY_BUTTON_STYLE2 = {
4869
+ pointerEvents: "auto",
4870
+ fontFamily: "Inter, sans-serif",
4871
+ fontSize: 12,
4872
+ color: "#000"
4873
+ };
4874
+ function CarouselOverlay({
4875
+ hover,
4876
+ onEdit
4877
+ }) {
4878
+ const { rect } = hover;
4879
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4880
+ "div",
4881
+ {
4882
+ "data-ohw-bridge": "",
4883
+ "data-ohw-carousel-overlay": "",
4884
+ className: "flex cursor-pointer items-center justify-center",
4885
+ style: {
4886
+ position: "fixed",
4887
+ top: rect.top,
4888
+ left: rect.left,
4889
+ width: rect.width,
4890
+ height: rect.height,
4891
+ zIndex: 2147483646,
4892
+ pointerEvents: "auto",
4893
+ boxShadow: "inset 0 0 0 1.5px var(--color-primary)",
4894
+ background: "color-mix(in srgb, var(--color-primary) 20%, transparent)"
4895
+ },
4896
+ onClick: () => onEdit(hover.key),
4897
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
4898
+ Button,
4899
+ {
4900
+ "data-ohw-carousel-overlay": "",
4901
+ variant: "outline",
4902
+ size: "sm",
4903
+ className: "cursor-pointer gap-1.5 hover:bg-background",
4904
+ style: OVERLAY_BUTTON_STYLE2,
4905
+ onMouseDown: (e) => e.preventDefault(),
4906
+ onClick: (e) => {
4907
+ e.stopPropagation();
4908
+ onEdit(hover.key);
4909
+ },
4910
+ children: [
4911
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react4.GalleryHorizontal, { size: 14 }),
4912
+ "Edit gallery"
4913
+ ]
4914
+ }
4915
+ )
4916
+ }
4917
+ );
4918
+ }
4919
+
4864
4920
  // src/OhhwellsBridge.tsx
4865
4921
  var import_react_dom3 = require("react-dom");
4866
4922
  var import_navigation2 = require("next/navigation");
@@ -5145,23 +5201,23 @@ var import_react7 = require("react");
5145
5201
  // src/ui/dialog.tsx
5146
5202
  var React7 = __toESM(require("react"), 1);
5147
5203
  var import_radix_ui5 = require("radix-ui");
5148
- var import_lucide_react4 = require("lucide-react");
5149
- var import_jsx_runtime12 = require("react/jsx-runtime");
5204
+ var import_lucide_react5 = require("lucide-react");
5205
+ var import_jsx_runtime13 = require("react/jsx-runtime");
5150
5206
  function Dialog2({
5151
5207
  ...props
5152
5208
  }) {
5153
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_radix_ui5.Dialog.Root, { "data-slot": "dialog", ...props });
5209
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_radix_ui5.Dialog.Root, { "data-slot": "dialog", ...props });
5154
5210
  }
5155
5211
  function DialogPortal({
5156
5212
  ...props
5157
5213
  }) {
5158
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_radix_ui5.Dialog.Portal, { ...props });
5214
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_radix_ui5.Dialog.Portal, { ...props });
5159
5215
  }
5160
5216
  function DialogOverlay({
5161
5217
  className,
5162
5218
  ...props
5163
5219
  }) {
5164
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
5220
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5165
5221
  import_radix_ui5.Dialog.Overlay,
5166
5222
  {
5167
5223
  "data-slot": "dialog-overlay",
@@ -5174,9 +5230,9 @@ function DialogOverlay({
5174
5230
  var DialogContent = React7.forwardRef(
5175
5231
  ({ className, children, showCloseButton = true, container, ...props }, ref) => {
5176
5232
  const positionMode = container ? "absolute" : "fixed";
5177
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(DialogPortal, { container: container ?? void 0, children: [
5178
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(DialogOverlay, { className: cn(positionMode, "inset-0") }),
5179
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
5233
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(DialogPortal, { container: container ?? void 0, children: [
5234
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DialogOverlay, { className: cn(positionMode, "inset-0") }),
5235
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
5180
5236
  import_radix_ui5.Dialog.Content,
5181
5237
  {
5182
5238
  ref,
@@ -5192,13 +5248,13 @@ var DialogContent = React7.forwardRef(
5192
5248
  ...props,
5193
5249
  children: [
5194
5250
  children,
5195
- showCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
5251
+ showCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5196
5252
  import_radix_ui5.Dialog.Close,
5197
5253
  {
5198
5254
  type: "button",
5199
5255
  className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
5200
5256
  "aria-label": "Close",
5201
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react4.X, { size: 16, "aria-hidden": true })
5257
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react5.X, { size: 16, "aria-hidden": true })
5202
5258
  }
5203
5259
  ) : null
5204
5260
  ]
@@ -5212,13 +5268,13 @@ function DialogHeader({
5212
5268
  className,
5213
5269
  ...props
5214
5270
  }) {
5215
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: cn("flex flex-col gap-1.5", className), ...props });
5271
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: cn("flex flex-col gap-1.5", className), ...props });
5216
5272
  }
5217
5273
  function DialogFooter({
5218
5274
  className,
5219
5275
  ...props
5220
5276
  }) {
5221
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
5277
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5222
5278
  "div",
5223
5279
  {
5224
5280
  className: cn("flex items-center justify-end gap-2", className),
@@ -5226,7 +5282,7 @@ function DialogFooter({
5226
5282
  }
5227
5283
  );
5228
5284
  }
5229
- var DialogTitle = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
5285
+ var DialogTitle = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5230
5286
  import_radix_ui5.Dialog.Title,
5231
5287
  {
5232
5288
  ref,
@@ -5238,7 +5294,7 @@ var DialogTitle = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE
5238
5294
  }
5239
5295
  ));
5240
5296
  DialogTitle.displayName = import_radix_ui5.Dialog.Title.displayName;
5241
- var DialogDescription = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
5297
+ var DialogDescription = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5242
5298
  import_radix_ui5.Dialog.Description,
5243
5299
  {
5244
5300
  ref,
@@ -5250,63 +5306,63 @@ DialogDescription.displayName = import_radix_ui5.Dialog.Description.displayName;
5250
5306
  var DialogClose = import_radix_ui5.Dialog.Close;
5251
5307
 
5252
5308
  // src/ui/link-modal/LinkEditorPanel.tsx
5253
- var import_lucide_react8 = require("lucide-react");
5309
+ var import_lucide_react9 = require("lucide-react");
5254
5310
 
5255
5311
  // src/ui/link-modal/DestinationBreadcrumb.tsx
5256
- var import_lucide_react5 = require("lucide-react");
5257
- var import_jsx_runtime13 = require("react/jsx-runtime");
5312
+ var import_lucide_react6 = require("lucide-react");
5313
+ var import_jsx_runtime14 = require("react/jsx-runtime");
5258
5314
  function DestinationBreadcrumb({
5259
5315
  pageTitle,
5260
5316
  sectionLabel
5261
5317
  }) {
5262
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex w-full flex-col gap-2", children: [
5263
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-sm font-medium! text-foreground m-0", children: "Destination" }),
5264
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-3", children: [
5265
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-2", children: [
5266
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react5.File, { size: 16, className: "shrink-0 text-foreground", "aria-hidden": true }),
5267
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "text-sm font-medium leading-none text-foreground!", children: pageTitle })
5318
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex w-full flex-col gap-2", children: [
5319
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-sm font-medium! text-foreground m-0", children: "Destination" }),
5320
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center gap-3", children: [
5321
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center gap-2", children: [
5322
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react6.File, { size: 16, className: "shrink-0 text-foreground", "aria-hidden": true }),
5323
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "text-sm font-medium leading-none text-foreground!", children: pageTitle })
5268
5324
  ] }),
5269
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5270
- import_lucide_react5.ArrowRight,
5325
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5326
+ import_lucide_react6.ArrowRight,
5271
5327
  {
5272
5328
  size: 16,
5273
5329
  className: "shrink-0 text-muted-foreground",
5274
5330
  "aria-hidden": true
5275
5331
  }
5276
5332
  ),
5277
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
5278
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5279
- import_lucide_react5.GalleryVertical,
5333
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
5334
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5335
+ import_lucide_react6.GalleryVertical,
5280
5336
  {
5281
5337
  size: 16,
5282
5338
  className: "shrink-0 text-foreground",
5283
5339
  "aria-hidden": true
5284
5340
  }
5285
5341
  ),
5286
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "truncate text-sm font-medium leading-none text-foreground", children: sectionLabel })
5342
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "truncate text-sm font-medium leading-none text-foreground", children: sectionLabel })
5287
5343
  ] })
5288
5344
  ] })
5289
5345
  ] });
5290
5346
  }
5291
5347
 
5292
5348
  // src/ui/link-modal/SectionTreeItem.tsx
5293
- var import_lucide_react6 = require("lucide-react");
5294
- var import_jsx_runtime14 = require("react/jsx-runtime");
5349
+ var import_lucide_react7 = require("lucide-react");
5350
+ var import_jsx_runtime15 = require("react/jsx-runtime");
5295
5351
  function SectionTreeItem({
5296
5352
  section,
5297
5353
  onSelect,
5298
5354
  selected
5299
5355
  }) {
5300
5356
  const interactive = Boolean(onSelect);
5301
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex h-9 w-full items-end pl-3", children: [
5302
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5357
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex h-9 w-full items-end pl-3", children: [
5358
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5303
5359
  "div",
5304
5360
  {
5305
5361
  className: "mr-[-1px] h-9 w-2 shrink-0 rounded-bl-sm border-b border-l border-border mb-4",
5306
5362
  "aria-hidden": true
5307
5363
  }
5308
5364
  ),
5309
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
5365
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
5310
5366
  "div",
5311
5367
  {
5312
5368
  role: interactive ? "button" : void 0,
@@ -5324,15 +5380,15 @@ function SectionTreeItem({
5324
5380
  interactive && selected && "border-primary"
5325
5381
  ),
5326
5382
  children: [
5327
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5328
- import_lucide_react6.GalleryVertical,
5383
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5384
+ import_lucide_react7.GalleryVertical,
5329
5385
  {
5330
5386
  size: 16,
5331
5387
  className: "shrink-0 text-foreground",
5332
5388
  "aria-hidden": true
5333
5389
  }
5334
5390
  ),
5335
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "truncate text-sm font-normal leading-5 text-foreground", children: section.label })
5391
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "truncate text-sm font-normal leading-5 text-foreground", children: section.label })
5336
5392
  ]
5337
5393
  }
5338
5394
  )
@@ -5344,10 +5400,10 @@ var import_react4 = require("react");
5344
5400
 
5345
5401
  // src/ui/input.tsx
5346
5402
  var React8 = __toESM(require("react"), 1);
5347
- var import_jsx_runtime15 = require("react/jsx-runtime");
5403
+ var import_jsx_runtime16 = require("react/jsx-runtime");
5348
5404
  var Input = React8.forwardRef(
5349
5405
  ({ className, type, ...props }, ref) => {
5350
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5406
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
5351
5407
  "input",
5352
5408
  {
5353
5409
  type,
@@ -5366,9 +5422,9 @@ Input.displayName = "Input";
5366
5422
 
5367
5423
  // src/ui/label.tsx
5368
5424
  var import_radix_ui6 = require("radix-ui");
5369
- var import_jsx_runtime16 = require("react/jsx-runtime");
5425
+ var import_jsx_runtime17 = require("react/jsx-runtime");
5370
5426
  function Label({ className, ...props }) {
5371
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
5427
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5372
5428
  import_radix_ui6.Label.Root,
5373
5429
  {
5374
5430
  "data-slot": "label",
@@ -5379,12 +5435,12 @@ function Label({ className, ...props }) {
5379
5435
  }
5380
5436
 
5381
5437
  // src/ui/link-modal/UrlOrPageInput.tsx
5382
- var import_lucide_react7 = require("lucide-react");
5383
- var import_jsx_runtime17 = require("react/jsx-runtime");
5438
+ var import_lucide_react8 = require("lucide-react");
5439
+ var import_jsx_runtime18 = require("react/jsx-runtime");
5384
5440
  function FieldChevron({
5385
5441
  onClick
5386
5442
  }) {
5387
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5443
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5388
5444
  "button",
5389
5445
  {
5390
5446
  type: "button",
@@ -5392,7 +5448,7 @@ function FieldChevron({
5392
5448
  onClick,
5393
5449
  "aria-label": "Open page list",
5394
5450
  tabIndex: -1,
5395
- children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react7.ChevronDown, { size: 16 })
5451
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.ChevronDown, { size: 16 })
5396
5452
  }
5397
5453
  );
5398
5454
  }
@@ -5453,19 +5509,19 @@ function UrlOrPageInput({
5453
5509
  "data-ohw-link-field flex h-[36px] w-full items-center overflow-hidden rounded-md border bg-background pl-3 pr-3 py-2 outline-none transition-[border-color,box-shadow]",
5454
5510
  urlError ? "border-destructive shadow-[0_0_0_1px_var(--ohw-destructive)]" : isFocused ? "border-primary shadow-[0_0_0_1px_var(--ohw-primary)]" : "border-input"
5455
5511
  );
5456
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex w-full flex-col gap-2 p-0", children: [
5457
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
5458
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { ref: rootRef, className: "relative w-full", children: [
5459
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { "data-ohw-link-field": true, className: fieldClassName, children: [
5460
- selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5461
- import_lucide_react7.File,
5512
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex w-full flex-col gap-2 p-0", children: [
5513
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
5514
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { ref: rootRef, className: "relative w-full", children: [
5515
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { "data-ohw-link-field": true, className: fieldClassName, children: [
5516
+ selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5517
+ import_lucide_react8.File,
5462
5518
  {
5463
5519
  size: 16,
5464
5520
  className: "shrink-0 text-foreground",
5465
5521
  "aria-hidden": true
5466
5522
  }
5467
5523
  ) }) : null,
5468
- readOnly ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "min-w-0 flex-1 truncate text-sm leading-5 text-foreground", children: selectedPage?.title ?? value }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5524
+ readOnly ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "min-w-0 flex-1 truncate text-sm leading-5 text-foreground", children: selectedPage?.title ?? value }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5469
5525
  Input,
5470
5526
  {
5471
5527
  ref: inputRef,
@@ -5491,7 +5547,7 @@ function UrlOrPageInput({
5491
5547
  )
5492
5548
  }
5493
5549
  ),
5494
- selectedPage && !readOnly ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5550
+ selectedPage && !readOnly ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5495
5551
  "button",
5496
5552
  {
5497
5553
  type: "button",
@@ -5499,26 +5555,26 @@ function UrlOrPageInput({
5499
5555
  onMouseDown: clearSelection,
5500
5556
  "aria-label": "Clear selected page",
5501
5557
  tabIndex: -1,
5502
- children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react7.X, { size: 16, "aria-hidden": true })
5558
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.X, { size: 16, "aria-hidden": true })
5503
5559
  }
5504
5560
  ) : null,
5505
- !readOnly ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(FieldChevron, { onClick: toggleDropdown }) : null
5561
+ !readOnly ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(FieldChevron, { onClick: toggleDropdown }) : null
5506
5562
  ] }),
5507
- dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5563
+ dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5508
5564
  "div",
5509
5565
  {
5510
5566
  "data-ohw-link-page-dropdown": "",
5511
5567
  className: "absolute left-0 right-0 top-[calc(100%+4px)] z-50 max-h-48 overflow-auto rounded-lg border border-border bg-popover py-1 shadow-lg",
5512
5568
  onMouseDown: (e) => e.preventDefault(),
5513
- children: filteredPages.map((page) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
5569
+ children: filteredPages.map((page) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
5514
5570
  "button",
5515
5571
  {
5516
5572
  type: "button",
5517
5573
  className: "flex h-9 w-full items-center gap-2 border-0 bg-transparent px-3 text-left text-sm leading-5 text-foreground outline-none hover:bg-muted",
5518
5574
  onClick: () => onPageSelect(page),
5519
5575
  children: [
5520
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react7.File, { size: 16, className: "shrink-0", "aria-hidden": true }),
5521
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "truncate", children: page.title })
5576
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.File, { size: 16, className: "shrink-0", "aria-hidden": true }),
5577
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "truncate", children: page.title })
5522
5578
  ]
5523
5579
  },
5524
5580
  page.path
@@ -5526,34 +5582,34 @@ function UrlOrPageInput({
5526
5582
  }
5527
5583
  ) : null
5528
5584
  ] }),
5529
- urlError ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "text-sm font-medium text-destructive", children: urlError }) : null
5585
+ urlError ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "text-sm font-medium text-destructive", children: urlError }) : null
5530
5586
  ] });
5531
5587
  }
5532
5588
 
5533
5589
  // src/ui/link-modal/LinkEditorPanel.tsx
5534
- var import_jsx_runtime18 = require("react/jsx-runtime");
5590
+ var import_jsx_runtime19 = require("react/jsx-runtime");
5535
5591
  function LinkEditorPanel({ state, onClose }) {
5536
5592
  const isCancel = state.secondaryLabel === "Cancel" || state.secondaryLabel === "Back to sections";
5537
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
5538
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DialogClose, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5593
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
5594
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DialogClose, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5539
5595
  "button",
5540
5596
  {
5541
5597
  type: "button",
5542
5598
  className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50 h-7",
5543
5599
  "aria-label": "Close",
5544
5600
  onClick: onClose,
5545
- children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.X, { size: 16, "aria-hidden": true })
5601
+ children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react9.X, { size: 16, "aria-hidden": true })
5546
5602
  }
5547
5603
  ) }),
5548
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DialogHeader, { className: "w-full gap-1.5 p-6 pr-12", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DialogTitle, { className: "m-0 w-full break-words", children: state.title }) }),
5549
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
5550
- state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5604
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DialogHeader, { className: "w-full gap-1.5 p-6 pr-12", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DialogTitle, { className: "m-0 w-full break-words", children: state.title }) }),
5605
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
5606
+ state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5551
5607
  DestinationBreadcrumb,
5552
5608
  {
5553
5609
  pageTitle: state.selectedPage.title,
5554
5610
  sectionLabel: state.selectedSection.label
5555
5611
  }
5556
- ) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5612
+ ) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5557
5613
  UrlOrPageInput,
5558
5614
  {
5559
5615
  value: state.searchValue,
@@ -5566,8 +5622,8 @@ function LinkEditorPanel({ state, onClose }) {
5566
5622
  urlError: state.urlError
5567
5623
  }
5568
5624
  ),
5569
- state.showChooseSection ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex flex-col justify-center gap-2", children: [
5570
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5625
+ state.showChooseSection ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col justify-center gap-2", children: [
5626
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5571
5627
  Button,
5572
5628
  {
5573
5629
  type: "button",
@@ -5578,15 +5634,15 @@ function LinkEditorPanel({ state, onClose }) {
5578
5634
  children: "Choose a section"
5579
5635
  }
5580
5636
  ),
5581
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
5582
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.Info, { size: 16, className: "shrink-0", "aria-hidden": true }),
5583
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { children: "Pick a section this link should scroll to." })
5637
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
5638
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react9.Info, { size: 16, className: "shrink-0", "aria-hidden": true }),
5639
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { children: "Pick a section this link should scroll to." })
5584
5640
  ] })
5585
5641
  ] }) : null,
5586
- state.showSectionRow && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
5642
+ state.showSectionRow && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
5587
5643
  ] }),
5588
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(DialogFooter, { className: "w-full px-6 pb-6", children: [
5589
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5644
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(DialogFooter, { className: "w-full px-6 pb-6", children: [
5645
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5590
5646
  Button,
5591
5647
  {
5592
5648
  type: "button",
@@ -5601,7 +5657,7 @@ function LinkEditorPanel({ state, onClose }) {
5601
5657
  children: state.secondaryLabel
5602
5658
  }
5603
5659
  ),
5604
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5660
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5605
5661
  Button,
5606
5662
  {
5607
5663
  type: "button",
@@ -5622,9 +5678,9 @@ function LinkEditorPanel({ state, onClose }) {
5622
5678
  // src/ui/link-modal/SectionPickerOverlay.tsx
5623
5679
  var import_react5 = require("react");
5624
5680
  var import_react_dom = require("react-dom");
5625
- var import_lucide_react9 = require("lucide-react");
5681
+ var import_lucide_react10 = require("lucide-react");
5626
5682
  var import_navigation = require("next/navigation");
5627
- var import_jsx_runtime19 = require("react/jsx-runtime");
5683
+ var import_jsx_runtime20 = require("react/jsx-runtime");
5628
5684
  var DIM_OVERLAY = "rgba(0, 0, 0, 0.45)";
5629
5685
  function rectsEqual(a, b) {
5630
5686
  if (a.size !== b.size) return false;
@@ -5847,7 +5903,7 @@ function SectionPickerOverlay({
5847
5903
  const portalRoot = typeof document !== "undefined" ? document.querySelector("[data-ohw-bridge-root]") ?? document.body : null;
5848
5904
  if (!portalRoot) return null;
5849
5905
  return (0, import_react_dom.createPortal)(
5850
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
5906
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
5851
5907
  "div",
5852
5908
  {
5853
5909
  "data-ohw-section-picker": "",
@@ -5857,12 +5913,12 @@ function SectionPickerOverlay({
5857
5913
  role: "dialog",
5858
5914
  "aria-label": "Choose a section",
5859
5915
  children: [
5860
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5916
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5861
5917
  "div",
5862
5918
  {
5863
5919
  className: "pointer-events-auto fixed left-5 z-[2]",
5864
5920
  style: { top: chromeClip.top + 20 },
5865
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
5921
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
5866
5922
  Button,
5867
5923
  {
5868
5924
  type: "button",
@@ -5871,14 +5927,14 @@ function SectionPickerOverlay({
5871
5927
  className: "h-8 min-w-0 gap-1 border-border bg-background px-2 py-1.5 shadow-sm hover:bg-muted cursor-pointer",
5872
5928
  onClick: onBack,
5873
5929
  children: [
5874
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react9.ArrowLeft, { className: "size-4 shrink-0", "aria-hidden": true }),
5930
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react10.ArrowLeft, { className: "size-4 shrink-0", "aria-hidden": true }),
5875
5931
  "Back"
5876
5932
  ]
5877
5933
  }
5878
5934
  )
5879
5935
  }
5880
5936
  ),
5881
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5937
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5882
5938
  "div",
5883
5939
  {
5884
5940
  className: "pointer-events-none fixed left-1/2 z-[2] rounded-lg px-4 py-3 text-xs leading-4 tracking-[0.18px] text-white shadow-md",
@@ -5891,7 +5947,7 @@ function SectionPickerOverlay({
5891
5947
  children: "Click on section to select"
5892
5948
  }
5893
5949
  ),
5894
- !isOnTargetPage ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5950
+ !isOnTargetPage ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5895
5951
  "div",
5896
5952
  {
5897
5953
  className: "pointer-events-none fixed left-1/2 z-[1] -translate-x-1/2 rounded-md bg-background/90 px-3 py-2 text-sm text-muted-foreground shadow-sm",
@@ -5899,13 +5955,13 @@ function SectionPickerOverlay({
5899
5955
  children: "Loading page preview\u2026"
5900
5956
  }
5901
5957
  ) : null,
5902
- isOnTargetPage && liveSections.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "pointer-events-auto fixed inset-0 z-[1] flex items-center justify-center bg-muted/40", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-sm text-muted-foreground", children: "No sections found on this page." }) }) : null,
5958
+ isOnTargetPage && liveSections.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "pointer-events-auto fixed inset-0 z-[1] flex items-center justify-center bg-muted/40", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "text-sm text-muted-foreground", children: "No sections found on this page." }) }) : null,
5903
5959
  isOnTargetPage ? liveSections.map((section) => {
5904
5960
  const rect = rects.get(section.id);
5905
5961
  if (!rect || rect.width <= 0 || rect.height <= 0) return null;
5906
5962
  const isSelected = selectedId === section.id;
5907
5963
  const isLit = isSelected || hoveredId === section.id;
5908
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5964
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5909
5965
  "button",
5910
5966
  {
5911
5967
  type: "button",
@@ -5919,13 +5975,13 @@ function SectionPickerOverlay({
5919
5975
  },
5920
5976
  "aria-label": `Select section ${section.label}`,
5921
5977
  onClick: () => handleSelect(section),
5922
- children: isSelected ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5978
+ children: isSelected ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5923
5979
  "span",
5924
5980
  {
5925
5981
  className: "absolute right-3 top-3 flex size-8 items-center justify-center rounded-full text-white",
5926
5982
  style: { backgroundColor: "var(--ohw-primary, #0885fe)" },
5927
5983
  "aria-hidden": true,
5928
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react9.Check, { className: "size-5" })
5984
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react10.Check, { className: "size-5" })
5929
5985
  }
5930
5986
  ) : null
5931
5987
  },
@@ -6104,7 +6160,7 @@ function useLinkModalState({
6104
6160
  }
6105
6161
 
6106
6162
  // src/ui/link-modal/LinkPopover.tsx
6107
- var import_jsx_runtime20 = require("react/jsx-runtime");
6163
+ var import_jsx_runtime21 = require("react/jsx-runtime");
6108
6164
  function postToParent(data) {
6109
6165
  window.parent?.postMessage(data, "*");
6110
6166
  }
@@ -6200,15 +6256,15 @@ function LinkPopover({
6200
6256
  );
6201
6257
  };
6202
6258
  }, [open, sectionPickerActive]);
6203
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
6204
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
6259
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
6260
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6205
6261
  Dialog2,
6206
6262
  {
6207
6263
  open: open && !sectionPickerActive,
6208
6264
  onOpenChange: (next) => {
6209
6265
  if (!next) onClose?.();
6210
6266
  },
6211
- children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
6267
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6212
6268
  DialogContent,
6213
6269
  {
6214
6270
  ref: panelRef,
@@ -6218,12 +6274,12 @@ function LinkPopover({
6218
6274
  "data-ohw-bridge": "",
6219
6275
  showCloseButton: false,
6220
6276
  className: "gap-0 p-0 w-full max-w-[448px] pointer-events-auto z-[2147483646] overflow-visible",
6221
- children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(LinkEditorPanel, { state, onClose })
6277
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(LinkEditorPanel, { state, onClose })
6222
6278
  }
6223
6279
  )
6224
6280
  }
6225
6281
  ),
6226
- sectionPickerActive && state.selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
6282
+ sectionPickerActive && state.selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6227
6283
  SectionPickerOverlay,
6228
6284
  {
6229
6285
  pagePath: state.selectedPage.path,
@@ -6529,15 +6585,99 @@ function insertNavbarItem(href, label, afterAnchor = null) {
6529
6585
  };
6530
6586
  }
6531
6587
 
6588
+ // src/lib/carousel.ts
6589
+ var import_react8 = require("react");
6590
+ var CAROUSEL_ATTR = "data-ohw-carousel";
6591
+ var CAROUSEL_VALUE_ATTR = "data-ohw-carousel-value";
6592
+ var CAROUSEL_SLIDE_ATTR = "data-ohw-carousel-slide";
6593
+ var CAROUSEL_EVENT = "ohw:carousel-change";
6594
+ function listCarouselKeys() {
6595
+ const keys = /* @__PURE__ */ new Set();
6596
+ document.querySelectorAll(`[${CAROUSEL_ATTR}]`).forEach((el) => {
6597
+ const key = el.getAttribute("data-ohw-key");
6598
+ if (key) keys.add(key);
6599
+ });
6600
+ return [...keys];
6601
+ }
6602
+ function containersForKey(key) {
6603
+ return Array.from(
6604
+ document.querySelectorAll(`[${CAROUSEL_ATTR}][data-ohw-key="${CSS.escape(key)}"]`)
6605
+ );
6606
+ }
6607
+ function isCarouselKey(key) {
6608
+ return containersForKey(key).length > 0;
6609
+ }
6610
+ function parseSlides(raw) {
6611
+ if (!raw) return [];
6612
+ try {
6613
+ const parsed = JSON.parse(raw);
6614
+ if (!Array.isArray(parsed)) return [];
6615
+ return parsed.filter((s) => Boolean(s) && typeof s === "object").map((s) => ({ src: String(s.src ?? ""), alt: String(s.alt ?? "") }));
6616
+ } catch {
6617
+ return [];
6618
+ }
6619
+ }
6620
+ function readCarouselValue(key) {
6621
+ const container = containersForKey(key)[0];
6622
+ if (!container) return [];
6623
+ const fromAttr = parseSlides(container.getAttribute(CAROUSEL_VALUE_ATTR));
6624
+ if (fromAttr.length > 0) return fromAttr;
6625
+ return Array.from(container.querySelectorAll(`[${CAROUSEL_SLIDE_ATTR}]`)).filter((slide) => slide.closest(`[${CAROUSEL_ATTR}]`) === container).sort((a, b) => slideIndex(a) - slideIndex(b)).map((slide) => {
6626
+ const img = slide instanceof HTMLImageElement ? slide : slide.querySelector("img");
6627
+ return { src: img?.src ?? "", alt: img?.alt ?? "" };
6628
+ });
6629
+ }
6630
+ function slideIndex(el) {
6631
+ const raw = el.getAttribute(CAROUSEL_SLIDE_ATTR);
6632
+ const n = raw ? parseInt(raw, 10) : NaN;
6633
+ return Number.isFinite(n) ? n : 0;
6634
+ }
6635
+ function applyCarouselValue(key, slides) {
6636
+ const value = JSON.stringify(slides);
6637
+ for (const container of containersForKey(key)) {
6638
+ if (container.getAttribute(CAROUSEL_VALUE_ATTR) === value) continue;
6639
+ container.setAttribute(CAROUSEL_VALUE_ATTR, value);
6640
+ container.dispatchEvent(
6641
+ new CustomEvent(CAROUSEL_EVENT, { detail: { images: slides } })
6642
+ );
6643
+ }
6644
+ }
6645
+ function applyCarouselNode(key, val) {
6646
+ if (!isCarouselKey(key)) return false;
6647
+ applyCarouselValue(key, parseSlides(val));
6648
+ return true;
6649
+ }
6650
+ function useOhwCarousel(key, initial) {
6651
+ const [images, setImages] = (0, import_react8.useState)(initial);
6652
+ (0, import_react8.useEffect)(() => {
6653
+ const el = document.querySelector(
6654
+ `[${CAROUSEL_ATTR}][data-ohw-key="${CSS.escape(key)}"]`
6655
+ );
6656
+ if (!el) return;
6657
+ const onChange = (e) => {
6658
+ const detail = e.detail;
6659
+ if (Array.isArray(detail?.images)) setImages(detail.images);
6660
+ };
6661
+ el.addEventListener(CAROUSEL_EVENT, onChange);
6662
+ return () => el.removeEventListener(CAROUSEL_EVENT, onChange);
6663
+ }, [key]);
6664
+ const bind = {
6665
+ [CAROUSEL_ATTR]: "",
6666
+ "data-ohw-key": key,
6667
+ [CAROUSEL_VALUE_ATTR]: JSON.stringify(images)
6668
+ };
6669
+ return { images, setImages, bind };
6670
+ }
6671
+
6532
6672
  // src/ui/navbar-container-chrome.tsx
6533
- var import_lucide_react10 = require("lucide-react");
6534
- var import_jsx_runtime21 = require("react/jsx-runtime");
6673
+ var import_lucide_react11 = require("lucide-react");
6674
+ var import_jsx_runtime22 = require("react/jsx-runtime");
6535
6675
  function NavbarContainerChrome({
6536
6676
  rect,
6537
6677
  onAdd
6538
6678
  }) {
6539
6679
  const chromeGap = 6;
6540
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6680
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6541
6681
  "div",
6542
6682
  {
6543
6683
  "data-ohw-navbar-container-chrome": "",
@@ -6549,7 +6689,7 @@ function NavbarContainerChrome({
6549
6689
  width: rect.width + chromeGap * 2,
6550
6690
  height: rect.height + chromeGap * 2
6551
6691
  },
6552
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6692
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6553
6693
  "button",
6554
6694
  {
6555
6695
  type: "button",
@@ -6566,7 +6706,7 @@ function NavbarContainerChrome({
6566
6706
  e.stopPropagation();
6567
6707
  onAdd();
6568
6708
  },
6569
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react10.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
6709
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react11.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
6570
6710
  }
6571
6711
  )
6572
6712
  }
@@ -6574,7 +6714,7 @@ function NavbarContainerChrome({
6574
6714
  }
6575
6715
 
6576
6716
  // src/ui/badge.tsx
6577
- var import_jsx_runtime22 = require("react/jsx-runtime");
6717
+ var import_jsx_runtime23 = require("react/jsx-runtime");
6578
6718
  var badgeVariants = cva(
6579
6719
  "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",
6580
6720
  {
@@ -6592,12 +6732,12 @@ var badgeVariants = cva(
6592
6732
  }
6593
6733
  );
6594
6734
  function Badge({ className, variant, ...props }) {
6595
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
6735
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
6596
6736
  }
6597
6737
 
6598
6738
  // src/OhhwellsBridge.tsx
6599
- var import_lucide_react11 = require("lucide-react");
6600
- var import_jsx_runtime23 = require("react/jsx-runtime");
6739
+ var import_lucide_react12 = require("lucide-react");
6740
+ var import_jsx_runtime24 = require("react/jsx-runtime");
6601
6741
  var PRIMARY2 = "#0885FE";
6602
6742
  var IMAGE_FADE_MS = 300;
6603
6743
  function runOpacityFade(el, onDone) {
@@ -6776,7 +6916,7 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
6776
6916
  const root = (0, import_client.createRoot)(container);
6777
6917
  (0, import_react_dom2.flushSync)(() => {
6778
6918
  root.render(
6779
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
6919
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6780
6920
  SchedulingWidget,
6781
6921
  {
6782
6922
  notifyOnConnect,
@@ -6873,6 +7013,9 @@ function collectEditableNodes() {
6873
7013
  nodes.push({ key: `${key}${VIDEO_AUTOPLAY_SUFFIX}`, type: "video-setting", text: String(video.autoplay) });
6874
7014
  nodes.push({ key: `${key}${VIDEO_MUTED_SUFFIX}`, type: "video-setting", text: String(video.muted) });
6875
7015
  });
7016
+ for (const key of listCarouselKeys()) {
7017
+ nodes.push({ key, type: "carousel", text: JSON.stringify(readCarouselValue(key)) });
7018
+ }
6876
7019
  return nodes;
6877
7020
  }
6878
7021
  function isMediaEditable(el) {
@@ -7259,7 +7402,7 @@ function EditGlowChrome({
7259
7402
  dragDisabled = false
7260
7403
  }) {
7261
7404
  const GAP = 6;
7262
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
7405
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
7263
7406
  "div",
7264
7407
  {
7265
7408
  ref: elRef,
@@ -7274,7 +7417,7 @@ function EditGlowChrome({
7274
7417
  zIndex: 2147483646
7275
7418
  },
7276
7419
  children: [
7277
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
7420
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
7278
7421
  "div",
7279
7422
  {
7280
7423
  style: {
@@ -7287,7 +7430,7 @@ function EditGlowChrome({
7287
7430
  }
7288
7431
  }
7289
7432
  ),
7290
- reorderHrefKey && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
7433
+ reorderHrefKey && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
7291
7434
  "div",
7292
7435
  {
7293
7436
  "data-ohw-drag-handle-container": "",
@@ -7299,7 +7442,7 @@ function EditGlowChrome({
7299
7442
  transform: "translate(calc(-100% - 7px), -50%)",
7300
7443
  pointerEvents: dragDisabled ? "none" : "auto"
7301
7444
  },
7302
- children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
7445
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
7303
7446
  DragHandle,
7304
7447
  {
7305
7448
  "aria-label": `Reorder ${reorderHrefKey}`,
@@ -7403,7 +7546,7 @@ function FloatingToolbar({
7403
7546
  onEditLink
7404
7547
  }) {
7405
7548
  const { top, left, transform } = calcToolbarPos(rect, parentScroll, 330);
7406
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
7549
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
7407
7550
  "div",
7408
7551
  {
7409
7552
  ref: elRef,
@@ -7424,12 +7567,12 @@ function FloatingToolbar({
7424
7567
  fontFamily: "sans-serif",
7425
7568
  pointerEvents: "auto"
7426
7569
  },
7427
- children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(CustomToolbar, { children: [
7428
- TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_react8.default.Fragment, { children: [
7429
- gi > 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CustomToolbarDivider, {}),
7570
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(CustomToolbar, { children: [
7571
+ TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_react9.default.Fragment, { children: [
7572
+ gi > 0 && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(CustomToolbarDivider, {}),
7430
7573
  btns.map((btn) => {
7431
7574
  const isActive = activeCommands.has(btn.cmd);
7432
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
7575
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
7433
7576
  CustomToolbarButton,
7434
7577
  {
7435
7578
  title: btn.title,
@@ -7438,7 +7581,7 @@ function FloatingToolbar({
7438
7581
  e.preventDefault();
7439
7582
  onCommand(btn.cmd);
7440
7583
  },
7441
- children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
7584
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
7442
7585
  "svg",
7443
7586
  {
7444
7587
  width: "16",
@@ -7459,7 +7602,7 @@ function FloatingToolbar({
7459
7602
  );
7460
7603
  })
7461
7604
  ] }, gi)),
7462
- showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
7605
+ showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
7463
7606
  CustomToolbarButton,
7464
7607
  {
7465
7608
  type: "button",
@@ -7473,7 +7616,7 @@ function FloatingToolbar({
7473
7616
  e.preventDefault();
7474
7617
  e.stopPropagation();
7475
7618
  },
7476
- children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.Link, { className: "size-4 shrink-0", "aria-hidden": true })
7619
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react12.Link, { className: "size-4 shrink-0", "aria-hidden": true })
7477
7620
  }
7478
7621
  ) : null
7479
7622
  ] })
@@ -7490,7 +7633,7 @@ function StateToggle({
7490
7633
  states,
7491
7634
  onStateChange
7492
7635
  }) {
7493
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
7636
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
7494
7637
  ToggleGroup,
7495
7638
  {
7496
7639
  "data-ohw-state-toggle": "",
@@ -7504,7 +7647,7 @@ function StateToggle({
7504
7647
  left: rect.right - 8,
7505
7648
  transform: "translateX(-100%)"
7506
7649
  },
7507
- children: states.map((state) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
7650
+ children: states.map((state) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
7508
7651
  }
7509
7652
  );
7510
7653
  }
@@ -7531,8 +7674,8 @@ function OhhwellsBridge() {
7531
7674
  const router = (0, import_navigation2.useRouter)();
7532
7675
  const searchParams = (0, import_navigation2.useSearchParams)();
7533
7676
  const isEditMode = isEditSessionActive();
7534
- const [bridgeRoot, setBridgeRoot] = (0, import_react8.useState)(null);
7535
- (0, import_react8.useEffect)(() => {
7677
+ const [bridgeRoot, setBridgeRoot] = (0, import_react9.useState)(null);
7678
+ (0, import_react9.useEffect)(() => {
7536
7679
  const figtreeFontId = "ohw-figtree-font";
7537
7680
  if (!document.getElementById(figtreeFontId)) {
7538
7681
  const preconnect1 = Object.assign(document.createElement("link"), { rel: "preconnect", href: "https://fonts.googleapis.com" });
@@ -7560,91 +7703,92 @@ function OhhwellsBridge() {
7560
7703
  const subdomainFromQuery = searchParams.get("subdomain");
7561
7704
  const subdomain = resolveSubdomain(subdomainFromQuery);
7562
7705
  useLinkHrefGuardian(pathname, subdomain, isEditMode);
7563
- const postToParent2 = (0, import_react8.useCallback)((data) => {
7706
+ const postToParent2 = (0, import_react9.useCallback)((data) => {
7564
7707
  if (typeof window !== "undefined" && window.parent !== window) {
7565
7708
  window.parent.postMessage(data, "*");
7566
7709
  }
7567
7710
  }, []);
7568
- const [fetchState, setFetchState] = (0, import_react8.useState)("idle");
7569
- const autoSaveTimers = (0, import_react8.useRef)(/* @__PURE__ */ new Map());
7570
- const activeElRef = (0, import_react8.useRef)(null);
7571
- const selectedElRef = (0, import_react8.useRef)(null);
7572
- const originalContentRef = (0, import_react8.useRef)(null);
7573
- const activeStateElRef = (0, import_react8.useRef)(null);
7574
- const parentScrollRef = (0, import_react8.useRef)(null);
7575
- const visibleViewportRef = (0, import_react8.useRef)(null);
7576
- const [dialogPortalContainer, setDialogPortalContainer] = (0, import_react8.useState)(null);
7577
- const attachVisibleViewport = (0, import_react8.useCallback)((node) => {
7711
+ const [fetchState, setFetchState] = (0, import_react9.useState)("idle");
7712
+ const autoSaveTimers = (0, import_react9.useRef)(/* @__PURE__ */ new Map());
7713
+ const activeElRef = (0, import_react9.useRef)(null);
7714
+ const selectedElRef = (0, import_react9.useRef)(null);
7715
+ const originalContentRef = (0, import_react9.useRef)(null);
7716
+ const activeStateElRef = (0, import_react9.useRef)(null);
7717
+ const parentScrollRef = (0, import_react9.useRef)(null);
7718
+ const visibleViewportRef = (0, import_react9.useRef)(null);
7719
+ const [dialogPortalContainer, setDialogPortalContainer] = (0, import_react9.useState)(null);
7720
+ const attachVisibleViewport = (0, import_react9.useCallback)((node) => {
7578
7721
  visibleViewportRef.current = node;
7579
7722
  setDialogPortalContainer(node);
7580
7723
  if (node) applyVisibleViewport(node, parentScrollRef.current);
7581
7724
  }, []);
7582
- const toolbarElRef = (0, import_react8.useRef)(null);
7583
- const glowElRef = (0, import_react8.useRef)(null);
7584
- const hoveredImageRef = (0, import_react8.useRef)(null);
7585
- const hoveredImageHasTextOverlapRef = (0, import_react8.useRef)(false);
7586
- const dragOverElRef = (0, import_react8.useRef)(null);
7587
- const [mediaHover, setMediaHover] = (0, import_react8.useState)(null);
7588
- const [uploadingRects, setUploadingRects] = (0, import_react8.useState)({});
7589
- const hoveredGapRef = (0, import_react8.useRef)(null);
7590
- const imageUnhoverTimerRef = (0, import_react8.useRef)(null);
7591
- const imageShowTimerRef = (0, import_react8.useRef)(null);
7592
- const editStylesRef = (0, import_react8.useRef)(null);
7593
- const activateRef = (0, import_react8.useRef)(() => {
7725
+ const toolbarElRef = (0, import_react9.useRef)(null);
7726
+ const glowElRef = (0, import_react9.useRef)(null);
7727
+ const hoveredImageRef = (0, import_react9.useRef)(null);
7728
+ const hoveredImageHasTextOverlapRef = (0, import_react9.useRef)(false);
7729
+ const dragOverElRef = (0, import_react9.useRef)(null);
7730
+ const [mediaHover, setMediaHover] = (0, import_react9.useState)(null);
7731
+ const [carouselHover, setCarouselHover] = (0, import_react9.useState)(null);
7732
+ const [uploadingRects, setUploadingRects] = (0, import_react9.useState)({});
7733
+ const hoveredGapRef = (0, import_react9.useRef)(null);
7734
+ const imageUnhoverTimerRef = (0, import_react9.useRef)(null);
7735
+ const imageShowTimerRef = (0, import_react9.useRef)(null);
7736
+ const editStylesRef = (0, import_react9.useRef)(null);
7737
+ const activateRef = (0, import_react9.useRef)(() => {
7594
7738
  });
7595
- const deactivateRef = (0, import_react8.useRef)(() => {
7739
+ const deactivateRef = (0, import_react9.useRef)(() => {
7596
7740
  });
7597
- const selectRef = (0, import_react8.useRef)(() => {
7741
+ const selectRef = (0, import_react9.useRef)(() => {
7598
7742
  });
7599
- const selectFrameRef = (0, import_react8.useRef)(() => {
7743
+ const selectFrameRef = (0, import_react9.useRef)(() => {
7600
7744
  });
7601
- const deselectRef = (0, import_react8.useRef)(() => {
7745
+ const deselectRef = (0, import_react9.useRef)(() => {
7602
7746
  });
7603
- const reselectNavigationItemRef = (0, import_react8.useRef)(() => {
7747
+ const reselectNavigationItemRef = (0, import_react9.useRef)(() => {
7604
7748
  });
7605
- const commitNavigationTextEditRef = (0, import_react8.useRef)(() => {
7749
+ const commitNavigationTextEditRef = (0, import_react9.useRef)(() => {
7606
7750
  });
7607
- const refreshActiveCommandsRef = (0, import_react8.useRef)(() => {
7751
+ const refreshActiveCommandsRef = (0, import_react9.useRef)(() => {
7608
7752
  });
7609
- const postToParentRef = (0, import_react8.useRef)(postToParent2);
7753
+ const postToParentRef = (0, import_react9.useRef)(postToParent2);
7610
7754
  postToParentRef.current = postToParent2;
7611
- const sectionsLoadedRef = (0, import_react8.useRef)(false);
7612
- const pendingScheduleConfigRequests = (0, import_react8.useRef)([]);
7613
- const [toolbarRect, setToolbarRect] = (0, import_react8.useState)(null);
7614
- const [toolbarVariant, setToolbarVariant] = (0, import_react8.useState)("none");
7615
- const toolbarVariantRef = (0, import_react8.useRef)("none");
7755
+ const sectionsLoadedRef = (0, import_react9.useRef)(false);
7756
+ const pendingScheduleConfigRequests = (0, import_react9.useRef)([]);
7757
+ const [toolbarRect, setToolbarRect] = (0, import_react9.useState)(null);
7758
+ const [toolbarVariant, setToolbarVariant] = (0, import_react9.useState)("none");
7759
+ const toolbarVariantRef = (0, import_react9.useRef)("none");
7616
7760
  toolbarVariantRef.current = toolbarVariant;
7617
- const [reorderHrefKey, setReorderHrefKey] = (0, import_react8.useState)(null);
7618
- const [reorderDragDisabled, setReorderDragDisabled] = (0, import_react8.useState)(false);
7619
- const [toggleState, setToggleState] = (0, import_react8.useState)(null);
7620
- const [maxBadge, setMaxBadge] = (0, import_react8.useState)(null);
7621
- const [activeCommands, setActiveCommands] = (0, import_react8.useState)(/* @__PURE__ */ new Set());
7622
- const [sectionGap, setSectionGap] = (0, import_react8.useState)(null);
7623
- const [toolbarShowEditLink, setToolbarShowEditLink] = (0, import_react8.useState)(false);
7624
- const hoveredNavContainerRef = (0, import_react8.useRef)(null);
7625
- const [hoveredNavContainerRect, setHoveredNavContainerRect] = (0, import_react8.useState)(null);
7626
- const hoveredItemElRef = (0, import_react8.useRef)(null);
7627
- const [hoveredItemRect, setHoveredItemRect] = (0, import_react8.useState)(null);
7628
- const siblingHintElRef = (0, import_react8.useRef)(null);
7629
- const [siblingHintRect, setSiblingHintRect] = (0, import_react8.useState)(null);
7630
- const [isItemDragging, setIsItemDragging] = (0, import_react8.useState)(false);
7631
- const [linkPopover, setLinkPopover] = (0, import_react8.useState)(null);
7632
- const linkPopoverSessionRef = (0, import_react8.useRef)(null);
7633
- const addNavAfterAnchorRef = (0, import_react8.useRef)(null);
7634
- const editContentRef = (0, import_react8.useRef)({});
7635
- const [sitePages, setSitePages] = (0, import_react8.useState)([]);
7636
- const [sectionsByPath, setSectionsByPath] = (0, import_react8.useState)({});
7637
- const sectionsPrefetchGenRef = (0, import_react8.useRef)(0);
7638
- const setLinkPopoverRef = (0, import_react8.useRef)(setLinkPopover);
7639
- const linkPopoverPanelRef = (0, import_react8.useRef)(null);
7640
- const linkPopoverOpenRef = (0, import_react8.useRef)(false);
7641
- const linkPopoverGraceUntilRef = (0, import_react8.useRef)(0);
7761
+ const [reorderHrefKey, setReorderHrefKey] = (0, import_react9.useState)(null);
7762
+ const [reorderDragDisabled, setReorderDragDisabled] = (0, import_react9.useState)(false);
7763
+ const [toggleState, setToggleState] = (0, import_react9.useState)(null);
7764
+ const [maxBadge, setMaxBadge] = (0, import_react9.useState)(null);
7765
+ const [activeCommands, setActiveCommands] = (0, import_react9.useState)(/* @__PURE__ */ new Set());
7766
+ const [sectionGap, setSectionGap] = (0, import_react9.useState)(null);
7767
+ const [toolbarShowEditLink, setToolbarShowEditLink] = (0, import_react9.useState)(false);
7768
+ const hoveredNavContainerRef = (0, import_react9.useRef)(null);
7769
+ const [hoveredNavContainerRect, setHoveredNavContainerRect] = (0, import_react9.useState)(null);
7770
+ const hoveredItemElRef = (0, import_react9.useRef)(null);
7771
+ const [hoveredItemRect, setHoveredItemRect] = (0, import_react9.useState)(null);
7772
+ const siblingHintElRef = (0, import_react9.useRef)(null);
7773
+ const [siblingHintRect, setSiblingHintRect] = (0, import_react9.useState)(null);
7774
+ const [isItemDragging, setIsItemDragging] = (0, import_react9.useState)(false);
7775
+ const [linkPopover, setLinkPopover] = (0, import_react9.useState)(null);
7776
+ const linkPopoverSessionRef = (0, import_react9.useRef)(null);
7777
+ const addNavAfterAnchorRef = (0, import_react9.useRef)(null);
7778
+ const editContentRef = (0, import_react9.useRef)({});
7779
+ const [sitePages, setSitePages] = (0, import_react9.useState)([]);
7780
+ const [sectionsByPath, setSectionsByPath] = (0, import_react9.useState)({});
7781
+ const sectionsPrefetchGenRef = (0, import_react9.useRef)(0);
7782
+ const setLinkPopoverRef = (0, import_react9.useRef)(setLinkPopover);
7783
+ const linkPopoverPanelRef = (0, import_react9.useRef)(null);
7784
+ const linkPopoverOpenRef = (0, import_react9.useRef)(false);
7785
+ const linkPopoverGraceUntilRef = (0, import_react9.useRef)(0);
7642
7786
  setLinkPopoverRef.current = setLinkPopover;
7643
7787
  linkPopoverSessionRef.current = linkPopover;
7644
7788
  const bumpLinkPopoverGrace = () => {
7645
7789
  linkPopoverGraceUntilRef.current = Date.now() + 350;
7646
7790
  };
7647
- const runSectionsPrefetch = (0, import_react8.useCallback)((pages) => {
7791
+ const runSectionsPrefetch = (0, import_react9.useCallback)((pages) => {
7648
7792
  if (!isEditMode || shouldUseDevFixtures() || pages.length === 0) return;
7649
7793
  const gen = ++sectionsPrefetchGenRef.current;
7650
7794
  const paths = pages.map((p) => p.path);
@@ -7663,9 +7807,9 @@ function OhhwellsBridge() {
7663
7807
  );
7664
7808
  });
7665
7809
  }, [isEditMode, pathname]);
7666
- const runSectionsPrefetchRef = (0, import_react8.useRef)(runSectionsPrefetch);
7810
+ const runSectionsPrefetchRef = (0, import_react9.useRef)(runSectionsPrefetch);
7667
7811
  runSectionsPrefetchRef.current = runSectionsPrefetch;
7668
- (0, import_react8.useEffect)(() => {
7812
+ (0, import_react9.useEffect)(() => {
7669
7813
  if (!linkPopover) return;
7670
7814
  if (hoveredImageRef.current) {
7671
7815
  hoveredImageRef.current = null;
@@ -7675,7 +7819,7 @@ function OhhwellsBridge() {
7675
7819
  setSectionGap(null);
7676
7820
  postToParent2({ type: "ow:image-unhover" });
7677
7821
  }, [linkPopover, postToParent2]);
7678
- (0, import_react8.useEffect)(() => {
7822
+ (0, import_react9.useEffect)(() => {
7679
7823
  if (!isEditMode) return;
7680
7824
  const useFixtures = shouldUseDevFixtures();
7681
7825
  if (useFixtures) {
@@ -7699,14 +7843,14 @@ function OhhwellsBridge() {
7699
7843
  if (!useFixtures) postToParent2({ type: "ow:request-site-pages" });
7700
7844
  return () => window.removeEventListener("message", onSitePages);
7701
7845
  }, [isEditMode, postToParent2]);
7702
- (0, import_react8.useEffect)(() => {
7846
+ (0, import_react9.useEffect)(() => {
7703
7847
  if (!isEditMode || shouldUseDevFixtures()) return;
7704
7848
  void loadAllSectionsManifest().then((manifest) => {
7705
7849
  if (Object.keys(manifest).length === 0) return;
7706
7850
  setSectionsByPath((prev) => ({ ...manifest, ...prev }));
7707
7851
  });
7708
7852
  }, [isEditMode]);
7709
- (0, import_react8.useEffect)(() => {
7853
+ (0, import_react9.useEffect)(() => {
7710
7854
  const update = () => {
7711
7855
  const el = activeElRef.current ?? selectedElRef.current;
7712
7856
  if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
@@ -7730,10 +7874,10 @@ function OhhwellsBridge() {
7730
7874
  vvp.removeEventListener("resize", update);
7731
7875
  };
7732
7876
  }, []);
7733
- const refreshStateRules = (0, import_react8.useCallback)(() => {
7877
+ const refreshStateRules = (0, import_react9.useCallback)(() => {
7734
7878
  editStylesRef.current?.forceHover && (editStylesRef.current.forceHover.textContent = collectStateRules());
7735
7879
  }, []);
7736
- const processConfigRequest = (0, import_react8.useCallback)((insertAfterVal) => {
7880
+ const processConfigRequest = (0, import_react9.useCallback)((insertAfterVal) => {
7737
7881
  const tracker = getSectionsTracker();
7738
7882
  let entries = [];
7739
7883
  try {
@@ -7756,7 +7900,7 @@ function OhhwellsBridge() {
7756
7900
  }
7757
7901
  window.postMessage({ type: "ow:schedule-config", insertAfter: insertAfterVal, scheduleId: null }, "*");
7758
7902
  }, [isEditMode]);
7759
- const deactivate = (0, import_react8.useCallback)(() => {
7903
+ const deactivate = (0, import_react9.useCallback)(() => {
7760
7904
  const el = activeElRef.current;
7761
7905
  if (!el) return;
7762
7906
  const key = el.dataset.ohwKey;
@@ -7787,7 +7931,7 @@ function OhhwellsBridge() {
7787
7931
  setToolbarShowEditLink(false);
7788
7932
  postToParent2({ type: "ow:exit-edit" });
7789
7933
  }, [postToParent2]);
7790
- const deselect = (0, import_react8.useCallback)(() => {
7934
+ const deselect = (0, import_react9.useCallback)(() => {
7791
7935
  selectedElRef.current = null;
7792
7936
  setReorderHrefKey(null);
7793
7937
  setReorderDragDisabled(false);
@@ -7801,7 +7945,7 @@ function OhhwellsBridge() {
7801
7945
  setToolbarVariant("none");
7802
7946
  }
7803
7947
  }, []);
7804
- const reselectNavigationItem = (0, import_react8.useCallback)((navAnchor) => {
7948
+ const reselectNavigationItem = (0, import_react9.useCallback)((navAnchor) => {
7805
7949
  selectedElRef.current = navAnchor;
7806
7950
  const { key, disabled } = getNavigationItemReorderState(navAnchor);
7807
7951
  setReorderHrefKey(key);
@@ -7811,7 +7955,7 @@ function OhhwellsBridge() {
7811
7955
  setToolbarShowEditLink(false);
7812
7956
  setActiveCommands(/* @__PURE__ */ new Set());
7813
7957
  }, []);
7814
- const commitNavigationTextEdit = (0, import_react8.useCallback)((navAnchor) => {
7958
+ const commitNavigationTextEdit = (0, import_react9.useCallback)((navAnchor) => {
7815
7959
  const el = activeElRef.current;
7816
7960
  if (!el) return;
7817
7961
  const key = el.dataset.ohwKey;
@@ -7837,7 +7981,7 @@ function OhhwellsBridge() {
7837
7981
  postToParent2({ type: "ow:exit-edit" });
7838
7982
  reselectNavigationItem(navAnchor);
7839
7983
  }, [postToParent2, reselectNavigationItem]);
7840
- const handleAddTopLevelNavItem = (0, import_react8.useCallback)(() => {
7984
+ const handleAddTopLevelNavItem = (0, import_react9.useCallback)(() => {
7841
7985
  const items = listNavbarItems();
7842
7986
  addNavAfterAnchorRef.current = items[items.length - 1] ?? null;
7843
7987
  deselectRef.current();
@@ -7849,17 +7993,17 @@ function OhhwellsBridge() {
7849
7993
  intent: "add-nav"
7850
7994
  });
7851
7995
  }, []);
7852
- const handleItemDragStart = (0, import_react8.useCallback)(() => {
7996
+ const handleItemDragStart = (0, import_react9.useCallback)(() => {
7853
7997
  siblingHintElRef.current = null;
7854
7998
  setSiblingHintRect(null);
7855
7999
  setIsItemDragging(true);
7856
8000
  }, []);
7857
- const handleItemDragEnd = (0, import_react8.useCallback)(() => {
8001
+ const handleItemDragEnd = (0, import_react9.useCallback)(() => {
7858
8002
  setIsItemDragging(false);
7859
8003
  }, []);
7860
8004
  reselectNavigationItemRef.current = reselectNavigationItem;
7861
8005
  commitNavigationTextEditRef.current = commitNavigationTextEdit;
7862
- const select = (0, import_react8.useCallback)((anchor) => {
8006
+ const select = (0, import_react9.useCallback)((anchor) => {
7863
8007
  if (!isNavigationItem(anchor)) return;
7864
8008
  if (activeElRef.current) deactivate();
7865
8009
  selectedElRef.current = anchor;
@@ -7879,7 +8023,7 @@ function OhhwellsBridge() {
7879
8023
  setToolbarShowEditLink(false);
7880
8024
  setActiveCommands(/* @__PURE__ */ new Set());
7881
8025
  }, [deactivate]);
7882
- const selectFrame = (0, import_react8.useCallback)((el) => {
8026
+ const selectFrame = (0, import_react9.useCallback)((el) => {
7883
8027
  if (!isNavigationContainer(el)) return;
7884
8028
  if (activeElRef.current) deactivate();
7885
8029
  selectedElRef.current = el;
@@ -7898,7 +8042,7 @@ function OhhwellsBridge() {
7898
8042
  setToolbarShowEditLink(false);
7899
8043
  setActiveCommands(/* @__PURE__ */ new Set());
7900
8044
  }, [deactivate]);
7901
- const activate = (0, import_react8.useCallback)((el, options) => {
8045
+ const activate = (0, import_react9.useCallback)((el, options) => {
7902
8046
  if (activeElRef.current === el) return;
7903
8047
  selectedElRef.current = null;
7904
8048
  deactivate();
@@ -7938,7 +8082,7 @@ function OhhwellsBridge() {
7938
8082
  selectRef.current = select;
7939
8083
  selectFrameRef.current = selectFrame;
7940
8084
  deselectRef.current = deselect;
7941
- (0, import_react8.useLayoutEffect)(() => {
8085
+ (0, import_react9.useLayoutEffect)(() => {
7942
8086
  if (!subdomain || isEditMode) {
7943
8087
  setFetchState("done");
7944
8088
  return;
@@ -7948,6 +8092,7 @@ function OhhwellsBridge() {
7948
8092
  for (const [key, val] of Object.entries(content)) {
7949
8093
  if (key === "__ohw_sections") continue;
7950
8094
  if (applyVideoSettingNode(key, val)) continue;
8095
+ if (applyCarouselNode(key, val)) continue;
7951
8096
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
7952
8097
  if (el.dataset.ohwEditable === "image") {
7953
8098
  const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
@@ -8007,7 +8152,7 @@ function OhhwellsBridge() {
8007
8152
  cancelled = true;
8008
8153
  };
8009
8154
  }, [subdomain, isEditMode]);
8010
- (0, import_react8.useEffect)(() => {
8155
+ (0, import_react9.useEffect)(() => {
8011
8156
  if (!subdomain || isEditMode) return;
8012
8157
  let debounceTimer = null;
8013
8158
  let observer = null;
@@ -8020,6 +8165,7 @@ function OhhwellsBridge() {
8020
8165
  for (const [key, val] of Object.entries(content)) {
8021
8166
  if (key === "__ohw_sections") continue;
8022
8167
  if (applyVideoSettingNode(key, val)) continue;
8168
+ if (applyCarouselNode(key, val)) continue;
8023
8169
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
8024
8170
  if (el.dataset.ohwEditable === "image") {
8025
8171
  const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
@@ -8056,16 +8202,16 @@ function OhhwellsBridge() {
8056
8202
  if (debounceTimer) clearTimeout(debounceTimer);
8057
8203
  };
8058
8204
  }, [subdomain, isEditMode, pathname]);
8059
- (0, import_react8.useLayoutEffect)(() => {
8205
+ (0, import_react9.useLayoutEffect)(() => {
8060
8206
  const el = document.getElementById("ohw-loader");
8061
8207
  if (!el) return;
8062
8208
  const visible = Boolean(subdomain) && fetchState !== "done";
8063
8209
  el.style.display = visible ? "flex" : "none";
8064
8210
  }, [subdomain, fetchState]);
8065
- (0, import_react8.useEffect)(() => {
8211
+ (0, import_react9.useEffect)(() => {
8066
8212
  postToParent2({ type: "ow:navigation", path: pathname });
8067
8213
  }, [pathname, postToParent2]);
8068
- (0, import_react8.useEffect)(() => {
8214
+ (0, import_react9.useEffect)(() => {
8069
8215
  if (!isEditMode) return;
8070
8216
  if (linkPopoverSessionRef.current?.intent === "add-nav") return;
8071
8217
  if (document.querySelector("[data-ohw-section-picker]")) return;
@@ -8073,7 +8219,7 @@ function OhhwellsBridge() {
8073
8219
  deselectRef.current();
8074
8220
  deactivateRef.current();
8075
8221
  }, [pathname, isEditMode]);
8076
- (0, import_react8.useEffect)(() => {
8222
+ (0, import_react9.useEffect)(() => {
8077
8223
  const contentForNav = () => {
8078
8224
  if (isEditMode) return editContentRef.current;
8079
8225
  if (!subdomain) return {};
@@ -8089,7 +8235,7 @@ function OhhwellsBridge() {
8089
8235
  observer.observe(nav, { childList: true, subtree: true });
8090
8236
  return () => observer.disconnect();
8091
8237
  }, [isEditMode, pathname, subdomain, fetchState]);
8092
- (0, import_react8.useEffect)(() => {
8238
+ (0, import_react9.useEffect)(() => {
8093
8239
  if (!isEditMode) return;
8094
8240
  const measure = () => {
8095
8241
  const h = document.body.scrollHeight;
@@ -8113,7 +8259,7 @@ function OhhwellsBridge() {
8113
8259
  window.removeEventListener("resize", handleResize);
8114
8260
  };
8115
8261
  }, [pathname, isEditMode, postToParent2]);
8116
- (0, import_react8.useEffect)(() => {
8262
+ (0, import_react9.useEffect)(() => {
8117
8263
  if (!subdomainFromQuery || isEditMode) return;
8118
8264
  const handleClick = (e) => {
8119
8265
  const anchor = e.target.closest("a");
@@ -8129,7 +8275,7 @@ function OhhwellsBridge() {
8129
8275
  document.addEventListener("click", handleClick, true);
8130
8276
  return () => document.removeEventListener("click", handleClick, true);
8131
8277
  }, [subdomainFromQuery, isEditMode, router]);
8132
- (0, import_react8.useEffect)(() => {
8278
+ (0, import_react9.useEffect)(() => {
8133
8279
  if (!isEditMode) {
8134
8280
  editStylesRef.current?.base.remove();
8135
8281
  editStylesRef.current?.forceHover.remove();
@@ -8958,6 +9104,7 @@ function OhhwellsBridge() {
8958
9104
  continue;
8959
9105
  }
8960
9106
  if (applyVideoSettingNode(key, val)) continue;
9107
+ if (applyCarouselNode(key, val)) continue;
8961
9108
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
8962
9109
  if (el.dataset.ohwEditable === "image") {
8963
9110
  const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
@@ -9222,6 +9369,48 @@ function OhhwellsBridge() {
9222
9369
  if (e.data?.type !== "ow:canvas-height" || typeof e.data.height !== "number") return;
9223
9370
  document.documentElement.style.setProperty("--ohw-canvas-h", `${e.data.height}px`);
9224
9371
  };
9372
+ const handleCarouselChange = (e) => {
9373
+ if (e.data?.type !== "ow:carousel-change") return;
9374
+ const { key, images } = e.data;
9375
+ if (!key || !Array.isArray(images)) return;
9376
+ const text = JSON.stringify(images);
9377
+ applyCarouselValue(key, images);
9378
+ editContentRef.current = { ...editContentRef.current, [key]: text };
9379
+ postToParentRef.current({ type: "ow:change", nodes: [{ key, text }] });
9380
+ setCarouselHover(null);
9381
+ };
9382
+ const findCarouselAtPoint = (clientX, clientY) => {
9383
+ const containers = Array.from(document.querySelectorAll(`[${CAROUSEL_ATTR}]`));
9384
+ for (let i = containers.length - 1; i >= 0; i--) {
9385
+ const r2 = containers[i].getBoundingClientRect();
9386
+ if (clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom) {
9387
+ return containers[i];
9388
+ }
9389
+ }
9390
+ return null;
9391
+ };
9392
+ const isPointOverEditable = (scope, clientX, clientY) => {
9393
+ const editables = scope.querySelectorAll("[data-ohw-editable], [data-ohw-href-key]");
9394
+ for (const el of editables) {
9395
+ const r2 = el.getBoundingClientRect();
9396
+ if (clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom) return true;
9397
+ }
9398
+ return false;
9399
+ };
9400
+ const handleCarouselHover = (e) => {
9401
+ const container = findCarouselAtPoint(e.clientX, e.clientY);
9402
+ const scope = container?.closest("[data-ohw-section]") ?? container?.parentElement ?? null;
9403
+ if (!container || !scope || isPointOverEditable(scope, e.clientX, e.clientY)) {
9404
+ setCarouselHover((prev) => prev ? null : prev);
9405
+ return;
9406
+ }
9407
+ const key = container.getAttribute("data-ohw-key") ?? "";
9408
+ if (!key) return;
9409
+ const r2 = getVisibleRect(container);
9410
+ setCarouselHover(
9411
+ (prev) => prev && prev.key === key && prev.rect.top === r2.top && prev.rect.left === r2.left && prev.rect.width === r2.width && prev.rect.height === r2.height ? prev : { key, rect: { top: r2.top, left: r2.left, width: r2.width, height: r2.height } }
9412
+ );
9413
+ };
9225
9414
  const applyToolbarPos = (rect) => {
9226
9415
  const ps = parentScrollRef.current;
9227
9416
  const approxW = 330;
@@ -9330,6 +9519,7 @@ function OhhwellsBridge() {
9330
9519
  window.addEventListener("message", handleRemoveSchedulingSection);
9331
9520
  window.addEventListener("message", handleImageUrl);
9332
9521
  window.addEventListener("message", handleImageUploading);
9522
+ window.addEventListener("message", handleCarouselChange);
9333
9523
  window.addEventListener("message", handleCanvasHeight);
9334
9524
  window.addEventListener("message", handleParentScroll);
9335
9525
  window.addEventListener("message", handlePointerSync);
@@ -9347,6 +9537,7 @@ function OhhwellsBridge() {
9347
9537
  document.addEventListener("mouseover", handleMouseOver, true);
9348
9538
  document.addEventListener("mouseout", handleMouseOut, true);
9349
9539
  document.addEventListener("mousemove", handleMouseMove, true);
9540
+ document.addEventListener("mousemove", handleCarouselHover, true);
9350
9541
  document.addEventListener("mouseleave", handleDocMouseLeave);
9351
9542
  document.addEventListener("dragover", handleDragOver, true);
9352
9543
  document.addEventListener("dragleave", handleDragLeave, true);
@@ -9362,6 +9553,7 @@ function OhhwellsBridge() {
9362
9553
  document.removeEventListener("mouseover", handleMouseOver, true);
9363
9554
  document.removeEventListener("mouseout", handleMouseOut, true);
9364
9555
  document.removeEventListener("mousemove", handleMouseMove, true);
9556
+ document.removeEventListener("mousemove", handleCarouselHover, true);
9365
9557
  document.removeEventListener("mouseleave", handleDocMouseLeave);
9366
9558
  document.removeEventListener("dragover", handleDragOver, true);
9367
9559
  document.removeEventListener("dragleave", handleDragLeave, true);
@@ -9377,6 +9569,7 @@ function OhhwellsBridge() {
9377
9569
  window.removeEventListener("message", handleRemoveSchedulingSection);
9378
9570
  window.removeEventListener("message", handleImageUrl);
9379
9571
  window.removeEventListener("message", handleImageUploading);
9572
+ window.removeEventListener("message", handleCarouselChange);
9380
9573
  window.removeEventListener("message", handleCanvasHeight);
9381
9574
  window.removeEventListener("message", handleParentScroll);
9382
9575
  window.removeEventListener("resize", handleViewportResize);
@@ -9390,7 +9583,7 @@ function OhhwellsBridge() {
9390
9583
  if (imageShowTimerRef.current) clearTimeout(imageShowTimerRef.current);
9391
9584
  };
9392
9585
  }, [isEditMode, refreshStateRules]);
9393
- (0, import_react8.useEffect)(() => {
9586
+ (0, import_react9.useEffect)(() => {
9394
9587
  const handler = (e) => {
9395
9588
  if (e.data?.type !== "ow:request-schedule-config") return;
9396
9589
  const insertAfterVal = e.data.insertAfter;
@@ -9406,7 +9599,7 @@ function OhhwellsBridge() {
9406
9599
  window.addEventListener("message", handler);
9407
9600
  return () => window.removeEventListener("message", handler);
9408
9601
  }, [processConfigRequest]);
9409
- (0, import_react8.useEffect)(() => {
9602
+ (0, import_react9.useEffect)(() => {
9410
9603
  if (!isEditMode) return;
9411
9604
  document.querySelectorAll("[data-ohw-active-state]").forEach((el) => {
9412
9605
  el.removeAttribute("data-ohw-active-state");
@@ -9435,19 +9628,19 @@ function OhhwellsBridge() {
9435
9628
  clearTimeout(timer);
9436
9629
  };
9437
9630
  }, [pathname, isEditMode, refreshStateRules, postToParent2]);
9438
- (0, import_react8.useEffect)(() => {
9631
+ (0, import_react9.useEffect)(() => {
9439
9632
  scrollToHashSectionWhenReady();
9440
9633
  const onHashChange = () => scrollToHashSectionWhenReady();
9441
9634
  window.addEventListener("hashchange", onHashChange);
9442
9635
  return () => window.removeEventListener("hashchange", onHashChange);
9443
9636
  }, [pathname]);
9444
- const handleCommand = (0, import_react8.useCallback)((cmd) => {
9637
+ const handleCommand = (0, import_react9.useCallback)((cmd) => {
9445
9638
  document.execCommand(cmd, false);
9446
9639
  activeElRef.current?.focus();
9447
9640
  if (activeElRef.current) setToolbarRect(getEditMeasureEl(activeElRef.current).getBoundingClientRect());
9448
9641
  refreshActiveCommandsRef.current();
9449
9642
  }, []);
9450
- const handleStateChange = (0, import_react8.useCallback)((state) => {
9643
+ const handleStateChange = (0, import_react9.useCallback)((state) => {
9451
9644
  if (!activeStateElRef.current) return;
9452
9645
  const el = activeStateElRef.current;
9453
9646
  if (state === "Default") {
@@ -9460,11 +9653,11 @@ function OhhwellsBridge() {
9460
9653
  }
9461
9654
  setToggleState((prev) => prev ? { ...prev, activeState: state } : null);
9462
9655
  }, [deactivate]);
9463
- const closeLinkPopover = (0, import_react8.useCallback)(() => {
9656
+ const closeLinkPopover = (0, import_react9.useCallback)(() => {
9464
9657
  addNavAfterAnchorRef.current = null;
9465
9658
  setLinkPopover(null);
9466
9659
  }, []);
9467
- const openLinkPopoverForActive = (0, import_react8.useCallback)(() => {
9660
+ const openLinkPopoverForActive = (0, import_react9.useCallback)(() => {
9468
9661
  const hrefCtx = getHrefKeyFromElement(activeElRef.current);
9469
9662
  if (!hrefCtx) return;
9470
9663
  bumpLinkPopoverGrace();
@@ -9475,7 +9668,7 @@ function OhhwellsBridge() {
9475
9668
  });
9476
9669
  deactivate();
9477
9670
  }, [deactivate]);
9478
- const openLinkPopoverForSelected = (0, import_react8.useCallback)(() => {
9671
+ const openLinkPopoverForSelected = (0, import_react9.useCallback)(() => {
9479
9672
  const anchor = selectedElRef.current;
9480
9673
  if (!anchor) return;
9481
9674
  const key = anchor.getAttribute("data-ohw-href-key");
@@ -9488,7 +9681,7 @@ function OhhwellsBridge() {
9488
9681
  });
9489
9682
  deselect();
9490
9683
  }, [deselect]);
9491
- const handleLinkPopoverSubmit = (0, import_react8.useCallback)(
9684
+ const handleLinkPopoverSubmit = (0, import_react9.useCallback)(
9492
9685
  (target) => {
9493
9686
  const session = linkPopoverSessionRef.current;
9494
9687
  if (!session) return;
@@ -9547,13 +9740,19 @@ function OhhwellsBridge() {
9547
9740
  const showEditLink = toolbarShowEditLink;
9548
9741
  const currentSections = sectionsByPath[pathname] ?? [];
9549
9742
  linkPopoverOpenRef.current = linkPopover !== null;
9550
- const handleMediaReplace = (0, import_react8.useCallback)(
9743
+ const handleMediaReplace = (0, import_react9.useCallback)(
9551
9744
  (key) => {
9552
9745
  postToParent2({ type: "ow:image-pick", key, elementType: mediaHover?.elementType ?? "image" });
9553
9746
  },
9554
9747
  [postToParent2, mediaHover?.elementType]
9555
9748
  );
9556
- const handleMediaFadeOutComplete = (0, import_react8.useCallback)((key) => {
9749
+ const handleEditCarousel = (0, import_react9.useCallback)(
9750
+ (key) => {
9751
+ postToParent2({ type: "ow:carousel-open", key, images: readCarouselValue(key) });
9752
+ },
9753
+ [postToParent2]
9754
+ );
9755
+ const handleMediaFadeOutComplete = (0, import_react9.useCallback)((key) => {
9557
9756
  setUploadingRects((prev) => {
9558
9757
  if (!(key in prev)) return prev;
9559
9758
  const next = { ...prev };
@@ -9561,7 +9760,7 @@ function OhhwellsBridge() {
9561
9760
  return next;
9562
9761
  });
9563
9762
  }, []);
9564
- const handleVideoSettingsChange = (0, import_react8.useCallback)(
9763
+ const handleVideoSettingsChange = (0, import_react9.useCallback)(
9565
9764
  (key, settings) => {
9566
9765
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
9567
9766
  const video = getVideoEl(el);
@@ -9584,9 +9783,9 @@ function OhhwellsBridge() {
9584
9783
  [postToParent2]
9585
9784
  );
9586
9785
  return bridgeRoot ? (0, import_react_dom3.createPortal)(
9587
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
9588
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
9589
- Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
9786
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
9787
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
9788
+ Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
9590
9789
  MediaOverlay,
9591
9790
  {
9592
9791
  hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
@@ -9597,7 +9796,7 @@ function OhhwellsBridge() {
9597
9796
  },
9598
9797
  `uploading-${key}`
9599
9798
  )),
9600
- mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
9799
+ mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
9601
9800
  MediaOverlay,
9602
9801
  {
9603
9802
  hover: mediaHover,
@@ -9606,17 +9805,18 @@ function OhhwellsBridge() {
9606
9805
  onVideoSettingsChange: handleVideoSettingsChange
9607
9806
  }
9608
9807
  ),
9609
- siblingHintRect && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
9610
- hoveredNavContainerRect && toolbarVariant !== "select-frame" && !linkPopover && !isItemDragging && !siblingHintRect && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
9611
- toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
9808
+ carouselHover && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(CarouselOverlay, { hover: carouselHover, onEdit: handleEditCarousel }),
9809
+ siblingHintRect && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
9810
+ hoveredNavContainerRect && toolbarVariant !== "select-frame" && !linkPopover && !isItemDragging && !siblingHintRect && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
9811
+ toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
9612
9812
  NavbarContainerChrome,
9613
9813
  {
9614
9814
  rect: toolbarRect,
9615
9815
  onAdd: handleAddTopLevelNavItem
9616
9816
  }
9617
9817
  ),
9618
- hoveredItemRect && !hoveredNavContainerRect && !siblingHintRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
9619
- toolbarRect && (toolbarVariant === "link-action" || toolbarVariant === "select-frame") && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
9818
+ hoveredItemRect && !hoveredNavContainerRect && !siblingHintRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
9819
+ toolbarRect && (toolbarVariant === "link-action" || toolbarVariant === "select-frame") && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
9620
9820
  ItemInteractionLayer,
9621
9821
  {
9622
9822
  rect: toolbarRect,
@@ -9627,7 +9827,7 @@ function OhhwellsBridge() {
9627
9827
  dragHandleLabel: reorderHrefKey ? `Reorder ${reorderHrefKey}` : "Reorder item",
9628
9828
  onDragHandleDragStart: handleItemDragStart,
9629
9829
  onDragHandleDragEnd: handleItemDragEnd,
9630
- toolbar: toolbarVariant === "link-action" && !isItemDragging ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
9830
+ toolbar: toolbarVariant === "link-action" && !isItemDragging ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
9631
9831
  ItemActionToolbar,
9632
9832
  {
9633
9833
  onEditLink: openLinkPopoverForSelected,
@@ -9638,8 +9838,8 @@ function OhhwellsBridge() {
9638
9838
  ) : void 0
9639
9839
  }
9640
9840
  ),
9641
- toolbarRect && toolbarVariant === "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
9642
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
9841
+ toolbarRect && toolbarVariant === "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
9842
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
9643
9843
  EditGlowChrome,
9644
9844
  {
9645
9845
  rect: toolbarRect,
@@ -9648,7 +9848,7 @@ function OhhwellsBridge() {
9648
9848
  dragDisabled: reorderDragDisabled
9649
9849
  }
9650
9850
  ),
9651
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
9851
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
9652
9852
  FloatingToolbar,
9653
9853
  {
9654
9854
  rect: toolbarRect,
@@ -9661,7 +9861,7 @@ function OhhwellsBridge() {
9661
9861
  }
9662
9862
  )
9663
9863
  ] }),
9664
- maxBadge && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
9864
+ maxBadge && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
9665
9865
  "div",
9666
9866
  {
9667
9867
  "data-ohw-max-badge": "",
@@ -9687,7 +9887,7 @@ function OhhwellsBridge() {
9687
9887
  ]
9688
9888
  }
9689
9889
  ),
9690
- toggleState && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
9890
+ toggleState && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
9691
9891
  StateToggle,
9692
9892
  {
9693
9893
  rect: toggleState.rect,
@@ -9696,15 +9896,15 @@ function OhhwellsBridge() {
9696
9896
  onStateChange: handleStateChange
9697
9897
  }
9698
9898
  ),
9699
- sectionGap && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
9899
+ sectionGap && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
9700
9900
  "div",
9701
9901
  {
9702
9902
  "data-ohw-section-insert-line": "",
9703
9903
  className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
9704
9904
  style: { top: sectionGap.y, transform: "translateY(-50%)" },
9705
9905
  children: [
9706
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
9707
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
9906
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
9907
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
9708
9908
  Badge,
9709
9909
  {
9710
9910
  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",
@@ -9717,11 +9917,11 @@ function OhhwellsBridge() {
9717
9917
  children: "Add Section"
9718
9918
  }
9719
9919
  ),
9720
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
9920
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
9721
9921
  ]
9722
9922
  }
9723
9923
  ),
9724
- linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
9924
+ linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
9725
9925
  LinkPopover,
9726
9926
  {
9727
9927
  panelRef: linkPopoverPanelRef,
@@ -9738,15 +9938,15 @@ function OhhwellsBridge() {
9738
9938
  },
9739
9939
  linkPopover.key
9740
9940
  ) : null,
9741
- sectionGap && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
9941
+ sectionGap && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
9742
9942
  "div",
9743
9943
  {
9744
9944
  "data-ohw-section-insert-line": "",
9745
9945
  className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
9746
9946
  style: { top: sectionGap.y, transform: "translateY(-50%)" },
9747
9947
  children: [
9748
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
9749
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
9948
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
9949
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
9750
9950
  Badge,
9751
9951
  {
9752
9952
  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",
@@ -9759,7 +9959,7 @@ function OhhwellsBridge() {
9759
9959
  children: "Add Section"
9760
9960
  }
9761
9961
  ),
9762
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
9962
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
9763
9963
  ]
9764
9964
  }
9765
9965
  )
@@ -9770,7 +9970,7 @@ function OhhwellsBridge() {
9770
9970
 
9771
9971
  // src/ui/drop-indicator.tsx
9772
9972
  var React10 = __toESM(require("react"), 1);
9773
- var import_jsx_runtime24 = require("react/jsx-runtime");
9973
+ var import_jsx_runtime25 = require("react/jsx-runtime");
9774
9974
  var dropIndicatorVariants = cva(
9775
9975
  "ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
9776
9976
  {
@@ -9794,7 +9994,7 @@ var dropIndicatorVariants = cva(
9794
9994
  );
9795
9995
  var DropIndicator = React10.forwardRef(
9796
9996
  ({ className, direction, state, ...props }, ref) => {
9797
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
9997
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
9798
9998
  "div",
9799
9999
  {
9800
10000
  ref,
@@ -9837,6 +10037,7 @@ DropIndicator.displayName = "DropIndicator";
9837
10037
  isValidUrl,
9838
10038
  parseTarget,
9839
10039
  toggleVariants,
10040
+ useOhwCarousel,
9840
10041
  validateUrlInput
9841
10042
  });
9842
10043
  //# sourceMappingURL=index.cjs.map