@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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deck.d.ts","sourceRoot":"","sources":["../../src/schemas/deck.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CenteredTextLayoutSchema,
|
|
3
|
+
ColumnSplitLayoutSchema,
|
|
4
|
+
DECK_COMPONENT_TYPES,
|
|
5
|
+
DECK_LAYOUT_TYPES,
|
|
6
|
+
DECK_MAX_SLIDES,
|
|
7
|
+
DECK_MEDIA_KINDS,
|
|
8
|
+
DECK_OVERLAY_PLACEMENTS,
|
|
9
|
+
DECK_SCHEMA_VERSION,
|
|
10
|
+
DECK_SPLIT_RATIOS,
|
|
11
|
+
DECK_STAGE_HEIGHT,
|
|
12
|
+
DECK_STAGE_WIDTH,
|
|
13
|
+
DECK_SURFACES,
|
|
14
|
+
DeckComponentSchema,
|
|
15
|
+
DeckIdSchema,
|
|
16
|
+
DeckImageGridItemSchema,
|
|
17
|
+
DeckImageGridSchema,
|
|
18
|
+
DeckImageSchema,
|
|
19
|
+
DeckLayoutSchema,
|
|
20
|
+
DeckMediaRefSchema,
|
|
21
|
+
DeckOverlayPanelSchema,
|
|
22
|
+
DeckRichTextSchema,
|
|
23
|
+
DeckSchema,
|
|
24
|
+
DeckSlideSchema,
|
|
25
|
+
DeckTextSpanSchema,
|
|
26
|
+
DeckVideoSchema,
|
|
27
|
+
FullBleedImageLayoutSchema,
|
|
28
|
+
PortalMediaRefSchema,
|
|
29
|
+
formatDeckIssues,
|
|
30
|
+
parseDeck,
|
|
31
|
+
serializeDeck
|
|
32
|
+
} from "../chunk-VAYZJKVR.js";
|
|
33
|
+
import "../chunk-JSBRDJBE.js";
|
|
34
|
+
export {
|
|
35
|
+
CenteredTextLayoutSchema,
|
|
36
|
+
ColumnSplitLayoutSchema,
|
|
37
|
+
DECK_COMPONENT_TYPES,
|
|
38
|
+
DECK_LAYOUT_TYPES,
|
|
39
|
+
DECK_MAX_SLIDES,
|
|
40
|
+
DECK_MEDIA_KINDS,
|
|
41
|
+
DECK_OVERLAY_PLACEMENTS,
|
|
42
|
+
DECK_SCHEMA_VERSION,
|
|
43
|
+
DECK_SPLIT_RATIOS,
|
|
44
|
+
DECK_STAGE_HEIGHT,
|
|
45
|
+
DECK_STAGE_WIDTH,
|
|
46
|
+
DECK_SURFACES,
|
|
47
|
+
DeckComponentSchema,
|
|
48
|
+
DeckIdSchema,
|
|
49
|
+
DeckImageGridItemSchema,
|
|
50
|
+
DeckImageGridSchema,
|
|
51
|
+
DeckImageSchema,
|
|
52
|
+
DeckLayoutSchema,
|
|
53
|
+
DeckMediaRefSchema,
|
|
54
|
+
DeckOverlayPanelSchema,
|
|
55
|
+
DeckRichTextSchema,
|
|
56
|
+
DeckSchema,
|
|
57
|
+
DeckSlideSchema,
|
|
58
|
+
DeckTextSpanSchema,
|
|
59
|
+
DeckVideoSchema,
|
|
60
|
+
FullBleedImageLayoutSchema,
|
|
61
|
+
PortalMediaRefSchema,
|
|
62
|
+
formatDeckIssues,
|
|
63
|
+
parseDeck,
|
|
64
|
+
serializeDeck
|
|
65
|
+
};
|
package/dist/schemas/index.js
CHANGED
|
@@ -1,41 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
MediaGridOptionsSchema
|
|
3
3
|
} from "../chunk-B7VBSE5X.js";
|
|
4
|
-
import {
|
|
5
|
-
AudienceSchema,
|
|
6
|
-
RoleSchema,
|
|
7
|
-
SessionSchema,
|
|
8
|
-
SiteUserSchema
|
|
9
|
-
} from "../chunk-6P4CJCXB.js";
|
|
10
|
-
import {
|
|
11
|
-
AudienceColorSchema,
|
|
12
|
-
AudienceNameSchema,
|
|
13
|
-
NormalizedUsernameSchema,
|
|
14
|
-
VIEWER_PASSWORD_MIN_LENGTH,
|
|
15
|
-
ViewerCredentialSchema,
|
|
16
|
-
ViewerPasswordSchema,
|
|
17
|
-
ViewerUsernameSchema,
|
|
18
|
-
normalizeUsername,
|
|
19
|
-
slugifyAudienceName
|
|
20
|
-
} from "../chunk-HBULBDGP.js";
|
|
21
|
-
import {
|
|
22
|
-
DEFAULT_LINK,
|
|
23
|
-
LinkTargetSchema,
|
|
24
|
-
LinkValueSchema,
|
|
25
|
-
isSafeHref
|
|
26
|
-
} from "../chunk-3ZRQ4G5F.js";
|
|
27
|
-
import {
|
|
28
|
-
DOCUMENT_BUCKET_MAX_BYTES,
|
|
29
|
-
DOCUMENT_GIT_MAX_BYTES,
|
|
30
|
-
DOCUMENT_KIND_TO_MIME,
|
|
31
|
-
DOCUMENT_MANIFEST_PATH,
|
|
32
|
-
DOCUMENT_MIME_TO_EXT,
|
|
33
|
-
DocumentManifestEntrySchema,
|
|
34
|
-
DocumentManifestSchema,
|
|
35
|
-
documentBucketPath,
|
|
36
|
-
documentFileUrl,
|
|
37
|
-
documentGitPath
|
|
38
|
-
} from "../chunk-BS5AQHZG.js";
|
|
39
4
|
import {
|
|
40
5
|
NavEntrySchema,
|
|
41
6
|
NavFileSchema
|
|
@@ -45,10 +10,10 @@ import {
|
|
|
45
10
|
getSectionSchema,
|
|
46
11
|
getSectionSchemaForType
|
|
47
12
|
} from "../chunk-DMCGN5AS.js";
|
|
48
|
-
import "../chunk-FTPETWXE.js";
|
|
49
13
|
import {
|
|
50
14
|
ChatbotConfigSchema,
|
|
51
15
|
ChatbotTaskSchema,
|
|
16
|
+
DeckBuilderConfigSchema,
|
|
52
17
|
ImageManifestSchema,
|
|
53
18
|
IndexSchema,
|
|
54
19
|
MediaConfigSchema,
|
|
@@ -63,8 +28,26 @@ import {
|
|
|
63
28
|
StatusSchema,
|
|
64
29
|
VariantSchema,
|
|
65
30
|
normalizeSiteIndex
|
|
66
|
-
} from "../chunk-
|
|
31
|
+
} from "../chunk-HSXMOS5Q.js";
|
|
67
32
|
import "../chunk-4TZJZU2T.js";
|
|
33
|
+
import "../chunk-FTPETWXE.js";
|
|
34
|
+
import {
|
|
35
|
+
AudienceSchema,
|
|
36
|
+
RoleSchema,
|
|
37
|
+
SessionSchema,
|
|
38
|
+
SiteUserSchema
|
|
39
|
+
} from "../chunk-6P4CJCXB.js";
|
|
40
|
+
import {
|
|
41
|
+
AudienceColorSchema,
|
|
42
|
+
AudienceNameSchema,
|
|
43
|
+
NormalizedUsernameSchema,
|
|
44
|
+
VIEWER_PASSWORD_MIN_LENGTH,
|
|
45
|
+
ViewerCredentialSchema,
|
|
46
|
+
ViewerPasswordSchema,
|
|
47
|
+
ViewerUsernameSchema,
|
|
48
|
+
normalizeUsername,
|
|
49
|
+
slugifyAudienceName
|
|
50
|
+
} from "../chunk-HBULBDGP.js";
|
|
68
51
|
import {
|
|
69
52
|
FontNameSchema,
|
|
70
53
|
HexColorSchema,
|
|
@@ -73,6 +56,24 @@ import {
|
|
|
73
56
|
TextLineSchema
|
|
74
57
|
} from "../chunk-GGXZZ77Z.js";
|
|
75
58
|
import "../chunk-NSCT3AMV.js";
|
|
59
|
+
import {
|
|
60
|
+
DEFAULT_LINK,
|
|
61
|
+
LinkTargetSchema,
|
|
62
|
+
LinkValueSchema,
|
|
63
|
+
isSafeHref
|
|
64
|
+
} from "../chunk-3ZRQ4G5F.js";
|
|
65
|
+
import {
|
|
66
|
+
DOCUMENT_BUCKET_MAX_BYTES,
|
|
67
|
+
DOCUMENT_GIT_MAX_BYTES,
|
|
68
|
+
DOCUMENT_KIND_TO_MIME,
|
|
69
|
+
DOCUMENT_MANIFEST_PATH,
|
|
70
|
+
DOCUMENT_MIME_TO_EXT,
|
|
71
|
+
DocumentManifestEntrySchema,
|
|
72
|
+
DocumentManifestSchema,
|
|
73
|
+
documentBucketPath,
|
|
74
|
+
documentFileUrl,
|
|
75
|
+
documentGitPath
|
|
76
|
+
} from "../chunk-BS5AQHZG.js";
|
|
76
77
|
import "../chunk-JSBRDJBE.js";
|
|
77
78
|
export {
|
|
78
79
|
AudienceColorSchema,
|
|
@@ -86,6 +87,7 @@ export {
|
|
|
86
87
|
DOCUMENT_KIND_TO_MIME,
|
|
87
88
|
DOCUMENT_MANIFEST_PATH,
|
|
88
89
|
DOCUMENT_MIME_TO_EXT,
|
|
90
|
+
DeckBuilderConfigSchema,
|
|
89
91
|
DocumentManifestEntrySchema,
|
|
90
92
|
DocumentManifestSchema,
|
|
91
93
|
FontNameSchema,
|
|
@@ -17,7 +17,7 @@ export declare const SectionMetaSchema: z.ZodObject<{
|
|
|
17
17
|
access: z.ZodArray<z.ZodString>;
|
|
18
18
|
}, z.core.$strip>;
|
|
19
19
|
export type SectionMeta = z.infer<typeof SectionMetaSchema>;
|
|
20
|
-
export declare const RESERVED_SLUGS: readonly ["edit", "api", "login", "set-password", "404", "present", "print", "audiences"];
|
|
20
|
+
export declare const RESERVED_SLUGS: readonly ["edit", "api", "login", "set-password", "404", "present", "print", "audiences", "decks"];
|
|
21
21
|
export declare const PageStatusSchema: z.ZodEnum<{
|
|
22
22
|
live: "live";
|
|
23
23
|
archived: "archived";
|
|
@@ -454,6 +454,15 @@ export declare const ChatbotConfigSchema: z.ZodObject<{
|
|
|
454
454
|
}, z.core.$strip>>>;
|
|
455
455
|
}, z.core.$strip>;
|
|
456
456
|
export type ChatbotConfig = z.infer<typeof ChatbotConfigSchema>;
|
|
457
|
+
/**
|
|
458
|
+
* Deck Builder config (ADR 0001/0002). An OBJECT rather than a bare audience
|
|
459
|
+
* array because `publicSharing` (#37) lands beside `audiences` — the same shape
|
|
460
|
+
* ChatbotConfigSchema has, for the same reason.
|
|
461
|
+
*/
|
|
462
|
+
export declare const DeckBuilderConfigSchema: z.ZodObject<{
|
|
463
|
+
audiences: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
464
|
+
}, z.core.$strip>;
|
|
465
|
+
export type DeckBuilderConfig = z.infer<typeof DeckBuilderConfigSchema>;
|
|
457
466
|
export declare const SiteConfigSchema: z.ZodObject<{
|
|
458
467
|
siteName: z.ZodDefault<z.ZodString>;
|
|
459
468
|
primaryColor: z.ZodDefault<z.ZodString>;
|
|
@@ -516,6 +525,9 @@ export declare const SiteConfigSchema: z.ZodObject<{
|
|
|
516
525
|
access: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
517
526
|
}, z.core.$strip>>>;
|
|
518
527
|
}, z.core.$strip>>;
|
|
528
|
+
deckBuilder: z.ZodDefault<z.ZodObject<{
|
|
529
|
+
audiences: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
530
|
+
}, z.core.$strip>>;
|
|
519
531
|
}, z.core.$strip>;
|
|
520
532
|
export type SiteConfig = z.infer<typeof SiteConfigSchema>;
|
|
521
533
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"site-config.d.ts","sourceRoot":"","sources":["../../src/schemas/site-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEtC,eAAO,MAAM,YAAY;;;;;+FAExB,CAAC;AAEF,eAAO,MAAM,iBAAiB;;;;;;;;;iBAI5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAQ5D,eAAO,MAAM,cAAc,
|
|
1
|
+
{"version":3,"file":"site-config.d.ts","sourceRoot":"","sources":["../../src/schemas/site-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEtC,eAAO,MAAM,YAAY;;;;;+FAExB,CAAC;AAEF,eAAO,MAAM,iBAAiB;;;;;;;;;iBAI5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAQ5D,eAAO,MAAM,cAAc,oGAAqG,CAAC;AAWjI,eAAO,MAAM,gBAAgB;;;EAA+B,CAAC;AAE7D,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAUrB,CAAC;AAEH,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAI9C,eAAO,MAAM,OAAO,QAA+B,CAAC;AAwCpD,QAAA,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAuEtB,CAAC;AAEL,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAAyE,CAAC;AAElG;;;;;;GAMG;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,GAAG;IAAE,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAA;CAAE,CAAC;AAEpF,oFAAoF;AACpF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,SAAS,CAE1D;AAMD,eAAO,MAAM,iBAAiB;;;;;iBAM5B,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;iBAiC5B,CAAC;AACL,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE;;;;GAIG;AACH,eAAO,MAAM,uBAAuB;;iBAWlC,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAsE3B,CAAC;AAEH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@drawnagency/primitives",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.112",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
"./package.json": "./package.json",
|
|
@@ -32,6 +32,14 @@
|
|
|
32
32
|
"types": "./dist/schemas/documents.d.ts",
|
|
33
33
|
"default": "./dist/schemas/documents.js"
|
|
34
34
|
},
|
|
35
|
+
"./schemas/deck": {
|
|
36
|
+
"types": "./dist/schemas/deck.d.ts",
|
|
37
|
+
"default": "./dist/schemas/deck.js"
|
|
38
|
+
},
|
|
39
|
+
"./schemas/deck-meta": {
|
|
40
|
+
"types": "./dist/schemas/deck-meta.d.ts",
|
|
41
|
+
"default": "./dist/schemas/deck-meta.js"
|
|
42
|
+
},
|
|
35
43
|
"./lib": {
|
|
36
44
|
"types": "./dist/lib/index.d.ts",
|
|
37
45
|
"default": "./dist/lib/index.js"
|
|
@@ -76,6 +84,26 @@
|
|
|
76
84
|
"types": "./dist/lib/index-ops.d.ts",
|
|
77
85
|
"default": "./dist/lib/index-ops.js"
|
|
78
86
|
},
|
|
87
|
+
"./lib/deck-access": {
|
|
88
|
+
"types": "./dist/lib/deck-access.d.ts",
|
|
89
|
+
"default": "./dist/lib/deck-access.js"
|
|
90
|
+
},
|
|
91
|
+
"./lib/deck-media-refs": {
|
|
92
|
+
"types": "./dist/lib/deck-media-refs.d.ts",
|
|
93
|
+
"default": "./dist/lib/deck-media-refs.js"
|
|
94
|
+
},
|
|
95
|
+
"./lib/deck-tool": {
|
|
96
|
+
"types": "./dist/lib/deck-tool.d.ts",
|
|
97
|
+
"default": "./dist/lib/deck-tool.js"
|
|
98
|
+
},
|
|
99
|
+
"./lib/deck-dexie": {
|
|
100
|
+
"types": "./dist/lib/deck-dexie.d.ts",
|
|
101
|
+
"default": "./dist/lib/deck-dexie.js"
|
|
102
|
+
},
|
|
103
|
+
"./lib/deck-media-assets": {
|
|
104
|
+
"types": "./dist/lib/deck-media-assets.d.ts",
|
|
105
|
+
"default": "./dist/lib/deck-media-assets.js"
|
|
106
|
+
},
|
|
79
107
|
"./lib/pdfjs-assets": {
|
|
80
108
|
"types": "./dist/lib/pdfjs-assets.d.ts",
|
|
81
109
|
"default": "./dist/lib/pdfjs-assets.js"
|
|
@@ -112,6 +140,14 @@
|
|
|
112
140
|
"types": "./dist/document/index.d.ts",
|
|
113
141
|
"default": "./dist/document/index.js"
|
|
114
142
|
},
|
|
143
|
+
"./deck": {
|
|
144
|
+
"types": "./dist/deck/index.d.ts",
|
|
145
|
+
"default": "./dist/deck/index.js"
|
|
146
|
+
},
|
|
147
|
+
"./deck-builder": {
|
|
148
|
+
"types": "./dist/deck-builder/index.d.ts",
|
|
149
|
+
"default": "./dist/deck-builder/index.js"
|
|
150
|
+
},
|
|
115
151
|
"./auth": {
|
|
116
152
|
"types": "./dist/auth/index.d.ts",
|
|
117
153
|
"default": "./dist/auth/index.js"
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { useEffect, useRef, type KeyboardEvent, type RefObject } from "react";
|
|
2
|
+
import { Square } from "lucide-react";
|
|
3
|
+
import { cn } from "../../lib/cn";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The composer every chat surface shares: an autosizing textarea, Enter-to-send
|
|
7
|
+
* with Shift+Enter for a newline, and a send button that becomes a stop button
|
|
8
|
+
* while a turn is in flight.
|
|
9
|
+
*
|
|
10
|
+
* Extracted for the Deck Builder's docked assistant (#35). Rendering it twice
|
|
11
|
+
* from one component is what keeps "Enter sends" from meaning two things on two
|
|
12
|
+
* panes of the same product.
|
|
13
|
+
*/
|
|
14
|
+
export function ChatComposer({
|
|
15
|
+
value,
|
|
16
|
+
onChange,
|
|
17
|
+
onSend,
|
|
18
|
+
onStop,
|
|
19
|
+
busy,
|
|
20
|
+
placeholder,
|
|
21
|
+
disabled,
|
|
22
|
+
className,
|
|
23
|
+
textareaRef,
|
|
24
|
+
maxLength = 4000,
|
|
25
|
+
}: {
|
|
26
|
+
value: string;
|
|
27
|
+
onChange: (value: string) => void;
|
|
28
|
+
onSend: () => void;
|
|
29
|
+
/** Omitted where a turn cannot be interrupted; the button then just disables. */
|
|
30
|
+
onStop?: () => void;
|
|
31
|
+
busy: boolean;
|
|
32
|
+
placeholder: string;
|
|
33
|
+
disabled?: boolean;
|
|
34
|
+
className?: string;
|
|
35
|
+
/** Exposed so a panel can focus the composer (open, clear, suggestion click). */
|
|
36
|
+
textareaRef?: RefObject<HTMLTextAreaElement | null>;
|
|
37
|
+
maxLength?: number;
|
|
38
|
+
}) {
|
|
39
|
+
const ownRef = useRef<HTMLTextAreaElement>(null);
|
|
40
|
+
const ref = textareaRef ?? ownRef;
|
|
41
|
+
|
|
42
|
+
// Height tracks content up to the className's 4-line max-h cap, then scrolls
|
|
43
|
+
// internally. Keyed on `value` so the post-send clear snaps it back to one
|
|
44
|
+
// row. (field-sizing: content would do this in CSS alone, but it's still
|
|
45
|
+
// Chromium-only.)
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
const el = ref.current;
|
|
48
|
+
if (!el) return;
|
|
49
|
+
el.style.height = "auto";
|
|
50
|
+
el.style.height = `${el.scrollHeight}px`;
|
|
51
|
+
}, [value, ref]);
|
|
52
|
+
|
|
53
|
+
function onKeyDown(e: KeyboardEvent<HTMLTextAreaElement>) {
|
|
54
|
+
if (e.key === "Enter" && !e.shiftKey) {
|
|
55
|
+
e.preventDefault();
|
|
56
|
+
onSend();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<form
|
|
62
|
+
className={cn("flex shrink-0 items-end gap-2 border-t border-base-200 p-2", className)}
|
|
63
|
+
onSubmit={(e) => {
|
|
64
|
+
e.preventDefault();
|
|
65
|
+
onSend();
|
|
66
|
+
}}
|
|
67
|
+
>
|
|
68
|
+
<textarea
|
|
69
|
+
ref={ref}
|
|
70
|
+
rows={1}
|
|
71
|
+
value={value}
|
|
72
|
+
onChange={(e) => onChange(e.target.value)}
|
|
73
|
+
onKeyDown={onKeyDown}
|
|
74
|
+
placeholder={placeholder}
|
|
75
|
+
maxLength={maxLength}
|
|
76
|
+
disabled={disabled}
|
|
77
|
+
className="max-h-[5.625rem] min-w-0 flex-1 resize-none overflow-y-auto rounded-inner border border-base-200 bg-base px-2 py-1 text-sm text-base-contrast focus:bg-[color-mix(in_srgb,var(--color-base),var(--color-base-contrast)_5%)] focus:outline-none disabled:opacity-60"
|
|
78
|
+
/>
|
|
79
|
+
{busy && onStop ? (
|
|
80
|
+
<button
|
|
81
|
+
type="button"
|
|
82
|
+
aria-label="Stop"
|
|
83
|
+
onClick={onStop}
|
|
84
|
+
className="flex cursor-pointer items-center rounded-inner bg-primary px-3 py-1.5 text-sm text-primary-contrast"
|
|
85
|
+
>
|
|
86
|
+
<Square size={12} fill="currentColor" aria-hidden="true" />
|
|
87
|
+
</button>
|
|
88
|
+
) : (
|
|
89
|
+
<button
|
|
90
|
+
type="submit"
|
|
91
|
+
aria-label="Send"
|
|
92
|
+
disabled={busy || disabled}
|
|
93
|
+
className="rounded-inner bg-primary px-3 py-1 text-sm text-primary-contrast disabled:opacity-50"
|
|
94
|
+
>
|
|
95
|
+
→
|
|
96
|
+
</button>
|
|
97
|
+
)}
|
|
98
|
+
</form>
|
|
99
|
+
);
|
|
100
|
+
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { useEffect, useRef, useState, type
|
|
2
|
-
import {
|
|
3
|
-
import { ArrowDown, ChevronDown, ChevronRight, History, Pin, PinOff, SquarePen, Square, Trash2 } from "lucide-react";
|
|
1
|
+
import { useEffect, useRef, useState, type MouseEvent } from "react";
|
|
2
|
+
import { ArrowDown, ChevronDown, ChevronRight, History, Pin, PinOff, SquarePen, Trash2 } from "lucide-react";
|
|
4
3
|
import { cn } from "../../lib/cn";
|
|
5
|
-
import { ensureSanitizer
|
|
4
|
+
import { ensureSanitizer } from "../../lib/sanitize";
|
|
5
|
+
import { assistantHtml, MD_STYLES, USER_BUBBLE_CLASS } from "./markdown";
|
|
6
|
+
import { ChatComposer } from "./ChatComposer";
|
|
6
7
|
import { resolveThinkingPhrases } from "../../lib/chatbot";
|
|
7
8
|
import { lockBodyScroll } from "../../lib/scroll-lock";
|
|
8
9
|
import { loadHistory, upsertConversation, setConversationPinned, removeConversation, type StoredConversation } from "./chat-history";
|
|
@@ -63,24 +64,10 @@ const ERROR_COPY: Record<string, string> = {
|
|
|
63
64
|
};
|
|
64
65
|
const RETRYABLE = new Set(["rate_limited", "upstream_error"]);
|
|
65
66
|
|
|
66
|
-
/**
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
export
|
|
70
|
-
return sanitizeHtml(marked.parse(md, { async: false, gfm: true, breaks: true }) as string);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// Tailwind preflight makes h1–h6 inherit size/weight, so headings only need
|
|
74
|
-
// weight + spacing to clamp to the message's text scale.
|
|
75
|
-
const MD_STYLES =
|
|
76
|
-
"[&_p:not(:first-child)]:mt-2 [&_ul]:mt-1 [&_ul]:list-disc [&_ul]:pl-4 " +
|
|
77
|
-
"[&_ol]:mt-1 [&_ol]:list-decimal [&_ol]:pl-4 [&_li:not(:first-child)]:mt-1 " +
|
|
78
|
-
"[&_a]:underline [&_a]:underline-offset-2 [&_a]:text-primary " +
|
|
79
|
-
"[&_code]:rounded-inner [&_code]:bg-base-200 [&_code]:px-1 [&_code]:font-mono [&_code]:text-[0.8em] " +
|
|
80
|
-
"[&_pre]:mt-2 [&_pre]:overflow-x-auto [&_pre]:rounded-inner [&_pre]:bg-base-200 [&_pre]:p-2 " +
|
|
81
|
-
"[&_h1]:mt-2 [&_h1]:font-semibold [&_h2]:mt-2 [&_h2]:font-semibold " +
|
|
82
|
-
"[&_h3]:mt-2 [&_h3]:font-semibold [&_h4]:mt-2 [&_h4]:font-semibold " +
|
|
83
|
-
"[&_blockquote]:mt-2 [&_blockquote]:border-l-2 [&_blockquote]:border-base-200 [&_blockquote]:pl-2";
|
|
67
|
+
/** Re-exported from ./markdown, where the rendering rules now live so the deck
|
|
68
|
+
* assistant shares them. Kept here because tests and callers import it from
|
|
69
|
+
* this module. */
|
|
70
|
+
export { assistantHtml };
|
|
84
71
|
|
|
85
72
|
/** Parse our /api/chat SSE frames out of a fetch body. Exported for tests. */
|
|
86
73
|
export async function streamChat(
|
|
@@ -207,25 +194,6 @@ export default function ChatPanel({ open, closing, animateEnter, onClose, siteNa
|
|
|
207
194
|
const listRef = useRef<HTMLDivElement>(null);
|
|
208
195
|
const pinnedRef = useRef(true);
|
|
209
196
|
|
|
210
|
-
// Autosize the composer: height tracks content up to the className's
|
|
211
|
-
// 4-line max-h cap, then it scrolls internally. Keyed on `input` so the
|
|
212
|
-
// post-send clear snaps it back to a single row. (field-sizing: content
|
|
213
|
-
// would do this in CSS alone, but it's still Chromium-only.)
|
|
214
|
-
useEffect(() => {
|
|
215
|
-
const el = composerRef.current;
|
|
216
|
-
if (!el) return;
|
|
217
|
-
el.style.height = "auto";
|
|
218
|
-
el.style.height = `${el.scrollHeight}px`;
|
|
219
|
-
}, [input]);
|
|
220
|
-
|
|
221
|
-
function onComposerKeyDown(e: KeyboardEvent<HTMLTextAreaElement>) {
|
|
222
|
-
// Chat convention: Enter sends, Shift+Enter inserts a newline.
|
|
223
|
-
if (e.key === "Enter" && !e.shiftKey) {
|
|
224
|
-
e.preventDefault();
|
|
225
|
-
void send();
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
|
|
229
197
|
// The tasks prop can shrink live (the configurator's Preview-as filters it):
|
|
230
198
|
// never keep a selected task that's no longer offered, or the next send would
|
|
231
199
|
// assemble a task the previewed audience can't access.
|
|
@@ -589,7 +557,7 @@ export default function ChatPanel({ open, closing, animateEnter, onClose, siteNa
|
|
|
589
557
|
)}
|
|
590
558
|
{messages.map((m, i) =>
|
|
591
559
|
m.role === "user" ? (
|
|
592
|
-
<div key={i} className=
|
|
560
|
+
<div key={i} className={USER_BUBBLE_CLASS}>
|
|
593
561
|
{m.content}
|
|
594
562
|
</div>
|
|
595
563
|
) : m.content === "" ? (
|
|
@@ -657,33 +625,16 @@ export default function ChatPanel({ open, closing, animateEnter, onClose, siteNa
|
|
|
657
625
|
)}
|
|
658
626
|
</div>
|
|
659
627
|
<p role="status" className="sr-only">{busy ? thinking : ""}</p>
|
|
660
|
-
<
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
value={input}
|
|
671
|
-
onChange={(e) => setInput(e.target.value)}
|
|
672
|
-
onKeyDown={onComposerKeyDown}
|
|
673
|
-
placeholder={`Ask about ${siteName}…`}
|
|
674
|
-
maxLength={4000}
|
|
675
|
-
className="max-h-[5.625rem] min-w-0 flex-1 resize-none overflow-y-auto rounded-inner border border-base-200 bg-base px-2 py-1 text-sm text-base-contrast focus:outline-none focus:bg-[color-mix(in_srgb,var(--color-base),var(--color-base-contrast)_5%)]"
|
|
676
|
-
/>
|
|
677
|
-
{busy ? (
|
|
678
|
-
<button type="button" aria-label="Stop" onClick={stop}
|
|
679
|
-
className="flex cursor-pointer items-center rounded-inner bg-primary px-3 py-1.5 text-sm text-primary-contrast">
|
|
680
|
-
<Square size={12} fill="currentColor" aria-hidden="true" />
|
|
681
|
-
</button>
|
|
682
|
-
) : (
|
|
683
|
-
<button type="submit" aria-label="Send"
|
|
684
|
-
className="rounded-inner bg-primary px-3 py-1 text-sm text-primary-contrast disabled:opacity-50">→</button>
|
|
685
|
-
)}
|
|
686
|
-
</form>
|
|
628
|
+
<ChatComposer
|
|
629
|
+
value={input}
|
|
630
|
+
onChange={setInput}
|
|
631
|
+
onSend={() => void send()}
|
|
632
|
+
onStop={stop}
|
|
633
|
+
busy={busy}
|
|
634
|
+
placeholder={`Ask about ${siteName}…`}
|
|
635
|
+
textareaRef={composerRef}
|
|
636
|
+
className={mode === "sheet" ? "pb-[max(0.5rem,env(safe-area-inset-bottom))]" : undefined}
|
|
637
|
+
/>
|
|
687
638
|
{isEditor && <p className="shrink-0 border-t border-base-200 px-3 py-1 text-[10px] text-base-contrast-light">Editor view — answers ground on published content.</p>}
|
|
688
639
|
</div>
|
|
689
640
|
</>
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { marked } from "marked";
|
|
2
|
+
import { sanitizeHtml } from "../../lib/sanitize";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The assistant-message treatment, shared by every chat surface (brand chat's
|
|
6
|
+
* ChatPanel and the Deck Builder's docked assistant). Extracted so a second
|
|
7
|
+
* chat pane is a second CALLER, not a second copy of the rendering rules —
|
|
8
|
+
* particularly the sanitizer gate below, which is a security property.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/** Assistant markdown → sanitized HTML. Callers MUST gate on the sanitizer
|
|
12
|
+
* having loaded (`mdReady`) — before then sanitizeHtml passes raw HTML
|
|
13
|
+
* through, and model output is untrusted. */
|
|
14
|
+
export function assistantHtml(md: string): string {
|
|
15
|
+
return sanitizeHtml(marked.parse(md, { async: false, gfm: true, breaks: true }) as string);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Tailwind preflight makes h1–h6 inherit size/weight, so headings only need
|
|
19
|
+
// weight + spacing to clamp to the message's text scale.
|
|
20
|
+
export const MD_STYLES =
|
|
21
|
+
"[&_p:not(:first-child)]:mt-2 [&_ul]:mt-1 [&_ul]:list-disc [&_ul]:pl-4 " +
|
|
22
|
+
"[&_ol]:mt-1 [&_ol]:list-decimal [&_ol]:pl-4 [&_li:not(:first-child)]:mt-1 " +
|
|
23
|
+
"[&_a]:underline [&_a]:underline-offset-2 [&_a]:text-primary " +
|
|
24
|
+
"[&_code]:rounded-inner [&_code]:bg-base-200 [&_code]:px-1 [&_code]:font-mono [&_code]:text-[0.8em] " +
|
|
25
|
+
"[&_pre]:mt-2 [&_pre]:overflow-x-auto [&_pre]:rounded-inner [&_pre]:bg-base-200 [&_pre]:p-2 " +
|
|
26
|
+
"[&_h1]:mt-2 [&_h1]:font-semibold [&_h2]:mt-2 [&_h2]:font-semibold " +
|
|
27
|
+
"[&_h3]:mt-2 [&_h3]:font-semibold [&_h4]:mt-2 [&_h4]:font-semibold " +
|
|
28
|
+
"[&_blockquote]:mt-2 [&_blockquote]:border-l-2 [&_blockquote]:border-base-200 [&_blockquote]:pl-2";
|
|
29
|
+
|
|
30
|
+
/** The user's turn: the only side of a transcript that gets a filled bubble. */
|
|
31
|
+
export const USER_BUBBLE_CLASS =
|
|
32
|
+
"ml-auto max-w-[85%] whitespace-pre-wrap rounded-outer bg-primary px-3 py-2 text-sm text-primary-contrast";
|
|
@@ -29,6 +29,16 @@ export function EditablePlainText({
|
|
|
29
29
|
...htmlAttrs
|
|
30
30
|
}: EditablePlainTextProps) {
|
|
31
31
|
const ref = useRef<HTMLElement>(null);
|
|
32
|
+
// React must NOT own the text node while the field is being typed into. Every
|
|
33
|
+
// keystroke commits (see useEditablePlainText), the parent echoes the new
|
|
34
|
+
// value straight back, and React's children diff then rewrites the element's
|
|
35
|
+
// text — which destroys the live text node and collapses the caret to offset
|
|
36
|
+
// 0, so a heading comes out backwards. In edit mode we therefore render the
|
|
37
|
+
// text React knew at the moment editing began and hand ownership to the
|
|
38
|
+
// effect below, which writes only when the DOM has genuinely drifted.
|
|
39
|
+
const uncontrolled = useRef(value);
|
|
40
|
+
if (!isEditMode) uncontrolled.current = value;
|
|
41
|
+
|
|
32
42
|
const {
|
|
33
43
|
value: localValue,
|
|
34
44
|
handleInput,
|
|
@@ -94,6 +104,6 @@ export function EditablePlainText({
|
|
|
94
104
|
"data-placeholder": isEditMode && placeholder ? placeholder : undefined,
|
|
95
105
|
...htmlAttrs,
|
|
96
106
|
},
|
|
97
|
-
value,
|
|
107
|
+
isEditMode ? uncontrolled.current : value,
|
|
98
108
|
);
|
|
99
109
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { cn } from "../../lib/cn";
|
|
2
|
+
import { contrastColor } from "../../lib/contrast";
|
|
3
|
+
import type { Audience } from "../../auth/types";
|
|
4
|
+
|
|
5
|
+
/** Multi-select audience chips — the site-settings idiom for "who sees this".
|
|
6
|
+
* Shared by the chatbot and deck-builder opt-ins so the two gates, which have
|
|
7
|
+
* identical strict-opt-in semantics, cannot come to look like different rules. */
|
|
8
|
+
export function AudienceChips({
|
|
9
|
+
audiences,
|
|
10
|
+
selected,
|
|
11
|
+
onToggle,
|
|
12
|
+
}: {
|
|
13
|
+
audiences: Audience[];
|
|
14
|
+
selected: string[];
|
|
15
|
+
onToggle: (name: string) => void;
|
|
16
|
+
}) {
|
|
17
|
+
return (
|
|
18
|
+
<div className="flex flex-wrap gap-1">
|
|
19
|
+
{audiences.map((a) => (
|
|
20
|
+
<button key={a.name} type="button" onClick={() => onToggle(a.name)}
|
|
21
|
+
className={cn("rounded-full border px-2 py-0.5 text-xs",
|
|
22
|
+
selected.includes(a.name) ? "border-primary bg-primary text-primary-contrast" : "border-base-200 bg-base-accent text-base-contrast")}
|
|
23
|
+
style={a.color && selected.includes(a.name) ? { backgroundColor: a.color, borderColor: a.color, color: contrastColor(a.color) } : undefined}>
|
|
24
|
+
{a.displayName}
|
|
25
|
+
</button>
|
|
26
|
+
))}
|
|
27
|
+
{audiences.length === 0 && <span className="text-xs text-base-contrast-light">No audiences configured</span>}
|
|
28
|
+
</div>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
@@ -2025,6 +2025,18 @@ export default function EditorShell({
|
|
|
2025
2025
|
</svg>
|
|
2026
2026
|
</Fab>
|
|
2027
2027
|
)}
|
|
2028
|
+
{/* Deck Builder (#34). Editors are super-admins over decks and are
|
|
2029
|
+
never gated by deckBuilder.audiences, so this is unconditional.
|
|
2030
|
+
An <a>, not a click handler: builder mode is its own route.
|
|
2031
|
+
bottom-52 clears the bottom-40 document FAB + gap. Taking over the
|
|
2032
|
+
editor top bar in place is #38 — this just goes there. */}
|
|
2033
|
+
<Fab href="/decks?next=%2Fedit" label="Build a deck" column="editor" className="bottom-52">
|
|
2034
|
+
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" aria-hidden="true">
|
|
2035
|
+
<rect x="3" y="4" width="18" height="12" rx="1" />
|
|
2036
|
+
<path d="M12 16v4" />
|
|
2037
|
+
<path d="M9 20h6" />
|
|
2038
|
+
</svg>
|
|
2039
|
+
</Fab>
|
|
2028
2040
|
{showDocumentEditor && resolvedActivePage?.document?.enabled && (
|
|
2029
2041
|
<Suspense fallback={<DocumentOverlayFallback />}>
|
|
2030
2042
|
{/* Branch/history view (viewSections !== null → previewing the
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { useEffect, useState } from "react";
|
|
2
2
|
import { Button } from "../shared/Button";
|
|
3
3
|
import { SubTabs } from "../shared/SubTabs";
|
|
4
|
-
import {
|
|
5
|
-
import { contrastColor } from "../../lib/contrast";
|
|
4
|
+
import { AudienceChips } from "./AudienceChips";
|
|
6
5
|
import ChatPanel from "../chat/ChatPanel";
|
|
7
6
|
import type { SiteConfig, ChatbotConfig, ChatbotTask } from "../../schemas/site-config";
|
|
8
7
|
import type { Audience } from "../../auth/types";
|
|
@@ -30,22 +29,6 @@ function slugify(label: string): string {
|
|
|
30
29
|
return label.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 32) || "task";
|
|
31
30
|
}
|
|
32
31
|
|
|
33
|
-
function AudienceChips({ audiences, selected, onToggle }: { audiences: Audience[]; selected: string[]; onToggle: (name: string) => void }) {
|
|
34
|
-
return (
|
|
35
|
-
<div className="flex flex-wrap gap-1">
|
|
36
|
-
{audiences.map((a) => (
|
|
37
|
-
<button key={a.name} type="button" onClick={() => onToggle(a.name)}
|
|
38
|
-
className={cn("rounded-full border px-2 py-0.5 text-xs",
|
|
39
|
-
selected.includes(a.name) ? "border-primary bg-primary text-primary-contrast" : "border-base-200 bg-base-accent text-base-contrast")}
|
|
40
|
-
style={a.color && selected.includes(a.name) ? { backgroundColor: a.color, borderColor: a.color, color: contrastColor(a.color) } : undefined}>
|
|
41
|
-
{a.displayName}
|
|
42
|
-
</button>
|
|
43
|
-
))}
|
|
44
|
-
{audiences.length === 0 && <span className="text-xs text-base-contrast-light">No audiences configured</span>}
|
|
45
|
-
</div>
|
|
46
|
-
);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
32
|
export function SiteSettingsChatbot({ siteConfig, onSiteConfigChange, audiences, platformEnabled }: Props) {
|
|
50
33
|
const chatbot = siteConfig.chatbot;
|
|
51
34
|
const [newTaskLabel, setNewTaskLabel] = useState("");
|