@drawnagency/primitives 0.1.118 → 0.1.120

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 (279) hide show
  1. package/dist/{chunk-O37AV27P.js → chunk-5JYHTHVR.js} +28 -0
  2. package/dist/{chunk-W72BPGR3.js → chunk-BZKHHUIN.js} +44 -8
  3. package/dist/{chunk-4NSOKEA7.js → chunk-HFHM4MNK.js} +12 -7
  4. package/dist/{chunk-CEFFP3CH.js → chunk-HZTPF6OK.js} +304 -83
  5. package/dist/{chunk-RIITGTV3.js → chunk-LQHBC7C6.js} +37 -2
  6. package/dist/{chunk-VY3IFGE3.js → chunk-QAMAIDXZ.js} +1 -1
  7. package/dist/{chunk-HRX3XJBU.js → chunk-RIN2QCYJ.js} +9 -11
  8. package/dist/{chunk-ZOTRHHUB.js → chunk-UNFPATDE.js} +8 -10
  9. package/dist/{chunk-ERLIL4RU.js → chunk-UZBFVVTC.js} +35 -37
  10. package/dist/{chunk-67P34WNW.js → chunk-ZKVQMIMJ.js} +3 -20
  11. package/dist/collab/rebase.js +4 -5
  12. package/dist/components/chat/ChatComposer.d.ts +0 -4
  13. package/dist/components/chat/ChatComposer.d.ts.map +1 -1
  14. package/dist/components/chat/ChatPanel.d.ts +2 -3
  15. package/dist/components/chat/ChatPanel.d.ts.map +1 -1
  16. package/dist/components/chat/markdown.d.ts +2 -3
  17. package/dist/components/chat/markdown.d.ts.map +1 -1
  18. package/dist/components/editor/AudienceIndicator.d.ts +3 -1
  19. package/dist/components/editor/AudienceIndicator.d.ts.map +1 -1
  20. package/dist/components/editor/IndicatorPill.d.ts +3 -1
  21. package/dist/components/editor/IndicatorPill.d.ts.map +1 -1
  22. package/dist/components/editor/PagesModal.d.ts +0 -2
  23. package/dist/components/editor/PagesModal.d.ts.map +1 -1
  24. package/dist/components/editor/SectionBulkEditModal.d.ts +25 -0
  25. package/dist/components/editor/SectionBulkEditModal.d.ts.map +1 -0
  26. package/dist/components/editor/StatusIndicator.d.ts +3 -1
  27. package/dist/components/editor/StatusIndicator.d.ts.map +1 -1
  28. package/dist/components/editor/index.js +28 -26
  29. package/dist/components/primitives/index.js +11 -15
  30. package/dist/components/sections/brand-guide.js +10 -13
  31. package/dist/components/sections/register-schemas.js +16 -21
  32. package/dist/components/sections/register.js +16 -21
  33. package/dist/components/shared/Popover.d.ts +1 -1
  34. package/dist/components/shared/Popover.d.ts.map +1 -1
  35. package/dist/components/shared/SectionSummaryRow.d.ts +1 -1
  36. package/dist/components/shell/AudienceChips.d.ts +1 -3
  37. package/dist/components/shell/AudienceChips.d.ts.map +1 -1
  38. package/dist/components/shell/EditorModal.d.ts.map +1 -1
  39. package/dist/components/shell/EditorShell.d.ts +0 -34
  40. package/dist/components/shell/EditorShell.d.ts.map +1 -1
  41. package/dist/components/shell/SiteSettingsModal.d.ts.map +1 -1
  42. package/dist/hooks/useSortableNavRow.d.ts +1 -1
  43. package/dist/hooks/useSortableRow.d.ts +1 -1
  44. package/dist/index.js +83 -90
  45. package/dist/lib/index-ops.js +5 -6
  46. package/dist/lib/index.js +27 -32
  47. package/dist/lib/pages.d.ts +0 -2
  48. package/dist/lib/pages.d.ts.map +1 -1
  49. package/dist/lib/sidecars.js +2 -2
  50. package/dist/lib/site-validation.js +13 -14
  51. package/dist/lib/storage-tier.js +4 -4
  52. package/dist/schemas/index.js +42 -45
  53. package/dist/schemas/site-config.d.ts +1 -277
  54. package/dist/schemas/site-config.d.ts.map +1 -1
  55. package/package.json +2 -42
  56. package/src/components/chat/ChatComposer.tsx +0 -4
  57. package/src/components/chat/ChatPanel.tsx +2 -3
  58. package/src/components/chat/markdown.ts +2 -3
  59. package/src/components/editor/AudienceIndicator.tsx +8 -4
  60. package/src/components/editor/IndicatorPill.tsx +4 -0
  61. package/src/components/editor/PagesModal.tsx +1 -15
  62. package/src/components/editor/SectionBulkEditModal.tsx +328 -0
  63. package/src/components/editor/StatusIndicator.tsx +7 -6
  64. package/src/components/shared/Popover.tsx +17 -4
  65. package/src/components/shared/SectionSummaryRow.tsx +1 -1
  66. package/src/components/shell/AudienceChips.tsx +1 -3
  67. package/src/components/shell/EditorModal.tsx +5 -2
  68. package/src/components/shell/EditorShell.tsx +15 -119
  69. package/src/components/shell/SiteSettingsModal.tsx +0 -11
  70. package/src/lib/pages.ts +0 -22
  71. package/src/schemas/index.ts +0 -4
  72. package/src/schemas/site-config.ts +4 -32
  73. package/dist/chunk-4TZJZU2T.js +0 -92
  74. package/dist/chunk-DIMDRBFK.js +0 -11
  75. package/dist/chunk-FV7JQRCN.js +0 -94
  76. package/dist/chunk-IIDKW7AV.js +0 -41
  77. package/dist/chunk-JCDZAFX2.js +0 -224
  78. package/dist/chunk-MM7KZS5C.js +0 -30
  79. package/dist/chunk-QQ3S3P5P.js +0 -38
  80. package/dist/chunk-TEOAKGZA.js +0 -784
  81. package/dist/chunk-VAYZJKVR.js +0 -209
  82. package/dist/components/editor/SectionOrderingModal.d.ts +0 -10
  83. package/dist/components/editor/SectionOrderingModal.d.ts.map +0 -1
  84. package/dist/components/shell/DocInspector.d.ts +0 -18
  85. package/dist/components/shell/DocInspector.d.ts.map +0 -1
  86. package/dist/components/shell/DocumentEditorOverlay.d.ts +0 -29
  87. package/dist/components/shell/DocumentEditorOverlay.d.ts.map +0 -1
  88. package/dist/components/shell/DocumentPresentOverlay.d.ts +0 -30
  89. package/dist/components/shell/DocumentPresentOverlay.d.ts.map +0 -1
  90. package/dist/components/shell/SiteSettingsDecks.d.ts +0 -13
  91. package/dist/components/shell/SiteSettingsDecks.d.ts.map +0 -1
  92. package/dist/deck/DeckComponentView.d.ts +0 -13
  93. package/dist/deck/DeckComponentView.d.ts.map +0 -1
  94. package/dist/deck/DeckPlayer.d.ts +0 -26
  95. package/dist/deck/DeckPlayer.d.ts.map +0 -1
  96. package/dist/deck/DeckSlideView.d.ts +0 -17
  97. package/dist/deck/DeckSlideView.d.ts.map +0 -1
  98. package/dist/deck/DeckStage.d.ts +0 -16
  99. package/dist/deck/DeckStage.d.ts.map +0 -1
  100. package/dist/deck/components/DeckImage.d.ts +0 -14
  101. package/dist/deck/components/DeckImage.d.ts.map +0 -1
  102. package/dist/deck/components/DeckImageGrid.d.ts +0 -27
  103. package/dist/deck/components/DeckImageGrid.d.ts.map +0 -1
  104. package/dist/deck/components/DeckRichText.d.ts +0 -22
  105. package/dist/deck/components/DeckRichText.d.ts.map +0 -1
  106. package/dist/deck/components/DeckVideo.d.ts +0 -15
  107. package/dist/deck/components/DeckVideo.d.ts.map +0 -1
  108. package/dist/deck/editing.d.ts +0 -50
  109. package/dist/deck/editing.d.ts.map +0 -1
  110. package/dist/deck/flip.d.ts +0 -11
  111. package/dist/deck/flip.d.ts.map +0 -1
  112. package/dist/deck/index.d.ts +0 -24
  113. package/dist/deck/index.d.ts.map +0 -1
  114. package/dist/deck/index.js +0 -51
  115. package/dist/deck/layouts/CenteredTextLayout.d.ts +0 -12
  116. package/dist/deck/layouts/CenteredTextLayout.d.ts.map +0 -1
  117. package/dist/deck/layouts/ColumnSplitLayout.d.ts +0 -14
  118. package/dist/deck/layouts/ColumnSplitLayout.d.ts.map +0 -1
  119. package/dist/deck/layouts/FullBleedImageLayout.d.ts +0 -14
  120. package/dist/deck/layouts/FullBleedImageLayout.d.ts.map +0 -1
  121. package/dist/deck/media.d.ts +0 -33
  122. package/dist/deck/media.d.ts.map +0 -1
  123. package/dist/deck/tokens.d.ts +0 -22
  124. package/dist/deck/tokens.d.ts.map +0 -1
  125. package/dist/deck/useStageScale.d.ts +0 -10
  126. package/dist/deck/useStageScale.d.ts.map +0 -1
  127. package/dist/deck-builder/DeckBuilderApp.d.ts +0 -30
  128. package/dist/deck-builder/DeckBuilderApp.d.ts.map +0 -1
  129. package/dist/deck-builder/DeckBuilderTopBar.d.ts +0 -24
  130. package/dist/deck-builder/DeckBuilderTopBar.d.ts.map +0 -1
  131. package/dist/deck-builder/DeckChatPanel.d.ts +0 -45
  132. package/dist/deck-builder/DeckChatPanel.d.ts.map +0 -1
  133. package/dist/deck-builder/DeckEditor.d.ts +0 -37
  134. package/dist/deck-builder/DeckEditor.d.ts.map +0 -1
  135. package/dist/deck-builder/DeckLibrary.d.ts +0 -22
  136. package/dist/deck-builder/DeckLibrary.d.ts.map +0 -1
  137. package/dist/deck-builder/DeckSlideSurface.d.ts +0 -31
  138. package/dist/deck-builder/DeckSlideSurface.d.ts.map +0 -1
  139. package/dist/deck-builder/deck-api.d.ts +0 -76
  140. package/dist/deck-builder/deck-api.d.ts.map +0 -1
  141. package/dist/deck-builder/deck-chat-client.d.ts +0 -44
  142. package/dist/deck-builder/deck-chat-client.d.ts.map +0 -1
  143. package/dist/deck-builder/deck-chat-history.d.ts +0 -10
  144. package/dist/deck-builder/deck-chat-history.d.ts.map +0 -1
  145. package/dist/deck-builder/index.d.ts +0 -13
  146. package/dist/deck-builder/index.d.ts.map +0 -1
  147. package/dist/deck-builder/index.js +0 -1498
  148. package/dist/deck-builder/starter-deck.d.ts +0 -23
  149. package/dist/deck-builder/starter-deck.d.ts.map +0 -1
  150. package/dist/deck-builder/types.d.ts +0 -29
  151. package/dist/deck-builder/types.d.ts.map +0 -1
  152. package/dist/deck-builder/useSortableSlide.d.ts +0 -29
  153. package/dist/deck-builder/useSortableSlide.d.ts.map +0 -1
  154. package/dist/document/assets/fonts/albra-grotesk-bold.woff +0 -0
  155. package/dist/document/assets/fonts/albra-grotesk-regular.woff +0 -0
  156. package/dist/document/assets/fonts/kapra-neue-expanded-medium.woff +0 -0
  157. package/dist/document/assets/fonts/kapra-neue-expanded-regular.woff +0 -0
  158. package/dist/document/components/DocCoverPage.d.ts +0 -11
  159. package/dist/document/components/DocCoverPage.d.ts.map +0 -1
  160. package/dist/document/components/DocPage.d.ts +0 -10
  161. package/dist/document/components/DocPage.d.ts.map +0 -1
  162. package/dist/document/components/DocRail.d.ts +0 -28
  163. package/dist/document/components/DocRail.d.ts.map +0 -1
  164. package/dist/document/components/DocSectionPage.d.ts +0 -12
  165. package/dist/document/components/DocSectionPage.d.ts.map +0 -1
  166. package/dist/document/components/DocViewer.d.ts +0 -21
  167. package/dist/document/components/DocViewer.d.ts.map +0 -1
  168. package/dist/document/components/Wordmark.d.ts +0 -4
  169. package/dist/document/components/Wordmark.d.ts.map +0 -1
  170. package/dist/document/components/measure.d.ts +0 -7
  171. package/dist/document/components/measure.d.ts.map +0 -1
  172. package/dist/document/components/useDocPages.d.ts +0 -12
  173. package/dist/document/components/useDocPages.d.ts.map +0 -1
  174. package/dist/document/engine/blocks.d.ts +0 -2
  175. package/dist/document/engine/blocks.d.ts.map +0 -1
  176. package/dist/document/engine/harvest.d.ts +0 -3
  177. package/dist/document/engine/harvest.d.ts.map +0 -1
  178. package/dist/document/engine/masonry.d.ts +0 -26
  179. package/dist/document/engine/masonry.d.ts.map +0 -1
  180. package/dist/document/engine/paginate.d.ts +0 -43
  181. package/dist/document/engine/paginate.d.ts.map +0 -1
  182. package/dist/document/engine/settings.d.ts +0 -91
  183. package/dist/document/engine/settings.d.ts.map +0 -1
  184. package/dist/document/engine/types.d.ts +0 -44
  185. package/dist/document/engine/types.d.ts.map +0 -1
  186. package/dist/document/index.d.ts +0 -13
  187. package/dist/document/index.d.ts.map +0 -1
  188. package/dist/document/index.js +0 -1030
  189. package/dist/document/styles/document.css +0 -217
  190. package/dist/lib/deck-access.d.ts +0 -86
  191. package/dist/lib/deck-access.d.ts.map +0 -1
  192. package/dist/lib/deck-access.js +0 -58
  193. package/dist/lib/deck-dexie.d.ts +0 -88
  194. package/dist/lib/deck-dexie.d.ts.map +0 -1
  195. package/dist/lib/deck-dexie.js +0 -22
  196. package/dist/lib/deck-edit.d.ts +0 -67
  197. package/dist/lib/deck-edit.d.ts.map +0 -1
  198. package/dist/lib/deck-media-assets.d.ts +0 -27
  199. package/dist/lib/deck-media-assets.d.ts.map +0 -1
  200. package/dist/lib/deck-media-assets.js +0 -25
  201. package/dist/lib/deck-media-refs.d.ts +0 -35
  202. package/dist/lib/deck-media-refs.d.ts.map +0 -1
  203. package/dist/lib/deck-media-refs.js +0 -36
  204. package/dist/lib/deck-tool.d.ts +0 -25
  205. package/dist/lib/deck-tool.d.ts.map +0 -1
  206. package/dist/lib/deck-tool.js +0 -58
  207. package/dist/lib/document-input.d.ts +0 -25
  208. package/dist/lib/document-input.d.ts.map +0 -1
  209. package/dist/schemas/deck-meta.d.ts +0 -85
  210. package/dist/schemas/deck-meta.d.ts.map +0 -1
  211. package/dist/schemas/deck-meta.js +0 -64
  212. package/dist/schemas/deck.d.ts +0 -954
  213. package/dist/schemas/deck.d.ts.map +0 -1
  214. package/dist/schemas/deck.js +0 -65
  215. package/src/components/editor/SectionOrderingModal.tsx +0 -80
  216. package/src/components/shell/DocInspector.tsx +0 -314
  217. package/src/components/shell/DocumentEditorOverlay.tsx +0 -179
  218. package/src/components/shell/DocumentPresentOverlay.tsx +0 -87
  219. package/src/components/shell/SiteSettingsDecks.tsx +0 -41
  220. package/src/deck/DeckComponentView.tsx +0 -28
  221. package/src/deck/DeckPlayer.tsx +0 -166
  222. package/src/deck/DeckSlideView.tsx +0 -38
  223. package/src/deck/DeckStage.tsx +0 -39
  224. package/src/deck/components/DeckImage.tsx +0 -38
  225. package/src/deck/components/DeckImageGrid.tsx +0 -254
  226. package/src/deck/components/DeckRichText.tsx +0 -111
  227. package/src/deck/components/DeckVideo.tsx +0 -81
  228. package/src/deck/editing.tsx +0 -201
  229. package/src/deck/flip.ts +0 -70
  230. package/src/deck/index.ts +0 -30
  231. package/src/deck/layouts/CenteredTextLayout.tsx +0 -29
  232. package/src/deck/layouts/ColumnSplitLayout.tsx +0 -69
  233. package/src/deck/layouts/FullBleedImageLayout.tsx +0 -58
  234. package/src/deck/media.tsx +0 -46
  235. package/src/deck/tokens.ts +0 -57
  236. package/src/deck/useStageScale.ts +0 -44
  237. package/src/deck-builder/DeckBuilderApp.tsx +0 -572
  238. package/src/deck-builder/DeckBuilderTopBar.tsx +0 -62
  239. package/src/deck-builder/DeckChatPanel.tsx +0 -334
  240. package/src/deck-builder/DeckEditor.tsx +0 -258
  241. package/src/deck-builder/DeckLibrary.tsx +0 -195
  242. package/src/deck-builder/DeckSlideSurface.tsx +0 -55
  243. package/src/deck-builder/deck-api.ts +0 -177
  244. package/src/deck-builder/deck-chat-client.ts +0 -129
  245. package/src/deck-builder/deck-chat-history.ts +0 -62
  246. package/src/deck-builder/index.ts +0 -12
  247. package/src/deck-builder/starter-deck.ts +0 -86
  248. package/src/deck-builder/types.ts +0 -24
  249. package/src/deck-builder/useSortableSlide.ts +0 -102
  250. package/src/document/assets/fonts/albra-grotesk-bold.woff +0 -0
  251. package/src/document/assets/fonts/albra-grotesk-regular.woff +0 -0
  252. package/src/document/assets/fonts/kapra-neue-expanded-medium.woff +0 -0
  253. package/src/document/assets/fonts/kapra-neue-expanded-regular.woff +0 -0
  254. package/src/document/components/DocCoverPage.tsx +0 -45
  255. package/src/document/components/DocPage.tsx +0 -40
  256. package/src/document/components/DocRail.tsx +0 -189
  257. package/src/document/components/DocSectionPage.tsx +0 -48
  258. package/src/document/components/DocViewer.tsx +0 -313
  259. package/src/document/components/Wordmark.tsx +0 -18
  260. package/src/document/components/measure.tsx +0 -133
  261. package/src/document/components/useDocPages.ts +0 -95
  262. package/src/document/engine/blocks.ts +0 -116
  263. package/src/document/engine/harvest.ts +0 -95
  264. package/src/document/engine/masonry.ts +0 -158
  265. package/src/document/engine/paginate.ts +0 -232
  266. package/src/document/engine/settings.ts +0 -125
  267. package/src/document/engine/types.ts +0 -64
  268. package/src/document/index.ts +0 -18
  269. package/src/document/styles/document.css +0 -217
  270. package/src/lib/deck-access.ts +0 -132
  271. package/src/lib/deck-dexie.ts +0 -190
  272. package/src/lib/deck-edit.ts +0 -196
  273. package/src/lib/deck-media-assets.ts +0 -57
  274. package/src/lib/deck-media-refs.ts +0 -67
  275. package/src/lib/deck-tool.ts +0 -95
  276. package/src/lib/document-input.ts +0 -57
  277. package/src/schemas/deck-meta.ts +0 -88
  278. package/src/schemas/deck.ts +0 -478
  279. package/dist/{chunk-DJABADOO.js → chunk-AJ2QOAZI.js} +3 -3
