@nimblebrain/synapse 0.17.1 → 0.19.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.
Files changed (95) hide show
  1. package/README.md +20 -18
  2. package/dist/chunk-54W6IAHM.js +24 -0
  3. package/dist/chunk-54W6IAHM.js.map +1 -0
  4. package/dist/{chunk-UPDBDXQB.js → chunk-DRLVEHCD.js} +6 -13
  5. package/dist/chunk-DRLVEHCD.js.map +1 -0
  6. package/dist/chunk-NP7ROSH2.cjs +33 -0
  7. package/dist/chunk-NP7ROSH2.cjs.map +1 -0
  8. package/dist/{chunk-SRQNQ26I.js → chunk-OYLZ5OCK.js} +4 -4
  9. package/dist/chunk-OYLZ5OCK.js.map +1 -0
  10. package/dist/chunk-P5DBJFSQ.js +8459 -0
  11. package/dist/chunk-P5DBJFSQ.js.map +1 -0
  12. package/dist/chunk-PZ5AY32C.js +9 -0
  13. package/dist/chunk-PZ5AY32C.js.map +1 -0
  14. package/dist/chunk-Q7SFCCGT.cjs +11 -0
  15. package/dist/chunk-Q7SFCCGT.cjs.map +1 -0
  16. package/dist/chunk-QXDCA7QW.cjs +8466 -0
  17. package/dist/chunk-QXDCA7QW.cjs.map +1 -0
  18. package/dist/{chunk-EHLQWCYV.cjs → chunk-RU64F5RS.cjs} +7 -7
  19. package/dist/chunk-RU64F5RS.cjs.map +1 -0
  20. package/dist/{chunk-TXJMGQYF.cjs → chunk-SZWHFTXV.cjs} +5 -13
  21. package/dist/chunk-SZWHFTXV.cjs.map +1 -0
  22. package/dist/codegen/cli.cjs +4 -4
  23. package/dist/codegen/cli.js +4 -4
  24. package/dist/codegen/index.cjs +1 -0
  25. package/dist/codegen/index.d.cts +1 -1
  26. package/dist/codegen/index.d.ts +1 -1
  27. package/dist/codegen/index.js +1 -0
  28. package/dist/connect.iife.global.js +66 -43
  29. package/dist/{detect-Bf8Q_0dK.d.ts → detect-DBwc8a21.d.ts} +2 -2
  30. package/dist/{detect-BHYg26_d.d.cts → detect-DZMJsyvZ.d.cts} +2 -2
  31. package/dist/host/index.cjs +15 -14
  32. package/dist/host/index.d.cts +3 -3
  33. package/dist/host/index.d.ts +3 -3
  34. package/dist/host/index.js +3 -2
  35. package/dist/index.cjs +42 -18
  36. package/dist/index.cjs.map +1 -1
  37. package/dist/index.d.cts +40 -13
  38. package/dist/index.d.ts +40 -13
  39. package/dist/index.js +35 -3
  40. package/dist/index.js.map +1 -1
  41. package/dist/react/index.cjs +12 -10
  42. package/dist/react/index.cjs.map +1 -1
  43. package/dist/react/index.d.cts +14 -5
  44. package/dist/react/index.d.ts +14 -5
  45. package/dist/react/index.js +7 -5
  46. package/dist/react/index.js.map +1 -1
  47. package/dist/schema-reader-GM4A4L44.js +4 -0
  48. package/dist/{schema-reader-776246MJ.js.map → schema-reader-GM4A4L44.js.map} +1 -1
  49. package/dist/{schema-reader-B6LTGBMJ.cjs → schema-reader-MWBRQ2TQ.cjs} +3 -2
  50. package/dist/{schema-reader-B6LTGBMJ.cjs.map → schema-reader-MWBRQ2TQ.cjs.map} +1 -1
  51. package/dist/{server-QIYIJHD5.cjs → server-LR6T6C44.cjs} +32 -20
  52. package/dist/server-LR6T6C44.cjs.map +1 -0
  53. package/dist/{server-5N76YCWC.js → server-UHPEE55X.js} +32 -21
  54. package/dist/server-UHPEE55X.js.map +1 -0
  55. package/dist/synapse-runtime.iife.global.js +66 -43
  56. package/dist/synapse-ui.iife.global.js +2 -2
  57. package/dist/{type-generator-UA3L4OIA.cjs → type-generator-YTPFWLVG.cjs} +3 -2
  58. package/dist/{type-generator-UA3L4OIA.cjs.map → type-generator-YTPFWLVG.cjs.map} +1 -1
  59. package/dist/type-generator-ZYSVFK3X.js +4 -0
  60. package/dist/{type-generator-MZ4X4DE5.js.map → type-generator-ZYSVFK3X.js.map} +1 -1
  61. package/dist/{types-uEO4VFJ2.d.ts → types-CG08aO82.d.cts} +14 -83
  62. package/dist/{types-uEO4VFJ2.d.cts → types-CG08aO82.d.ts} +14 -83
  63. package/dist/ui/base.cjs +1 -0
  64. package/dist/ui/base.cjs.map +1 -1
  65. package/dist/ui/base.js +1 -0
  66. package/dist/ui/base.js.map +1 -1
  67. package/dist/ui/index.cjs +314 -87
  68. package/dist/ui/index.cjs.map +1 -1
  69. package/dist/ui/index.d.cts +29 -2
  70. package/dist/ui/index.d.ts +29 -2
  71. package/dist/ui/index.js +315 -89
  72. package/dist/ui/index.js.map +1 -1
  73. package/dist/vite/index.cjs +74 -30
  74. package/dist/vite/index.cjs.map +1 -1
  75. package/dist/vite/index.d.cts +5 -1
  76. package/dist/vite/index.d.ts +5 -1
  77. package/dist/vite/index.js +74 -30
  78. package/dist/vite/index.js.map +1 -1
  79. package/dist/{writer-NDK4U6C5.cjs → writer-HDRCQSX2.cjs} +3 -3
  80. package/dist/{writer-NDK4U6C5.cjs.map → writer-HDRCQSX2.cjs.map} +1 -1
  81. package/dist/{writer-ZNBXYUYC.js → writer-QNDPMEYD.js} +3 -3
  82. package/dist/{writer-ZNBXYUYC.js.map → writer-QNDPMEYD.js.map} +1 -1
  83. package/package.json +8 -5
  84. package/dist/chunk-EHLQWCYV.cjs.map +0 -1
  85. package/dist/chunk-FDMRJZKT.cjs +0 -788
  86. package/dist/chunk-FDMRJZKT.cjs.map +0 -1
  87. package/dist/chunk-SRQNQ26I.js.map +0 -1
  88. package/dist/chunk-TXJMGQYF.cjs.map +0 -1
  89. package/dist/chunk-UPDBDXQB.js.map +0 -1
  90. package/dist/chunk-VYR6V47N.js +0 -781
  91. package/dist/chunk-VYR6V47N.js.map +0 -1
  92. package/dist/schema-reader-776246MJ.js +0 -3
  93. package/dist/server-5N76YCWC.js.map +0 -1
  94. package/dist/server-QIYIJHD5.cjs.map +0 -1
  95. package/dist/type-generator-MZ4X4DE5.js +0 -3
