@drawnagency/primitives 0.1.99 → 0.1.101

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 (120) hide show
  1. package/dist/{chunk-FAZFADJK.js → chunk-3TO4RRHY.js} +3 -1
  2. package/dist/{chunk-HKHEAH5F.js → chunk-6SLGKRLW.js} +8 -60
  3. package/dist/chunk-BS5AQHZG.js +45 -0
  4. package/dist/{chunk-GYCBWGVW.js → chunk-LBHQWIVL.js} +79 -24
  5. package/dist/{chunk-KP4DWTPR.js → chunk-P3NNI3QI.js} +328 -4
  6. package/dist/components/chat/ChatPanel.d.ts.map +1 -1
  7. package/dist/components/docfile/DocFileOverlay.d.ts +12 -0
  8. package/dist/components/docfile/DocFileOverlay.d.ts.map +1 -0
  9. package/dist/components/docfile/DocFilePane.d.ts +17 -0
  10. package/dist/components/docfile/DocFilePane.d.ts.map +1 -0
  11. package/dist/components/docfile/doc-file-state.d.ts +38 -0
  12. package/dist/components/docfile/doc-file-state.d.ts.map +1 -0
  13. package/dist/components/editor/SettingsForm.d.ts.map +1 -1
  14. package/dist/components/editor/index.js +1 -1
  15. package/dist/components/primitives/DocumentDropZone.d.ts +18 -0
  16. package/dist/components/primitives/DocumentDropZone.d.ts.map +1 -0
  17. package/dist/components/sections/Document/index.d.ts +24 -0
  18. package/dist/components/sections/Document/index.d.ts.map +1 -0
  19. package/dist/components/sections/all-sections.d.ts +10 -0
  20. package/dist/components/sections/all-sections.d.ts.map +1 -1
  21. package/dist/components/sections/brand-guide.d.ts +10 -0
  22. package/dist/components/sections/brand-guide.d.ts.map +1 -1
  23. package/dist/components/sections/brand-guide.js +3 -1
  24. package/dist/components/sections/register-schemas.js +5 -3
  25. package/dist/components/sections/register.js +5 -3
  26. package/dist/components/shared/DocumentSourceField.d.ts +13 -0
  27. package/dist/components/shared/DocumentSourceField.d.ts.map +1 -0
  28. package/dist/components/shared/Navigation.d.ts.map +1 -1
  29. package/dist/components/shell/EditorModal.d.ts.map +1 -1
  30. package/dist/components/shell/EditorShell.d.ts.map +1 -1
  31. package/dist/components/shell/MediaBreadcrumb.d.ts.map +1 -1
  32. package/dist/components/shell/MediaFolderTile.d.ts +3 -1
  33. package/dist/components/shell/MediaFolderTile.d.ts.map +1 -1
  34. package/dist/components/shell/MediaFolderTree.d.ts +3 -0
  35. package/dist/components/shell/MediaFolderTree.d.ts.map +1 -1
  36. package/dist/components/shell/MediaLibraryContext.d.ts +24 -1
  37. package/dist/components/shell/MediaLibraryContext.d.ts.map +1 -1
  38. package/dist/components/shell/MediaLibraryModal.d.ts +21 -1
  39. package/dist/components/shell/MediaLibraryModal.d.ts.map +1 -1
  40. package/dist/hooks/useDocumentUploads.d.ts +32 -0
  41. package/dist/hooks/useDocumentUploads.d.ts.map +1 -0
  42. package/dist/hooks/useEditorPublish.d.ts +18 -1
  43. package/dist/hooks/useEditorPublish.d.ts.map +1 -1
  44. package/dist/hooks/useMediaPipeline.d.ts +14 -1
  45. package/dist/hooks/useMediaPipeline.d.ts.map +1 -1
  46. package/dist/hooks/useResolvedDocument.d.ts +12 -0
  47. package/dist/hooks/useResolvedDocument.d.ts.map +1 -0
  48. package/dist/index.js +56 -32
  49. package/dist/lib/dexie.d.ts +13 -0
  50. package/dist/lib/dexie.d.ts.map +1 -1
  51. package/dist/lib/dexie.js +39 -2
  52. package/dist/lib/document-refs.d.ts +22 -0
  53. package/dist/lib/document-refs.d.ts.map +1 -0
  54. package/dist/lib/document-uploads.d.ts +38 -0
  55. package/dist/lib/document-uploads.d.ts.map +1 -0
  56. package/dist/lib/documents.d.ts +65 -0
  57. package/dist/lib/documents.d.ts.map +1 -0
  58. package/dist/lib/index.js +4 -4
  59. package/dist/lib/media-folders.d.ts +8 -0
  60. package/dist/lib/media-folders.d.ts.map +1 -1
  61. package/dist/lib/media-folders.js +2 -0
  62. package/dist/lib/nav.d.ts +29 -1
  63. package/dist/lib/nav.d.ts.map +1 -1
  64. package/dist/lib/platform-broker.d.ts +12 -0
  65. package/dist/lib/platform-broker.d.ts.map +1 -1
  66. package/dist/lib/platform-broker.js +12 -3
  67. package/dist/lib/registry.d.ts +10 -0
  68. package/dist/lib/registry.d.ts.map +1 -1
  69. package/dist/lib/save-chunks.d.ts +15 -0
  70. package/dist/lib/save-chunks.d.ts.map +1 -1
  71. package/dist/lib/scroll-lock.d.ts +2 -0
  72. package/dist/lib/scroll-lock.d.ts.map +1 -0
  73. package/dist/schemas/documents.d.ts +80 -0
  74. package/dist/schemas/documents.d.ts.map +1 -0
  75. package/dist/schemas/documents.js +25 -0
  76. package/dist/schemas/index.d.ts +1 -0
  77. package/dist/schemas/index.d.ts.map +1 -1
  78. package/dist/schemas/index.js +23 -1
  79. package/dist/storage/index.d.ts +2 -2
  80. package/dist/storage/index.d.ts.map +1 -1
  81. package/dist/storage/index.js +3 -1
  82. package/dist/storage/types.d.ts +59 -3
  83. package/dist/storage/types.d.ts.map +1 -1
  84. package/package.json +5 -1
  85. package/src/components/chat/ChatPanel.tsx +5 -4
  86. package/src/components/docfile/DocFileOverlay.tsx +54 -0
  87. package/src/components/docfile/DocFilePane.tsx +133 -0
  88. package/src/components/docfile/doc-file-state.ts +208 -0
  89. package/src/components/editor/SettingsForm.tsx +10 -0
  90. package/src/components/primitives/DocumentDropZone.tsx +79 -0
  91. package/src/components/sections/Document/index.tsx +194 -0
  92. package/src/components/sections/brand-guide.ts +2 -1
  93. package/src/components/shared/DocumentSourceField.tsx +51 -0
  94. package/src/components/shared/Navigation.tsx +53 -10
  95. package/src/components/shell/EditorModal.tsx +2 -5
  96. package/src/components/shell/EditorShell.tsx +132 -8
  97. package/src/components/shell/MediaBreadcrumb.tsx +14 -1
  98. package/src/components/shell/MediaFolderTile.tsx +4 -2
  99. package/src/components/shell/MediaFolderTree.tsx +20 -3
  100. package/src/components/shell/MediaLibraryContext.tsx +24 -1
  101. package/src/components/shell/MediaLibraryModal.tsx +223 -45
  102. package/src/hooks/useDocumentUploads.ts +336 -0
  103. package/src/hooks/useEditorPublish.ts +180 -8
  104. package/src/hooks/useMediaPipeline.ts +141 -5
  105. package/src/hooks/useResolvedDocument.ts +25 -0
  106. package/src/lib/dexie.ts +66 -1
  107. package/src/lib/document-refs.ts +83 -0
  108. package/src/lib/document-uploads.ts +66 -0
  109. package/src/lib/documents.ts +138 -0
  110. package/src/lib/media-folders.ts +9 -0
  111. package/src/lib/nav.ts +46 -2
  112. package/src/lib/platform-broker.ts +18 -3
  113. package/src/lib/registry.ts +9 -0
  114. package/src/lib/save-chunks.ts +42 -0
  115. package/src/lib/scroll-lock.ts +27 -0
  116. package/src/schemas/documents.ts +82 -0
  117. package/src/schemas/index.ts +1 -0
  118. package/src/storage/index.ts +2 -2
  119. package/src/storage/types.ts +58 -4
  120. /package/dist/{chunk-FOY5TF7D.js → chunk-ZDQ3TT47.js} +0 -0
