@drawnagency/primitives 0.1.77 → 0.1.79

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 (78) hide show
  1. package/dist/{chunk-B2DLHZKC.js → chunk-2DDWWTRX.js} +1 -1
  2. package/dist/{chunk-S55OZ7F2.js → chunk-3LNKOLZP.js} +4 -0
  3. package/dist/{chunk-63BQQNZO.js → chunk-4XXLH5CL.js} +5 -5
  4. package/dist/{chunk-YP7IHMC3.js → chunk-DR22HM44.js} +1 -1
  5. package/dist/{chunk-IFHRHV7S.js → chunk-EMGLZQCM.js} +1 -1
  6. package/dist/{chunk-RO4E5UJI.js → chunk-FRTJNS5F.js} +7 -7
  7. package/dist/{chunk-SFKYUKVN.js → chunk-QB5Q23G2.js} +1 -1
  8. package/dist/{chunk-SWIHUIFT.js → chunk-RSITF24B.js} +20 -2
  9. package/dist/{chunk-UUCOJL7O.js → chunk-RWMSDDQM.js} +4 -4
  10. package/dist/{chunk-XFDEUK37.js → chunk-UNUJPLZV.js} +1 -1
  11. package/dist/components/editor/index.js +4 -4
  12. package/dist/components/primitives/index.js +5 -5
  13. package/dist/components/sections/brand-guide.js +5 -5
  14. package/dist/components/sections/register-schemas.js +8 -8
  15. package/dist/components/sections/register.js +8 -8
  16. package/dist/components/shell/EditorShell.d.ts.map +1 -1
  17. package/dist/components/shell/MediaBreadcrumb.d.ts +10 -0
  18. package/dist/components/shell/MediaBreadcrumb.d.ts.map +1 -0
  19. package/dist/components/shell/MediaFolderTile.d.ts +15 -0
  20. package/dist/components/shell/MediaFolderTile.d.ts.map +1 -0
  21. package/dist/components/shell/MediaFolderTree.d.ts +20 -0
  22. package/dist/components/shell/MediaFolderTree.d.ts.map +1 -0
  23. package/dist/components/shell/MediaLibraryModal.d.ts +15 -3
  24. package/dist/components/shell/MediaLibraryModal.d.ts.map +1 -1
  25. package/dist/components/shell/MoveToFolderDialog.d.ts +16 -0
  26. package/dist/components/shell/MoveToFolderDialog.d.ts.map +1 -0
  27. package/dist/components/shell/SiteSettingsDisplay.d.ts.map +1 -1
  28. package/dist/hooks/useEditorPublish.d.ts.map +1 -1
  29. package/dist/hooks/useMediaFolderDnd.d.ts +27 -0
  30. package/dist/hooks/useMediaFolderDnd.d.ts.map +1 -0
  31. package/dist/hooks/useMediaPipeline.d.ts +14 -2
  32. package/dist/hooks/useMediaPipeline.d.ts.map +1 -1
  33. package/dist/index.js +8 -4
  34. package/dist/lib/corner-radius.d.ts +6 -0
  35. package/dist/lib/corner-radius.d.ts.map +1 -0
  36. package/dist/lib/index.js +2 -2
  37. package/dist/lib/media-dnd.d.ts +26 -0
  38. package/dist/lib/media-dnd.d.ts.map +1 -0
  39. package/dist/lib/media-folders.d.ts +59 -0
  40. package/dist/lib/media-folders.d.ts.map +1 -0
  41. package/dist/media/folder-drop.d.ts +22 -0
  42. package/dist/media/folder-drop.d.ts.map +1 -0
  43. package/dist/media/index.js +6 -2
  44. package/dist/media/types.d.ts +1 -1
  45. package/dist/media/types.d.ts.map +1 -1
  46. package/dist/media/utils.d.ts +7 -0
  47. package/dist/media/utils.d.ts.map +1 -1
  48. package/dist/schemas/index.js +4 -2
  49. package/dist/schemas/media.d.ts +11 -0
  50. package/dist/schemas/media.d.ts.map +1 -1
  51. package/dist/schemas/site-config.d.ts +6 -0
  52. package/dist/schemas/site-config.d.ts.map +1 -1
  53. package/package.json +1 -1
  54. package/src/components/brandguide/Colors.tsx +2 -2
  55. package/src/components/chat/ChatPanel.tsx +8 -8
  56. package/src/components/primitives/ResolvedMedia.tsx +1 -1
  57. package/src/components/sections/Button/CTAButton.tsx +1 -1
  58. package/src/components/sections/Media/MediaBlock.tsx +1 -1
  59. package/src/components/shared/Navigation.tsx +5 -5
  60. package/src/components/shell/EditorModal.tsx +7 -7
  61. package/src/components/shell/EditorShell.tsx +23 -4
  62. package/src/components/shell/MediaBreadcrumb.tsx +77 -0
  63. package/src/components/shell/MediaFolderTile.tsx +141 -0
  64. package/src/components/shell/MediaFolderTree.tsx +127 -0
  65. package/src/components/shell/MediaLibraryModal.tsx +611 -229
  66. package/src/components/shell/MoveToFolderDialog.tsx +78 -0
  67. package/src/components/shell/SiteSettingsDisplay.tsx +19 -0
  68. package/src/hooks/useEditorPublish.ts +14 -11
  69. package/src/hooks/useMediaFolderDnd.ts +129 -0
  70. package/src/hooks/useMediaPipeline.ts +162 -6
  71. package/src/lib/corner-radius.ts +22 -0
  72. package/src/lib/media-dnd.ts +62 -0
  73. package/src/lib/media-folders.ts +232 -0
  74. package/src/media/folder-drop.ts +62 -0
  75. package/src/media/types.ts +2 -0
  76. package/src/media/utils.ts +10 -0
  77. package/src/schemas/media.ts +13 -0
  78. package/src/schemas/site-config.ts +4 -0