package/dist/ui/index.cjs CHANGED
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var chunkRX6XCLFF_cjs = require('../chunk-RX6XCLFF.cjs');
4
+ require('../chunk-Q7SFCCGT.cjs');
4
5
  var react = require('react');
5
6
  var jsxRuntime = require('react/jsx-runtime');
6
7
 
@@ -22,6 +23,7 @@ var tokens = {
22
23
  ring: "var(--color-ring-primary, #2563eb)",
23
24
  // ── Status / brand semantics ──
24
25
  danger: "var(--nb-color-danger, #dc2626)",
26
+ dangerFg: "var(--nb-color-danger-foreground, #ffffff)",
25
27
  success: "var(--nb-color-success, #059669)",
26
28
  warning: "var(--nb-color-warning, #f59e0b)",
27
29
  processing: "var(--nb-color-processing, #7c3aed)",
@@ -294,6 +296,10 @@ function Button({
294
296
  vars["--nb-btn-bg"] = tokens.accent;
295
297
  vars["--nb-btn-bg-hover"] = `color-mix(in oklab, ${tokens.accent} 88%, black)`;
296
298
  vars["--nb-btn-fg"] = tokens.accentFg;
299
+ } else if (variant === "danger") {
300
+ vars["--nb-btn-bg"] = tokens.danger;
301
+ vars["--nb-btn-bg-hover"] = `color-mix(in oklab, ${tokens.danger} 88%, black)`;
302
+ vars["--nb-btn-fg"] = tokens.dangerFg;
297
303
  } else if (variant === "secondary") {
298
304
  vars["--nb-btn-bg"] = tokens.bgSubtle;
299
305
  vars["--nb-btn-bg-hover"] = tokens.bgRaised;
@@ -412,8 +418,283 @@ function Card({
412
418
  }
413
419
  );
414
420
  }
415
- var STYLE_ID3 = "nb-synapse-drawer";
421
+ function inClosedDetails(el) {
422
+ const details = el.closest("details:not([open])");
423
+ if (!details) return false;
424
+ const summary = details.querySelector("summary");
425
+ return !summary || !summary.contains(el);
426
+ }
427
+ var CANDIDATES = "a[href], button, input, select, textarea, summary, [tabindex]";
428
+ function tabbables(panel) {
429
+ return Array.from(panel.querySelectorAll(CANDIDATES)).filter(
430
+ (el) => el.tabIndex >= 0 && !el.matches(":disabled") && !el.closest("[hidden]") && !inClosedDetails(el) && el.type !== "hidden"
431
+ );
432
+ }
433
+ var openOverlays = [];
434
+ var lockedOverflow = "";
435
+ var handledEscapes = /* @__PURE__ */ new WeakSet();
436
+ function isInnermost(self) {
437
+ const selfAt = openOverlays.indexOf(self);
438
+ return openOverlays.every((other, at) => {
439
+ if (other === self || !other.panel || !self.panel) return true;
440
+ if (self.panel.contains(other.panel)) return false;
441
+ if (other.panel.contains(self.panel)) return true;
442
+ return at < selfAt;
443
+ });
444
+ }
445
+ function useModal(open, panelRef, { onEscape, initialFocus }) {
446
+ const escapeRef = react.useRef(onEscape);
447
+ escapeRef.current = onEscape;
448
+ const initialFocusRef = react.useRef(initialFocus);
449
+ initialFocusRef.current = initialFocus;
450
+ react.useEffect(() => {
451
+ if (!open) return;
452
+ const panel = panelRef.current;
453
+ const previouslyFocused = document.activeElement;
454
+ const entry = { panel, restoreTo: previouslyFocused };
455
+ const nested = openOverlays.filter((o) => panel && o.panel && panel.contains(o.panel)).at(-1);
456
+ if (nested) {
457
+ entry.restoreTo = nested.restoreTo;
458
+ nested.restoreTo = panel;
459
+ }
460
+ const { body } = document;
461
+ if (openOverlays.length === 0) lockedOverflow = body.style.overflow;
462
+ openOverlays.push(entry);
463
+ const innermost = () => isInnermost(entry);
464
+ if (!(panel && previouslyFocused && panel.contains(previouslyFocused))) {
465
+ (initialFocusRef.current?.() ?? panel)?.focus();
466
+ }
467
+ body.style.overflow = "hidden";
468
+ const onWindowKeyDown = (e) => {
469
+ if (e.key !== "Escape" || handledEscapes.has(e) || !innermost()) return;
470
+ handledEscapes.add(e);
471
+ e.preventDefault();
472
+ escapeRef.current();
473
+ };
474
+ window.addEventListener("keydown", onWindowKeyDown);
475
+ const onPanelKeyDown = (e) => {
476
+ if (e.key !== "Tab" || !panel || !innermost()) return;
477
+ const focusables = tabbables(panel);
478
+ if (focusables.length === 0) {
479
+ e.preventDefault();
480
+ return;
481
+ }
482
+ const first = focusables[0];
483
+ const last = focusables[focusables.length - 1];
484
+ const active = document.activeElement;
485
+ if (e.shiftKey && (active === first || active === panel)) {
486
+ e.preventDefault();
487
+ last.focus();
488
+ } else if (!e.shiftKey && active === last) {
489
+ e.preventDefault();
490
+ first.focus();
491
+ }
492
+ };
493
+ panel?.addEventListener("keydown", onPanelKeyDown);
494
+ return () => {
495
+ window.removeEventListener("keydown", onWindowKeyDown);
496
+ panel?.removeEventListener("keydown", onPanelKeyDown);
497
+ const at = openOverlays.indexOf(entry);
498
+ if (at !== -1) openOverlays.splice(at, 1);
499
+ if (openOverlays.length === 0) body.style.overflow = lockedOverflow;
500
+ entry.restoreTo?.focus?.();
501
+ };
502
+ }, [open, panelRef]);
503
+ }
504
+ var STYLE_ID3 = "nb-synapse-confirm-dialog";
416
505
  var RULES3 = `
506
+ /* border-box on both, because the kit cannot assume the host resets it: under
507
+ content-box a full-width panel is its padding wider than a phone screen. */
508
+ .nb-confirm-scrim {
509
+ box-sizing: border-box;
510
+ position: fixed; inset: 0; z-index: 1010;
511
+ display: flex; align-items: center; justify-content: center;
512
+ padding: 1rem;
513
+ background: rgba(0, 0, 0, 0.4);
514
+ animation: nb-confirm-fade 160ms ease;
515
+ }
516
+ .nb-confirm {
517
+ box-sizing: border-box;
518
+ width: 100%; max-width: 28rem; max-height: 100%;
519
+ overflow-y: auto;
520
+ outline: none;
521
+ animation: nb-confirm-in 160ms cubic-bezier(0.2, 0, 0, 1);
522
+ }
523
+ .nb-confirm__actions {
524
+ display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 0.5rem;
525
+ }
526
+ @keyframes nb-confirm-fade { from { opacity: 0; } }
527
+ @keyframes nb-confirm-in { from { opacity: 0; transform: translateY(4px); } }
528
+ @media (pointer: coarse) {
529
+ .nb-confirm__actions .nb-btn { min-height: 44px; }
530
+ }
531
+ `;
532
+ function ConfirmDialog({
533
+ open,
534
+ onOpenChange,
535
+ title,
536
+ description,
537
+ children,
538
+ confirmLabel = "Confirm",
539
+ cancelLabel = "Cancel",
540
+ pendingLabel,
541
+ destructive = false,
542
+ onConfirm
543
+ }) {
544
+ chunkRX6XCLFF_cjs.ensureStyle(STYLE_ID3, RULES3);
545
+ const panelRef = react.useRef(null);
546
+ const titleId = react.useId();
547
+ const descriptionId = react.useId();
548
+ const [pending, setPending] = react.useState(false);
549
+ const [error, setError] = react.useState(null);
550
+ react.useEffect(() => {
551
+ if (open) {
552
+ setError(null);
553
+ setPending(false);
554
+ }
555
+ }, [open]);
556
+ const dismiss = () => {
557
+ if (!pending) onOpenChange(false);
558
+ };
559
+ const focusTarget = () => panelRef.current?.querySelector(
560
+ destructive ? "[data-nb-confirm-cancel]" : "[data-nb-confirm-confirm]"
561
+ );
562
+ useModal(open, panelRef, { onEscape: dismiss, initialFocus: focusTarget });
563
+ react.useEffect(() => {
564
+ if (error) focusTarget()?.focus();
565
+ }, [error]);
566
+ const confirm = async () => {
567
+ if (pending) return;
568
+ setPending(true);
569
+ setError(null);
570
+ try {
571
+ await onConfirm();
572
+ setPending(false);
573
+ onOpenChange(false);
574
+ } catch (err) {
575
+ const message = err instanceof Error ? err.message : String(err);
576
+ setError(message || "That didn't go through. Try again.");
577
+ setPending(false);
578
+ }
579
+ };
580
+ if (!open) return null;
581
+ const panelStyle = {
582
+ padding: "1.25rem",
583
+ borderRadius: tokens.radiusMd,
584
+ border: `${tokens.borderWidth} solid ${tokens.border}`,
585
+ background: tokens.bg,
586
+ color: tokens.fg,
587
+ boxShadow: tokens.shadowLg,
588
+ fontFamily: tokens.fontSans
589
+ };
590
+ return (
591
+ // biome-ignore lint/a11y/useKeyWithClickEvents: scrim click is a bonus mouse affordance; Escape and Cancel are the keyboard dismissal paths.
592
+ // biome-ignore lint/a11y/noStaticElementInteractions: the scrim is a decorative dismissal backdrop; the panel below owns the alertdialog role/semantics.
593
+ /* @__PURE__ */ jsxRuntime.jsx(
594
+ "div",
595
+ {
596
+ className: "nb-confirm-scrim",
597
+ onClick: (e) => {
598
+ if (e.target === e.currentTarget) dismiss();
599
+ },
600
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
601
+ "div",
602
+ {
603
+ ref: panelRef,
604
+ role: "alertdialog",
605
+ "aria-modal": "true",
606
+ "aria-labelledby": titleId,
607
+ "aria-describedby": description != null ? descriptionId : void 0,
608
+ "aria-busy": pending || void 0,
609
+ tabIndex: -1,
610
+ className: "nb-confirm",
611
+ style: panelStyle,
612
+ children: [
613
+ /* @__PURE__ */ jsxRuntime.jsx(
614
+ "h2",
615
+ {
616
+ id: titleId,
617
+ style: {
618
+ margin: 0,
619
+ fontFamily: tokens.fontSans,
620
+ fontSize: tokens.textBaseSize,
621
+ lineHeight: tokens.textBaseLine,
622
+ fontWeight: tokens.weightSemibold,
623
+ color: tokens.fg
624
+ },
625
+ children: title
626
+ }
627
+ ),
628
+ description != null ? /* @__PURE__ */ jsxRuntime.jsx(
629
+ "p",
630
+ {
631
+ id: descriptionId,
632
+ style: {
633
+ margin: "0.25rem 0 0",
634
+ fontSize: tokens.textSmSize,
635
+ lineHeight: tokens.textSmLine,
636
+ color: tokens.fgMuted
637
+ },
638
+ children: description
639
+ }
640
+ ) : null,
641
+ children != null ? /* @__PURE__ */ jsxRuntime.jsx(
642
+ "div",
643
+ {
644
+ style: {
645
+ marginTop: "1rem",
646
+ fontSize: tokens.textSmSize,
647
+ lineHeight: tokens.textSmLine
648
+ },
649
+ children
650
+ }
651
+ ) : null,
652
+ error ? /* @__PURE__ */ jsxRuntime.jsx(
653
+ "p",
654
+ {
655
+ role: "alert",
656
+ style: {
657
+ margin: "0.75rem 0 0",
658
+ fontSize: tokens.textSmSize,
659
+ lineHeight: tokens.textSmLine,
660
+ color: tokens.danger
661
+ },
662
+ children: error
663
+ }
664
+ ) : null,
665
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nb-confirm__actions", style: { marginTop: "1.25rem" }, children: [
666
+ /* @__PURE__ */ jsxRuntime.jsx(
667
+ Button,
668
+ {
669
+ variant: "secondary",
670
+ size: "sm",
671
+ "data-nb-confirm-cancel": "",
672
+ disabled: pending,
673
+ onClick: dismiss,
674
+ children: cancelLabel
675
+ }
676
+ ),
677
+ /* @__PURE__ */ jsxRuntime.jsx(
678
+ Button,
679
+ {
680
+ variant: destructive ? "danger" : "primary",
681
+ size: "sm",
682
+ "data-nb-confirm-confirm": "",
683
+ disabled: pending,
684
+ onClick: () => void confirm(),
685
+ children: pending ? pendingLabel ?? confirmLabel : confirmLabel
686
+ }
687
+ )
688
+ ] })
689
+ ]
690
+ }
691
+ )
692
+ }
693
+ )
694
+ );
695
+ }
696
+ var STYLE_ID4 = "nb-synapse-drawer";
697
+ var RULES4 = `
417
698
  .nb-drawer-scrim {
418
699
  position: fixed; inset: 0; z-index: 1000;
419
700
  display: flex; background: rgba(0, 0, 0, 0.32);
@@ -440,18 +721,6 @@ var RULES3 = `
440
721
  .nb-drawer-iconbtn { min-width: 44px; min-height: 44px; }