@@ -1,4 +1,4 @@
1
- import { Fragment, Suspense, lazy, useContext, useState, useCallback, useEffect, useRef, useMemo, type ReactNode } from "react";
1
+ import { Fragment, useContext, useState, useCallback, useEffect, useRef, useMemo, type ReactNode } from "react";
2
2
 
3
3
  import { monitorForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
4
4
  import { combine } from "@atlaskit/pragmatic-drag-and-drop/combine";
@@ -15,10 +15,6 @@ import { composePreviewImage, PREVIEW_COMPOSE_VERSION } from "../../media/compos
15
15
  import { derivePreviewInputs, servedPreviewSize } from "../../media/preview-inputs";
16
16
  import { resolveMedia } from "../../media/resolve";
17
17
  import { getMediaProvider } from "../../media";
18
- // Sanctioned outside->inside import: document/ is a sealed subtree, but the
19
- // Document mode toggle wiring needs the patch shape it edits (mirrors the same
20
- // sanctioned import in schemas/site-config.ts and lib/pages.ts).
21
- import type { DocumentOptions } from "../../document/engine/settings";
22
18
  import { SiteConfigSchema } from "../../schemas/site-config";
23
19
  import { ensureSanitizer } from "../../lib/sanitize";
24
20
  import { resolveChatbotName } from "../../lib/chatbot";
@@ -45,19 +41,8 @@ import { buildInsertMenuOptions, resolveInsertedContent } from "../../lib/insert
45
41
 
46
42
  ensureSectionsRegistered();
47
43
  import { BugReportFAB } from "./BugReportFAB";
48
- // Lazy boundary: the document editor/presentation overlays (and the whole
49
- // document engine they pull in) must not weigh /edit on sites that never use
50
- // document mode — they load only when a document-enabled page opens the overlay.
51
- // Named exports → adapt to the default-export shape React.lazy expects (mirrors
52
- // the ChatPanel lazy import convention in ChatWidget).
53
- const DocumentEditorOverlay = lazy(() =>
54
- import("./DocumentEditorOverlay").then((m) => ({ default: m.DocumentEditorOverlay })),
55
- );
56
- const DocumentPresentOverlay = lazy(() =>
57
- import("./DocumentPresentOverlay").then((m) => ({ default: m.DocumentPresentOverlay })),
58
- );
59
44
  import { SectionWrapper } from "../editor/SectionWrapper";
60
- import { SectionOrderingModal } from "../editor/SectionOrderingModal";
45
+ import { SectionBulkEditModal } from "../editor/SectionBulkEditModal";
61
46
  import { MoveSectionModal } from "../editor/MoveSectionModal";
62
47
  import { SectionLayout } from "../sections/SectionLayout";
63
48
  import {
@@ -103,7 +88,7 @@ import type { ViewerCredential } from "../../schemas/audience";
103
88
  import {
104
89
  homePage, pageById, pageBySlug, pageDisplayTitle, addSectionToPage, removeSectionFromPages,
105
90
  reorderVisibleSectionInPage, audiencePasses,
106
- setHomePage, setPageArchived, setPageFields, setPageAudience, setPageDocument, deletePage, addPage,
91
+ setHomePage, setPageArchived, setPageFields, setPageAudience, deletePage, addPage,
107
92
  moveSection as moveSectionReducer,
108
93
  } from "../../lib/pages";
109
94
  import { PagesContext } from "../shared/PagesContext";
@@ -128,7 +113,7 @@ import { FabStack } from "../shared/FabStack";
128
113
  import { Tooltip } from "../shared/Tooltip";
129
114
  import { SegmentedControl } from "../shared/SegmentedControl";
130
115
  import { computeDisplaySections } from "./view-branch";
131
- import { ImageIcon, ListOrderedIcon, FilesIcon, JoystickIcon, Settings, X, FileText, Presentation, Eye, Pencil } from "lucide-react";
116
+ import { ImageIcon, ListChecks, FilesIcon, JoystickIcon, Settings, X, Eye, Pencil } from "lucide-react";
132
117
  import { ErrorBoundary } from "../shared/ErrorBoundary";
133
118
  import { HistoryToolbar } from "./HistoryToolbar";
134
119
  import { RestoreModal } from "./RestoreModal";
@@ -259,7 +244,7 @@ export default function EditorShell({
259
244
  useEffect(() => { deletedSectionsRef.current = deletedSections; }, [deletedSections]);
260
245
  const [pendingDeleteSectionId, setPendingDeleteSectionId] = useState<string | null>(null);
261
246
  // One shared aria-live region for every reorder — sections (via
262
- // onReorderSections, the dispatch point shared by SectionOrderingModal's
247
+ // onReorderSections, the dispatch point shared by SectionBulkEditModal's
263
248
  // drag and SectionWrapper's Move up/down) and pages/groups (via
264
249
  // handleMoveNavEntry, shared the same way by PagesModal/NavGroupRow's drag
265
250
  // and their own Move up/down). The section canvas's own per-block drag
@@ -299,7 +284,6 @@ export default function EditorShell({
299
284
  const [showRestoreModal, setShowRestoreModal] = useState(false);
300
285
  const [showOrderingModal, setShowOrderingModal] = useState(false);
301
286
  const [showPagesModal, setShowPagesModal] = useState(false);
302
- const [showDocumentEditor, setShowDocumentEditor] = useState(false);
303
287
  const [isRestoring, setIsRestoring] = useState(false);
304
288
  const [rejectedUploads, setRejectedUploads] = useState<{ name: string; reason: "size" | "type" }[]>([]);
305
289
  // Surfaces useMediaPipeline's onUploadError (oversized/disallowed files,
@@ -488,26 +472,6 @@ export default function EditorShell({
488
472
  return audiences.filter((a) => resolvedActivePage.access.includes(a.name));
489
473
  }, [resolvedActivePage, audiences]);
490
474
 
491
- // The sections shown on the canvas when previewing the published ("live")
492
- // branch — the SAME list computeDisplaySections renders for viewBranch "live".
493
- // Only meaningful while viewSections !== null (branch view); the read-only
494
- // document presentation overlay renders exactly these so it mirrors the canvas.
495
- // (viewSections is set only for the live branch, so its non-null-ness IS the
496
- // "branch view" signal at this level.)
497
- const branchDisplaySections = useMemo(
498
- () =>
499
- viewSections && resolvedActivePage
500
- ? computeDisplaySections({
501
- isEditMode: false,
502
- viewBranch: "live",
503
- sections,
504
- viewSections,
505
- activePageSectionIds: resolvedActivePage.order,
506
- })
507
- : [],
508
- [viewSections, resolvedActivePage, sections],
509
- );
510
-
511
475
  const getPageHeadings = useCallback(
512
476
  (pageId: string) => {
513
477
  const page = pageById(siteIndex, pageId);
@@ -1867,11 +1831,6 @@ export default function EditorShell({
1867
1831
  persistence.markIndexDirty(); setLocalChangesExist(true);
1868
1832
  }, [persistence]);
1869
1833
 
1870
- const handleSetPageDocument = useCallback((id: string, patch: Partial<DocumentOptions>) => {
1871
- setSiteIndex((prev) => setPageDocument(prev, id, patch));
1872
- persistence.markIndexDirty(); setLocalChangesExist(true);
1873
- }, [persistence]);
1874
-
1875
1834
  const handleSetPageAudience = useCallback((id: string, access: string[]) => {
1876
1835
  const { index: next, resetSectionIds } = setPageAudience(siteIndexRef.current, id, access);
1877
1836
  setSiteIndex(next);
@@ -2176,55 +2135,12 @@ export default function EditorShell({
2176
2135
  audiences={audiences}
2177
2136
  authoringDefaults={authoringDefaults}
2178
2137
  onAuthoringDefaultsChange={onAuthoringDefaultsChange}
2179
- docEditEnabled={Boolean(resolvedActivePage?.document?.enabled)}
2180
- onDocEditClick={() => setShowDocumentEditor(true)}
2181
2138
  // Bug reports persist via Supabase. On the password-only
2182
2139
  // (zero-Supabase) path there's no backend and the editor session
2183
2140
  // has userId: null, so the button would always 401 — hide it there.
2184
2141
  showBugReport={!capabilities.passwordOnly}
2185
2142
  />
2186
2143
 
2187
- {/* Deck Builder (#34). Editors are super-admins over decks and are
2188
- never gated by deckBuilder.audiences, so this is unconditional.
2189
- An <a>, not a click handler: builder mode is its own route.
2190
- Standalone (not in EditorToolbar's FabStack): bottom-60 clears
2191
- the stack's three members with room to spare. Taking over the
2192
- editor top bar in place is #38 — this just goes there. */}
2193
- <Fab href="/decks?next=%2Fedit" label="Build a deck" column="editor" className="bottom-60">
2194
- <Presentation size={20} aria-hidden="true" />
2195
- </Fab>
2196
- {showDocumentEditor && resolvedActivePage?.document?.enabled && (
2197
- <Suspense fallback={<DocumentOverlayFallback />}>
2198
- {/* Branch/history view (viewSections !== null → previewing the
2199
- published branch): presentation only, never the editor. Drew's
2200
- product decision — old versions are the record, and we have no
2201
- way to edit them, so opening the editor over one would be a lie.
2202
- The draft view (viewSections === null) still opens the real
2203
- editor. NOTE: viewSections drives the "Published" branch preview
2204
- only; the separate historySelectEvent commit view
2205
- (EditorContext.historyState) is the OTHER read-only case — the
2206
- document FAB in EditorToolbar is gated on !historyState, which
2207
- keeps this overlay from ever being opened onto it in the
2208
- first place. */}
2209
- {viewSections !== null ? (
2210
- <DocumentPresentOverlay
2211
- page={resolvedActivePage}
2212
- sections={branchDisplaySections}
2213
- manifest={mediaManifest}
2214
- onClose={() => setShowDocumentEditor(false)}
2215
- />
2216
- ) : (
2217
- <DocumentEditorOverlay
2218
- page={resolvedActivePage}
2219
- sections={activeSections}
2220
- manifest={mediaManifest}
2221
- onUpdateDocument={(patch) => handleSetPageDocument(resolvedActivePage.id, patch)}
2222
- onClose={() => setShowDocumentEditor(false)}
2223
- />
2224
- )}
2225
- </Suspense>
2226
- )}
2227
-
2228
2144
  {/* Editor chat FAB: chat while editing, against the DRAFT chatbot
2229
2145
  config (tasks + prompt reflect unsaved changes; grounding is
2230
2146
  published content). Gated only on the platform switch — editors
@@ -2445,13 +2361,17 @@ export default function EditorShell({
2445
2361
  <EditorModal
2446
2362
  isOpen={showOrderingModal}
2447
2363
  onClose={() => setShowOrderingModal(false)}
2448
- title="Reorder Sections"
2364
+ title="Edit sections"
2449
2365
  size="settings"
2450
2366
  >
2451
- <SectionOrderingModal
2367
+ <SectionBulkEditModal
2452
2368
  sections={activeSections}
2453
2369
  mediaManifest={mediaManifest}
2370
+ audiences={pageAudiences}
2371
+ locks={collab.locks}
2454
2372
  onReorder={onReorderSections}
2373
+ onStatusChange={onStatusChange}
2374
+ onAccessChange={onAccessChange}
2455
2375
  />
2456
2376
  </EditorModal>
2457
2377
  <EditorModal isOpen={showPagesModal} onClose={() => setShowPagesModal(false)} title="Pages" size="settings">
@@ -2468,7 +2388,6 @@ export default function EditorShell({
2468
2388
  onSetArchived={handleSetArchived}
2469
2389
  onSetFields={handleSetPageFields}
2470
2390
  onSetAudience={handleSetPageAudience}
2471
- onSetDocument={handleSetPageDocument}
2472
2391
  onConfirmDelete={handleDeletePage}
2473
2392
  />
2474
2393
  </EditorModal>
@@ -2975,15 +2894,6 @@ function EditorContent({
2975
2894
  );
2976
2895
  }
2977
2896
 
2978
- // Suspense fallback while the lazy document overlay chunk loads.
2979
- function DocumentOverlayFallback() {
2980
- return (
2981
- <div className="fixed inset-0 z-50 flex items-center justify-center bg-base" role="status" aria-live="polite">
2982
- <span className="text-sm text-base-contrast-light">Loading document editor…</span>
2983
- </div>
2984
- );
2985
- }
2986
-
2987
2897
  function GlobalModal() {
2988
2898
  const { modalState, closeModal } = useEditorModal();
2989
2899
 
@@ -3111,8 +3021,6 @@ function EditorToolbar({
3111
3021
  audiences,
3112
3022
  authoringDefaults,
3113
3023
  onAuthoringDefaultsChange,
3114
- docEditEnabled,
3115
- onDocEditClick,
3116
3024
  showBugReport,
3117
3025
  }: {
3118
3026
  buttonState: "synced" | "publish" | "saveAndPublish";
@@ -3139,11 +3047,6 @@ function EditorToolbar({
3139
3047
  audiences: Audience[];
3140
3048
  authoringDefaults: AuthoringDefaults;
3141
3049
  onAuthoringDefaultsChange: (next: AuthoringDefaults) => void;
3142
- /** Whether the active page has document mode on — gates the "Edit as
3143
- * document" FAB this toolbar stacks alongside its own mode-toggle FAB.
3144
- * Owned by EditorShell (resolvedActivePage lives above the Provider). */
3145
- docEditEnabled: boolean;
3146
- onDocEditClick: () => void;
3147
3050
  /** Whether to render BugReportFAB in this toolbar's FabStack — false on
3148
3051
  * the password-only (zero-Supabase) path, which has no backend for it. */
3149
3052
  showBugReport: boolean;
@@ -3233,8 +3136,8 @@ function EditorToolbar({
3233
3136
  <Tooltip side="bottom" content="Media library">
3234
3137
  <IconButton icon={<ImageIcon size={16} />} label="Media library" size="md" onClick={onMediaClick} className="border border-base-200 bg-base-accent" />
3235
3138
  </Tooltip>
3236
- <Tooltip side="bottom" content="Reorder sections">
3237
- <IconButton icon={<ListOrderedIcon size={16} />} label="Reorder sections" size="md" onClick={onOrderingClick} className="border border-base-200 bg-base-accent" />
3139
+ <Tooltip side="bottom" content="Edit sections">
3140
+ <IconButton icon={<ListChecks size={16} />} label="Edit sections" size="md" onClick={onOrderingClick} className="border border-base-200 bg-base-accent" />
3238
3141
  </Tooltip>
3239
3142
  <Tooltip side="bottom" content="Pages">
3240
3143
  <IconButton icon={<FilesIcon size={16} />} label="Pages" size="md" onClick={onPagesClick} className="border border-base-200 bg-base-accent" />
@@ -3267,17 +3170,10 @@ function EditorToolbar({
3267
3170
  <FabStack>
3268
3171
  {/* Bug reports persist via Supabase; hidden on the password-only
3269
3172
  path (showBugReport, threaded from EditorShell's capabilities).
3270
- History is presentation only, never editing (branch-preview
3271
- already routes to DocumentPresentOverlay; !historyState covers
3272
- the separate historySelectEvent commit view) — FabStack
3173
+ History is presentation only, never editing — FabStack
3273
3174
  unmounts with the rest of this block whenever history is
3274
- active, which hides all three FABs together. */}
3175
+ active, which hides its FABs together. */}
3275
3176
  {showBugReport && <BugReportFAB stacked />}
3276
- {docEditEnabled && (
3277
- <Fab stacked label="Edit as document" column="editor" onClick={onDocEditClick}>
3278
- <FileText size={20} aria-hidden="true" />
3279
- </Fab>
3280
- )}
3281
3177
  <Fab
3282
3178
  stacked
3283
3179
  label={isEditMode ? "Switch to view mode" : "Switch to edit mode"}
@@ -6,7 +6,6 @@ import { SiteSettingsViewerAccess } from "./SiteSettingsViewerAccess";
6
6
  import { SiteSettingsDisplay } from "./SiteSettingsDisplay";
7
7
  import { SiteSettingsUsers } from "./SiteSettingsUsers";
8
8
  import { SiteSettingsChatbot } from "./SiteSettingsChatbot";
9
- import { SiteSettingsDecks } from "./SiteSettingsDecks";
10
9
  import { SiteSettingsTags } from "./SiteSettingsTags";
11
10
  import type { SiteTagging } from "../../lib/registry";
12
11
  import type { SiteConfig } from "../../schemas/site-config";
@@ -88,16 +87,6 @@ export function SiteSettingsModal({
88
87
  </div>
89
88
  ),
90
89
  },
91
- {
92
- id: "decks",
93
- label: "Decks",
94
- show: true,
95
- content: (
96
- <div data-testid="site-settings-tab-panel" className="flex flex-1 flex-col overflow-y-auto px-6 py-4">
97
- <SiteSettingsDecks siteConfig={siteConfig} onSiteConfigChange={onSiteConfigChange} audiences={audiences} />
98
- </div>
99
- ),
100
- },
101
90
  {
102
91
  id: "tags",
103
92
  label: "Tags",
package/src/lib/pages.ts CHANGED
@@ -1,9 +1,5 @@
1
1
  import type { Page, SiteIndex, SectionMeta } from "../schemas/site-config";
2
2
  import { RESERVED_SLUGS } from "../schemas/site-config";
3
- // Sanctioned outside->inside import: document/ is a sealed subtree, but pages.ts
4
- // is allowed to reach into its engine to write the page-level document options
5
- // block (mirrors the same sanctioned import in schemas/site-config.ts).
6
- import { documentOptionsSchema, type DocumentOptions } from "../document/engine/settings";
7
3
  import { navEntries } from "./nav-tree";
8
4
  import { slugifyPageSlug } from "./slug";
9
5
 
@@ -101,24 +97,6 @@ export function setPageFields(
101
97
  return mapPages(index, (p) => (p.id === pageId ? { ...p, ...patch } : p));
102
98
  }
103
99
 
104
- export function setPageDocument(index: SiteIndex, pageId: string, patch: Partial<DocumentOptions>): SiteIndex {
105
- return {
106
- ...index,
107
- pages: index.pages.map((p) => {
108
- if (p.id !== pageId) return p;
109
- const current = p.document ?? documentOptionsSchema.parse({});
110
- return {
111
- ...p,
112
- document: documentOptionsSchema.parse({
113
- ...current,
114
- ...patch,
115
- sections: { ...current.sections, ...(patch.sections ?? {}) },
116
- }),
117
- };
118
- }),
119
- };
120
- }
121
-
122
100
  export function setPageAudience(
123
101
  index: SiteIndex,
124
102
  pageId: string,
@@ -9,7 +9,3 @@ export * from "./media-grid-options";
9
9
  export * from "./auth";
10
10
  export * from "./link";
11
11
  export * from "./documents";
12
- // ./deck is deliberately NOT re-exported here: this barrel is reached from the
13
- // primitives root export, which viewer pages pull in. Decks are not site
14
- // content and not a section type — reach the deck schema through its own
15
- // subpath export instead (see tests/deck/viewer-isolation.test.ts).
@@ -2,10 +2,6 @@ import { z } from "zod";
2
2
  import { MediaConfigSchema } from "./media";
3
3
  import { HexColorSchema, FontNameSchema } from "./shared";
4
4
  import { CORNER_RADIUS_OPTIONS } from "../lib/corner-radius";
5
- // Sanctioned outside->inside import: document/ is a sealed subtree, but
6
- // site-config.ts is allowed to reach into its engine to wire the page-level
7
- // document options block onto PageSchema.
8
- import { documentOptionsSchema } from "../document/engine/settings";
9
5
  import type { NavEntry } from "./nav";
10
6
  import type { TagEntry } from "./tags";
11
7
 
@@ -21,19 +17,19 @@ export const SectionMetaSchema = z.object({
21
17
 
22
18
  export type SectionMeta = z.infer<typeof SectionMetaSchema>;
23
19
 
24
- // Page slugs that would shadow a platform route. KEEP IN SYNC with the root,
25
- // /edit/*, and /present/* route patterns injected in
20
+ // Page slugs that would shadow a platform route. KEEP IN SYNC with the root
21
+ // and /edit/* route patterns injected in
26
22
  // packages/core/src/integration.ts — if a new root-level route is added there,
27
23
  // add its first segment here (the test in Step 1 guards the known set). This is
28
24
  // the single source of truth for reserved slugs; the schema, uniquePageSlug, and
29
25
  // /api/save all import it.
30
- export const RESERVED_SLUGS = ["edit", "api", "login", "set-password", "404", "present", "print", "audiences", "decks"] as const;
26
+ export const RESERVED_SLUGS = ["edit", "api", "login", "set-password", "404", "audiences"] as const;
31
27
 
32
28
  // Subset of RESERVED_SLUGS the index schema hard-rejects at parse time. Only
33
29
  // slugs reserved since before client sites existed may hard-fail here: parse-
34
30
  // rejecting a newly-reserved slug would brick an already-deployed index that
35
31
  // uses it (viewer AND editor refuse to load, leaving no in-product rename
36
- // path). Newly reserved slugs ("present") are enforced at authoring time only —
32
+ // path). Newly reserved slugs ("audiences") are enforced at authoring time only —
37
33
  // PagesModal and uniquePageSlug block new uses via RESERVED_SLUGS, and the
38
34
  // injected platform route simply shadows a grandfathered page until renamed.
39
35
  const PARSE_REJECTED_SLUGS = ["edit", "api", "login", "set-password", "404"] as const;
@@ -49,7 +45,6 @@ export const PageSchema = z.object({
49
45
  status: PageStatusSchema,
50
46
  access: z.array(z.string()),
51
47
  order: z.array(z.string()),
52
- document: documentOptionsSchema.optional(),
53
48
  });
54
49
 
55
50
  export type Page = z.infer<typeof PageSchema>;
@@ -238,26 +233,6 @@ export const ChatbotConfigSchema = z
238
233
  });
239
234
  export type ChatbotConfig = z.infer<typeof ChatbotConfigSchema>;
240
235
 
241
- /**
242
- * Deck Builder config (ADR 0001/0002). An OBJECT rather than a bare audience
243
- * array because `publicSharing` (#37) lands beside `audiences` — the same shape
244
- * ChatbotConfigSchema has, for the same reason.
245
- */
246
- export const DeckBuilderConfigSchema = z.object({
247
- // Audience names whose members may CREATE decks — a Deck Creator. Strict
248
- // opt-in exactly like chatbot.audiences: [] = no viewer may build a deck.
249
- // Editors are super-admins over decks and are never gated by this list.
250
- // Gates: [...slug].astro's FAB, /decks, and POST /api/decks (canCreateDeck).
251
- audiences: z
252
- .array(z.string())
253
- .default([])
254
- .describe(
255
- "Audience names allowed to create decks in the Deck Builder. Strict opt-in — an empty list means no viewer can. Editors always can.",
256
- ),
257
- });
258
-
259
- export type DeckBuilderConfig = z.infer<typeof DeckBuilderConfigSchema>;
260
-
261
236
  export const SiteConfigSchema = z.object({
262
237
  siteName: z.string().default("Brand Portal"),
263
238
  primaryColor: HexColorSchema.default("#009ca6"),
@@ -328,9 +303,6 @@ export const SiteConfigSchema = z.object({
328
303
  // sites table, not here). Every field defaults so pre-existing
329
304
  // site-config.json files keep parsing.
330
305
  chatbot: ChatbotConfigSchema.default({ enabled: false, name: "Portal Assistant", audienceNames: {}, thinkingPhrases: [], systemPrompt: "", audiences: [], tasks: [], audiencePrompts: {} }),
331
- // Deck Builder config (editor-owned). Defaults so pre-existing
332
- // site-config.json files keep parsing — and the default is closed.
333
- deckBuilder: DeckBuilderConfigSchema.default({ audiences: [] }),
334
306
  });
335
307
 
336
308
  export type SiteConfig = z.infer<typeof SiteConfigSchema>;
@@ -1,92 +0,0 @@
1
- // src/document/engine/settings.ts
2
- import { z } from "zod";
3
- var sectionSettingsSchema = z.object({
4
- excluded: z.boolean().default(false),
5
- textPlacement: z.enum(["top", "leftColumn"]).default("top"),
6
- // "right" is only meaningful with textPlacement "leftColumn"; settingsFor
7
- // normalizes the invalid combo.
8
- imagePlacement: z.enum(["fullWidth", "right"]).default("fullWidth"),
9
- // When true, text that overflows the first page is dropped instead of
10
- // flowing onto Cont. pages (images still paginate normally).
11
- dropTextOverflow: z.boolean().default(false),
12
- // Also start new pages at sub-heading boundaries. Only read from PARENT
13
- // entries (link_heading ids / __preamble); inert on sub-chunk entries.
14
- splitAt: z.enum(["none", "sub_heading"]).default("none"),
15
- imageLayout: z.discriminatedUnion("mode", [
16
- z.object({
17
- mode: z.literal("grid"),
18
- rows: z.union([z.literal(1), z.literal(2), z.literal(3)]).default(2),
19
- columns: z.union([z.literal(2), z.literal(3), z.literal(4)]).default(4),
20
- // "cover" crops each image to its cell; "contain" letterboxes the
21
- // natural image inside it.
22
- fit: z.enum(["cover", "contain"]).default("cover")
23
- }),
24
- z.object({
25
- mode: z.literal("masonry"),
26
- flow: z.enum(["rows", "columns"]).default("rows"),
27
- columns: z.union([z.literal(2), z.literal(3), z.literal(4), z.literal(5), z.literal(6)]).default(3),
28
- // rows flow only: "auto" = greedy target-height fill (legacy behavior);
29
- // 1-4 forces an exact aspect-balanced row count.
30
- rows: z.union([z.literal("auto"), z.literal(1), z.literal(2), z.literal(3), z.literal(4)]).default("auto")
31
- })
32
- ]).default({ mode: "masonry", flow: "rows", columns: 3, rows: "auto" })
33
- });
34
- var DEFAULTS = sectionSettingsSchema.parse({});
35
- function salvage(raw) {
36
- const fast = sectionSettingsSchema.safeParse(raw ?? {});
37
- if (fast.success) return { settings: fast.data, rejected: [] };
38
- if (!raw || typeof raw !== "object") return { settings: DEFAULTS, rejected: [] };
39
- const src = raw;
40
- const out = {};
41
- const rejected = [];
42
- for (const [key, field] of Object.entries(sectionSettingsSchema.shape)) {
43
- const parsed = field.safeParse(src[key]);
44
- if (parsed.success) {
45
- out[key] = parsed.data;
46
- } else {
47
- rejected.push(key);
48
- out[key] = DEFAULTS[key];
49
- }
50
- }
51
- return { settings: out, rejected };
52
- }
53
- function settingsFor(all, chunkId) {
54
- const s = salvage(all?.[chunkId]).settings;
55
- if (s.textPlacement === "top" && s.imagePlacement === "right") {
56
- return { ...s, imagePlacement: "fullWidth" };
57
- }
58
- return s;
59
- }
60
- function settingsIssuesFor(all, chunkId) {
61
- return salvage(all?.[chunkId]).rejected;
62
- }
63
- var documentMetaSchema = z.object({
64
- client: z.string().default(""),
65
- project: z.string().default(""),
66
- dateLabel: z.string().default("")
67
- });
68
- var documentCoverSchema = z.object({
69
- bgColor: z.string().default("#333333"),
70
- accentColor: z.string().default("#EB9500"),
71
- title: z.string().default(""),
72
- label: z.string().default("BRAND GUIDELINES"),
73
- date: z.string().default(""),
74
- // Media-library image id shown between masthead and title lockup; null = solid cover.
75
- imageId: z.string().nullable().default(null)
76
- });
77
- var documentOptionsSchema = z.object({
78
- enabled: z.boolean().default(false),
79
- // `.default({})` doesn't typecheck even though `{}` parses fine at
80
- // runtime — zod v4 infers the default's type from the object schema's
81
- // required input shape, not its post-default output shape.
82
- meta: documentMetaSchema.default(() => documentMetaSchema.parse({})),
83
- cover: documentCoverSchema.default(() => documentCoverSchema.parse({})),
84
- sections: z.record(z.string(), sectionSettingsSchema).default({})
85
- });
86
-
87
- export {
88
- sectionSettingsSchema,
89
- settingsFor,
90
- settingsIssuesFor,
91
- documentOptionsSchema
92
- };
@@ -1,11 +0,0 @@
1
- // src/lib/reorder.ts
2
- function computeReorderTarget(fromIndex, overIndex, edge) {
3
- let toIndex = overIndex;
4
- if (edge === "bottom") toIndex = overIndex + 1;
5
- if (fromIndex < toIndex) toIndex--;
6
- return fromIndex === toIndex ? null : toIndex;
7
- }
8
-
9
- export {
10
- computeReorderTarget
11
- };
@@ -1,94 +0,0 @@
1
- import {
2
- serializeDeck
3
- } from "./chunk-VAYZJKVR.js";
4
-
5
- // src/lib/deck-dexie.ts
6
- import Dexie from "dexie";
7
- var DeckDraftDatabase = class extends Dexie {
8
- drafts;
9
- constructor(name) {
10
- super(name);
11
- this.version(1).stores({ drafts: "deckId" });
12
- }
13
- };
14
- function databaseName(siteId, scope) {
15
- return `brand-portal-decks-${siteId}-${scope}`;
16
- }
17
- var db = null;
18
- function initDeckDraftStore(siteId, scope) {
19
- const name = databaseName(siteId, scope);
20
- if (db?.name === name) return;
21
- db?.close();
22
- db = new DeckDraftDatabase(name);
23
- }
24
- function getDb() {
25
- if (!db) throw new Error("Deck draft store not initialized. Call initDeckDraftStore first.");
26
- return db;
27
- }
28
- async function listDeckDrafts() {
29
- const rows = await getDb().drafts.toArray();
30
- return rows.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
31
- }
32
- async function getDeckDraft(deckId) {
33
- return await getDb().drafts.get(deckId) ?? null;
34
- }
35
- async function putDeckDraft(deck) {
36
- const db2 = getDb();
37
- return db2.transaction("rw", db2.drafts, async () => {
38
- const existing = await db2.drafts.get(deck.id);
39
- const row = {
40
- deckId: deck.id,
41
- deck,
42
- baseVersion: existing?.baseVersion ?? null,
43
- publishedText: existing?.publishedText ?? null,
44
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
45
- };
46
- await db2.drafts.put(row);
47
- return row;
48
- });
49
- }
50
- async function markDeckDraftPublished(deck, version, updatedAt) {
51
- const row = {
52
- deckId: deck.id,
53
- deck,
54
- baseVersion: version,
55
- publishedText: serializeDeck(deck),
56
- updatedAt: updatedAt ?? (/* @__PURE__ */ new Date()).toISOString()
57
- };
58
- await getDb().drafts.put(row);
59
- return row;
60
- }
61
- async function recordDeckPublish(deckId, publishedDeck, version) {
62
- const db2 = getDb();
63
- return db2.transaction("rw", db2.drafts, async () => {
64
- const existing = await db2.drafts.get(deckId);
65
- if (!existing) return null;
66
- const row = {
67
- ...existing,
68
- baseVersion: version,
69
- publishedText: serializeDeck(publishedDeck),
70
- // "Now", as the previous implementation stamped: a publish is activity the
71
- // deck grid should sort on, even though it did not change the body.
72
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
73
- };
74
- await db2.drafts.put(row);
75
- return row;
76
- });
77
- }
78
- async function deleteDeckDraft(deckId) {
79
- await getDb().drafts.delete(deckId);
80
- }
81
- function hasUnpublishedChanges(row) {
82
- return row.publishedText === null || serializeDeck(row.deck) !== row.publishedText;
83
- }
84
-
85
- export {
86
- initDeckDraftStore,
87
- listDeckDrafts,
88
- getDeckDraft,
89
- putDeckDraft,
90
- markDeckDraftPublished,
91
- recordDeckPublish,
92
- deleteDeckDraft,
93
- hasUnpublishedChanges
94
- };
@@ -1,41 +0,0 @@
1
- import {
2
- cn
3
- } from "./chunk-7EOSDFS3.js";
4
-
5
- // src/components/shared/IconButton.tsx
6
- import { forwardRef } from "react";
7
- import { jsx } from "react/jsx-runtime";
8
- var sizeClasses = {
9
- sm: "h-chrome-sm w-chrome-sm",
10
- md: "h-chrome-md w-chrome-md",
11
- lg: "h-chrome-lg w-chrome-lg"
12
- };
13
- var intentClasses = {
14
- default: "text-base-contrast-light hover:text-base-contrast",
15
- destructive: "text-destructive hover:text-destructive-hover",
16
- primary: "text-primary/60 hover:text-primary"
17
- };
18
- var IconButton = forwardRef(
19
- function IconButton2({ icon, label, size = "md", intent = "default", className, ...rest }, ref) {
20
- return /* @__PURE__ */ jsx(
21
- "button",
22
- {
23
- ref,
24
- type: "button",
25
- className: cn(
26
- "cursor-pointer flex items-center justify-center rounded transition-colors",
27
- sizeClasses[size],
28
- intentClasses[intent],
29
- className
30
- ),
31
- "aria-label": label,
32
- ...rest,
33
- children: icon
34
- }
35
- );
36
- }
37
- );
38
-
39
- export {
40
- IconButton
41
- };