@@ -1 +1 @@
1
- {"version":3,"file":"useMediaPipeline.d.ts","sourceRoot":"","sources":["../../src/hooks/useMediaPipeline.ts"],"names":[],"mappings":"AAEA,OAAO,EAAmB,KAAK,SAAS,EAAmB,MAAM,gBAAgB,CAAC;AAClF,OAAO,KAAK,EAAE,aAAa,EAAiC,MAAM,gBAAgB,CAAC;AACnF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,yCAAyC,CAAC;AAUxF,UAAU,qBAAqB;IAC7B,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAC9B,aAAa,EAAE,aAAa,CAAC;IAC7B,gBAAgB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC,CAAC;IACtE,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;IACnE,oBAAoB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;IACpE,kBAAkB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACtE,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;IAIvE,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3C;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,QAAQ,EACR,WAAW,EACX,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,GACd,EAAE,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+BA0R8B,IAAI,EAAE;6BA4CR,MAAM,EAAE;+BA+CZ,MAAM,OAAO,MAAM;;;wBA2B1B,IAAI,eAAe,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI;EA8EpF"}
1
+ {"version":3,"file":"useMediaPipeline.d.ts","sourceRoot":"","sources":["../../src/hooks/useMediaPipeline.ts"],"names":[],"mappings":"AAEA,OAAO,EAAmB,KAAK,SAAS,EAAmB,MAAM,gBAAgB,CAAC;AAClF,OAAO,KAAK,EAAE,aAAa,EAAiC,MAAM,gBAAgB,CAAC;AACnF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,yCAAyC,CAAC;AAexF,UAAU,qBAAqB;IAC7B,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAC9B,aAAa,EAAE,aAAa,CAAC;IAC7B,gBAAgB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC,CAAC;IACtE,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;IACnE,oBAAoB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;IACpE,kBAAkB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACtE,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;IAIvE,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAG1C,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5C;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,QAAQ,EACR,WAAW,EACX,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,EACb,cAAc,GACf,EAAE,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+BAkS8B,IAAI,EAAE,mBAAkB,MAAM,GAAG,IAAI;6BAyDvC,MAAM,EAAE;+BA+CZ,MAAM,OAAO,MAAM;+BAiBnB,MAAM,YAAY,MAAM,GAAG,IAAI,KAAG,MAAM;6BAW1C,MAAM,QAAQ,MAAM;2BAWtB,MAAM,YAAY,MAAM,GAAG,IAAI;6BA4BvB,MAAM,YAAY,MAAM,GAAG,QAAQ;2BAd3C,MAAM,EAAE,YAAY,MAAM,GAAG,IAAI;kCA4DhE;QAAE,IAAI,EAAE,IAAI,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,EAAE,mBAC9B,MAAM,GAAG,IAAI;;;wBAiCO,IAAI,eAAe,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI;EAoFpF"}
package/dist/index.js CHANGED
@@ -32,6 +32,7 @@ import {
32
32
  ProcessingQueue,
33
33
  displayFilename,
34
34
  displayFilenameExt,
35
+ displayName,
35
36
  formatFileSize,
36
37
  generateVideoPoster,
37
38
  getMediaProvider,
@@ -42,13 +43,13 @@ import {
42
43
  resolveMedia,
43
44
  sanitizeMediaName,
44
45
  setMediaProvider
45
- } from "./chunk-S55OZ7F2.js";
46
+ } from "./chunk-3LNKOLZP.js";
46
47
  import {
47
48
  AudienceColorSchema,
48
49
  AudienceNameSchema,
49
50
  MediaGridOptionsSchema,
50
51
  slugifyAudienceName
51
- } from "./chunk-SFKYUKVN.js";
52
+ } from "./chunk-QB5Q23G2.js";
52
53
  import {
53
54
  AudienceSchema,
54
55
  RoleSchema,
@@ -70,7 +71,7 @@ import {
70
71
  loadStaticSiteContent,
71
72
  mergeSiteContent,
72
73
  safeRedirect
73
- } from "./chunk-XFDEUK37.js";
74
+ } from "./chunk-UNUJPLZV.js";
74
75
  import {
75
76
  createEvent,
76
77
  darkModeEvent,
@@ -111,6 +112,7 @@ import {
111
112
  ImageManifestSchema,
112
113
  IndexSchema,
113
114
  MediaConfigSchema,
115
+ MediaFolderSchema,
114
116
  MediaItemSchema,
115
117
  MediaReferenceSchema,
116
118
  PageSchema,
@@ -122,7 +124,7 @@ import {
122
124
  TextLineSchema,
123
125
  VariantSchema,
124
126
  normalizeSiteIndex
125
- } from "./chunk-SWIHUIFT.js";
127
+ } from "./chunk-RSITF24B.js";
126
128
  import {
127
129
  clearRegistry,
128
130
  createRegistry,
@@ -173,6 +175,7 @@ export {
173
175
  LinkValueSchema,
174
176
  MIME_TO_EXT,
175
177
  MediaConfigSchema,
178
+ MediaFolderSchema,
176
179
  MediaGridOptionsSchema,
177
180
  MediaItemSchema,
178
181
  MediaReferenceSchema,
@@ -208,6 +211,7 @@ export {
208
211
  deriveUiCapabilities,
209
212
  displayFilename,
210
213
  displayFilenameExt,
214
+ displayName,
211
215
  editModeEvent,
212
216
  ensureSanitizer,
213
217
  env,
@@ -0,0 +1,6 @@
1
+ export declare const CORNER_RADIUS_OPTIONS: readonly ["none", "small", "medium", "large"];
2
+ export type CornerRadius = (typeof CORNER_RADIUS_OPTIONS)[number];
3
+ export declare const CORNER_RADIUS_VALUES: Record<CornerRadius, string>;
4
+ /** CSS length for `--radius-outer`; unknown/missing values fall back to medium. */
5
+ export declare function cornerRadiusValue(radius?: string | null): string;
6
+ //# sourceMappingURL=corner-radius.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"corner-radius.d.ts","sourceRoot":"","sources":["../../src/lib/corner-radius.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,qBAAqB,+CAAgD,CAAC;AAEnF,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAIlE,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAK7D,CAAC;AAEF,mFAAmF;AACnF,wBAAgB,iBAAiB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAEhE"}
package/dist/lib/index.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  loadStaticSiteContent,
8
8
  mergeSiteContent,
9
9
  safeRedirect
10
- } from "../chunk-XFDEUK37.js";
10
+ } from "../chunk-UNUJPLZV.js";
11
11
  import {
12
12
  createEvent,
13
13
  darkModeEvent,
@@ -33,7 +33,7 @@ import {
33
33
  audiencePasses
34
34
  } from "../chunk-4YEOTFVU.js";
35
35
  import "../chunk-TZQPOR5A.js";
36
- import "../chunk-SWIHUIFT.js";
36
+ import "../chunk-RSITF24B.js";
37
37
  import {
38
38
  clearRegistry,
39
39
  createRegistry,
@@ -0,0 +1,26 @@
1
+ import type { MediaFolder, MediaItem } from "../media/types";
2
+ export interface MediaDragData {
3
+ dragType: "media-item";
4
+ mediaIds: string[];
5
+ [key: string | symbol]: unknown;
6
+ }
7
+ export interface MediaFolderDragData {
8
+ dragType: "media-folder";
9
+ folderId: string;
10
+ [key: string | symbol]: unknown;
11
+ }
12
+ export interface MediaFolderDropData {
13
+ dropType: "media-folder";
14
+ targetFolderId: string | null;
15
+ [key: string | symbol]: unknown;
16
+ }
17
+ export declare function buildMediaDragData(mediaIds: string[]): MediaDragData;
18
+ export declare function buildFolderDragData(folderId: string): MediaFolderDragData;
19
+ export declare function buildFolderDropData(targetFolderId: string | null): MediaFolderDropData;
20
+ export declare function isMediaDragData(d: Record<string | symbol, unknown>): d is MediaDragData;
21
+ export declare function isFolderDragData(d: Record<string | symbol, unknown>): d is MediaFolderDragData;
22
+ /** True when at least one dragged item would actually change folder. */
23
+ export declare function canDropMediaInto(drag: MediaDragData, targetFolderId: string | null, folders: Record<string, MediaFolder>, itemsById: Record<string, MediaItem>): boolean;
24
+ /** Folder drops delegate to the tree-integrity guard (self/descendant/no-op). */
25
+ export declare function canDropFolderInto(drag: MediaFolderDragData, targetFolderId: string | null, folders: Record<string, MediaFolder>): boolean;
26
+ //# sourceMappingURL=media-dnd.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media-dnd.d.ts","sourceRoot":"","sources":["../../src/lib/media-dnd.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG7D,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,YAAY,CAAC;IACvB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;CACjC;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,cAAc,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;CACjC;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,cAAc,CAAC;IACzB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;CACjC;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,aAAa,CAEpE;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,mBAAmB,CAEzE;AAED,wBAAgB,mBAAmB,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,GAAG,mBAAmB,CAEtF;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,aAAa,CAEvF;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,mBAAmB,CAE9F;AAED,wEAAwE;AACxE,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,aAAa,EACnB,cAAc,EAAE,MAAM,GAAG,IAAI,EAC7B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EACpC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GACnC,OAAO,CAKT;AAED,iFAAiF;AACjF,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,mBAAmB,EACzB,cAAc,EAAE,MAAM,GAAG,IAAI,EAC7B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GACnC,OAAO,CAET"}
@@ -0,0 +1,59 @@
1
+ import type { MediaFolder, MediaItem, MediaManifest } from "../media/types";
2
+ export interface FolderTreeNode {
3
+ id: string;
4
+ name: string;
5
+ children: FolderTreeNode[];
6
+ }
7
+ export interface FolderUploadPlan {
8
+ /** New folder entities to merge into manifest.folders, keyed by new id. */
9
+ newFolders: Record<string, MediaFolder>;
10
+ /** Display-folder target per uploaded file (null = root). */
11
+ fileTargets: {
12
+ file: File;
13
+ folderId: string | null;
14
+ }[];
15
+ }
16
+ /** Display-folder id. NOT related to MediaItem.folder (the git storage dir). */
17
+ export declare function createFolderId(): string;
18
+ /** True when this folder's parent chain loops back to itself. */
19
+ export declare function isCyclicFolder(folders: Record<string, MediaFolder>, id: string): boolean;
20
+ /**
21
+ * Effective parent for rendering: null (root) when the parent is missing,
22
+ * dangling, or `id` itself sits on a parent cycle. Cycle members re-root,
23
+ * which breaks the loop for their (kept) descendants — corrupt manifests
24
+ * always render, and healMediaManifest persists this view on save.
25
+ */
26
+ export declare function effectiveParentId(folders: Record<string, MediaFolder>, id: string): string | null;
27
+ /** Direct children of `parentId`, alphabetically (case-insensitive). */
28
+ export declare function childFolderIds(folders: Record<string, MediaFolder>, parentId: string | null): string[];
29
+ export declare function buildFolderTree(folders: Record<string, MediaFolder>): FolderTreeNode[];
30
+ /** Names from root to `id` inclusive, cycle-safe. */
31
+ export declare function folderPathNames(folders: Record<string, MediaFolder>, id: string): string[];
32
+ /** Folder ids from root to `id` inclusive, cycle-safe. */
33
+ export declare function folderPathIds(folders: Record<string, MediaFolder>, id: string): string[];
34
+ /** All folders under `id` (by effective parent), INCLUDING `id` itself. */
35
+ export declare function descendantFolderIds(folders: Record<string, MediaFolder>, id: string): Set<string>;
36
+ /** May `id` re-parent to `targetParentId`? Blocks self/descendant targets and no-ops. */
37
+ export declare function canMoveFolder(folders: Record<string, MediaFolder>, id: string, targetParentId: string | null): boolean;
38
+ /** Trimmed `desired`, auto-suffixed " (2)", " (3)"… on case-insensitive sibling collision. */
39
+ export declare function uniqueFolderName(folders: Record<string, MediaFolder>, parentId: string | null, desired: string, excludeId?: string): string;
40
+ /** The folder an item renders in: its folderId when it points at a real folder, else root. */
41
+ export declare function itemFolderId(folders: Record<string, MediaFolder>, item: Pick<MediaItem, "folderId">): string | null;
42
+ /** Recursive item counts per folder id (an item counts toward every ancestor). */
43
+ export declare function recursiveItemCounts(folders: Record<string, MediaFolder>, items: MediaItem[]): Record<string, number>;
44
+ /** Pure heal: dangling folderIds dropped, orphan/cyclic folders re-rooted. */
45
+ export declare function healMediaManifest(manifest: MediaManifest): MediaManifest;
46
+ /**
47
+ * Save-time manifest assembly: merge uploaded pending items, apply deletions,
48
+ * preserve every other manifest key (folders!), then heal.
49
+ */
50
+ export declare function assembleSavedManifest(manifest: MediaManifest, uploadedItems: MediaItem[], deletedIds: string[]): MediaManifest;
51
+ /**
52
+ * Map webkitRelativePath-style paths onto folder entities under
53
+ * `currentFolderId`, merging with existing folders by case-insensitive name.
54
+ */
55
+ export declare function planFolderUpload(files: {
56
+ file: File;
57
+ relativePath: string;
58
+ }[], folders: Record<string, MediaFolder>, currentFolderId: string | null, newId?: () => string): FolderUploadPlan;
59
+ //# sourceMappingURL=media-folders.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media-folders.d.ts","sourceRoot":"","sources":["../../src/lib/media-folders.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ export interface DroppedFile {
2
+ file: File;
3
+ relativePath: string;
4
+ }
5
+ /** Structural subset of FileSystemEntry — lets tests fake the tree. */
6
+ export interface EntryLike {
7
+ isFile: boolean;
8
+ isDirectory: boolean;
9
+ name: string;
10
+ fullPath: string;
11
+ file?: (cb: (f: File) => void, err: (e: unknown) => void) => void;
12
+ createReader?: () => {
13
+ readEntries: (cb: (entries: EntryLike[]) => void, err: (e: unknown) => void) => void;
14
+ };
15
+ }
16
+ export declare function traverseEntries(entries: EntryLike[]): Promise<DroppedFile[]>;
17
+ /**
18
+ * Dropped-payload traversal. Returns null when nothing in the drop is a
19
+ * directory — the caller should fall back to the plain flat-file path.
20
+ */
21
+ export declare function collectDroppedFiles(dataTransfer: DataTransfer): Promise<DroppedFile[] | null>;
22
+ //# sourceMappingURL=folder-drop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"folder-drop.d.ts","sourceRoot":"","sources":["../../src/media/folder-drop.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,IAAI,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,uEAAuE;AACvE,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,KAAK,IAAI,CAAC;IAClE,YAAY,CAAC,EAAE,MAAM;QACnB,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,KAAK,IAAI,CAAC;KACtF,CAAC;CACH;AAoBD,wBAAsB,eAAe,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAWlF;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,CASnG"}
@@ -5,6 +5,7 @@ import {
5
5
  ProcessingQueue,
6
6
  displayFilename,
7
7
  displayFilenameExt,
8
+ displayName,
8
9
  formatFileSize,
9
10
  generateVideoPoster,
10
11
  getMediaProvider,
@@ -15,14 +16,15 @@ import {
15
16
  resolveMedia,
16
17
  sanitizeMediaName,
17
18
  setMediaProvider
18
- } from "../chunk-S55OZ7F2.js";
19
+ } from "../chunk-3LNKOLZP.js";
19
20
  import "../chunk-4YEOTFVU.js";
20
21
  import {
21
22
  ImageManifestSchema,
22
23
  MediaConfigSchema,
24
+ MediaFolderSchema,
23
25
  MediaItemSchema,
24
26
  VariantSchema
25
- } from "../chunk-SWIHUIFT.js";
27
+ } from "../chunk-RSITF24B.js";
26
28
  import "../chunk-JSBRDJBE.js";
27
29
  export {
28
30
  BAKED_MEDIA_KEYS,
@@ -30,11 +32,13 @@ export {
30
32
  ImageManifestSchema,
31
33
  MIME_TO_EXT,
32
34
  MediaConfigSchema,
35
+ MediaFolderSchema,
33
36
  MediaItemSchema,
34
37
  ProcessingQueue,
35
38
  VariantSchema,
36
39
  displayFilename,
37
40
  displayFilenameExt,
41
+ displayName,
38
42
  formatFileSize,
39
43
  generateVideoPoster,
40
44
  getMediaProvider,
@@ -1,4 +1,4 @@
1
- export { VariantSchema, MediaItemSchema, ImageManifestSchema, MediaConfigSchema, type Variant, type MediaItem, type MediaManifest, type MediaConfig, } from "../schemas/media";
1
+ export { VariantSchema, MediaItemSchema, ImageManifestSchema, MediaConfigSchema, MediaFolderSchema, type Variant, type MediaItem, type MediaManifest, type MediaConfig, type MediaFolder, } from "../schemas/media";
2
2
  export type MediaKind = "image" | "animated" | "video";
3
3
  export interface MediaFile {
4
4
  buffer: ArrayBuffer;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/media/types.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,iBAAiB,EACjB,KAAK,OAAO,EACZ,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,WAAW,GACjB,MAAM,kBAAkB,CAAC;AAI1B,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,UAAU,GAAG,OAAO,CAAC;AAEvD,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,WAAW,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,KAAK,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,KAAK,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,OAAO,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG,gBAAgB,GAAG,aAAa,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/media/types.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,KAAK,OAAO,EACZ,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,WAAW,GACjB,MAAM,kBAAkB,CAAC;AAI1B,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,UAAU,GAAG,OAAO,CAAC;AAEvD,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,WAAW,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,KAAK,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,KAAK,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,OAAO,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG,gBAAgB,GAAG,aAAa,CAAC"}
@@ -1,3 +1,4 @@
1
+ import type { MediaItem } from "./types";
1
2
  export declare function hashFileBuffer(buffer: ArrayBuffer): Promise<string>;
2
3
  export declare function sanitizeMediaName(name: string): string;
3
4
  export declare const MIME_TO_EXT: Record<string, string>;
@@ -6,4 +7,10 @@ export declare function mimeToExt(mime: string): string;
6
7
  export declare function displayFilenameExt(mime: string): string;
7
8
  export declare function displayFilename(originalName: string, mimeType: string): string;
8
9
  export declare function formatFileSize(bytes: number): string;
10
+ /**
11
+ * Display name for a media item. v2 batch-rename seam: will read a future
12
+ * optional `displayName` field with originalName fallback — UI must call this
13
+ * instead of touching originalName directly.
14
+ */
15
+ export declare function displayName(item: Pick<MediaItem, "originalName">): string;
9
16
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/media/utils.ts"],"names":[],"mappings":"AAEA,wBAAsB,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAqBzE;AAKD,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;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIpD"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/media/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC,wBAAsB,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAqBzE;AAKD,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;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIpD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,GAAG,MAAM,CAEzE"}
@@ -3,7 +3,7 @@ import {
3
3
  AudienceNameSchema,
4
4
  MediaGridOptionsSchema,
5
5
  slugifyAudienceName
6
- } from "../chunk-SFKYUKVN.js";
6
+ } from "../chunk-QB5Q23G2.js";
7
7
  import {
8
8
  AudienceSchema,
9
9
  RoleSchema,
@@ -28,6 +28,7 @@ import {
28
28
  ImageManifestSchema,
29
29
  IndexSchema,
30
30
  MediaConfigSchema,
31
+ MediaFolderSchema,
31
32
  MediaItemSchema,
32
33
  MediaReferenceSchema,
33
34
  PageSchema,
@@ -39,7 +40,7 @@ import {
39
40
  TextLineSchema,
40
41
  VariantSchema,
41
42
  normalizeSiteIndex
42
- } from "../chunk-SWIHUIFT.js";
43
+ } from "../chunk-RSITF24B.js";
43
44
  import "../chunk-VKAGMEKE.js";
44
45
  import "../chunk-NSCT3AMV.js";
45
46
  import "../chunk-JSBRDJBE.js";
@@ -57,6 +58,7 @@ export {
57
58
  LinkTargetSchema,
58
59
  LinkValueSchema,
59
60
  MediaConfigSchema,
61
+ MediaFolderSchema,
60
62
  MediaGridOptionsSchema,
61
63
  MediaItemSchema,
62
64
  MediaReferenceSchema,
@@ -5,6 +5,11 @@ export declare const VariantSchema: z.ZodObject<{
5
5
  size: z.ZodNumber;
6
6
  }, z.core.$strip>;
7
7
  export type Variant = z.infer<typeof VariantSchema>;
8
+ export declare const MediaFolderSchema: z.ZodObject<{
9
+ name: z.ZodString;
10
+ parentId: z.ZodNullable<z.ZodString>;
11
+ }, z.core.$strip>;
12
+ export type MediaFolder = z.infer<typeof MediaFolderSchema>;
8
13
  export declare const MediaItemSchema: z.ZodObject<{
9
14
  id: z.ZodString;
10
15
  hash: z.ZodString;
@@ -31,6 +36,7 @@ export declare const MediaItemSchema: z.ZodObject<{
31
36
  }>>;
32
37
  url: z.ZodOptional<z.ZodString>;
33
38
  duration: z.ZodOptional<z.ZodNumber>;
39
+ folderId: z.ZodOptional<z.ZodString>;
34
40
  }, z.core.$strip>;
35
41
  export type MediaItem = z.infer<typeof MediaItemSchema>;
36
42
  export declare const ImageManifestSchema: z.ZodObject<{
@@ -60,7 +66,12 @@ export declare const ImageManifestSchema: z.ZodObject<{
60
66
  }>>;
61
67
  url: z.ZodOptional<z.ZodString>;
62
68
  duration: z.ZodOptional<z.ZodNumber>;
69
+ folderId: z.ZodOptional<z.ZodString>;
63
70
  }, z.core.$strip>>;
71
+ folders: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
72
+ name: z.ZodString;
73
+ parentId: z.ZodNullable<z.ZodString>;
74
+ }, z.core.$strip>>>;
64
75
  }, z.core.$strip>;
65
76
  export type MediaManifest = z.infer<typeof ImageManifestSchema>;
66
77
  export declare const MediaConfigSchema: z.ZodObject<{
@@ -1 +1 @@
1
- {"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../../src/schemas/media.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,aAAa;;;;iBAIxB,CAAC;AAEH,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAEpD,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;iBAqB1B,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAE9B,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,eAAO,MAAM,iBAAiB;;;;;iBAO5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC"}
1
+ {"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../../src/schemas/media.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,aAAa;;;;iBAIxB,CAAC;AAEH,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAIpD,eAAO,MAAM,iBAAiB;;;iBAG5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAwB1B,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAG9B,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,eAAO,MAAM,iBAAiB;;;;;iBAO5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC"}
@@ -179,6 +179,12 @@ export declare const SiteConfigSchema: z.ZodObject<{
179
179
  light: "light";
180
180
  dark: "dark";
181
181
  }>>;
182
+ cornerRadius: z.ZodDefault<z.ZodEnum<{
183
+ none: "none";
184
+ small: "small";
185
+ medium: "medium";
186
+ large: "large";
187
+ }>>;
182
188
  headingFont: z.ZodDefault<z.ZodString>;
183
189
  bodyFont: z.ZodDefault<z.ZodString>;
184
190
  uppercaseHeadings: z.ZodDefault<z.ZodBoolean>;
@@ -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;AAO5D,eAAO,MAAM,cAAc,0DAA2D,CAAC;AAEvF,eAAO,MAAM,gBAAgB;;;EAA+B,CAAC;AAE7D,eAAO,MAAM,UAAU;;;;;;;;;;;;iBASrB,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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAyB3B,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;AASxB,eAAO,MAAM,iBAAiB;;;;;;;;;iBAI5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAO5D,eAAO,MAAM,cAAc,0DAA2D,CAAC;AAEvF,eAAO,MAAM,gBAAgB;;;EAA+B,CAAC;AAE7D,eAAO,MAAM,UAAU;;;;;;;;;;;;iBASrB,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.77",
3
+ "version": "0.1.79",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  "./package.json": "./package.json",
@@ -125,7 +125,7 @@ function ColorsView({
125
125
  const hex = color.spaces[0]?.hex;
126
126
  const contrast = getContrastClass(hex);
127
127
  return (
128
- <div key={i} className="overflow-hidden rounded-md border border-base-200">
128
+ <div key={i} className="overflow-hidden rounded-outer border border-base-200">
129
129
  <div className={cn("relative flex min-h-[80px] items-end p-3", contrast)} style={{ backgroundColor: hex || "#ccc" }}>
130
130
  {color.name && <span className="text-sm font-bold">{color.name}</span>}
131
131
  {copiedIndex === i && (
@@ -267,7 +267,7 @@ function ColorSwatchEditable({
267
267
  };
268
268
 
269
269
  return (
270
- <div className="overflow-hidden rounded-md border border-base-200">
270
+ <div className="overflow-hidden rounded-outer border border-base-200">
271
271
  <div className={cn("flex min-h-[80px] items-end p-3", contrast)} style={{ backgroundColor: hex || "#ccc" }}>
272
272
  <EditablePlainText
273
273
  tag="span"
@@ -39,8 +39,8 @@ const MD_STYLES =
39
39
  "[&_p:not(:first-child)]:mt-2 [&_ul]:mt-1 [&_ul]:list-disc [&_ul]:pl-4 " +
40
40
  "[&_ol]:mt-1 [&_ol]:list-decimal [&_ol]:pl-4 [&_li:not(:first-child)]:mt-1 " +
41
41
  "[&_a]:underline [&_a]:underline-offset-2 [&_a]:text-primary " +
42
- "[&_code]:rounded [&_code]:bg-base-200 [&_code]:px-1 [&_code]:font-mono [&_code]:text-[0.8em] " +
43
- "[&_pre]:mt-2 [&_pre]:overflow-x-auto [&_pre]:rounded [&_pre]:bg-base-200 [&_pre]:p-2 " +
42
+ "[&_code]:rounded-inner [&_code]:bg-base-200 [&_code]:px-1 [&_code]:font-mono [&_code]:text-[0.8em] " +
43
+ "[&_pre]:mt-2 [&_pre]:overflow-x-auto [&_pre]:rounded-inner [&_pre]:bg-base-200 [&_pre]:p-2 " +
44
44
  "[&_h1]:mt-2 [&_h1]:font-semibold [&_h2]:mt-2 [&_h2]:font-semibold " +
45
45
  "[&_h3]:mt-2 [&_h3]:font-semibold [&_h4]:mt-2 [&_h4]:font-semibold " +
46
46
  "[&_blockquote]:mt-2 [&_blockquote]:border-l-2 [&_blockquote]:border-base-200 [&_blockquote]:pl-2";
@@ -209,13 +209,13 @@ export default function ChatPanel({ open, onClose, siteName, tasks, isEditor, dr
209
209
  return (
210
210
  <div role="dialog" aria-label={`Chat with ${siteName}`}
211
211
  className={cn(
212
- "fixed z-40 flex h-[28rem] w-80 flex-col rounded-lg border border-base-200 bg-base shadow-xl",
212
+ "fixed z-40 flex h-[28rem] w-80 flex-col rounded-outer border border-base-200 bg-base shadow-xl",
213
213
  variant === "editor" ? "bottom-4 fab-panel-left max-w-[calc(100vw-5.25rem)]" : "bottom-20 right-4",
214
214
  )}>
215
215
 
216
216
  <div className="flex items-center justify-between gap-2 border-b border-base-200 px-3 py-2">
217
217
  <span className="text-sm font-medium text-base-contrast">Portal Assistant</span>
218
- <IconButton icon={<RemoveIcon size={18} />} label="Close chat" onClick={onClose} className="rounded-md hover:bg-base-accent" />
218
+ <IconButton icon={<RemoveIcon size={18} />} label="Close chat" onClick={onClose} className="rounded-inner hover:bg-base-accent" />
219
219
  </div>
220
220
  {tasks.length > 0 && (
221
221
  <div className="border-b border-base-200 px-3 py-2">
@@ -233,11 +233,11 @@ export default function ChatPanel({ open, onClose, siteName, tasks, isEditor, dr
233
233
  m.role === "assistant" && mdReady && m.content ? (
234
234
  <div
235
235
  key={i}
236
- className={cn("max-w-[85%] rounded-lg bg-base-accent px-3 py-2 text-sm text-base-contrast", MD_STYLES)}
236
+ className={cn("max-w-[85%] rounded-outer bg-base-accent px-3 py-2 text-sm text-base-contrast", MD_STYLES)}
237
237
  dangerouslySetInnerHTML={{ __html: assistantHtml(m.content) }}
238
238
  />
239
239
  ) : (
240
- <div key={i} className={cn("max-w-[85%] whitespace-pre-wrap rounded-lg px-3 py-2 text-sm",
240
+ <div key={i} className={cn("max-w-[85%] whitespace-pre-wrap rounded-outer px-3 py-2 text-sm",
241
241
  m.role === "user" ? "ml-auto bg-primary text-primary-contrast" : "bg-base-accent text-base-contrast")}>
242
242
  {m.content || (busy && i === messages.length - 1 ? "…" : m.content)}
243
243
  </div>
@@ -254,10 +254,10 @@ export default function ChatPanel({ open, onClose, siteName, tasks, isEditor, dr
254
254
  onKeyDown={onComposerKeyDown}
255
255
  placeholder={`Ask about ${siteName}…`}
256
256
  maxLength={4000}
257
- className="max-h-[5.625rem] min-w-0 flex-1 resize-none overflow-y-auto rounded 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%)]"
257
+ 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%)]"
258
258
  />
259
259
  <button type="submit" aria-label="Send" disabled={busy}
260
- className="rounded bg-primary px-3 py-1 text-sm text-primary-contrast disabled:opacity-50">→</button>
260
+ className="rounded-inner bg-primary px-3 py-1 text-sm text-primary-contrast disabled:opacity-50">→</button>
261
261
  </form>
262
262
  {isEditor && <p className="border-t border-base-200 px-3 py-1 text-[10px] text-base-contrast-light">Editor view — answers ground on published content.</p>}
263
263
  </div>
@@ -93,7 +93,7 @@ export function ResolvedMedia({
93
93
  )}
94
94
  </>
95
95
  ) : (
96
- <div className="flex aspect-video h-full w-full flex-col items-center justify-center gap-1 rounded bg-base-accent text-base-contrast-light/50">
96
+ <div className="flex aspect-video h-full w-full flex-col items-center justify-center gap-1 rounded-outer bg-base-accent text-base-contrast-light/50">
97
97
  <ImageIcon size={24} />
98
98
  <span className="text-sm">No Image</span>
99
99
  </div>
@@ -12,7 +12,7 @@ interface Props {
12
12
  }
13
13
 
14
14
  export default function Button({ text, link, download, onChange }: Props) {
15
- const base = "inline-block rounded-md px-6 py-3 font-bold transition-colors";
15
+ const base = "inline-block rounded-outer px-6 py-3 font-bold transition-colors";
16
16
  const variant = "border-2 border-primary text-primary hover:bg-primary hover:text-primary-contrast";
17
17
 
18
18
  if (onChange) {
@@ -77,7 +77,7 @@ export function MediaBlock({ refValue, options, link, isEditMode, onRefChange }:
77
77
  <div
78
78
  data-testid="media-open-surface"
79
79
  className={cn(
80
- "overflow-hidden rounded-md",
80
+ "overflow-hidden rounded-outer",
81
81
  showBorder && "border border-base-200",
82
82
  options.square && "aspect-square",
83
83
  onImageClick && "cursor-pointer",
@@ -89,7 +89,7 @@ export default function Navigation({ siteNav: initialNav, siteName, darkMode, la
89
89
  <li key={pid}>
90
90
  <button
91
91
  onClick={() => handleHeadingNav(parent.href)}
92
- className={cn("cursor-pointer w-full rounded px-2 py-1 text-left text-sm transition-colors",
92
+ className={cn("cursor-pointer w-full rounded-inner px-2 py-1 text-left text-sm transition-colors",
93
93
  activeParentId === pid ? "font-bold text-primary" : "text-base-contrast-light hover:text-primary",
94
94
  !isEditMode && parent.status && parent.status !== "live" && "opacity-50")}
95
95
  >
@@ -102,7 +102,7 @@ export default function Navigation({ siteNav: initialNav, siteName, darkMode, la
102
102
  return (
103
103
  <li key={cid}>
104
104
  <button onClick={() => handleHeadingNav(child.href)}
105
- className={cn("cursor-pointer w-full rounded px-2 py-1 text-left text-sm transition-colors",
105
+ className={cn("cursor-pointer w-full rounded-inner px-2 py-1 text-left text-sm transition-colors",
106
106
  activeChildId === cid ? "font-bold text-primary" : "text-base-contrast-light hover:text-primary",
107
107
  !isEditMode && child.status && child.status !== "live" && "opacity-50")}>
108
108
  {child.label}
@@ -150,7 +150,7 @@ export default function Navigation({ siteNav: initialNav, siteName, darkMode, la
150
150
  {asButton ? (
151
151
  <button
152
152
  onClick={() => handlePageClick(page.id)}
153
- className={cn("cursor-pointer w-full rounded px-3 py-2 text-left text-sm font-bold transition-colors",
153
+ className={cn("cursor-pointer w-full rounded-inner px-3 py-2 text-left text-sm font-bold transition-colors",
154
154
  page.isActive ? "text-primary" : "text-base-contrast hover:text-primary")}
155
155
  >
156
156
  {page.title}
@@ -158,7 +158,7 @@ export default function Navigation({ siteNav: initialNav, siteName, darkMode, la
158
158
  ) : (
159
159
  <a
160
160
  href={page.href}
161
- className={cn("block w-full rounded px-3 py-2 text-left text-sm font-bold transition-colors",
161
+ className={cn("block w-full rounded-inner px-3 py-2 text-left text-sm font-bold transition-colors",
162
162
  page.isActive ? "text-primary" : "text-base-contrast hover:text-primary")}
163
163
  >
164
164
  {page.title}
@@ -179,7 +179,7 @@ export default function Navigation({ siteNav: initialNav, siteName, darkMode, la
179
179
  type="button"
180
180
  aria-expanded={isOpen}
181
181
  onClick={() => setOpenGroups((g) => ({ ...g, [label]: !isOpen }))}
182
- className="flex w-full cursor-pointer items-center justify-between rounded px-3 py-1 text-xs font-semibold uppercase tracking-wide text-base-contrast/70 transition-colors hover:text-primary"
182
+ className="flex w-full cursor-pointer items-center justify-between rounded-inner px-3 py-1 text-xs font-semibold uppercase tracking-wide text-base-contrast/70 transition-colors hover:text-primary"
183
183
  >
184
184
  <span>{`${label} (${pages.length})`}</span>
185
185
  <ChevronRight size={14} aria-hidden="true" className={cn("transition-transform", isOpen && "rotate-90")} />
@@ -59,15 +59,15 @@ export function EditorModal({ isOpen, onClose, title, blocking = false, size = "
59
59
  aria-modal="true"
60
60
  aria-labelledby={titleId}
61
61
  className={cn(
62
- "mx-4 w-full rounded-lg bg-base shadow-lg",
62
+ "mx-4 flex w-full flex-col rounded-lg bg-base shadow-lg",
63
63
  size === "large"
64
- ? "max-w-[1400px] max-h-[900px] h-[90vh] flex flex-col"
64
+ ? "max-w-[1400px] max-h-[900px] h-[90vh]"
65
65
  : size === "settings"
66
- ? "max-w-lg flex flex-col min-h-[32rem] max-h-[calc(100vh-4rem)]"
67
- : "max-w-md",
66
+ ? "max-w-lg min-h-[min(32rem,calc(100vh-4rem))] max-h-[calc(100vh-4rem)]"
67
+ : "max-w-md max-h-[calc(100vh-4rem)]",
68
68
  )}
69
69
  >
70
- <div className="flex items-center justify-between border-b border-base-200 px-6 py-4">
70
+ <div className="flex shrink-0 items-center justify-between border-b border-base-200 px-6 py-4">
71
71
  <h3 id={titleId} className="text-lg font-semibold text-base-contrast">{title}</h3>
72
72
  {!blocking && (
73
73
  <IconButton
@@ -81,8 +81,8 @@ export function EditorModal({ isOpen, onClose, title, blocking = false, size = "
81
81
  </div>
82
82
  <div className={cn(
83
83
  !noPadding && "px-6 py-4",
84
- size === "large" && "flex-1 overflow-y-auto",
85
- size === "settings" && "flex-1 flex flex-col overflow-hidden",
84
+ "flex-1 overflow-y-auto",
85
+ size === "settings" && "flex flex-col",
86
86
  )}>
87
87
  {children}
88
88
  </div>