@drawnagency/primitives 0.1.82 → 0.1.83

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.
@@ -3,7 +3,7 @@ import {
3
3
  pluralize,
4
4
  stripHtmlToPlainText,
5
5
  truncate
6
- } from "./chunk-22GU6GNP.js";
6
+ } from "./chunk-665DW3HR.js";
7
7
  import {
8
8
  DeleteButton,
9
9
  DragHandle,
@@ -51,7 +51,7 @@ import {
51
51
  } from "./chunk-TZQPOR5A.js";
52
52
  import {
53
53
  SingleMediaReferenceSchema
54
- } from "./chunk-ETJYYUQX.js";
54
+ } from "./chunk-E3MTIMOG.js";
55
55
  import {
56
56
  defineSection,
57
57
  getSection
@@ -30,7 +30,7 @@ import {
30
30
  import {
31
31
  HexColorSchema,
32
32
  SingleMediaReferenceSchema
33
- } from "./chunk-ETJYYUQX.js";
33
+ } from "./chunk-E3MTIMOG.js";
34
34
  import {
35
35
  defineSection
36
36
  } from "./chunk-VKAGMEKE.js";
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-TZQPOR5A.js";
10
10
  import {
11
11
  IndexSchema
12
- } from "./chunk-ETJYYUQX.js";
12
+ } from "./chunk-E3MTIMOG.js";
13
13
  import {
14
14
  getAllSchemas
15
15
  } from "./chunk-VKAGMEKE.js";
@@ -130,7 +130,7 @@ var SectionMetaSchema = z3.object({
130
130
  status: StatusSchema,
131
131
  access: z3.array(z3.string())
132
132
  });
133
- var RESERVED_SLUGS = ["edit", "api", "login", "set-password", "404", "present"];
133
+ var RESERVED_SLUGS = ["edit", "api", "login", "set-password", "404", "present", "print"];
134
134
  var PARSE_REJECTED_SLUGS = ["edit", "api", "login", "set-password", "404"];
135
135
  var PageStatusSchema = z3.enum(["live", "archived"]);
136
136
  var PageSchema = z3.object({
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  HexColorSchema
3
- } from "./chunk-ETJYYUQX.js";
3
+ } from "./chunk-E3MTIMOG.js";
4
4
 
5
5
  // src/schemas/audience.ts
6
6
  import { z } from "zod";
@@ -24,7 +24,7 @@ import {
24
24
  cn
25
25
  } from "../../chunk-7EOSDFS3.js";
26
26
  import "../../chunk-YBVK254P.js";
27
- import "../../chunk-ETJYYUQX.js";
27
+ import "../../chunk-E3MTIMOG.js";
28
28
  import "../../chunk-FM4M4Q2W.js";
29
29
  import "../../chunk-JSBRDJBE.js";
30
30
 
@@ -23,7 +23,7 @@ import {
23
23
  cn
24
24
  } from "../../chunk-7EOSDFS3.js";
25
25
  import "../../chunk-YBVK254P.js";
26
- import "../../chunk-ETJYYUQX.js";
26
+ import "../../chunk-E3MTIMOG.js";
27
27
  import "../../chunk-VKAGMEKE.js";
28
28
  import "../../chunk-FM4M4Q2W.js";
29
29
  import "../../chunk-JSBRDJBE.js";
@@ -2,7 +2,7 @@ import {
2
2
  ColorItemSchema,
3
3
  ColorSpaceSchema,
4
4
  brandGuideSectionDefs
5
- } from "../../chunk-22GU6GNP.js";
5
+ } from "../../chunk-665DW3HR.js";
6
6
  import "../../chunk-5THS4K5D.js";
7
7
  import "../../chunk-DKXISNJ2.js";
8
8
  import "../../chunk-MBJUWOM2.js";
@@ -11,7 +11,7 @@ import "../../chunk-PZJL2S3Z.js";
11
11
  import "../../chunk-WDSVHKAH.js";