441
722
  }
442
723
  `;
443
- function inClosedDetails(el) {
444
- const details = el.closest("details:not([open])");
445
- if (!details) return false;
446
- const summary = details.querySelector("summary");
447
- return !summary || !summary.contains(el);
448
- }
449
- var CANDIDATES = "a[href], button, input, select, textarea, summary, [tabindex]";
450
- function tabbables(panel) {
451
- return Array.from(panel.querySelectorAll(CANDIDATES)).filter(
452
- (el) => el.tabIndex >= 0 && !el.matches(":disabled") && !el.closest("[hidden]") && !inClosedDetails(el) && el.type !== "hidden"
453
- );
454
- }
455
724
  var DrawerContext = react.createContext(null);
456
725
  function DrawerRoot({
457
726
  open,
@@ -463,54 +732,11 @@ function DrawerRoot({
463
732
  children,
464
733
  ...rest
465
734
  }) {
466
- chunkRX6XCLFF_cjs.ensureStyle(STYLE_ID3, RULES3);
735
+ chunkRX6XCLFF_cjs.ensureStyle(STYLE_ID4, RULES4);
467
736
  const panelRef = react.useRef(null);
468
737
  const labelId = react.useId();
469
738
  const [hasTitle, setHasTitle] = react.useState(false);
470
- react.useEffect(() => {
471
- if (!open) return;
472
- const onKey = (e) => {
473
- if (e.key === "Escape") {
474
- e.preventDefault();
475
- (onEscape ?? onClose)();
476
- }
477
- };
478
- window.addEventListener("keydown", onKey);
479
- return () => window.removeEventListener("keydown", onKey);
480
- }, [open, onEscape, onClose]);
481
- react.useEffect(() => {
482
- if (!open) return;
483
- const panel = panelRef.current;
484
- const previouslyFocused = document.activeElement;
485
- panel?.focus();
486
- const { body } = document;
487
- const prevOverflow = body.style.overflow;
488
- body.style.overflow = "hidden";
489
- const onKeyDown = (e) => {
490
- if (e.key !== "Tab" || !panel) return;
491
- const focusables = tabbables(panel);
492
- if (focusables.length === 0) {
493
- e.preventDefault();
494
- return;
495
- }
496
- const first = focusables[0];
497
- const last = focusables[focusables.length - 1];
498
- const active = document.activeElement;
499
- if (e.shiftKey && (active === first || active === panel)) {
500
- e.preventDefault();
501
- last.focus();
502
- } else if (!e.shiftKey && active === last) {
503
- e.preventDefault();
504
- first.focus();
505
- }
506
- };
507
- panel?.addEventListener("keydown", onKeyDown);
508
- return () => {
509
- panel?.removeEventListener("keydown", onKeyDown);
510
- body.style.overflow = prevOverflow;
511
- previouslyFocused?.focus?.();
512
- };
513
- }, [open]);
739
+ useModal(open, panelRef, { onEscape: onEscape ?? onClose });
514
740
  const ctxValue = react.useMemo(() => ({ labelId, setHasTitle }), [labelId]);
515
741
  if (!open) return null;
516
742
  const isBottom = side === "bottom";
@@ -742,8 +968,8 @@ function EmptyState({ icon, title, description, action, style, ...rest }) {
742
968
  }
743
969
  );
744
970
  }
745
- var STYLE_ID4 = "nb-synapse-listrow";
746
- var RULES4 = `
971
+ var STYLE_ID5 = "nb-synapse-listrow";
972
+ var RULES5 = `
747
973
  .nb-listrow { transition: background 140ms ease; }
748
974
  .nb-listrow--interactive { cursor: pointer; }
749
975
  .nb-listrow--interactive:hover { background: var(--nb-listrow-hover); }
@@ -758,7 +984,7 @@ function ListRow({
758
984
  className,
759
985
  ...rest
760
986
  }) {
761
- chunkRX6XCLFF_cjs.ensureStyle(STYLE_ID4, RULES4);
987
+ chunkRX6XCLFF_cjs.ensureStyle(STYLE_ID5, RULES5);
762
988
  const rowStyle = {
763
989
  "--nb-listrow-hover": tokens.bgSubtle,
764
990
  display: "grid",
@@ -841,8 +1067,8 @@ function ListRow({
841
1067
  }
842
1068
  );
843
1069
  }
844
- var STYLE_ID5 = "nb-synapse-page-header";
845
- var RULES5 = `
1070
+ var STYLE_ID6 = "nb-synapse-page-header";
1071
+ var RULES6 = `
846
1072
  .nb-page-header__desc {
847
1073
  display: -webkit-box;
848
1074
  -webkit-box-orient: vertical;
@@ -861,7 +1087,7 @@ function PageHeader({
861
1087
  style,
862
1088
  ...rest
863
1089
  }) {
864
- chunkRX6XCLFF_cjs.ensureStyle(STYLE_ID5, RULES5);
1090
+ chunkRX6XCLFF_cjs.ensureStyle(STYLE_ID6, RULES6);
865
1091
  const descVars = descriptionLines > 0 ? { "--nb-ph-desc-lines": String(descriptionLines) } : {};
866
1092
  return /* @__PURE__ */ jsxRuntime.jsxs(
867
1093
  "header",
@@ -947,8 +1173,8 @@ function Pagination({ page, pageCount, onChange, style, ...rest }) {
947
1173
  }
948
1174
  );
949
1175
  }
950
- var STYLE_ID6 = "nb-synapse-prose";
951
- var RULES6 = `
1176
+ var STYLE_ID7 = "nb-synapse-prose";
1177
+ var RULES7 = `
952
1178
  .nb-prose {
953
1179
  font-family: ${tokens.fontSans};
954
1180
  font-size: ${tokens.textBaseSize};
@@ -973,15 +1199,15 @@ var RULES6 = `
973
1199
  .nb-prose strong { font-weight: ${tokens.weightSemibold}; }