@@ -27,6 +27,7 @@ function withIdempotencyTrailer(subject, key) {
27
27
  ${IDEMPOTENCY_TRAILER}: ${key}`;
28
28
  }
29
29
  var ASSET_CACHE_CONTROL = "max-age=31536000, immutable";
30
+ var DOCUMENT_CACHE_CONTROL = "private, max-age=31536000, immutable";
30
31
 
31
32
  export {
32
33
  StorageConflictError,
@@ -34,5 +35,6 @@ export {
34
35
  IDEMPOTENCY_TRAILER,
35
36
  IDEMPOTENCY_KEY_RE,
36
37
  withIdempotencyTrailer,
37
- ASSET_CACHE_CONTROL
38
+ ASSET_CACHE_CONTROL,
39
+ DOCUMENT_CACHE_CONTROL
38
40
  };
@@ -1,9 +1,15 @@
1
1
  import {
2
2
  brandGuideSectionDefs,
3
+ duplicateChildAt,
4
+ isSpacer,
5
+ occupiedColumns,
3
6
  pluralize,
7
+ removeChildAt,
8
+ setChildColSpan,
4
9
  stripHtmlToPlainText,
10
+ trimTrailingSpacers,
5
11
  truncate
6
- } from "./chunk-KP4DWTPR.js";
12
+ } from "./chunk-P3NNI3QI.js";
7
13
  import {
8
14
  DeleteButton,
9
15
  DragHandle,
@@ -17,7 +23,7 @@ import {
17
23
  buildBlockDropData,
18
24
  canDropBlock,
19
25
  isBlockDragData
20
- } from "./chunk-GYCBWGVW.js";
26
+ } from "./chunk-LBHQWIVL.js";
21
27
  import {
22
28
  EditableRichText,
23
29
  defineHeadingSection
@@ -717,64 +723,6 @@ function useBlockDropZone({ containerId, index, toColumn, allowedEdges, enabled
717
723
  return { dropRef, closestEdge };
718
724
  }
719
725
 
720
- // src/lib/container-ops.ts
721
- function getContainerChildren(block) {
722
- const content = block.content;
723
- return Array.isArray(content?.children) ? content.children : [];
724
- }
725
- function withChildren(container, children) {
726
- return { ...container, content: { ...container.content, children } };
727
- }
728
- function containerColumns(container) {
729
- const n = container.content?.columns;
730
- return typeof n === "number" && n >= 1 ? n : 1;
731
- }
732
- function removeChildAt(container, index) {
733
- const children = getContainerChildren(container);
734
- if (index < 0 || index >= children.length) return { container, removed: null };
735
- const next = [...children];
736
- const [removed] = next.splice(index, 1);
737
- return { container: withChildren(container, next), removed };
738
- }
739
- function duplicateChildAt(container, index, newId2) {
740
- const children = getContainerChildren(container);
741
- if (index < 0 || index >= children.length) return container;
742
- const clone = { ...JSON.parse(JSON.stringify(children[index])), id: newId2() };
743
- const next = [...children];
744
- next.splice(index + 1, 0, clone);
745
- return withChildren(container, next);
746
- }
747
- function setChildColSpan(container, index, span) {
748
- const children = getContainerChildren(container);
749
- if (index < 0 || index >= children.length) return container;
750
- const clamped = Math.max(1, Math.min(span, containerColumns(container)));
751
- const next = children.map((child, i) => {
752
- if (i !== index) return child;
753
- if (clamped <= 1) {
754
- const { layout: _drop, ...rest } = child;
755
- return rest;
756
- }
757
- return { ...child, layout: { ...child.layout, colSpan: clamped } };
758
- });
759
- return withChildren(container, next);
760
- }
761
- function effectiveSpan(child, columns) {
762
- return isSpacer(child) ? 1 : Math.min(child.layout?.colSpan ?? 1, columns);
763
- }
764
- function isSpacer(child) {
765
- return child.type === "spacer";
766
- }
767
- function occupiedColumns(children, columns) {
768
- return children.reduce((sum, c) => sum + effectiveSpan(c, columns), 0);
769
- }
770
- function trimTrailingSpacers(container) {
771
- const children = getContainerChildren(container);
772
- let end = children.length;
773
- while (end > 0 && isSpacer(children[end - 1])) end--;
774
- if (end === children.length) return container;
775
- return withChildren(container, children.slice(0, end));
776
- }
777
-
778
726
  // src/components/sections/Container/Container.tsx
779
727
  import { jsx as jsx13, jsxs as jsxs5 } from "react/jsx-runtime";
780
728
  var ROW_EDGES = ["left", "right"];
@@ -0,0 +1,45 @@
1
+ // src/schemas/documents.ts
2
+ import { z } from "zod";
3
+ var DOCUMENT_MANIFEST_PATH = "src/content/document-manifest.json";
4
+ var DOCUMENT_GIT_MAX_BYTES = 2621440;
5
+ var DOCUMENT_BUCKET_MAX_BYTES = 209715200;
6
+ var DOCUMENT_MIME_TO_EXT = {
7
+ "application/pdf": "pdf",
8
+ "text/html": "html"
9
+ };
10
+ var DOCUMENT_KIND_TO_MIME = {
11
+ pdf: "application/pdf",
12
+ html: "text/html"
13
+ };
14
+ var DocumentManifestEntrySchema = z.object({
15
+ filename: z.string(),
16
+ size: z.number().int().positive(),
17
+ kind: z.enum(["pdf", "html"]),
18
+ storage: z.enum(["git", "bucket"]),
19
+ /** git: repo path under assets/documents/…; bucket: site-relative object key. */
20
+ path: z.string()
21
+ });
22
+ var DocumentManifestSchema = z.record(z.string(), DocumentManifestEntrySchema);
23
+ function documentFileUrl(documentId, filename, opts = {}) {
24
+ const base = `/api/document-file/${documentId}/${encodeURIComponent(filename)}`;
25
+ return opts.download ? `${base}?download=1` : base;
26
+ }
27
+ function documentGitPath(slugName, hash, kind) {
28
+ return `assets/documents/${slugName}-${hash}/original.${kind}`;
29
+ }
30
+ function documentBucketPath(documentId, kind) {
31
+ return `documents/${documentId}/original.${kind}`;
32
+ }
33
+
34
+ export {
35
+ DOCUMENT_MANIFEST_PATH,
36
+ DOCUMENT_GIT_MAX_BYTES,
37
+ DOCUMENT_BUCKET_MAX_BYTES,
38
+ DOCUMENT_MIME_TO_EXT,
39
+ DOCUMENT_KIND_TO_MIME,
40
+ DocumentManifestEntrySchema,
41
+ DocumentManifestSchema,
42
+ documentFileUrl,
43
+ documentGitPath,
44
+ documentBucketPath
45
+ };
@@ -15,6 +15,9 @@ import {
15
15
  useMediaLibrary,
16
16
  useResolvedMedia
17
17
  } from "./chunk-26ALJO4K.js";
18
+ import {
19
+ formatFileSize
20
+ } from "./chunk-3COSXTOY.js";
18
21
  import {
19
22
  cn
20
23
  } from "./chunk-7EOSDFS3.js";
@@ -356,9 +359,52 @@ function VideoSourceField({ value, onChange }) {
356
359
  ] });
357
360
  }
358
361
 
362
+ // src/hooks/useResolvedDocument.ts
363
+ import { useMemo } from "react";
364
+ function useResolvedDocument(documentId) {
365
+ const ctx = useMediaLibrary();
366
+ return useMemo(() => {
367
+ if (!documentId) return { entry: null, missing: false };
368
+ const committed = ctx?.documentManifest?.[documentId];
369
+ const pending = ctx?.pendingDocuments?.find((d) => d.id === documentId)?.entry;
370
+ const entry = committed ?? pending ?? null;
371
+ return { entry, missing: entry === null };
372
+ }, [documentId, ctx]);
373
+ }
374
+
375
+ // src/components/shared/DocumentSourceField.tsx
376
+ import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
377
+ function DocumentSourceField({ value, onChange }) {
378
+ const mediaLibrary = useMediaLibrary();
379
+ const documentId = value?.documentId || void 0;
380
+ const { entry, missing } = useResolvedDocument(documentId);
381
+ return /* @__PURE__ */ jsxs6("div", { className: "flex flex-col gap-3", children: [
382
+ /* @__PURE__ */ jsx8(FormLabel, { children: "Document" }),
383
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-3", children: [
384
+ entry ? /* @__PURE__ */ jsxs6("span", { className: "min-w-0 flex-1 truncate text-sm text-base-contrast", children: [
385
+ entry.filename,
386
+ /* @__PURE__ */ jsxs6("span", { className: "text-base-contrast-light", children: [
387
+ " \xB7 ",
388
+ formatFileSize(entry.size)
389
+ ] })
390
+ ] }) : /* @__PURE__ */ jsx8("span", { className: "flex-1 text-sm text-base-contrast-light", children: missing ? "File missing" : "No document selected" }),
391
+ /* @__PURE__ */ jsx8(
392
+ Button,
393
+ {
394
+ type: "button",
395
+ variant: "secondary",
396
+ size: "sm",
397
+ onClick: () => mediaLibrary?.openSelectModal((id) => onChange({ documentId: id }), { kinds: ["document"] }),
398
+ children: documentId ? "Replace document" : "Choose document"
399
+ }
400
+ )
401
+ ] })
402
+ ] });
403
+ }
404
+
359
405
  // src/components/shared/Tabs.tsx
360
406
  import { useState as useState2 } from "react";
361
- import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
407
+ import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
362
408
  function Tabs({ tabs, defaultTabId, activeTabId, onTabChange, fullBleedTabBar }) {
363
409
  const [uncontrolledId, setUncontrolledId] = useState2(defaultTabId ?? tabs[0]?.id);
364
410
  const isControlled = activeTabId !== void 0;
@@ -368,8 +414,8 @@ function Tabs({ tabs, defaultTabId, activeTabId, onTabChange, fullBleedTabBar })
368
414
  if (!isControlled) setUncontrolledId(id);
369
415
  onTabChange?.(id);
370
416
  }
371
- return /* @__PURE__ */ jsxs6("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
372
- /* @__PURE__ */ jsx8("div", { className: cn("border-b border-base-200", fullBleedTabBar && "-mx-6 px-6"), children: /* @__PURE__ */ jsx8("div", { className: "flex", role: "tablist", children: tabs.map((tab) => /* @__PURE__ */ jsx8(
417
+ return /* @__PURE__ */ jsxs7("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
418
+ /* @__PURE__ */ jsx9("div", { className: cn("border-b border-base-200", fullBleedTabBar && "-mx-6 px-6"), children: /* @__PURE__ */ jsx9("div", { className: "flex", role: "tablist", children: tabs.map((tab) => /* @__PURE__ */ jsx9(
373
419
  "button",
374
420
  {
375
421
  type: "button",
@@ -384,12 +430,12 @@ function Tabs({ tabs, defaultTabId, activeTabId, onTabChange, fullBleedTabBar })
384
430
  },
385
431
  tab.id
386
432
  )) }) }),
387
- /* @__PURE__ */ jsx8("div", { role: "tabpanel", className: cn("flex min-h-0 flex-1 flex-col px-px", fullBleedTabBar && "pt-4"), children: activeTab?.content })
433
+ /* @__PURE__ */ jsx9("div", { role: "tabpanel", className: cn("flex min-h-0 flex-1 flex-col px-px", fullBleedTabBar && "pt-4"), children: activeTab?.content })
388
434
  ] });
389
435
  }
390
436
 
391
437
  // src/components/editor/SettingsForm.tsx
392
- import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
438
+ import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
393
439
  function resolveValues(schema, values) {
394
440
  const resolved = {};
395
441
  for (const [key, field] of Object.entries(schema)) {
@@ -429,9 +475,9 @@ function RangeField({
429
475
  onChange
430
476
  }) {
431
477
  const id = useId2();
432
- return /* @__PURE__ */ jsxs7("div", { children: [
433
- /* @__PURE__ */ jsx9(FormLabel, { htmlFor: id, children: field.label }),
434
- /* @__PURE__ */ jsx9(
478
+ return /* @__PURE__ */ jsxs8("div", { children: [
479
+ /* @__PURE__ */ jsx10(FormLabel, { htmlFor: id, children: field.label }),
480
+ /* @__PURE__ */ jsx10(
435
481
  "input",
436
482
  {
437
483
  id,
@@ -451,7 +497,7 @@ function RangeField({
451
497
  function renderField(key, field, value, handleFieldChange) {
452
498
  switch (field.type) {
453
499
  case "text":
454
- return /* @__PURE__ */ jsx9(
500
+ return /* @__PURE__ */ jsx10(
455
501
  Input,
456
502
  {
457
503
  label: field.label,
@@ -462,7 +508,7 @@ function renderField(key, field, value, handleFieldChange) {
462
508
  key
463
509
  );
464
510
  case "number":
465
- return /* @__PURE__ */ jsx9(
511
+ return /* @__PURE__ */ jsx10(
466
512
  Input,
467
513
  {
468
514
  label: field.label,
@@ -473,7 +519,7 @@ function renderField(key, field, value, handleFieldChange) {
473
519
  key
474
520
  );
475
521
  case "checkbox":
476
- return /* @__PURE__ */ jsx9(
522
+ return /* @__PURE__ */ jsx10(
477
523
  Checkbox,
478
524
  {
479
525
  label: field.label,
@@ -483,7 +529,7 @@ function renderField(key, field, value, handleFieldChange) {
483
529
  key
484
530
  );
485
531
  case "select":
486
- return /* @__PURE__ */ jsx9(
532
+ return /* @__PURE__ */ jsx10(
487
533
  Select,
488
534
  {
489
535
  label: field.label,
@@ -494,7 +540,7 @@ function renderField(key, field, value, handleFieldChange) {
494
540
  key
495
541
  );
496
542
  case "range":
497
- return /* @__PURE__ */ jsx9(
543
+ return /* @__PURE__ */ jsx10(
498
544
  RangeField,
499
545
  {
500
546
  field,
@@ -504,7 +550,7 @@ function renderField(key, field, value, handleFieldChange) {
504
550
  key
505
551
  );
506
552
  case "link":
507
- return /* @__PURE__ */ jsx9(
553
+ return /* @__PURE__ */ jsx10(
508
554
  LinkField,
509
555
  {
510
556
  label: field.label,
@@ -514,7 +560,7 @@ function renderField(key, field, value, handleFieldChange) {
514
560
  key
515
561
  );
516
562
  case "video-source":
517
- return /* @__PURE__ */ jsx9(
563
+ return /* @__PURE__ */ jsx10(
518
564
  VideoSourceField,
519
565
  {
520
566
  value,
@@ -522,6 +568,15 @@ function renderField(key, field, value, handleFieldChange) {
522
568
  },
523
569
  key
524
570
  );
571
+ case "document-source":
572
+ return /* @__PURE__ */ jsx10(
573
+ DocumentSourceField,
574
+ {
575
+ value,
576
+ onChange: (v) => handleFieldChange(key, v)
577
+ },
578
+ key
579
+ );
525
580
  default:
526
581
  return null;
527
582
  }
@@ -539,12 +594,12 @@ function SettingsForm({ schema, values, onChange, tabs }) {
539
594
  const otherKeys = Object.keys(schema).filter((key) => !listed.has(key));
540
595
  const panel = "flex min-h-0 flex-1 flex-col gap-4 overflow-y-auto px-px";
541
596
  const tabItems = [
542
- ...tabs.map((t) => ({ id: t.label, label: t.label, content: /* @__PURE__ */ jsx9("div", { className: panel, children: fields(t.fields) }) })),
543
- ...otherKeys.length > 0 ? [{ id: "__other__", label: "Other", content: /* @__PURE__ */ jsx9("div", { className: panel, children: fields(otherKeys) }) }] : []
597
+ ...tabs.map((t) => ({ id: t.label, label: t.label, content: /* @__PURE__ */ jsx10("div", { className: panel, children: fields(t.fields) }) })),
598
+ ...otherKeys.length > 0 ? [{ id: "__other__", label: "Other", content: /* @__PURE__ */ jsx10("div", { className: panel, children: fields(otherKeys) }) }] : []
544
599
  ];
545
- return /* @__PURE__ */ jsx9(Tabs, { tabs: tabItems, fullBleedTabBar: true });
600
+ return /* @__PURE__ */ jsx10(Tabs, { tabs: tabItems, fullBleedTabBar: true });
546
601
  }
547
- return /* @__PURE__ */ jsx9("div", { className: "flex flex-col gap-4", children: Object.entries(schema).map(([key, field]) => renderField(key, field, local[key], handleFieldChange)) });
602
+ return /* @__PURE__ */ jsx10("div", { className: "flex flex-col gap-4", children: Object.entries(schema).map(([key, field]) => renderField(key, field, local[key], handleFieldChange)) });
548
603
  }
549
604
 
550
605
  // src/components/shared/Popover.tsx
@@ -600,7 +655,7 @@ function useFocusTrap(ref, active) {
600
655
  }
601
656
 
602
657
  // src/components/shared/Popover.tsx
603
- import { jsx as jsx10 } from "react/jsx-runtime";
658
+ import { jsx as jsx11 } from "react/jsx-runtime";
604
659
  function Popover({
605
660
  isOpen,
606
661
  onClose,
@@ -683,7 +738,7 @@ function Popover({
683
738
  if (portal) {
684
739
  if (!fixedPos) return null;
685
740
  return createPortal(
686
- /* @__PURE__ */ jsx10(
741
+ /* @__PURE__ */ jsx11(
687
742
  "div",
688
743
  {
689
744
  ref: panelRef,
@@ -702,7 +757,7 @@ function Popover({
702
757
  document.body
703
758
  );
704
759
  }
705
- return /* @__PURE__ */ jsx10(
760
+ return /* @__PURE__ */ jsx11(
706
761
  "div",
707
762
  {
708
763
  ref: panelRef,
@@ -720,10 +775,10 @@ function Popover({
720
775
 
721
776
  // src/components/shared/PopoverItem.tsx
722
777
  import { forwardRef as forwardRef2 } from "react";
723
- import { jsx as jsx11 } from "react/jsx-runtime";
778
+ import { jsx as jsx12 } from "react/jsx-runtime";
724
779
  var PopoverItem = forwardRef2(
725
780
  function PopoverItem2({ className, children, ...rest }, ref) {
726
- return /* @__PURE__ */ jsx11(
781
+ return /* @__PURE__ */ jsx12(
727
782
  "button",
728
783
  {
729
784
  ref,