12
12
  import "../../chunk-7EOSDFS3.js";
13
13
  import "../../chunk-YBVK254P.js";
14
- import "../../chunk-ETJYYUQX.js";
14
+ import "../../chunk-E3MTIMOG.js";
15
15
  import "../../chunk-VKAGMEKE.js";
16
16
  import "../../chunk-FM4M4Q2W.js";
17
17
  import "../../chunk-JSBRDJBE.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  allSectionDefs
3
- } from "../../chunk-5UDIQLGQ.js";
4
- import "../../chunk-22GU6GNP.js";
3
+ } from "../../chunk-56J4QMF4.js";
4
+ import "../../chunk-665DW3HR.js";
5
5
  import "../../chunk-Q6LZOH5M.js";
6
6
  import "../../chunk-5THS4K5D.js";
7
7
  import "../../chunk-FDBZZ4AT.js";
@@ -16,7 +16,7 @@ import "../../chunk-53DKVAB6.js";
16
16
  import "../../chunk-7EOSDFS3.js";
17
17
  import "../../chunk-YBVK254P.js";
18
18
  import "../../chunk-TZQPOR5A.js";
19
- import "../../chunk-ETJYYUQX.js";
19
+ import "../../chunk-E3MTIMOG.js";
20
20
  import {
21
21
  registerRichText,
22
22
  registerSchema
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  allSectionDefs
3
- } from "../../chunk-5UDIQLGQ.js";
4
- import "../../chunk-22GU6GNP.js";
3
+ } from "../../chunk-56J4QMF4.js";
4
+ import "../../chunk-665DW3HR.js";
5
5
  import "../../chunk-Q6LZOH5M.js";
6
6
  import "../../chunk-5THS4K5D.js";
7
7
  import "../../chunk-FDBZZ4AT.js";
@@ -16,7 +16,7 @@ import "../../chunk-53DKVAB6.js";
16
16
  import "../../chunk-7EOSDFS3.js";
17
17
  import "../../chunk-YBVK254P.js";
18
18
  import "../../chunk-TZQPOR5A.js";
19
- import "../../chunk-ETJYYUQX.js";
19
+ import "../../chunk-E3MTIMOG.js";
20
20
  import {
21
21
  registerSection
22
22
  } from "../../chunk-VKAGMEKE.js";