974
1200
  `;
975
1201
  function Prose({ html, children, className, ...rest }) {
976
- chunkRX6XCLFF_cjs.ensureStyle(STYLE_ID6, RULES6);
1202
+ chunkRX6XCLFF_cjs.ensureStyle(STYLE_ID7, RULES7);
977
1203
  const cls = `nb-prose ${className ?? ""}`.trim();
978
1204
  if (html !== void 0) {
979
1205
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cls, dangerouslySetInnerHTML: { __html: html }, ...rest });
980
1206
  }
981
1207
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cls, ...rest, children });
982
1208
  }
983
- var STYLE_ID7 = "nb-synapse-searchfield";
984
- var RULES7 = `
1209
+ var STYLE_ID8 = "nb-synapse-searchfield";
1210
+ var RULES8 = `
985
1211
  .nb-search { font-family: var(--nb-search-font); color: var(--nb-search-fg); outline: none; }
986
1212
  .nb-search::placeholder { color: var(--nb-search-placeholder); }
987
1213
  .nb-search--underline {
@@ -1011,7 +1237,7 @@ function SearchField({
1011
1237
  type = "search",
1012
1238
  ...rest
1013
1239
  }) {
1014
- chunkRX6XCLFF_cjs.ensureStyle(STYLE_ID7, RULES7);
1240
+ chunkRX6XCLFF_cjs.ensureStyle(STYLE_ID8, RULES8);
1015
1241
  const fieldStyle = {
1016
1242
  "--nb-search-font": tokens.fontSans,
1017
1243
  "--nb-search-fg": tokens.fg,
@@ -1034,8 +1260,8 @@ function SearchField({
1034
1260
  }
1035
1261
  );
1036
1262
  }
1037
- var STYLE_ID8 = "nb-synapse-segmented";
1038
- var RULES8 = `
1263
+ var STYLE_ID9 = "nb-synapse-segmented";
1264
+ var RULES9 = `
1039
1265
  .nb-seg {
1040
1266
  display: inline-flex;
1041
1267
  gap: 2px;
@@ -1070,7 +1296,7 @@ function SegmentedControl({
1070
1296
  className,
1071
1297
  ...rest
1072
1298
  }) {
1073
- chunkRX6XCLFF_cjs.ensureStyle(STYLE_ID8, RULES8);
1299
+ chunkRX6XCLFF_cjs.ensureStyle(STYLE_ID9, RULES9);
1074
1300
  const trackStyle = {
1075
1301
  "--nb-seg-radius": tokens.radiusSm,
1076
1302
  "--nb-seg-track": tokens.bgSubtle,
@@ -1099,14 +1325,14 @@ function SegmentedControl({
1099
1325
  )) })
1100
1326
  );
1101
1327
  }
1102
- var STYLE_ID9 = "nb-synapse-spinner";
1103
- var RULES9 = `
1328
+ var STYLE_ID10 = "nb-synapse-spinner";
1329
+ var RULES10 = `
1104
1330
  @keyframes nb-spin { to { transform: rotate(360deg); } }
1105
1331
  .nb-spinner { animation: nb-spin 0.7s linear infinite; }
1106
1332
  @media (prefers-reduced-motion: reduce) { .nb-spinner { animation-duration: 1.6s; } }
1107
1333
  `;
