@pactor-app/ui 1.46.0 → 1.47.0

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.
@@ -307,14 +307,14 @@ function InteractionProvider({
307
307
  }
308
308
 
309
309
  // src/interaction/host.tsx
310
- import { XIcon } from "lucide-react";
310
+ import { Loader2, XIcon } from "lucide-react";
311
311
  import {
312
312
  createPageRuntime,
313
313
  PageRuntimeView,
314
314
  useI18n as useI18n2,
315
315
  useRenderer
316
316
  } from "@pactor-app/runtime";
317
- import { useEffect as useEffect2, useState as useState2, useSyncExternalStore } from "react";
317
+ import { useEffect as useEffect2, useRef, useState as useState2, useSyncExternalStore } from "react";
318
318
  import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
319
319
  function toCssWidth(width) {
320
320
  if (width === void 0) {
@@ -357,7 +357,18 @@ function OverlayEntryView({
357
357
  resolvePage
358
358
  }) {
359
359
  const { t } = useI18n2();
360
+ const childRuntimeRef = useRef(null);
360
361
  const handleCancel = () => manager.close(entry.id);
362
+ const handleConfirm = () => {
363
+ const footer2 = entry.footer ?? {};
364
+ const forms = entry.page ? childRuntimeRef.current?.context.forms : renderer.context.forms;
365
+ const handle = forms?.get(footer2.confirmForm ?? "default");
366
+ if (handle?.submit) {
367
+ handle.submit();
368
+ return;
369
+ }
370
+ manager.close(entry.id, { success: true });
371
+ };
361
372
  let body = null;
362
373
  if (entry.content) {
363
374
  body = renderer.renderChildren([entry.content], {
@@ -370,12 +381,24 @@ function OverlayEntryView({
370
381
  {
371
382
  entry,
372
383
  renderer,
373
- resolvePage
384
+ resolvePage,
385
+ onRuntime: (runtime) => {
386
+ childRuntimeRef.current = runtime;
387
+ }
374
388
  }
375
389
  );
376
390
  }
391
+ const footer = entry.footer ? /* @__PURE__ */ jsx2(
392
+ OverlayFooter,
393
+ {
394
+ footer: entry.footer,
395
+ slot: entry.type === "drawer" ? "drawer-footer" : "overlay-modal-footer",
396
+ onCancel: handleCancel,
397
+ onConfirm: handleConfirm
398
+ }
399
+ ) : null;
377
400
  if (entry.type === "drawer") {
378
- return /* @__PURE__ */ jsx2(ShadcnDrawerView, { entry, onCancel: handleCancel, children: body });
401
+ return /* @__PURE__ */ jsx2(ShadcnDrawerView, { entry, onCancel: handleCancel, footer, children: body });
379
402
  }
380
403
  return /* @__PURE__ */ jsx2(
381
404
  Dialog,
@@ -412,16 +435,64 @@ function OverlayEntryView({
412
435
  }
413
436
  )
414
437
  ] }),
415
- /* @__PURE__ */ jsx2("div", { "data-slot": "overlay-modal-body", children: body })
438
+ /* @__PURE__ */ jsx2("div", { "data-slot": "overlay-modal-body", children: body }),
439
+ footer
416
440
  ]
417
441
  }
418
442
  )
419
443
  }
420
444
  );
421
445
  }
446
+ function OverlayFooter({
447
+ footer,
448
+ slot,
449
+ onCancel,
450
+ onConfirm
451
+ }) {
452
+ const { t } = useI18n2();
453
+ if (footer.hideCancel && footer.hideConfirm) {
454
+ return null;
455
+ }
456
+ const confirmBusy = footer.confirmLoading === true;
457
+ return /* @__PURE__ */ jsxs2(
458
+ "div",
459
+ {
460
+ "data-slot": slot,
461
+ className: cn(
462
+ "flex items-center justify-end gap-2",
463
+ slot === "drawer-footer" && "border-t border-border px-6 py-4"
464
+ ),
465
+ children: [
466
+ footer.hideCancel ? null : /* @__PURE__ */ jsx2(
467
+ Button,
468
+ {
469
+ variant: "outline",
470
+ disabled: confirmBusy,
471
+ onClick: onCancel,
472
+ "data-slot": "overlay-cancel",
473
+ children: footer.cancelText ?? t("pactor.overlay.cancel")
474
+ }
475
+ ),
476
+ footer.hideConfirm ? null : /* @__PURE__ */ jsxs2(
477
+ Button,
478
+ {
479
+ disabled: footer.confirmDisabled === true || confirmBusy,
480
+ onClick: onConfirm,
481
+ "data-slot": "overlay-confirm",
482
+ children: [
483
+ confirmBusy ? /* @__PURE__ */ jsx2(Loader2, { className: "animate-spin" }) : null,
484
+ footer.confirmText ?? t("pactor.overlay.confirm")
485
+ ]
486
+ }
487
+ )
488
+ ]
489
+ }
490
+ );
491
+ }
422
492
  function ShadcnDrawerView({
423
493
  entry,
424
494
  onCancel,
495
+ footer,
425
496
  children
426
497
  }) {
427
498
  const { t } = useI18n2();
@@ -465,7 +536,8 @@ function ShadcnDrawerView({
465
536
  ]
466
537
  }
467
538
  ),
468
- /* @__PURE__ */ jsx2("div", { "data-slot": "drawer-body", className: "flex-1 overflow-auto p-6", children })
539
+ /* @__PURE__ */ jsx2("div", { "data-slot": "drawer-body", className: "flex-1 overflow-auto p-6", children }),
540
+ footer
469
541
  ]
470
542
  }
471
543
  )
@@ -475,7 +547,8 @@ function ShadcnDrawerView({
475
547
  function PageOverlayBody({
476
548
  entry,
477
549
  renderer,
478
- resolvePage
550
+ resolvePage,
551
+ onRuntime
479
552
  }) {
480
553
  const [child, setChild] = useState2(null);
481
554
  const [error, setError] = useState2(null);
@@ -509,6 +582,7 @@ function PageOverlayBody({
509
582
  route: { params: entry.params ?? {} }
510
583
  });
511
584
  setChild(created);
585
+ onRuntime?.(created);
512
586
  } catch (cause) {
513
587
  if (!cancelled) {
514
588
  setError(cause instanceof Error ? cause : new Error(String(cause)));
@@ -517,6 +591,7 @@ function PageOverlayBody({
517
591
  })();
518
592
  return () => {
519
593
  cancelled = true;
594
+ onRuntime?.(null);
520
595
  void created?.destroy();
521
596
  };
522
597
  }, [entry.id]);
@@ -2,7 +2,7 @@ import {
2
2
  Icon,
3
3
  Menu,
4
4
  Sidebar
5
- } from "./chunk-FU4P7CAM.js";
5
+ } from "./chunk-B2Y6JC36.js";
6
6
  import {
7
7
  Accordion,
8
8
  AccordionContent,
@@ -15,7 +15,7 @@ import {
15
15
  Popover,
16
16
  PopoverContent,
17
17
  PopoverTrigger
18
- } from "./chunk-7OBUSV5S.js";
18
+ } from "./chunk-YHTRCBKF.js";
19
19
  import {
20
20
  cn
21
21
  } from "./chunk-WKJUCGV4.js";