@@ -1 +1 @@
1
- {"version":3,"file":"EditorShell.d.ts","sourceRoot":"","sources":["../../../src/components/shell/EditorShell.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AASjD,OAAO,EAAoC,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAwDtF,OAAO,KAAK,EAAE,eAAe,EAA2D,MAAM,oBAAoB,CAAC;AAmCnH,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAoBxD,UAAU,KAAK;IACb,OAAO,EAAE,MAAM,CAAC;IAIhB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,YAAY,EAAE;QACZ,KAAK,EAAE,OAAO,CAAC;QACf,aAAa,EAAE,OAAO,CAAC;QACvB,YAAY,EAAE,OAAO,CAAC;QACtB,cAAc,EAAE,OAAO,CAAC;QACxB,kBAAkB,EAAE,OAAO,CAAC;QAC5B,cAAc,EAAE,OAAO,CAAC;KACzB,CAAC;IACF,WAAW,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAA;KAAE,GAAG,IAAI,CAAC;IAIhE,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAKjC,eAAe,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;CAC1C;AAED,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAClC,OAAO,EACP,YAAY,EACZ,MAAM,EACN,SAAS,EAAE,gBAAgB,EAC3B,YAAY,EACZ,WAAW,EACX,sBAA8B,EAC9B,eAAe,GAChB,EAAE,KAAK,2CAqiDP;AAuED;6EAC6E;AAC7E,wBAAgB,kBAAkB,CAChC,YAAY,EAAE,WAAW,CAAC,YAAY,CAAC,EACvC,aAAa,EAAE,MAAM,GAAG,IAAI,EAC5B,eAAe,EAAE,MAAM,GAAG,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAK/B"}
1
+ {"version":3,"file":"EditorShell.d.ts","sourceRoot":"","sources":["../../../src/components/shell/EditorShell.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AASjD,OAAO,EAAoC,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAwDtF,OAAO,KAAK,EAAE,eAAe,EAA2D,MAAM,oBAAoB,CAAC;AAmCnH,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAoBxD,UAAU,KAAK;IACb,OAAO,EAAE,MAAM,CAAC;IAIhB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,YAAY,EAAE;QACZ,KAAK,EAAE,OAAO,CAAC;QACf,aAAa,EAAE,OAAO,CAAC;QACvB,YAAY,EAAE,OAAO,CAAC;QACtB,cAAc,EAAE,OAAO,CAAC;QACxB,kBAAkB,EAAE,OAAO,CAAC;QAC5B,cAAc,EAAE,OAAO,CAAC;KACzB,CAAC;IACF,WAAW,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAA;KAAE,GAAG,IAAI,CAAC;IAIhE,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAKjC,eAAe,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;CAC1C;AAED,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAClC,OAAO,EACP,YAAY,EACZ,MAAM,EACN,SAAS,EAAE,gBAAgB,EAC3B,YAAY,EACZ,WAAW,EACX,sBAA8B,EAC9B,eAAe,GAChB,EAAE,KAAK,2CAsiDP;AAuED;6EAC6E;AAC7E,wBAAgB,kBAAkB,CAChC,YAAY,EAAE,WAAW,CAAC,YAAY,CAAC,EACvC,aAAa,EAAE,MAAM,GAAG,IAAI,EAC5B,eAAe,EAAE,MAAM,GAAG,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAK/B"}
@@ -9,10 +9,13 @@ export interface DocViewerProps {
9
9
  selectedChunkId?: string | null;
10
10
  onSelectChunk?: (chunkId: string | null) => void;
11
11
  onClose?: () => void;
12
+ /** Present mode only: when set, the toolbar shows a "Download PDF" link (the /present
13
+ * route passes the gated /api/document-pdf href when a PDF exists for this viewer). */
14
+ downloadHref?: string | null;
12
15
  onDocState?: (state: {
13
16
  chunks: Chunk[];
14
17
  warningsByChunk: Record<string, string[]>;
15
18
  }) => void;
16
19
  }
17
- export declare function DocViewer({ source, document: doc, host, mode, selectedChunkId, onSelectChunk, onClose, onDocState, }: DocViewerProps): import("react/jsx-runtime").JSX.Element;
20
+ export declare function DocViewer({ source, document: doc, host, mode, selectedChunkId, onSelectChunk, onClose, downloadHref, onDocState, }: DocViewerProps): import("react/jsx-runtime").JSX.Element;
18
21
  //# sourceMappingURL=DocViewer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DocViewer.d.ts","sourceRoot":"","sources":["../../../src/document/components/DocViewer.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D,OAAO,KAAK,EAAE,KAAK,EAAY,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGzE,OAAO,EAAkB,KAAK,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAOhE,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAChC,QAAQ,EAAE,eAAe,CAAC;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,SAAS,GAAG,MAAM,CAAC;IAEzB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACjD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAKrB,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QAAC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;KAAE,KAAK,IAAI,CAAC;CAC9F;AAUD,wBAAgB,SAAS,CAAC,EACxB,MAAM,EACN,QAAQ,EAAE,GAAG,EACb,IAAI,EACJ,IAAI,EACJ,eAAe,EACf,aAAa,EACb,OAAO,EACP,UAAU,GACX,EAAE,cAAc,2CA8JhB"}
1
+ {"version":3,"file":"DocViewer.d.ts","sourceRoot":"","sources":["../../../src/document/components/DocViewer.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D,OAAO,KAAK,EAAE,KAAK,EAAY,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGzE,OAAO,EAAkB,KAAK,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAOhE,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAChC,QAAQ,EAAE,eAAe,CAAC;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,SAAS,GAAG,MAAM,CAAC;IAEzB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACjD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB;2FACuF;IACvF,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAK7B,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QAAC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;KAAE,KAAK,IAAI,CAAC;CAC9F;AAUD,wBAAgB,SAAS,CAAC,EACxB,MAAM,EACN,QAAQ,EAAE,GAAG,EACb,IAAI,EACJ,IAAI,EACJ,eAAe,EACf,aAAa,EACb,OAAO,EACP,YAAY,EACZ,UAAU,GACX,EAAE,cAAc,2CA0KhB"}
@@ -764,6 +764,7 @@ function DocViewer({
764
764
  selectedChunkId,
765
765
  onSelectChunk,
766
766
  onClose,
767
+ downloadHref,
767
768
  onDocState
768
769
  }) {
769
770
  const { chunks, pages, measuring, warningsByChunk } = useDocPages({ source, sections: doc.sections });
@@ -847,16 +848,28 @@ function DocViewer({
847
848
  /* @__PURE__ */ jsxs6("div", { className: "flex h-full min-h-0 min-w-0 flex-1 flex-col", children: [
848
849
  mode === "present" ? /* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between border-b border-base-200 bg-base px-4 py-2", children: [
849
850
  /* @__PURE__ */ jsx6("span", { className: "text-sm font-medium text-base-contrast", children: source?.pageTitle ?? "Document" }),
850
- onClose ? /* @__PURE__ */ jsx6(
851
- "button",
852
- {
853
- type: "button",
854
- "aria-label": "Close",
855
- onClick: onClose,
856
- className: "rounded border border-base-200 px-3 py-1 text-xs font-medium text-base-contrast hover:bg-base-accent/30",
857
- children: "\u2715"
858
- }
859
- ) : null
851
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2", children: [
852
+ downloadHref ? /* @__PURE__ */ jsx6(
853
+ "a",
854
+ {
855
+ href: downloadHref,
856
+ download: true,
857
+ "aria-label": "Download PDF",
858
+ className: "rounded border border-base-200 px-3 py-1 text-xs font-medium text-base-contrast hover:bg-base-accent/30",
859
+ children: "Download PDF"
860
+ }
861
+ ) : null,
862
+ onClose ? /* @__PURE__ */ jsx6(
863
+ "button",
864
+ {
865
+ type: "button",
866
+ "aria-label": "Close",
867
+ onClick: onClose,
868
+ className: "rounded border border-base-200 px-3 py-1 text-xs font-medium text-base-contrast hover:bg-base-accent/30",
869
+ children: "\u2715"
870
+ }
871
+ ) : null
872
+ ] })
860
873
  ] }) : null,
861
874
  /* @__PURE__ */ jsxs6("div", { className: "flex min-h-0 min-w-0 flex-1", children: [
862
875
  railOpen ? /* @__PURE__ */ jsx6(
package/dist/index.js CHANGED
@@ -49,7 +49,7 @@ import {
49
49
  AudienceNameSchema,
50
50
  MediaGridOptionsSchema,
51
51
  slugifyAudienceName
52
- } from "./chunk-Y54G2XSC.js";
52
+ } from "./chunk-EP3LVOXZ.js";
53
53
  import {
54
54
  AudienceSchema,
55
55
  RoleSchema,
@@ -71,7 +71,7 @@ import {
71
71
  loadStaticSiteContent,
72
72
  mergeSiteContent,
73
73
  safeRedirect
74
- } from "./chunk-6NRVX6NQ.js";
74
+ } from "./chunk-DO3ZENLN.js";
75
75
  import {
76
76
  curatedIcons,
77
77
  getIcon
@@ -124,7 +124,7 @@ import {
124
124
  TextLineSchema,
125
125
  VariantSchema,
126
126
  normalizeSiteIndex
127
- } from "./chunk-ETJYYUQX.js";
127
+ } from "./chunk-E3MTIMOG.js";
128
128
  import {
129
129
  clearRegistry,
130
130
  createRegistry,
package/dist/lib/index.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  loadStaticSiteContent,
8
8
  mergeSiteContent,
9
9
  safeRedirect
10
- } from "../chunk-6NRVX6NQ.js";
10
+ } from "../chunk-DO3ZENLN.js";
11
11
  import {
12
12
  curatedIcons,
13
13
  getIcon
@@ -33,7 +33,7 @@ import {
33
33
  } from "../chunk-YBVK254P.js";
34
34
  import "../chunk-75P6HWPN.js";
35
35
  import "../chunk-TZQPOR5A.js";
36
- import "../chunk-ETJYYUQX.js";
36
+ import "../chunk-E3MTIMOG.js";
37
37
  import {
38
38
  clearRegistry,
39
39
  createRegistry,
@@ -24,7 +24,7 @@ import {
24
24
  MediaFolderSchema,
25
25
  MediaItemSchema,
26
26
  VariantSchema
27
- } from "../chunk-ETJYYUQX.js";
27
+ } from "../chunk-E3MTIMOG.js";
28
28
  import "../chunk-FM4M4Q2W.js";
29
29
  import "../chunk-JSBRDJBE.js";
30
30
  export {
@@ -3,7 +3,7 @@ import {
3
3
  AudienceNameSchema,
4
4
  MediaGridOptionsSchema,
5
5
  slugifyAudienceName
6
- } from "../chunk-Y54G2XSC.js";
6
+ } from "../chunk-EP3LVOXZ.js";
7
7
  import {
8
8
  AudienceSchema,
9
9
  RoleSchema,
@@ -40,7 +40,7 @@ import {
40
40
  TextLineSchema,
41
41
  VariantSchema,
42
42
  normalizeSiteIndex
43
- } from "../chunk-ETJYYUQX.js";
43
+ } from "../chunk-E3MTIMOG.js";
44
44
  import "../chunk-VKAGMEKE.js";
45
45
  import "../chunk-FM4M4Q2W.js";
46
46
  import "../chunk-NSCT3AMV.js";
@@ -10,7 +10,7 @@ export declare const SectionMetaSchema: z.ZodObject<{
10
10
  access: z.ZodArray<z.ZodString>;
11
11
  }, z.core.$strip>;
12
12
  export type SectionMeta = z.infer<typeof SectionMetaSchema>;
13
- export declare const RESERVED_SLUGS: readonly ["edit", "api", "login", "set-password", "404", "present"];
13
+ export declare const RESERVED_SLUGS: readonly ["edit", "api", "login", "set-password", "404", "present", "print"];
14
14
  export declare const PageStatusSchema: z.ZodEnum<{
15
15
  live: "live";
16
16
  archived: "archived";
@@ -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;AAaxB,eAAO,MAAM,iBAAiB;;;;;;;;;iBAI5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAQ5D,eAAO,MAAM,cAAc,qEAAsE,CAAC;AAWlG,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;AA0C9C,QAAA,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA6CtB,CAAC;AAEL,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAAyE,CAAC;AAElG,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAE7D,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;;;;;;;;;;;iBAwB5B,CAAC;AACL,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA4B3B,CAAC;AAEH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,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;AAaxB,eAAO,MAAM,iBAAiB;;;;;;;;;iBAI5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAQ5D,eAAO,MAAM,cAAc,8EAA+E,CAAC;AAW3G,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;AA0C9C,QAAA,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA6CtB,CAAC;AAEL,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAAyE,CAAC;AAElG,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAE7D,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;;;;;;;;;;;iBAwB5B,CAAC;AACL,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA4B3B,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.82",
3
+ "version": "0.1.83",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  "./package.json": "./package.json",
@@ -1473,8 +1473,9 @@ export default function EditorShell({
1473
1473
  className="cursor-pointer fixed bottom-40 right-4 lg:right-auto z-50 flex h-10 w-10 items-center justify-center rounded-full bg-primary text-primary-contrast shadow-lg hover:opacity-90 transition-opacity fab-container-right"
1474
1474
  >
1475
1475
  <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" aria-hidden="true">
1476
- <rect x="3" y="4" width="18" height="14" rx="2" />
1477
- <path d="M8 21h8" />
1476
+ <rect x="3" y="5" width="18" height="14" rx="1" />
1477
+ <path d="M7 10h10" />
1478
+ <path d="M7 14h7" />
1478
1479
  </svg>
1479
1480
  </button>
1480
1481
  )}
@@ -20,6 +20,9 @@ export interface DocViewerProps {
20
20
  selectedChunkId?: string | null;
21
21
  onSelectChunk?: (chunkId: string | null) => void; // null = cover selected
22
22
  onClose?: () => void; // present mode: close control
23
+ /** Present mode only: when set, the toolbar shows a "Download PDF" link (the /present
24
+ * route passes the gated /api/document-pdf href when a PDF exists for this viewer). */
25
+ downloadHref?: string | null;
23
26
  // Optional pagination-state hook (present mode unaffected — the present route
24
27
  // never passes it). Fires, identity-guarded, whenever the internal useDocPages
25
28
  // output changes, so a host (the edit overlay) can reuse this single pass for
@@ -43,6 +46,7 @@ export function DocViewer({
43
46
  selectedChunkId,
44
47
  onSelectChunk,
45
48
  onClose,
49
+ downloadHref,
46
50
  onDocState,
47
51
  }: DocViewerProps) {
48
52
  const { chunks, pages, measuring, warningsByChunk } = useDocPages({ source, sections: doc.sections });
@@ -154,16 +158,28 @@ export function DocViewer({
154
158
  {mode === "present" ? (
155
159
  <div className="flex items-center justify-between border-b border-base-200 bg-base px-4 py-2">
156
160
  <span className="text-sm font-medium text-base-contrast">{source?.pageTitle ?? "Document"}</span>
157
- {onClose ? (
158
- <button
159
- type="button"
160
- aria-label="Close"
161
- onClick={onClose}
162
- className="rounded border border-base-200 px-3 py-1 text-xs font-medium text-base-contrast hover:bg-base-accent/30"
163
- >
164
- ✕
165
- </button>
166
- ) : null}
161
+ <div className="flex items-center gap-2">
162
+ {downloadHref ? (
163
+ <a
164
+ href={downloadHref}
165
+ download
166
+ aria-label="Download PDF"
167
+ className="rounded border border-base-200 px-3 py-1 text-xs font-medium text-base-contrast hover:bg-base-accent/30"
168
+ >
169
+ Download PDF
170
+ </a>
171
+ ) : null}
172
+ {onClose ? (
173
+ <button
174
+ type="button"
175
+ aria-label="Close"
176
+ onClick={onClose}
177
+ className="rounded border border-base-200 px-3 py-1 text-xs font-medium text-base-contrast hover:bg-base-accent/30"
178
+ >
179
+ ✕
180
+ </button>
181
+ ) : null}
182
+ </div>
167
183
  </div>
168
184
  ) : null}
169
185
  <div className="flex min-h-0 min-w-0 flex-1">
@@ -25,7 +25,7 @@ export type SectionMeta = z.infer<typeof SectionMetaSchema>;
25
25
  // add its first segment here (the test in Step 1 guards the known set). This is
26
26
  // the single source of truth for reserved slugs; the schema, uniquePageSlug, and
27
27
  // /api/save all import it.
28
- export const RESERVED_SLUGS = ["edit", "api", "login", "set-password", "404", "present"] as const;
28
+ export const RESERVED_SLUGS = ["edit", "api", "login", "set-password", "404", "present", "print"] as const;
29
29
 
30
30
  // Subset of RESERVED_SLUGS the index schema hard-rejects at parse time. Only
31
31
  // slugs reserved since before client sites existed may hard-fail here: parse-