@drawnagency/primitives 0.1.39 → 0.1.40

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 (31) hide show
  1. package/dist/{chunk-GQV2554Z.js → chunk-62OWSJ7V.js} +1 -1
  2. package/dist/{chunk-LW5EGJFM.js → chunk-A4RARGF2.js} +1 -0
  3. package/dist/{chunk-I6ZPOEK2.js → chunk-BU52OBPW.js} +1 -1
  4. package/dist/{chunk-TNHX35TE.js → chunk-VY67DS3O.js} +8 -0
  5. package/dist/components/primitives/MediaSettingsForms.d.ts +6 -2
  6. package/dist/components/primitives/MediaSettingsForms.d.ts.map +1 -1
  7. package/dist/components/primitives/ResolvedMedia.d.ts +2 -1
  8. package/dist/components/primitives/ResolvedMedia.d.ts.map +1 -1
  9. package/dist/components/shell/EditorShell.d.ts.map +1 -1
  10. package/dist/components/shell/MediaLibraryModal.d.ts.map +1 -1
  11. package/dist/components/shell/SiteSettingsDisplay.d.ts.map +1 -1
  12. package/dist/index.js +6 -4
  13. package/dist/lib/dexie.d.ts.map +1 -1
  14. package/dist/lib/dexie.js +1 -2
  15. package/dist/lib/index.js +2 -2
  16. package/dist/media/index.js +3 -1
  17. package/dist/media/utils.d.ts +1 -0
  18. package/dist/media/utils.d.ts.map +1 -1
  19. package/dist/schemas/index.js +2 -2
  20. package/dist/schemas/site-config.d.ts +1 -0
  21. package/dist/schemas/site-config.d.ts.map +1 -1
  22. package/package.json +1 -1
  23. package/src/components/primitives/MediaSettingsForms.tsx +25 -6
  24. package/src/components/primitives/ResolvedMedia.tsx +8 -1
  25. package/src/components/sections/MediaGrid/MediaGrid.tsx +3 -0
  26. package/src/components/shell/EditorShell.tsx +1 -0
  27. package/src/components/shell/MediaLibraryModal.tsx +2 -5
  28. package/src/components/shell/SiteSettingsDisplay.tsx +7 -0
  29. package/src/lib/dexie.ts +1 -2
  30. package/src/media/utils.ts +8 -0
  31. package/src/schemas/site-config.ts +1 -0
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  HexColorSchema
3
- } from "./chunk-LW5EGJFM.js";
3
+ } from "./chunk-A4RARGF2.js";
4
4
 
5
5
  // src/schemas/audience.ts
6
6
  import { z } from "zod";
@@ -180,6 +180,7 @@ var SiteConfigSchema = z3.object({
180
180
  darkMode: z3.enum(["light", "dark", "optional"]).default("light"),
181
181
  headingFont: z3.string().default("system-ui"),
182
182
  bodyFont: z3.string().default("system-ui"),
183
+ uppercaseHeadings: z3.boolean().default(true),
183
184
  googleFontsUrl: z3.string().refine((url) => url.startsWith("https://fonts.googleapis.com/"), "Must be a Google Fonts URL").nullable().default(null),
184
185
  media: MediaConfigSchema.default(MediaConfigSchema.parse({}))
185
186
  });
@@ -3,7 +3,7 @@ import {
3
3
  getAllSchemas,
4
4
  getSection,
5
5
  getSectionSchema
6
- } from "./chunk-LW5EGJFM.js";
6
+ } from "./chunk-A4RARGF2.js";
7
7
  import {
8
8
  safeNextPath
9
9
  } from "./chunk-S2L3BPLS.js";
@@ -44,6 +44,13 @@ function displayFilenameExt(mime) {
44
44
  const ext = MIME_TO_EXT[mime];
45
45
  return ext ? `.${ext}` : "";
46
46
  }