1108
1334
  function Spinner({ size = 16, color, style, className, ...rest }) {
1109
- chunkRX6XCLFF_cjs.ensureStyle(STYLE_ID9, RULES9);
1335
+ chunkRX6XCLFF_cjs.ensureStyle(STYLE_ID10, RULES10);
1110
1336
  const spinnerStyle = {
1111
1337
  display: "inline-block",
1112
1338
  flexShrink: 0,
@@ -1135,7 +1361,7 @@ var COLOR = {
1135
1361
  failed: tokens.danger,
1136
1362
  idle: tokens.fgFaint
1137
1363
  };
1138
- var STYLE_ID10 = "nb-synapse-statusdot";
1364
+ var STYLE_ID11 = "nb-synapse-statusdot";
1139
1365
  var KEYFRAMES = `
1140
1366
  @keyframes nb-statusdot-pulse {
1141
1367
  0% { box-shadow: 0 0 0 0 var(--nb-statusdot-ring); transform: scale(1); }
@@ -1157,7 +1383,7 @@ function StatusDot({
1157
1383
  className,
1158
1384
  ...rest
1159
1385
  }) {
1160
- chunkRX6XCLFF_cjs.ensureStyle(STYLE_ID10, KEYFRAMES);
1386
+ chunkRX6XCLFF_cjs.ensureStyle(STYLE_ID11, KEYFRAMES);
1161
1387
  const dotColor = color ?? COLOR[status];
1162
1388
  const working = status === "working";
1163
1389
  const dotStyle = {
@@ -1180,8 +1406,8 @@ function StatusDot({
1180
1406
  }
1181
1407
  );
1182
1408
  }
1183
- var STYLE_ID11 = "nb-synapse-table";
1184
- var RULES10 = `
1409
+ var STYLE_ID12 = "nb-synapse-table";
1410
+ var RULES11 = `
1185
1411
  .nb-table { width: 100%; border-collapse: collapse; font-family: var(--nb-table-font); }
1186
1412
  .nb-table th, .nb-table td {
1187
1413
  padding: 0.55rem 0.75rem;
@@ -1211,7 +1437,7 @@ function Table({
1211
1437
  className,
1212
1438
  ...rest
1213
1439
  }) {
1214
- chunkRX6XCLFF_cjs.ensureStyle(STYLE_ID11, RULES10);
1440
+ chunkRX6XCLFF_cjs.ensureStyle(STYLE_ID12, RULES11);
1215
1441
  const vars = {
1216
1442
  "--nb-table-font": tokens.fontSans,
1217
1443
  "--nb-table-fg": tokens.fg,
@@ -1277,8 +1503,8 @@ function Table({
1277
1503
  }
1278
1504
  );
1279
1505
  }
1280
- var STYLE_ID12 = "nb-synapse-tabs";
1281
- var RULES11 = `
1506
+ var STYLE_ID13 = "nb-synapse-tabs";
1507
+ var RULES12 = `
1282
1508
  .nb-tabs {
1283
1509
  display: flex;
1284
1510
  align-items: stretch;
@@ -1336,7 +1562,7 @@ function Tabs({
1336
1562
  onKeyDown: callerKeyDown,
1337
1563
  ...rest
1338
1564
  }) {
1339
- chunkRX6XCLFF_cjs.ensureStyle(STYLE_ID12, RULES11);
1565
+ chunkRX6XCLFF_cjs.ensureStyle(STYLE_ID13, RULES12);
1340
1566
  const barRef = react.useRef(null);
1341
1567
  const barStyle = {
1342
1568
  "--nb-tabs-gap": "1.25rem",
@@ -1613,8 +1839,8 @@ function useSidebar() {
1613
1839
  if (!ctx) throw new Error("useSidebar must be used within <SidebarLayout>");
1614
1840
  return ctx;
1615
1841
  }
1616
- var STYLE_ID13 = "nb-synapse-sidebarlayout";
1617
- var RULES12 = `
1842
+ var STYLE_ID14 = "nb-synapse-sidebarlayout";
1843
+ var RULES13 = `
1618
1844
  .nb-sidebar-drawer { transition: transform 220ms cubic-bezier(0.2, 0, 0, 1); }
1619
1845
  .nb-sidebar-scrim { animation: nb-sidebar-fade 180ms ease; }
1620
1846
  @keyframes nb-sidebar-fade { from { opacity: 0; } to { opacity: 1; } }
@@ -1664,7 +1890,7 @@ function SidebarLayoutRoot({
1664
1890
  }
1665
1891
  function Sidebar({ style, children, ...rest }) {
1666
1892
  const { collapsed, mode, side, width, open, setOpen } = useSidebar();
1667
- chunkRX6XCLFF_cjs.ensureStyle(STYLE_ID13, RULES12);
1893
+ chunkRX6XCLFF_cjs.ensureStyle(STYLE_ID14, RULES13);
1668
1894
  if (!collapsed) {
1669
1895
  const border = `${tokens.borderWidth} solid ${tokens.border}`;
1670
1896
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -1795,6 +2021,7 @@ exports.Badge = Badge;
1795
2021
  exports.Breadcrumb = Breadcrumb;
1796
2022
  exports.Button = Button;
1797
2023
  exports.Card = Card;
2024
+ exports.ConfirmDialog = ConfirmDialog;
1798
2025
  exports.Divider = Divider;
1799
2026
  exports.Drawer = Drawer;
1800
2027
  exports.EmptyState = EmptyState;