@drawnagency/primitives 0.1.111 → 0.1.112
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-3GAG6ZXB.js → chunk-3SZNUCXI.js} +8 -4
- package/dist/chunk-4I5OO5UB.js +785 -0
- package/dist/{chunk-ALMEC3XN.js → chunk-5KNXTMUC.js} +22 -18
- package/dist/{chunk-OUYB2GCW.js → chunk-BR4MIPTM.js} +1 -57
- package/dist/chunk-CXZ5YJG4.js +85 -0
- package/dist/{chunk-RA5IOFPY.js → chunk-DNY72JZN.js} +16 -38
- package/dist/{chunk-7MI3HCOF.js → chunk-EPWBPIV6.js} +10 -6
- package/dist/chunk-FV7JQRCN.js +94 -0
- package/dist/{chunk-UVIYI4J6.js → chunk-HSXMOS5Q.js} +15 -2
- package/dist/chunk-IIDKW7AV.js +41 -0
- package/dist/chunk-IINIZBQB.js +204 -0
- package/dist/chunk-MM7KZS5C.js +30 -0
- package/dist/{chunk-VCCNKTFD.js → chunk-OGGZ5AXT.js} +3 -31
- package/dist/{chunk-XQMDWXD6.js → chunk-P3ZNCHW7.js} +1 -1
- package/dist/chunk-QQ3S3P5P.js +38 -0
- package/dist/{chunk-ELQ4C677.js → chunk-TALRVOGO.js} +9 -44
- package/dist/chunk-VAYZJKVR.js +209 -0
- package/dist/{chunk-OTDA6KWL.js → chunk-VLPELTPI.js} +1 -1
- package/dist/{chunk-7WQJ57XG.js → chunk-VT3PYGVW.js} +68 -260
- package/dist/chunk-WUJ3XNFI.js +62 -0
- package/dist/{chunk-NXGIHSL5.js → chunk-Z2LO4PSQ.js} +11 -91
- package/dist/collab/rebase.js +1 -1
- package/dist/components/chat/ChatComposer.d.ts +25 -0
- package/dist/components/chat/ChatComposer.d.ts.map +1 -0
- package/dist/components/chat/ChatPanel.d.ts +5 -4
- package/dist/components/chat/ChatPanel.d.ts.map +1 -1
- package/dist/components/chat/markdown.d.ts +14 -0
- package/dist/components/chat/markdown.d.ts.map +1 -0
- package/dist/components/editor/index.js +16 -11
- package/dist/components/primitives/EditablePlainText.d.ts.map +1 -1
- package/dist/components/primitives/index.js +15 -10
- package/dist/components/sections/brand-guide.js +11 -9
- package/dist/components/sections/register-schemas.js +19 -14
- package/dist/components/sections/register.js +19 -14
- package/dist/components/shell/AudienceChips.d.ts +10 -0
- package/dist/components/shell/AudienceChips.d.ts.map +1 -0
- package/dist/components/shell/EditorShell.d.ts.map +1 -1
- package/dist/components/shell/SiteSettingsChatbot.d.ts.map +1 -1
- package/dist/components/shell/SiteSettingsDecks.d.ts +13 -0
- package/dist/components/shell/SiteSettingsDecks.d.ts.map +1 -0
- package/dist/components/shell/SiteSettingsModal.d.ts.map +1 -1
- package/dist/deck/DeckComponentView.d.ts +13 -0
- package/dist/deck/DeckComponentView.d.ts.map +1 -0
- package/dist/deck/DeckPlayer.d.ts +26 -0
- package/dist/deck/DeckPlayer.d.ts.map +1 -0
- package/dist/deck/DeckSlideView.d.ts +17 -0
- package/dist/deck/DeckSlideView.d.ts.map +1 -0
- package/dist/deck/DeckStage.d.ts +16 -0
- package/dist/deck/DeckStage.d.ts.map +1 -0
- package/dist/deck/components/DeckImage.d.ts +14 -0
- package/dist/deck/components/DeckImage.d.ts.map +1 -0
- package/dist/deck/components/DeckImageGrid.d.ts +27 -0
- package/dist/deck/components/DeckImageGrid.d.ts.map +1 -0
- package/dist/deck/components/DeckRichText.d.ts +22 -0
- package/dist/deck/components/DeckRichText.d.ts.map +1 -0
- package/dist/deck/components/DeckVideo.d.ts +15 -0
- package/dist/deck/components/DeckVideo.d.ts.map +1 -0
- package/dist/deck/editing.d.ts +50 -0
- package/dist/deck/editing.d.ts.map +1 -0
- package/dist/deck/flip.d.ts +11 -0
- package/dist/deck/flip.d.ts.map +1 -0
- package/dist/deck/index.d.ts +24 -0
- package/dist/deck/index.d.ts.map +1 -0
- package/dist/deck/index.js +53 -0
- package/dist/deck/layouts/CenteredTextLayout.d.ts +12 -0
- package/dist/deck/layouts/CenteredTextLayout.d.ts.map +1 -0
- package/dist/deck/layouts/ColumnSplitLayout.d.ts +14 -0
- package/dist/deck/layouts/ColumnSplitLayout.d.ts.map +1 -0
- package/dist/deck/layouts/FullBleedImageLayout.d.ts +14 -0
- package/dist/deck/layouts/FullBleedImageLayout.d.ts.map +1 -0
- package/dist/deck/media.d.ts +33 -0
- package/dist/deck/media.d.ts.map +1 -0
- package/dist/deck/tokens.d.ts +22 -0
- package/dist/deck/tokens.d.ts.map +1 -0
- package/dist/deck/useStageScale.d.ts +10 -0
- package/dist/deck/useStageScale.d.ts.map +1 -0
- package/dist/deck-builder/DeckBuilderApp.d.ts +30 -0
- package/dist/deck-builder/DeckBuilderApp.d.ts.map +1 -0
- package/dist/deck-builder/DeckBuilderTopBar.d.ts +24 -0
- package/dist/deck-builder/DeckBuilderTopBar.d.ts.map +1 -0
- package/dist/deck-builder/DeckChatPanel.d.ts +45 -0
- package/dist/deck-builder/DeckChatPanel.d.ts.map +1 -0
- package/dist/deck-builder/DeckEditor.d.ts +37 -0
- package/dist/deck-builder/DeckEditor.d.ts.map +1 -0
- package/dist/deck-builder/DeckLibrary.d.ts +22 -0
- package/dist/deck-builder/DeckLibrary.d.ts.map +1 -0
- package/dist/deck-builder/DeckSlideSurface.d.ts +31 -0
- package/dist/deck-builder/DeckSlideSurface.d.ts.map +1 -0
- package/dist/deck-builder/deck-api.d.ts +76 -0
- package/dist/deck-builder/deck-api.d.ts.map +1 -0
- package/dist/deck-builder/deck-chat-client.d.ts +44 -0
- package/dist/deck-builder/deck-chat-client.d.ts.map +1 -0
- package/dist/deck-builder/deck-chat-history.d.ts +10 -0
- package/dist/deck-builder/deck-chat-history.d.ts.map +1 -0
- package/dist/deck-builder/index.d.ts +13 -0
- package/dist/deck-builder/index.d.ts.map +1 -0
- package/dist/deck-builder/index.js +1505 -0
- package/dist/deck-builder/starter-deck.d.ts +23 -0
- package/dist/deck-builder/starter-deck.d.ts.map +1 -0
- package/dist/deck-builder/types.d.ts +29 -0
- package/dist/deck-builder/types.d.ts.map +1 -0
- package/dist/deck-builder/useSortableSlide.d.ts +29 -0
- package/dist/deck-builder/useSortableSlide.d.ts.map +1 -0
- package/dist/index.js +70 -63
- package/dist/lib/deck-access.d.ts +86 -0
- package/dist/lib/deck-access.d.ts.map +1 -0
- package/dist/lib/deck-access.js +58 -0
- package/dist/lib/deck-dexie.d.ts +88 -0
- package/dist/lib/deck-dexie.d.ts.map +1 -0
- package/dist/lib/deck-dexie.js +22 -0
- package/dist/lib/deck-edit.d.ts +67 -0
- package/dist/lib/deck-edit.d.ts.map +1 -0
- package/dist/lib/deck-media-assets.d.ts +27 -0
- package/dist/lib/deck-media-assets.d.ts.map +1 -0
- package/dist/lib/deck-media-assets.js +25 -0
- package/dist/lib/deck-media-refs.d.ts +35 -0
- package/dist/lib/deck-media-refs.d.ts.map +1 -0
- package/dist/lib/deck-media-refs.js +36 -0
- package/dist/lib/deck-tool.d.ts +25 -0
- package/dist/lib/deck-tool.d.ts.map +1 -0
- package/dist/lib/deck-tool.js +58 -0
- package/dist/lib/index-ops.js +2 -2
- package/dist/lib/index.js +17 -12
- package/dist/lib/nav.d.ts.map +1 -1
- package/dist/media/index.js +3 -3
- package/dist/schemas/deck-meta.d.ts +85 -0
- package/dist/schemas/deck-meta.d.ts.map +1 -0
- package/dist/schemas/deck-meta.js +64 -0
- package/dist/schemas/deck.d.ts +954 -0
- package/dist/schemas/deck.d.ts.map +1 -0
- package/dist/schemas/deck.js +65 -0
- package/dist/schemas/index.js +39 -37
- package/dist/schemas/site-config.d.ts +13 -1
- package/dist/schemas/site-config.d.ts.map +1 -1
- package/package.json +37 -1
- package/src/components/chat/ChatComposer.tsx +100 -0
- package/src/components/chat/ChatPanel.tsx +20 -69
- package/src/components/chat/markdown.ts +32 -0
- package/src/components/primitives/EditablePlainText.tsx +11 -1
- package/src/components/shell/AudienceChips.tsx +30 -0
- package/src/components/shell/EditorShell.tsx +12 -0
- package/src/components/shell/SiteSettingsChatbot.tsx +1 -18
- package/src/components/shell/SiteSettingsDecks.tsx +41 -0
- package/src/components/shell/SiteSettingsModal.tsx +11 -0
- package/src/deck/DeckComponentView.tsx +28 -0
- package/src/deck/DeckPlayer.tsx +166 -0
- package/src/deck/DeckSlideView.tsx +38 -0
- package/src/deck/DeckStage.tsx +39 -0
- package/src/deck/components/DeckImage.tsx +38 -0
- package/src/deck/components/DeckImageGrid.tsx +254 -0
- package/src/deck/components/DeckRichText.tsx +111 -0
- package/src/deck/components/DeckVideo.tsx +81 -0
- package/src/deck/editing.tsx +201 -0
- package/src/deck/flip.ts +70 -0
- package/src/deck/index.ts +30 -0
- package/src/deck/layouts/CenteredTextLayout.tsx +29 -0
- package/src/deck/layouts/ColumnSplitLayout.tsx +69 -0
- package/src/deck/layouts/FullBleedImageLayout.tsx +58 -0
- package/src/deck/media.tsx +46 -0
- package/src/deck/tokens.ts +57 -0
- package/src/deck/useStageScale.ts +44 -0
- package/src/deck-builder/DeckBuilderApp.tsx +572 -0
- package/src/deck-builder/DeckBuilderTopBar.tsx +62 -0
- package/src/deck-builder/DeckChatPanel.tsx +334 -0
- package/src/deck-builder/DeckEditor.tsx +258 -0
- package/src/deck-builder/DeckLibrary.tsx +195 -0
- package/src/deck-builder/DeckSlideSurface.tsx +55 -0
- package/src/deck-builder/deck-api.ts +177 -0
- package/src/deck-builder/deck-chat-client.ts +129 -0
- package/src/deck-builder/deck-chat-history.ts +62 -0
- package/src/deck-builder/index.ts +12 -0
- package/src/deck-builder/starter-deck.ts +86 -0
- package/src/deck-builder/types.ts +24 -0
- package/src/deck-builder/useSortableSlide.ts +102 -0
- package/src/lib/deck-access.ts +132 -0
- package/src/lib/deck-dexie.ts +190 -0
- package/src/lib/deck-edit.ts +196 -0
- package/src/lib/deck-media-assets.ts +57 -0
- package/src/lib/deck-media-refs.ts +67 -0
- package/src/lib/deck-tool.ts +95 -0
- package/src/lib/nav.ts +21 -1
- package/src/schemas/deck-meta.ts +88 -0
- package/src/schemas/deck.ts +478 -0
- package/src/schemas/index.ts +4 -0
- package/src/schemas/site-config.ts +24 -1
|
@@ -1,34 +1,24 @@
|
|
|
1
1
|
import {
|
|
2
2
|
brandGuideSectionDefs,
|
|
3
|
-
duplicateChildAt,
|
|
4
|
-
isSpacer,
|
|
5
|
-
occupiedColumns,
|
|
6
3
|
pluralize,
|
|
7
|
-
removeChildAt,
|
|
8
|
-
setChildColSpan,
|
|
9
4
|
stripHtmlToPlainText,
|
|
10
|
-
trimTrailingSpacers,
|
|
11
5
|
truncate
|
|
12
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-Z2LO4PSQ.js";
|
|
13
7
|
import {
|
|
14
8
|
DeleteButton,
|
|
15
9
|
DragHandle,
|
|
16
|
-
Kbd,
|
|
17
|
-
Popover,
|
|
18
|
-
PopoverItem,
|
|
19
10
|
SettingsButton,
|
|
20
11
|
SettingsForm,
|
|
21
|
-
Tooltip,
|
|
22
12
|
buildBlockDragData,
|
|
23
13
|
buildBlockDropData,
|
|
24
14
|
canDropBlock,
|
|
25
15
|
isBlockDragData
|
|
26
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-VT3PYGVW.js";
|
|
27
17
|
import {
|
|
28
18
|
EditableRichText,
|
|
29
19
|
defineHeadingSection,
|
|
30
20
|
useSanitizedHtml
|
|
31
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-EPWBPIV6.js";
|
|
32
22
|
import {
|
|
33
23
|
EditablePlainText,
|
|
34
24
|
ImageDropZone,
|
|
@@ -38,18 +28,28 @@ import {
|
|
|
38
28
|
containerGridClass,
|
|
39
29
|
masonryColumnsClass,
|
|
40
30
|
spacerHiddenClass
|
|
41
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-3SZNUCXI.js";
|
|
42
32
|
import {
|
|
43
33
|
useMediaLibrary,
|
|
44
34
|
useResolvedMedia
|
|
45
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-TALRVOGO.js";
|
|
36
|
+
import {
|
|
37
|
+
Kbd,
|
|
38
|
+
Popover,
|
|
39
|
+
PopoverItem,
|
|
40
|
+
Tooltip
|
|
41
|
+
} from "./chunk-IINIZBQB.js";
|
|
46
42
|
import {
|
|
47
43
|
embedUrl
|
|
48
44
|
} from "./chunk-Y4JQGO6G.js";
|
|
49
45
|
import {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
46
|
+
duplicateChildAt,
|
|
47
|
+
isSpacer,
|
|
48
|
+
occupiedColumns,
|
|
49
|
+
removeChildAt,
|
|
50
|
+
setChildColSpan,
|
|
51
|
+
trimTrailingSpacers
|
|
52
|
+
} from "./chunk-CXZ5YJG4.js";
|
|
53
53
|
import {
|
|
54
54
|
cn
|
|
55
55
|
} from "./chunk-7EOSDFS3.js";
|
|
@@ -63,6 +63,10 @@ import {
|
|
|
63
63
|
import {
|
|
64
64
|
SingleMediaReferenceSchema
|
|
65
65
|
} from "./chunk-GGXZZ77Z.js";
|
|
66
|
+
import {
|
|
67
|
+
DEFAULT_LINK,
|
|
68
|
+
LinkValueSchema
|
|
69
|
+
} from "./chunk-3ZRQ4G5F.js";
|
|
66
70
|
|
|
67
71
|
// src/components/sections/LinkHeading/index.tsx
|
|
68
72
|
import { Heading1 } from "lucide-react";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
FormLabel,
|
|
3
3
|
Input
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-TALRVOGO.js";
|
|
5
5
|
import {
|
|
6
6
|
cn
|
|
7
7
|
} from "./chunk-7EOSDFS3.js";
|
|
@@ -130,63 +130,7 @@ function LinkField({ label, value, onChange }) {
|
|
|
130
130
|
] });
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
-
// src/components/shared/Button.tsx
|
|
134
|
-
import { forwardRef } from "react";
|
|
135
|
-
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
136
|
-
var boxSize = {
|
|
137
|
-
sm: "rounded px-3 py-1.5 text-xs font-medium",
|
|
138
|
-
md: "rounded px-4 py-2 text-sm font-medium"
|
|
139
|
-
};
|
|
140
|
-
var ghostSize = {
|
|
141
|
-
sm: "text-xs font-medium",
|
|
142
|
-
md: "text-sm font-medium"
|
|
143
|
-
};
|
|
144
|
-
var variantClasses = {
|
|
145
|
-
primary: "bg-base-contrast text-base-accent hover:bg-base-contrast/90",
|
|
146
|
-
brand: "bg-primary text-primary-contrast hover:opacity-90",
|
|
147
|
-
secondary: "border border-base-200 text-base-contrast hover:bg-base-accent",
|
|
148
|
-
destructive: "border border-red-600 text-red-600 hover:bg-red-600 hover:text-white"
|
|
149
|
-
};
|
|
150
|
-
var ghostToneClasses = {
|
|
151
|
-
neutral: "text-base-contrast-light hover:text-base-contrast",
|
|
152
|
-
destructive: "text-red-600 hover:text-red-800"
|
|
153
|
-
};
|
|
154
|
-
var Button = forwardRef(function Button2({
|
|
155
|
-
variant = "primary",
|
|
156
|
-
size = "sm",
|
|
157
|
-
tone = "neutral",
|
|
158
|
-
fullWidth = false,
|
|
159
|
-
isLoading = false,
|
|
160
|
-
loadingLabel,
|
|
161
|
-
disabled,
|
|
162
|
-
className,
|
|
163
|
-
children,
|
|
164
|
-
...rest
|
|
165
|
-
}, ref) {
|
|
166
|
-
const isGhost = variant === "ghost";
|
|
167
|
-
const resolvedDisabled = disabled || isLoading;
|
|
168
|
-
const label = isLoading && loadingLabel ? loadingLabel : children;
|
|
169
|
-
return /* @__PURE__ */ jsx3(
|
|
170
|
-
"button",
|
|
171
|
-
{
|
|
172
|
-
ref,
|
|
173
|
-
disabled: resolvedDisabled,
|
|
174
|
-
className: cn(
|
|
175
|
-
"inline-flex items-center justify-center transition-colors",
|
|
176
|
-
isGhost ? ghostSize[size] : boxSize[size],
|
|
177
|
-
isGhost ? ghostToneClasses[tone] : variantClasses[variant],
|
|
178
|
-
fullWidth && "w-full",
|
|
179
|
-
resolvedDisabled ? "cursor-not-allowed opacity-50" : "cursor-pointer",
|
|
180
|
-
className
|
|
181
|
-
),
|
|
182
|
-
...rest,
|
|
183
|
-
children: label
|
|
184
|
-
}
|
|
185
|
-
);
|
|
186
|
-
});
|
|
187
|
-
|
|
188
133
|
export {
|
|
189
|
-
Button,
|
|
190
134
|
PagesContext,
|
|
191
135
|
usePages,
|
|
192
136
|
Select,
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// src/lib/insert-menu.ts
|
|
2
|
+
var PRESET_PREFIX = "__preset:";
|
|
3
|
+
var INSERT_MENU_ORDER = [
|
|
4
|
+
"container",
|
|
5
|
+
"link_heading",
|
|
6
|
+
"sub_heading",
|
|
7
|
+
"sub_sub_heading",
|
|
8
|
+
"prose",
|
|
9
|
+
"media",
|
|
10
|
+
"video",
|
|
11
|
+
"button",
|
|
12
|
+
"colors",
|
|
13
|
+
"document",
|
|
14
|
+
"icon_list",
|
|
15
|
+
`${PRESET_PREFIX}do_dont_list`,
|
|
16
|
+
"dodont_media"
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
// src/lib/container-ops.ts
|
|
20
|
+
function getContainerChildren(block) {
|
|
21
|
+
const content = block.content;
|
|
22
|
+
return Array.isArray(content?.children) ? content.children : [];
|
|
23
|
+
}
|
|
24
|
+
function withChildren(container, children) {
|
|
25
|
+
return { ...container, content: { ...container.content, children } };
|
|
26
|
+
}
|
|
27
|
+
function containerColumns(container) {
|
|
28
|
+
const n = container.content?.columns;
|
|
29
|
+
return typeof n === "number" && n >= 1 ? n : 1;
|
|
30
|
+
}
|
|
31
|
+
function removeChildAt(container, index) {
|
|
32
|
+
const children = getContainerChildren(container);
|
|
33
|
+
if (index < 0 || index >= children.length) return { container, removed: null };
|
|
34
|
+
const next = [...children];
|
|
35
|
+
const [removed] = next.splice(index, 1);
|
|
36
|
+
return { container: withChildren(container, next), removed };
|
|
37
|
+
}
|
|
38
|
+
function duplicateChildAt(container, index, newId) {
|
|
39
|
+
const children = getContainerChildren(container);
|
|
40
|
+
if (index < 0 || index >= children.length) return container;
|
|
41
|
+
const clone = { ...JSON.parse(JSON.stringify(children[index])), id: newId() };
|
|
42
|
+
const next = [...children];
|
|
43
|
+
next.splice(index + 1, 0, clone);
|
|
44
|
+
return withChildren(container, next);
|
|
45
|
+
}
|
|
46
|
+
function setChildColSpan(container, index, span) {
|
|
47
|
+
const children = getContainerChildren(container);
|
|
48
|
+
if (index < 0 || index >= children.length) return container;
|
|
49
|
+
const clamped = Math.max(1, Math.min(span, containerColumns(container)));
|
|
50
|
+
const next = children.map((child, i) => {
|
|
51
|
+
if (i !== index) return child;
|
|
52
|
+
if (clamped <= 1) {
|
|
53
|
+
const { layout: _drop, ...rest } = child;
|
|
54
|
+
return rest;
|
|
55
|
+
}
|
|
56
|
+
return { ...child, layout: { ...child.layout, colSpan: clamped } };
|
|
57
|
+
});
|
|
58
|
+
return withChildren(container, next);
|
|
59
|
+
}
|
|
60
|
+
function effectiveSpan(child, columns) {
|
|
61
|
+
return isSpacer(child) ? 1 : Math.min(child.layout?.colSpan ?? 1, columns);
|
|
62
|
+
}
|
|
63
|
+
function isSpacer(child) {
|
|
64
|
+
return child.type === "spacer";
|
|
65
|
+
}
|
|
66
|
+
function occupiedColumns(children, columns) {
|
|
67
|
+
return children.reduce((sum, c) => sum + effectiveSpan(c, columns), 0);
|
|
68
|
+
}
|
|
69
|
+
function trimTrailingSpacers(container) {
|
|
70
|
+
const children = getContainerChildren(container);
|
|
71
|
+
let end = children.length;
|
|
72
|
+
while (end > 0 && isSpacer(children[end - 1])) end--;
|
|
73
|
+
if (end === children.length) return container;
|
|
74
|
+
return withChildren(container, children.slice(0, end));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export {
|
|
78
|
+
getContainerChildren,
|
|
79
|
+
removeChildAt,
|
|
80
|
+
duplicateChildAt,
|
|
81
|
+
setChildColSpan,
|
|
82
|
+
isSpacer,
|
|
83
|
+
occupiedColumns,
|
|
84
|
+
trimTrailingSpacers
|
|
85
|
+
};
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getContainerChildren
|
|
3
|
+
} from "./chunk-CXZ5YJG4.js";
|
|
1
4
|
import {
|
|
2
5
|
getSection
|
|
3
6
|
} from "./chunk-FTPETWXE.js";
|
|
@@ -12,6 +15,17 @@ function toSectionId(text) {
|
|
|
12
15
|
}
|
|
13
16
|
return `section-${Math.abs(hash).toString(36)}`;
|
|
14
17
|
}
|
|
18
|
+
function flattenForNav(sections) {
|
|
19
|
+
const flat = [];
|
|
20
|
+
const walk = (loaded) => {
|
|
21
|
+
flat.push(loaded);
|
|
22
|
+
for (const child of getContainerChildren(loaded.section)) {
|
|
23
|
+
walk({ section: child, meta: loaded.meta });
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
sections.forEach(walk);
|
|
27
|
+
return flat;
|
|
28
|
+
}
|
|
15
29
|
function generateNavLinks(sections, registry) {
|
|
16
30
|
const nav = [];
|
|
17
31
|
let currentParent = null;
|
|
@@ -20,7 +34,7 @@ function generateNavLinks(sections, registry) {
|
|
|
20
34
|
const def = registry ? registry.getSection(type) : getSection(type);
|
|
21
35
|
return def?.navRole;
|
|
22
36
|
};
|
|
23
|
-
for (const { section, meta } of sections) {
|
|
37
|
+
for (const { section, meta } of flattenForNav(sections)) {
|
|
24
38
|
const content = section.content;
|
|
25
39
|
if (!content.heading) continue;
|
|
26
40
|
const role = lookupRole(section.type);
|
|
@@ -66,43 +80,7 @@ function generateNavLinks(sections, registry) {
|
|
|
66
80
|
return nav;
|
|
67
81
|
}
|
|
68
82
|
|
|
69
|
-
// src/lib/sanitize.ts
|
|
70
|
-
var purifierPromise = null;
|
|
71
|
-
var purifier = null;
|
|
72
|
-
if (typeof window !== "undefined") {
|
|
73
|
-
purifierPromise = import("dompurify").then((mod) => {
|
|
74
|
-
const DOMPurify = mod.default ?? mod;
|
|
75
|
-
purifier = (html) => DOMPurify.sanitize(html);
|
|
76
|
-
return mod;
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
var sanitizeCache = /* @__PURE__ */ new Map();
|
|
80
|
-
var SANITIZE_CACHE_LIMIT = 500;
|
|
81
|
-
function sanitizeHtml(html) {
|
|
82
|
-
if (!html) return "";
|
|
83
|
-
if (!purifier) return html;
|
|
84
|
-
const cached = sanitizeCache.get(html);
|
|
85
|
-
if (cached !== void 0) return cached;
|
|
86
|
-
const clean = purifier(html);
|
|
87
|
-
if (sanitizeCache.size >= SANITIZE_CACHE_LIMIT) {
|
|
88
|
-
const oldest = sanitizeCache.keys().next().value;
|
|
89
|
-
if (oldest !== void 0) sanitizeCache.delete(oldest);
|
|
90
|
-
}
|
|
91
|
-
sanitizeCache.set(html, clean);
|
|
92
|
-
return clean;
|
|
93
|
-
}
|
|
94
|
-
function isSanitizerReady() {
|
|
95
|
-
return typeof window === "undefined" || purifier !== null;
|
|
96
|
-
}
|
|
97
|
-
async function ensureSanitizer() {
|
|
98
|
-
if (typeof window === "undefined") return;
|
|
99
|
-
if (!purifier && purifierPromise) await purifierPromise;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
83
|
export {
|
|
103
84
|
toSectionId,
|
|
104
|
-
generateNavLinks
|
|
105
|
-
sanitizeHtml,
|
|
106
|
-
isSanitizerReady,
|
|
107
|
-
ensureSanitizer
|
|
85
|
+
generateNavLinks
|
|
108
86
|
};
|
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
import {
|
|
2
2
|
EditablePlainText
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-3SZNUCXI.js";
|
|
4
4
|
import {
|
|
5
|
-
Button,
|
|
6
5
|
usePages
|
|
7
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-BR4MIPTM.js";
|
|
7
|
+
import {
|
|
8
|
+
Button
|
|
9
|
+
} from "./chunk-WUJ3XNFI.js";
|
|
10
|
+
import {
|
|
11
|
+
toSectionId
|
|
12
|
+
} from "./chunk-DNY72JZN.js";
|
|
8
13
|
import {
|
|
9
14
|
ensureSanitizer,
|
|
10
15
|
isSanitizerReady,
|
|
11
|
-
sanitizeHtml
|
|
12
|
-
|
|
13
|
-
} from "./chunk-RA5IOFPY.js";
|
|
16
|
+
sanitizeHtml
|
|
17
|
+
} from "./chunk-QQ3S3P5P.js";
|
|
14
18
|
import {
|
|
15
19
|
cn
|
|
16
20
|
} from "./chunk-7EOSDFS3.js";
|
|
@@ -0,0 +1,94 @@
|
|
|
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
|
+
};
|
|
@@ -74,7 +74,7 @@ var SectionMetaSchema = z2.object({
|
|
|
74
74
|
status: StatusSchema,
|
|
75
75
|
access: z2.array(z2.string())
|
|
76
76
|
});
|
|
77
|
-
var RESERVED_SLUGS = ["edit", "api", "login", "set-password", "404", "present", "print", "audiences"];
|
|
77
|
+
var RESERVED_SLUGS = ["edit", "api", "login", "set-password", "404", "present", "print", "audiences", "decks"];
|
|
78
78
|
var PARSE_REJECTED_SLUGS = ["edit", "api", "login", "set-password", "404"];
|
|
79
79
|
var PageStatusSchema = z2.enum(["live", "archived"]);
|
|
80
80
|
var PageSchema = z2.object({
|
|
@@ -232,6 +232,15 @@ var ChatbotConfigSchema = z2.object({
|
|
|
232
232
|
seen.add(t.id);
|
|
233
233
|
}
|
|
234
234
|
});
|
|
235
|
+
var DeckBuilderConfigSchema = z2.object({
|
|
236
|
+
// Audience names whose members may CREATE decks — a Deck Creator. Strict
|
|
237
|
+
// opt-in exactly like chatbot.audiences: [] = no viewer may build a deck.
|
|
238
|
+
// Editors are super-admins over decks and are never gated by this list.
|
|
239
|
+
// Gates: [...slug].astro's FAB, /decks, and POST /api/decks (canCreateDeck).
|
|
240
|
+
audiences: z2.array(z2.string()).default([]).describe(
|
|
241
|
+
"Audience names allowed to create decks in the Deck Builder. Strict opt-in \u2014 an empty list means no viewer can. Editors always can."
|
|
242
|
+
)
|
|
243
|
+
});
|
|
235
244
|
var SiteConfigSchema = z2.object({
|
|
236
245
|
siteName: z2.string().default("Brand Portal"),
|
|
237
246
|
primaryColor: HexColorSchema.default("#009ca6"),
|
|
@@ -286,7 +295,10 @@ var SiteConfigSchema = z2.object({
|
|
|
286
295
|
// Brand chatbot config (editor-owned; the platform kill switch lives in the
|
|
287
296
|
// sites table, not here). Every field defaults so pre-existing
|
|
288
297
|
// site-config.json files keep parsing.
|
|
289
|
-
chatbot: ChatbotConfigSchema.default({ enabled: false, name: "Portal Assistant", audienceNames: {}, thinkingPhrases: [], systemPrompt: "", audiences: [], tasks: [], audiencePrompts: {} })
|
|
298
|
+
chatbot: ChatbotConfigSchema.default({ enabled: false, name: "Portal Assistant", audienceNames: {}, thinkingPhrases: [], systemPrompt: "", audiences: [], tasks: [], audiencePrompts: {} }),
|
|
299
|
+
// Deck Builder config (editor-owned). Defaults so pre-existing
|
|
300
|
+
// site-config.json files keep parsing — and the default is closed.
|
|
301
|
+
deckBuilder: DeckBuilderConfigSchema.default({ audiences: [] })
|
|
290
302
|
});
|
|
291
303
|
|
|
292
304
|
export {
|
|
@@ -305,5 +317,6 @@ export {
|
|
|
305
317
|
normalizeSiteIndex,
|
|
306
318
|
ChatbotTaskSchema,
|
|
307
319
|
ChatbotConfigSchema,
|
|
320
|
+
DeckBuilderConfigSchema,
|
|
308
321
|
SiteConfigSchema
|
|
309
322
|
};
|
|
@@ -0,0 +1,41 @@
|
|
|
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
|
+
};
|