47
+ function displayFilename(originalName, mimeType) {
48
+ const ext = MIME_TO_EXT[mimeType];
49
+ if (!ext) return originalName;
50
+ const suffix = `.${ext}`;
51
+ if (originalName.endsWith(suffix)) return originalName;
52
+ return `${originalName}${suffix}`;
53
+ }
47
54
 
48
55
  // src/media/queue.ts
49
56
  var ProcessingQueue = class {
@@ -287,6 +294,7 @@ export {
287
294
  EXT_TO_MIME,
288
295
  mimeToExt,
289
296
  displayFilenameExt,
297
+ displayFilename,
290
298
  ProcessingQueue,
291
299
  resolveMedia,
292
300
  resolveManifestReferences,
@@ -1,18 +1,22 @@
1
- export declare function ImageSettingsForm({ border, objectFit, onChange, }: {
1
+ export declare function ImageSettingsForm({ border, objectFit, invertFrom: initialInvertFrom, onChange, }: {
2
2
  border?: boolean;
3
3
  objectFit?: "cover" | "contain";
4
+ invertFrom?: string;
4
5
  onChange: (update: {
5
6
  border?: boolean;
6
7
  objectFit?: "cover" | "contain";
8
+ invertFrom?: string;
7
9
  }) => void;
8
10
  }): import("react/jsx-runtime").JSX.Element;
9
- export declare function DoDontImageSettingsForm({ border, objectFit, doDont: initialDoDont, onChange, }: {
11
+ export declare function DoDontImageSettingsForm({ border, objectFit, invertFrom, doDont: initialDoDont, onChange, }: {
10
12
  border?: boolean;
11
13
  objectFit?: "cover" | "contain";
14
+ invertFrom?: string;
12
15
  doDont: "do" | "dont";
13
16
  onChange: (update: {
14
17
  border?: boolean;
15
18
  objectFit?: "cover" | "contain";
19
+ invertFrom?: string;
16
20
  doDont: "do" | "dont";
17
21
  }) => void;
18
22
  }): import("react/jsx-runtime").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"MediaSettingsForms.d.ts","sourceRoot":"","sources":["../../../src/components/primitives/MediaSettingsForms.tsx"],"names":[],"mappings":"AAMA,wBAAgB,iBAAiB,CAAC,EAChC,MAAM,EACN,SAAS,EACT,QAAQ,GACT,EAAE;IACD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAChC,QAAQ,EAAE,CAAC,MAAM,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;KAAE,KAAK,IAAI,CAAC;CACnF,2CA+BA;AAED,wBAAgB,uBAAuB,CAAC,EACtC,MAAM,EACN,SAAS,EACT,MAAM,EAAE,aAAa,EACrB,QAAQ,GACT,EAAE;IACD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAChC,MAAM,EAAE,IAAI,GAAG,MAAM,CAAC;IACtB,QAAQ,EAAE,CAAC,MAAM,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAAC,MAAM,EAAE,IAAI,GAAG,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CAC1G,2CAmDA"}
1
+ {"version":3,"file":"MediaSettingsForms.d.ts","sourceRoot":"","sources":["../../../src/components/primitives/MediaSettingsForms.tsx"],"names":[],"mappings":"AAMA,wBAAgB,iBAAiB,CAAC,EAChC,MAAM,EACN,SAAS,EACT,UAAU,EAAE,iBAAiB,EAC7B,QAAQ,GACT,EAAE;IACD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,CAAC,MAAM,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CACxG,2CA6CA;AAED,wBAAgB,uBAAuB,CAAC,EACtC,MAAM,EACN,SAAS,EACT,UAAU,EACV,MAAM,EAAE,aAAa,EACrB,QAAQ,GACT,EAAE;IACD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,IAAI,GAAG,MAAM,CAAC;IACtB,QAAQ,EAAE,CAAC,MAAM,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,IAAI,GAAG,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CAC/H,2CAoDA"}
@@ -5,7 +5,8 @@ interface ResolvedMediaProps {
5
5
  alt?: string;
6
6
  className?: string;
7
7
  imgClassName?: string;
8
+ invertFrom?: string;
8
9
  }
9
- export declare function ResolvedMedia({ imageId, src: propSrc, srcset: propSrcset, alt: propAlt, className, imgClassName, }: ResolvedMediaProps): import("react/jsx-runtime").JSX.Element;
10
+ export declare function ResolvedMedia({ imageId, src: propSrc, srcset: propSrcset, alt: propAlt, className, imgClassName, invertFrom, }: ResolvedMediaProps): import("react/jsx-runtime").JSX.Element;
10
11
  export {};
11
12
  //# sourceMappingURL=ResolvedMedia.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ResolvedMedia.d.ts","sourceRoot":"","sources":["../../../src/components/primitives/ResolvedMedia.tsx"],"names":[],"mappings":"AAIA,UAAU,kBAAkB;IAC1B,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EACP,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,UAAU,EAClB,GAAG,EAAE,OAAO,EACZ,SAAS,EACT,YAAY,GACb,EAAE,kBAAkB,2CA0BpB"}
1
+ {"version":3,"file":"ResolvedMedia.d.ts","sourceRoot":"","sources":["../../../src/components/primitives/ResolvedMedia.tsx"],"names":[],"mappings":"AAIA,UAAU,kBAAkB;IAC1B,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EACP,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,UAAU,EAClB,GAAG,EAAE,OAAO,EACZ,SAAS,EACT,YAAY,EACZ,UAAU,GACX,EAAE,kBAAkB,2CA+BpB"}
@@ -1 +1 @@
1
- {"version":3,"file":"EditorShell.d.ts","sourceRoot":"","sources":["../../../src/components/shell/EditorShell.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAqDjD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAQxD,UAAU,KAAK;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,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;CACjE;AAED,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAClC,OAAO,EACP,MAAM,EACN,SAAS,EAAE,gBAAgB,EAC3B,YAAY,EACZ,WAAW,GACZ,EAAE,KAAK,2CAqoBP"}
1
+ {"version":3,"file":"EditorShell.d.ts","sourceRoot":"","sources":["../../../src/components/shell/EditorShell.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAqDjD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAQxD,UAAU,KAAK;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,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;CACjE;AAED,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAClC,OAAO,EACP,MAAM,EACN,SAAS,EAAE,gBAAgB,EAC3B,YAAY,EACZ,WAAW,GACZ,EAAE,KAAK,2CAsoBP"}
@@ -1 +1 @@
1
- {"version":3,"file":"MediaLibraryModal.d.ts","sourceRoot":"","sources":["../../../src/components/shell/MediaLibraryModal.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAa,MAAM,mBAAmB,CAAC;AAG9D,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC1B,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,QAAQ,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IAClC,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAClC,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AA+ED,wBAAgB,iBAAiB,CAAC,EAChC,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,iBAAiB,EACjB,WAAgB,EAChB,WAAW,GACZ,EAAE,sBAAsB,2CAuQxB"}
1
+ {"version":3,"file":"MediaLibraryModal.d.ts","sourceRoot":"","sources":["../../../src/components/shell/MediaLibraryModal.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAa,MAAM,mBAAmB,CAAC;AAG9D,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC1B,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,QAAQ,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IAClC,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAClC,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AA4ED,wBAAgB,iBAAiB,CAAC,EAChC,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,iBAAiB,EACjB,WAAgB,EAChB,WAAW,GACZ,EAAE,sBAAsB,2CAuQxB"}
@@ -1 +1 @@
1
- {"version":3,"file":"SiteSettingsDisplay.d.ts","sourceRoot":"","sources":["../../../src/components/shell/SiteSettingsDisplay.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5D,UAAU,KAAK;IACb,UAAU,EAAE,UAAU,CAAC;IACvB,QAAQ,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;CACxC;AAQD,wBAAgB,mBAAmB,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,KAAK,2CAyDlE"}
1
+ {"version":3,"file":"SiteSettingsDisplay.d.ts","sourceRoot":"","sources":["../../../src/components/shell/SiteSettingsDisplay.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5D,UAAU,KAAK;IACb,UAAU,EAAE,UAAU,CAAC;IACvB,QAAQ,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;CACxC;AAQD,wBAAgB,mBAAmB,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,KAAK,2CA+DlE"}
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  AudienceNameSchema,
4
4
  MediaGridOptionsSchema,
5
5
  slugifyAudienceName
6
- } from "./chunk-GQV2554Z.js";
6
+ } from "./chunk-62OWSJ7V.js";
7
7
  import {
8
8
  AudienceSchema,
9
9
  RoleSchema,
@@ -30,7 +30,7 @@ import {
30
30
  safeRedirect,
31
31
  sanitizeHtml,
32
32
  toSectionId
33
- } from "./chunk-I6ZPOEK2.js";
33
+ } from "./chunk-BU52OBPW.js";
34
34
  import {
35
35
  ColorItemSchema,
36
36
  ColorSpaceSchema,
@@ -51,7 +51,7 @@ import {
51
51
  getSectionSchema,
52
52
  registerSchema,
53
53
  registerSection
54
- } from "./chunk-LW5EGJFM.js";
54
+ } from "./chunk-A4RARGF2.js";
55
55
  import {
56
56
  AUDIENCE_COOKIE,
57
57
  LastOwnerError,
@@ -73,6 +73,7 @@ import {
73
73
  EXT_TO_MIME,
74
74
  MIME_TO_EXT,
75
75
  ProcessingQueue,
76
+ displayFilename,
76
77
  displayFilenameExt,
77
78
  generateVideoPoster,
78
79
  getMediaProvider,
@@ -82,7 +83,7 @@ import {
82
83
  resolveMedia,
83
84
  sanitizeMediaName,
84
85
  setMediaProvider
85
- } from "./chunk-TNHX35TE.js";
86
+ } from "./chunk-VY67DS3O.js";
86
87
  import {
87
88
  ImageManifestSchema,
88
89
  MediaConfigSchema,
@@ -125,6 +126,7 @@ export {
125
126
  darkModeEvent,
126
127
  defineSection,
127
128
  deriveContrast,
129
+ displayFilename,
128
130
  displayFilenameExt,
129
131
  editModeEvent,
130
132
  ensureSanitizer,
@@ -1 +1 @@
1
- {"version":3,"file":"dexie.d.ts","sourceRoot":"","sources":["../../src/lib/dexie.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dexie.d.ts","sourceRoot":"","sources":["../../src/lib/dexie.ts"],"names":[],"mappings":"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"}
package/dist/lib/dexie.js CHANGED
@@ -106,14 +106,13 @@ async function restoreLocalChanges() {
106
106
  }
107
107
  async function discardLocalChanges() {
108
108
  const database = getDb();
109
- await database.transaction("rw", [database.sections, database.siteIndex, database.meta, database.siteConfig, database.pendingMedia, database.pendingMediaDeletions, database.mediaManifest], async () => {
109
+ await database.transaction("rw", [database.sections, database.siteIndex, database.meta, database.siteConfig, database.pendingMedia, database.pendingMediaDeletions], async () => {
110
110
  await database.sections.clear();
111
111
  await database.siteIndex.clear();
112
112
  await database.meta.clear();
113
113
  await database.siteConfig.clear();
114
114
  await database.pendingMedia.clear();
115
115
  await database.pendingMediaDeletions.clear();
116
- await database.mediaManifest.clear();
117
116
  });
118
117
  }
119
118
  async function persistSiteIndex(index, deletedSections = []) {
package/dist/lib/index.js CHANGED
@@ -18,7 +18,7 @@ import {
18
18
  safeRedirect,
19
19
  sanitizeHtml,
20
20
  toSectionId
21
- } from "../chunk-I6ZPOEK2.js";
21
+ } from "../chunk-BU52OBPW.js";
22
22
  import {
23
23
  clearRegistry,
24
24
  createRegistry,
@@ -29,7 +29,7 @@ import {
29
29
  getSection,
30
30
  registerSchema,
31
31
  registerSection
32
- } from "../chunk-LW5EGJFM.js";
32
+ } from "../chunk-A4RARGF2.js";
33
33
  import "../chunk-S2L3BPLS.js";
34
34
  import {
35
35
  env
@@ -2,6 +2,7 @@ import {
2
2
  EXT_TO_MIME,
3
3
  MIME_TO_EXT,
4
4
  ProcessingQueue,
5
+ displayFilename,
5
6
  displayFilenameExt,
6
7
  generateVideoPoster,
7
8
  getMediaProvider,
@@ -11,7 +12,7 @@ import {
11
12
  resolveMedia,
12
13
  sanitizeMediaName,
13
14
  setMediaProvider
14
- } from "../chunk-TNHX35TE.js";
15
+ } from "../chunk-VY67DS3O.js";
15
16
  import {
16
17
  ImageManifestSchema,
17
18
  MediaConfigSchema,
@@ -26,6 +27,7 @@ export {
26
27
  MediaItemSchema,
27
28
  ProcessingQueue,
28
29
  VariantSchema,
30
+ displayFilename,
29
31
  displayFilenameExt,
30
32
  generateVideoPoster,
31
33
  getMediaProvider,
@@ -4,4 +4,5 @@ export declare const MIME_TO_EXT: Record<string, string>;
4
4
  export declare const EXT_TO_MIME: Record<string, string>;
5
5
  export declare function mimeToExt(mime: string): string;
6
6
  export declare function displayFilenameExt(mime: string): string;
7
+ export declare function displayFilename(originalName: string, mimeType: string): string;
7
8
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/media/utils.ts"],"names":[],"mappings":"AAAA,wBAAsB,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAqBzE;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAI9C,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAK9C,CAAC;AAEF,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGvD"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/media/utils.ts"],"names":[],"mappings":"AAAA,wBAAsB,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAqBzE;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAI9C,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAK9C,CAAC;AAEF,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGvD;AAED,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAM9E"}
@@ -3,7 +3,7 @@ import {
3
3
  AudienceNameSchema,
4
4
  MediaGridOptionsSchema,
5
5
  slugifyAudienceName
6
- } from "../chunk-GQV2554Z.js";
6
+ } from "../chunk-62OWSJ7V.js";
7
7
  import {
8
8
  AudienceSchema,
9
9
  RoleSchema,
@@ -21,7 +21,7 @@ import {
21
21
  TextLineSchema,
22
22
  getSectionContentSchema,
23
23
  getSectionSchema
24
- } from "../chunk-LW5EGJFM.js";
24
+ } from "../chunk-A4RARGF2.js";
25
25
  import {
26
26
  ImageManifestSchema,
27
27
  MediaConfigSchema,
@@ -37,6 +37,7 @@ export declare const SiteConfigSchema: z.ZodObject<{
37
37
  }>>;
38
38
  headingFont: z.ZodDefault<z.ZodString>;
39
39
  bodyFont: z.ZodDefault<z.ZodString>;
40
+ uppercaseHeadings: z.ZodDefault<z.ZodBoolean>;
40
41
  googleFontsUrl: z.ZodDefault<z.ZodNullable<z.ZodString>>;
41
42
  media: z.ZodDefault<z.ZodObject<{
42
43
  sizes: z.ZodDefault<z.ZodArray<z.ZodNumber>>;
@@ -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,eAAO,MAAM,iBAAiB;;;;;;;;;iBAI5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,eAAO,MAAM,WAAW;;;;;;;;;;;;;;iBAYvB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEpD,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;iBAY3B,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;AAQxB,eAAO,MAAM,iBAAiB;;;;;;;;;iBAI5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,eAAO,MAAM,WAAW;;;;;;;;;;;;;;iBAYvB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEpD,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;iBAa3B,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.39",
3
+ "version": "0.1.40",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  "./package.json": "./package.json",
@@ -7,14 +7,17 @@ import { Select } from "../shared/Select";
7
7
  export function ImageSettingsForm({
8
8
  border,
9
9
  objectFit,
10
+ invertFrom: initialInvertFrom,
10
11
  onChange,
11
12
  }: {
12
13
  border?: boolean;
13
14
  objectFit?: "cover" | "contain";
14
- onChange: (update: { border?: boolean; objectFit?: "cover" | "contain" }) => void;
15
+ invertFrom?: string;
16
+ onChange: (update: { border?: boolean; objectFit?: "cover" | "contain"; invertFrom?: string }) => void;
15
17
  }) {
16
18
  const [itemBorder, setItemBorder] = useState(border);
17
19
  const [fit, setFit] = useState(objectFit);
20
+ const [invertFrom, setInvertFrom] = useState(initialInvertFrom ?? "");
18
21
 
19
22
  return (
20
23
  <div className="space-y-4">
@@ -24,7 +27,7 @@ export function ImageSettingsForm({
24
27
  onChange={(v) => {
25
28
  const val = (v || undefined) as "cover" | "contain" | undefined;
26
29
  setFit(val);
27
- onChange({ border: itemBorder, objectFit: val });
30
+ onChange({ border: itemBorder, objectFit: val, invertFrom: invertFrom || undefined });
28
31
  }}
29
32
  options={[
30
33
  { value: "", label: "Default (inherit from grid)" },
@@ -32,12 +35,25 @@ export function ImageSettingsForm({
32
35
  { value: "cover", label: "Crop to fill" },
33
36
  ]}
34
37
  />
38
+ <Select
39
+ label="Invert colors"
40
+ value={invertFrom}
41
+ onChange={(v) => {
42
+ setInvertFrom(v);
43
+ onChange({ border: itemBorder, objectFit: fit, invertFrom: v || undefined });
44
+ }}
45
+ options={[
46
+ { value: "", label: "None" },
47
+ { value: "light", label: "Invert on light theme" },
48
+ { value: "dark", label: "Invert on dark theme" },
49
+ ]}
50
+ />
35
51
  <Checkbox
36
52
  checked={itemBorder ?? false}
37
53
  onChange={(v) => {
38
54
  const val = v || undefined;
39
55
  setItemBorder(val);
40
- onChange({ border: val, objectFit: fit });
56
+ onChange({ border: val, objectFit: fit, invertFrom: invertFrom || undefined });
41
57
  }}
42
58
  label="Override border settings"
43
59
  />
@@ -48,18 +64,20 @@ export function ImageSettingsForm({
48
64
  export function DoDontImageSettingsForm({
49
65
  border,
50
66
  objectFit,
67
+ invertFrom,
51
68
  doDont: initialDoDont,
52
69
  onChange,
53
70
  }: {
54
71
  border?: boolean;
55
72
  objectFit?: "cover" | "contain";
73
+ invertFrom?: string;
56
74
  doDont: "do" | "dont";
57
- onChange: (update: { border?: boolean; objectFit?: "cover" | "contain"; doDont: "do" | "dont" }) => void;
75
+ onChange: (update: { border?: boolean; objectFit?: "cover" | "contain"; invertFrom?: string; doDont: "do" | "dont" }) => void;
58
76
  }) {
59
77
  const [doDont, setDoDont] = useState<"do" | "dont">(initialDoDont);
60
- const latestRef = useRef<{ border?: boolean; objectFit?: "cover" | "contain" }>({ border, objectFit });
78
+ const latestRef = useRef<{ border?: boolean; objectFit?: "cover" | "contain"; invertFrom?: string }>({ border, objectFit, invertFrom });
61
79
 
62
- const handleBaseChange = (updated: { border?: boolean; objectFit?: "cover" | "contain" }) => {
80
+ const handleBaseChange = (updated: { border?: boolean; objectFit?: "cover" | "contain"; invertFrom?: string }) => {
63
81
  latestRef.current = updated;
64
82
  onChange({ ...updated, doDont });
65
83
  };
@@ -69,6 +87,7 @@ export function DoDontImageSettingsForm({
69
87
  <ImageSettingsForm
70
88
  border={border}
71
89
  objectFit={objectFit}
90
+ invertFrom={invertFrom}
72
91
  onChange={handleBaseChange}
73
92
  />
74
93
  <hr className="border-base-200" />
@@ -9,6 +9,7 @@ interface ResolvedMediaProps {
9
9
  alt?: string;
10
10
  className?: string;
11
11
  imgClassName?: string;
12
+ invertFrom?: string;
12
13
  }
13
14
 
14
15
  export function ResolvedMedia({
@@ -18,6 +19,7 @@ export function ResolvedMedia({
18
19
  alt: propAlt,
19
20
  className,
20
21
  imgClassName,
22
+ invertFrom,
21
23
  }: ResolvedMediaProps) {
22
24
  const resolved = useResolvedMedia(imageId);
23
25
  const src = propSrc || resolved.src;
@@ -26,7 +28,12 @@ export function ResolvedMedia({
26
28
  const alt = propAlt ?? resolved.alt;
27
29
  const kind = resolved.kind;
28
30
 
29
- const mediaClass = cn("h-full w-full", imgClassName);
31
+ const invertClass =
32
+ invertFrom === "light" ? "invert dark:invert-0" :
33
+ invertFrom === "dark" ? "dark:invert" :
34
+ undefined;
35
+
36
+ const mediaClass = cn("h-full w-full", imgClassName, invertClass);
30
37
 
31
38
  return (
32
39
  <div className={className}>
@@ -77,6 +77,7 @@ function MediaGridEditable({ media, columns, square, border, crop, showCaptions,
77
77
  <DoDontImageSettingsForm
78
78
  border={item.border}
79
79
  objectFit={item.objectFit}
80
+ invertFrom={item.invertFrom}
80
81
  doDont={item.doDont}
81
82
  onChange={(updated) => {
82
83
  const newMedia = media.map((m, i) => i === index ? { ...m, ...updated } : m);
@@ -90,6 +91,7 @@ function MediaGridEditable({ media, columns, square, border, crop, showCaptions,
90
91
  <ImageSettingsForm
91
92
  border={item.border}
92
93
  objectFit={item.objectFit}
94
+ invertFrom={item.invertFrom}
93
95
  onChange={(updated) => {
94
96
  const newMedia = media.map((m, i) => i === index ? { ...m, ...updated } : m);
95
97
  onChange({ type: sectionType, content: { columns, media: newMedia }, ...opts } as SectionContent);
@@ -173,6 +175,7 @@ function MediaGridItem({
173
175
  alt={itemAny.alt as string | undefined}
174
176
  className="h-full w-full"
175
177
  imgClassName={fitClass}
178
+ invertFrom={item.invertFrom}
176
179
  />
177
180
  );
178
181
 
@@ -190,6 +190,7 @@ export default function EditorShell({
190
190
  root.style.setProperty("--color-primary-contrast", config.primaryContrast);
191
191
  root.style.setProperty("--font-heading", `${config.headingFont}, system-ui, sans-serif`);
192
192
  root.style.setProperty("--font-body", `${config.bodyFont}, system-ui, sans-serif`);
193
+ root.style.setProperty("--heading-text-transform", config.uppercaseHeadings ? "uppercase" : "none");
193
194
 
194
195
  if (config.googleFontsUrl) {
195
196
  if (fontLinkRef.current?.href !== config.googleFontsUrl) {
@@ -4,7 +4,7 @@ import { cn } from "../../lib/cn";
4
4
  import { Button } from "../shared/Button";
5
5
  import { Select } from "../shared/Select";
6
6
  import type { MediaItem, MediaKind } from "../../media/types";
7
- import { displayFilenameExt, mimeToExt } from "../../media/utils";
7
+ import { displayFilename, mimeToExt } from "../../media/utils";
8
8
 
9
9
  export interface MediaLibraryModalProps {
10
10
  mode: "select" | "manage";
@@ -39,9 +39,6 @@ function thumbnailSrc(item: MediaItem, localUrls: Record<string, string>): strin
39
39
  return `/api/media/${item.id}/poster.webp`;
40
40
  }
41
41
 
42
- function displayFilename(item: MediaItem): string {
43
- return `${item.originalName}${displayFilenameExt(item.mimeType)}`;
44
- }
45
42
 
46
43
  function UploadZone({ onUpload }: { onUpload: (files: File[]) => void }) {
47
44
  const [dragging, setDragging] = useState(false);
@@ -342,7 +339,7 @@ export function MediaLibraryModal({
342
339
  {/* Filename overlay — bottom, visible on hover */}
343
340
  <div className="absolute inset-x-0 bottom-0 bg-gradient-to-t from-black/60 to-transparent px-2 pb-1.5 pt-4 opacity-0 transition-opacity group-hover:opacity-100">
344
341
  <p className="truncate text-[11px] text-white">
345
- {displayFilename(item)}
342
+ {displayFilename(item.originalName, item.mimeType)}
346
343
  </p>
347
344
  </div>
348
345
  </div>
@@ -1,3 +1,4 @@
1
+ import { Checkbox } from "../shared/Checkbox";
1
2
  import { ColorPicker } from "../shared/ColorPicker";
2
3
  import { FontPicker } from "../shared/FontPicker";
3
4
  import { Input } from "../shared/Input";
@@ -68,6 +69,12 @@ export function SiteSettingsDisplay({ siteConfig, onChange }: Props) {
68
69
  onChange={(family) => handleFontChange("headingFont", family)}
69
70
  />
70
71
 
72
+ <Checkbox
73
+ checked={siteConfig.uppercaseHeadings}
74
+ onChange={(v) => update({ uppercaseHeadings: v })}
75
+ label="Uppercase headings"
76
+ />
77
+
71
78
  <FontPicker
72
79
  label="Body font"
73
80
  value={siteConfig.bodyFont}
package/src/lib/dexie.ts CHANGED
@@ -184,14 +184,13 @@ export async function restoreLocalChanges(): Promise<{
184
184
 
185
185
  export async function discardLocalChanges(): Promise<void> {
186
186
  const database = getDb();
187
- await database.transaction("rw", [database.sections, database.siteIndex, database.meta, database.siteConfig, database.pendingMedia, database.pendingMediaDeletions, database.mediaManifest], async () => {
187
+ await database.transaction("rw", [database.sections, database.siteIndex, database.meta, database.siteConfig, database.pendingMedia, database.pendingMediaDeletions], async () => {
188
188
  await database.sections.clear();
189
189
  await database.siteIndex.clear();
190
190
  await database.meta.clear();
191
191
  await database.siteConfig.clear();
192
192
  await database.pendingMedia.clear();
193
193
  await database.pendingMediaDeletions.clear();
194
- await database.mediaManifest.clear();
195
194
  });
196
195
  }
197
196
 
@@ -46,3 +46,11 @@ export function displayFilenameExt(mime: string): string {
46
46
  const ext = MIME_TO_EXT[mime];
47
47
  return ext ? `.${ext}` : "";
48
48
  }
49
+
50
+ export function displayFilename(originalName: string, mimeType: string): string {
51
+ const ext = MIME_TO_EXT[mimeType];
52
+ if (!ext) return originalName;
53
+ const suffix = `.${ext}`;
54
+ if (originalName.endsWith(suffix)) return originalName;
55
+ return `${originalName}${suffix}`;
56
+ }
@@ -37,6 +37,7 @@ export const SiteConfigSchema = z.object({
37
37
  darkMode: z.enum(["light", "dark", "optional"]).default("light"),
38
38
  headingFont: z.string().default("system-ui"),
39
39
  bodyFont: z.string().default("system-ui"),
40
+ uppercaseHeadings: z.boolean().default(true),
40
41
  googleFontsUrl: z.string()
41
42
  .refine(url => url.startsWith("https://fonts.googleapis.com/"), "Must be a Google Fonts URL")
42
43
  .nullable()