@anvilkit/plugin-asset-manager 0.1.5 → 0.1.7

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 (224) hide show
  1. package/README.md +27 -19
  2. package/dist/adapters/data-url.cjs +9 -5
  3. package/dist/adapters/extract-image-dimensions.cjs +12 -8
  4. package/dist/adapters/in-memory.cjs +9 -5
  5. package/dist/adapters/s3-presigned.cjs +9 -5
  6. package/dist/index.cjs +16 -5
  7. package/dist/index.d.cts +11 -3
  8. package/dist/index.d.cts.map +1 -1
  9. package/dist/index.d.ts +11 -3
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +2 -1
  12. package/dist/plugin.cjs +76 -9
  13. package/dist/plugin.d.cts +3 -2
  14. package/dist/plugin.d.cts.map +1 -1
  15. package/dist/plugin.d.ts +3 -2
  16. package/dist/plugin.d.ts.map +1 -1
  17. package/dist/plugin.js +67 -4
  18. package/dist/sources/composite-source.cjs +137 -0
  19. package/dist/sources/composite-source.d.cts +39 -0
  20. package/dist/sources/composite-source.d.cts.map +1 -0
  21. package/dist/sources/composite-source.d.ts +39 -0
  22. package/dist/sources/composite-source.d.ts.map +1 -0
  23. package/dist/sources/composite-source.js +99 -0
  24. package/dist/sources/federated-search.cjs +163 -0
  25. package/dist/sources/federated-search.d.cts +33 -0
  26. package/dist/sources/federated-search.d.cts.map +1 -0
  27. package/dist/sources/federated-search.d.ts +33 -0
  28. package/dist/sources/federated-search.d.ts.map +1 -0
  29. package/dist/sources/federated-search.js +113 -0
  30. package/dist/sources/provider.cjs +18 -0
  31. package/dist/sources/provider.d.cts +51 -0
  32. package/dist/sources/provider.d.cts.map +1 -0
  33. package/dist/sources/provider.d.ts +51 -0
  34. package/dist/sources/provider.d.ts.map +1 -0
  35. package/dist/sources/provider.js +1 -0
  36. package/dist/sources/unsplash/client.cjs +189 -0
  37. package/dist/sources/unsplash/client.d.cts +87 -0
  38. package/dist/sources/unsplash/client.d.cts.map +1 -0
  39. package/dist/sources/unsplash/client.d.ts +87 -0
  40. package/dist/sources/unsplash/client.d.ts.map +1 -0
  41. package/dist/sources/unsplash/client.js +151 -0
  42. package/dist/sources/unsplash/index.cjs +192 -0
  43. package/dist/sources/unsplash/index.d.cts +16 -0
  44. package/dist/sources/unsplash/index.d.cts.map +1 -0
  45. package/dist/sources/unsplash/index.d.ts +16 -0
  46. package/dist/sources/unsplash/index.d.ts.map +1 -0
  47. package/dist/sources/unsplash/index.js +148 -0
  48. package/dist/sources/unsplash/themes.cjs +141 -0
  49. package/dist/sources/unsplash/themes.d.cts +18 -0
  50. package/dist/sources/unsplash/themes.d.cts.map +1 -0
  51. package/dist/sources/unsplash/themes.d.ts +18 -0
  52. package/dist/sources/unsplash/themes.d.ts.map +1 -0
  53. package/dist/sources/unsplash/themes.js +93 -0
  54. package/dist/sources/unsplash/throttle-cache.cjs +86 -0
  55. package/dist/sources/unsplash/throttle-cache.d.cts +25 -0
  56. package/dist/sources/unsplash/throttle-cache.d.cts.map +1 -0
  57. package/dist/sources/unsplash/throttle-cache.d.ts +25 -0
  58. package/dist/sources/unsplash/throttle-cache.d.ts.map +1 -0
  59. package/dist/sources/unsplash/throttle-cache.js +45 -0
  60. package/dist/testing/index.cjs +9 -5
  61. package/dist/types/categories.cjs +18 -0
  62. package/dist/types/categories.d.cts +48 -0
  63. package/dist/types/categories.d.cts.map +1 -0
  64. package/dist/types/categories.d.ts +48 -0
  65. package/dist/types/categories.d.ts.map +1 -0
  66. package/dist/types/categories.js +1 -0
  67. package/dist/types/data-source.cjs +18 -0
  68. package/dist/types/data-source.d.cts +59 -0
  69. package/dist/types/data-source.d.cts.map +1 -0
  70. package/dist/types/data-source.d.ts +59 -0
  71. package/dist/types/data-source.d.ts.map +1 -0
  72. package/dist/types/data-source.js +1 -0
  73. package/dist/types/filter.cjs +18 -0
  74. package/dist/types/filter.d.cts +55 -0
  75. package/dist/types/filter.d.cts.map +1 -0
  76. package/dist/types/filter.d.ts +55 -0
  77. package/dist/types/filter.d.ts.map +1 -0
  78. package/dist/types/filter.js +1 -0
  79. package/dist/types/folders.cjs +42 -0
  80. package/dist/types/folders.d.cts +46 -0
  81. package/dist/types/folders.d.cts.map +1 -0
  82. package/dist/types/folders.d.ts +46 -0
  83. package/dist/types/folders.d.ts.map +1 -0
  84. package/dist/types/folders.js +4 -0
  85. package/dist/types/options.cjs +18 -0
  86. package/dist/types/options.d.cts +68 -0
  87. package/dist/types/options.d.cts.map +1 -0
  88. package/dist/types/options.d.ts +68 -0
  89. package/dist/types/options.d.ts.map +1 -0
  90. package/dist/types/options.js +1 -0
  91. package/dist/types/types.d.cts +15 -27
  92. package/dist/types/types.d.cts.map +1 -1
  93. package/dist/types/types.d.ts +15 -27
  94. package/dist/types/types.d.ts.map +1 -1
  95. package/dist/types/unsplash.cjs +18 -0
  96. package/dist/types/unsplash.d.cts +60 -0
  97. package/dist/types/unsplash.d.cts.map +1 -0
  98. package/dist/types/unsplash.d.ts +60 -0
  99. package/dist/types/unsplash.d.ts.map +1 -0
  100. package/dist/types/unsplash.js +1 -0
  101. package/dist/ui/AssetBrowser.cjs +69 -104
  102. package/dist/ui/AssetBrowser.d.cts +17 -7
  103. package/dist/ui/AssetBrowser.d.cts.map +1 -1
  104. package/dist/ui/AssetBrowser.d.ts +17 -7
  105. package/dist/ui/AssetBrowser.d.ts.map +1 -1
  106. package/dist/ui/AssetBrowser.js +60 -99
  107. package/dist/ui/AssetCommandPalette.cjs +9 -5
  108. package/dist/ui/AssetManagerUI.cjs +17 -7
  109. package/dist/ui/AssetManagerUI.d.cts +19 -3
  110. package/dist/ui/AssetManagerUI.d.cts.map +1 -1
  111. package/dist/ui/AssetManagerUI.d.ts +19 -3
  112. package/dist/ui/AssetManagerUI.d.ts.map +1 -1
  113. package/dist/ui/AssetManagerUI.js +8 -2
  114. package/dist/ui/DeleteAssetDialog.cjs +9 -5
  115. package/dist/ui/DeleteFolderDialog.cjs +78 -0
  116. package/dist/ui/DeleteFolderDialog.d.cts +11 -0
  117. package/dist/ui/DeleteFolderDialog.d.cts.map +1 -0
  118. package/dist/ui/DeleteFolderDialog.d.ts +11 -0
  119. package/dist/ui/DeleteFolderDialog.d.ts.map +1 -0
  120. package/dist/ui/DeleteFolderDialog.js +40 -0
  121. package/dist/ui/EmptyFolderState.cjs +53 -0
  122. package/dist/ui/EmptyFolderState.d.cts +6 -0
  123. package/dist/ui/EmptyFolderState.d.cts.map +1 -0
  124. package/dist/ui/EmptyFolderState.d.ts +6 -0
  125. package/dist/ui/EmptyFolderState.d.ts.map +1 -0
  126. package/dist/ui/EmptyFolderState.js +15 -0
  127. package/dist/ui/FolderBreadcrumb.cjs +73 -0
  128. package/dist/ui/FolderBreadcrumb.d.cts +9 -0
  129. package/dist/ui/FolderBreadcrumb.d.cts.map +1 -0
  130. package/dist/ui/FolderBreadcrumb.d.ts +9 -0
  131. package/dist/ui/FolderBreadcrumb.d.ts.map +1 -0
  132. package/dist/ui/FolderBreadcrumb.js +35 -0
  133. package/dist/ui/FolderNameDialog.cjs +98 -0
  134. package/dist/ui/FolderNameDialog.d.cts +14 -0
  135. package/dist/ui/FolderNameDialog.d.cts.map +1 -0
  136. package/dist/ui/FolderNameDialog.d.ts +14 -0
  137. package/dist/ui/FolderNameDialog.d.ts.map +1 -0
  138. package/dist/ui/FolderNameDialog.js +60 -0
  139. package/dist/ui/FolderTree.cjs +83 -0
  140. package/dist/ui/FolderTree.d.cts +13 -0
  141. package/dist/ui/FolderTree.d.cts.map +1 -0
  142. package/dist/ui/FolderTree.d.ts +13 -0
  143. package/dist/ui/FolderTree.d.ts.map +1 -0
  144. package/dist/ui/FolderTree.js +42 -0
  145. package/dist/ui/MetadataPanel.cjs +16 -9
  146. package/dist/ui/MetadataPanel.d.cts.map +1 -1
  147. package/dist/ui/MetadataPanel.d.ts.map +1 -1
  148. package/dist/ui/MetadataPanel.js +7 -4
  149. package/dist/ui/MoveTargetPicker.cjs +84 -0
  150. package/dist/ui/MoveTargetPicker.d.cts +16 -0
  151. package/dist/ui/MoveTargetPicker.d.cts.map +1 -0
  152. package/dist/ui/MoveTargetPicker.d.ts +16 -0
  153. package/dist/ui/MoveTargetPicker.d.ts.map +1 -0
  154. package/dist/ui/MoveTargetPicker.js +46 -0
  155. package/dist/ui/ReplaceAssetDialog.cjs +9 -5
  156. package/dist/ui/ReplaceAssetDialog.d.cts +2 -1
  157. package/dist/ui/ReplaceAssetDialog.d.cts.map +1 -1
  158. package/dist/ui/ReplaceAssetDialog.d.ts +2 -1
  159. package/dist/ui/ReplaceAssetDialog.d.ts.map +1 -1
  160. package/dist/ui/UnsplashPanel.cjs +134 -0
  161. package/dist/ui/UnsplashPanel.d.cts +28 -0
  162. package/dist/ui/UnsplashPanel.d.cts.map +1 -0
  163. package/dist/ui/UnsplashPanel.d.ts +28 -0
  164. package/dist/ui/UnsplashPanel.d.ts.map +1 -0
  165. package/dist/ui/UnsplashPanel.js +96 -0
  166. package/dist/ui/UploadButton.cjs +10 -10
  167. package/dist/ui/UploadButton.d.cts +9 -2
  168. package/dist/ui/UploadButton.d.cts.map +1 -1
  169. package/dist/ui/UploadButton.d.ts +9 -2
  170. package/dist/ui/UploadButton.d.ts.map +1 -1
  171. package/dist/ui/UploadButton.js +1 -5
  172. package/dist/ui/index.cjs +46 -5
  173. package/dist/ui/index.d.cts +14 -0
  174. package/dist/ui/index.d.cts.map +1 -1
  175. package/dist/ui/index.d.ts +14 -0
  176. package/dist/ui/index.d.ts.map +1 -1
  177. package/dist/ui/index.js +7 -0
  178. package/dist/utils/asset-reference.cjs +12 -8
  179. package/dist/utils/csp.cjs +12 -8
  180. package/dist/utils/data-source.cjs +177 -0
  181. package/dist/utils/data-source.d.cts +63 -0
  182. package/dist/utils/data-source.d.cts.map +1 -0
  183. package/dist/utils/data-source.d.ts +63 -0
  184. package/dist/utils/data-source.d.ts.map +1 -0
  185. package/dist/utils/data-source.js +136 -0
  186. package/dist/utils/errors.cjs +31 -9
  187. package/dist/utils/errors.d.cts +27 -0
  188. package/dist/utils/errors.d.cts.map +1 -1
  189. package/dist/utils/errors.d.ts +27 -0
  190. package/dist/utils/errors.d.ts.map +1 -1
  191. package/dist/utils/errors.js +16 -1
  192. package/dist/utils/folders.cjs +261 -0
  193. package/dist/utils/folders.d.cts +49 -0
  194. package/dist/utils/folders.d.cts.map +1 -0
  195. package/dist/utils/folders.d.ts +49 -0
  196. package/dist/utils/folders.d.ts.map +1 -0
  197. package/dist/utils/folders.js +223 -0
  198. package/dist/utils/header-action.cjs +12 -8
  199. package/dist/utils/infer-kind.cjs +12 -8
  200. package/dist/utils/registry.cjs +36 -17
  201. package/dist/utils/registry.d.cts +21 -1
  202. package/dist/utils/registry.d.cts.map +1 -1
  203. package/dist/utils/registry.d.ts +21 -1
  204. package/dist/utils/registry.d.ts.map +1 -1
  205. package/dist/utils/registry.js +20 -11
  206. package/dist/utils/resolver.cjs +9 -5
  207. package/dist/utils/retry.cjs +13 -9
  208. package/dist/utils/studio-asset-source.cjs +14 -7
  209. package/dist/utils/studio-asset-source.d.cts +6 -1
  210. package/dist/utils/studio-asset-source.d.cts.map +1 -1
  211. package/dist/utils/studio-asset-source.d.ts +6 -1
  212. package/dist/utils/studio-asset-source.d.ts.map +1 -1
  213. package/dist/utils/studio-asset-source.js +1 -1
  214. package/dist/utils/validate-upload-result.cjs +9 -5
  215. package/dist/utils/validate-upload-result.d.cts +2 -1
  216. package/dist/utils/validate-upload-result.d.cts.map +1 -1
  217. package/dist/utils/validate-upload-result.d.ts +2 -1
  218. package/dist/utils/validate-upload-result.d.ts.map +1 -1
  219. package/dist/version.cjs +12 -8
  220. package/dist/version.d.cts +1 -1
  221. package/dist/version.d.ts +1 -1
  222. package/dist/version.js +1 -1
  223. package/meta/config.json +1 -1
  224. package/package.json +19 -9
@@ -0,0 +1,60 @@
1
+ /**
2
+ * @file Unsplash configuration types (PRD 0002 §8.2, §8.3).
3
+ *
4
+ * Types only — the runtime client, default themes, and `resolveThemes` land in
5
+ * Phase 1 under the lazy `./sources/unsplash` subpath. Defining the config shape
6
+ * here keeps the `AssetManagerOptions.unsplash` field fully typed now.
7
+ */
8
+ export interface UnsplashTheme {
9
+ readonly id: string;
10
+ /** i18n message key (not inline copy). */
11
+ readonly label: string;
12
+ /** Tried first via `GET /topics/:id/photos`. */
13
+ readonly topicSlugs?: readonly string[];
14
+ /** Fallback / supplement via `GET /search/photos`. */
15
+ readonly query?: string;
16
+ readonly orientation?: "landscape" | "portrait" | "squarish";
17
+ /** Defaults to `"high"`. */
18
+ readonly contentFilter?: "low" | "high";
19
+ }
20
+ export interface UnsplashThemeConfig {
21
+ /** Replace the default theme set entirely. */
22
+ readonly themes?: readonly UnsplashTheme[];
23
+ /** Append to the defaults. */
24
+ readonly additionalThemes?: readonly UnsplashTheme[];
25
+ /** Theme ids to drop from the defaults. */
26
+ readonly excludeThemes?: readonly string[];
27
+ readonly defaultThemeId?: string;
28
+ /** When `false`, the `__all__` free-search pseudo-theme is not prepended. */
29
+ readonly allowFreeSearch?: boolean;
30
+ }
31
+ export interface UnsplashSourceOptions {
32
+ /** RECOMMENDED — proxy injects the `Client-ID` server-side. */
33
+ readonly proxyEndpoint?: string | URL;
34
+ /** DEV ONLY — ships the key to the browser; ignored when `proxyEndpoint` is set. */
35
+ readonly accessKey?: string;
36
+ /** Defaults to `!!(proxyEndpoint || accessKey)`; the package never bundles a key. */
37
+ readonly enabled?: boolean;
38
+ /** REQUIRED when enabled — `utm_source` for mandatory attribution. */
39
+ readonly appName: string;
40
+ readonly themes?: UnsplashThemeConfig;
41
+ /** Default 24 (clamped 1–30). */
42
+ readonly perPage?: number;
43
+ /** Throttle floor between JSON requests. Default 1200. */
44
+ readonly minRequestIntervalMs?: number;
45
+ /** Result LRU TTL. Default 300_000. */
46
+ readonly cacheTtlMs?: number;
47
+ /**
48
+ * Per-request timeout for search / topic / photo lookups (ms). A request
49
+ * that exceeds it aborts and surfaces as a retryable `PROVIDER_NETWORK`
50
+ * error, so a blocked or flaky network path (e.g. a VPN/proxy black-holing
51
+ * `api.unsplash.com`) lets the sidebar fall back to "Unsplash unavailable"
52
+ * instead of spinning. Default 15_000. Ignored if not a positive number.
53
+ */
54
+ readonly requestTimeoutMs?: number;
55
+ /** Injectable fetch for tests / SSR. */
56
+ readonly fetch?: typeof globalThis.fetch;
57
+ /** Opt-in re-host instead of hotlinking. Default false. */
58
+ readonly rehostOnPick?: boolean;
59
+ }
60
+ //# sourceMappingURL=unsplash.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unsplash.d.cts","sourceRoot":"","sources":["../../src/types/unsplash.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,0CAA0C;IAC1C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,gDAAgD;IAChD,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,sDAAsD;IACtD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,GAAG,UAAU,GAAG,UAAU,CAAC;IAC7D,4BAA4B;IAC5B,QAAQ,CAAC,aAAa,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;CACxC;AAED,MAAM,WAAW,mBAAmB;IACnC,8CAA8C;IAC9C,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IAC3C,8BAA8B;IAC9B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IACrD,2CAA2C;IAC3C,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,6EAA6E;IAC7E,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;CACnC;AAED,MAAM,WAAW,qBAAqB;IACrC,+DAA+D;IAC/D,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;IACtC,oFAAoF;IACpF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,qFAAqF;IACrF,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,sEAAsE;IACtE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,mBAAmB,CAAC;IACtC,iCAAiC;IACjC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,0DAA0D;IAC1D,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IACvC,uCAAuC;IACvC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;;OAMG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,wCAAwC;IACxC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IACzC,2DAA2D;IAC3D,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;CAChC"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * @file Unsplash configuration types (PRD 0002 §8.2, §8.3).
3
+ *
4
+ * Types only — the runtime client, default themes, and `resolveThemes` land in
5
+ * Phase 1 under the lazy `./sources/unsplash` subpath. Defining the config shape
6
+ * here keeps the `AssetManagerOptions.unsplash` field fully typed now.
7
+ */
8
+ export interface UnsplashTheme {
9
+ readonly id: string;
10
+ /** i18n message key (not inline copy). */
11
+ readonly label: string;
12
+ /** Tried first via `GET /topics/:id/photos`. */
13
+ readonly topicSlugs?: readonly string[];
14
+ /** Fallback / supplement via `GET /search/photos`. */
15
+ readonly query?: string;
16
+ readonly orientation?: "landscape" | "portrait" | "squarish";
17
+ /** Defaults to `"high"`. */
18
+ readonly contentFilter?: "low" | "high";
19
+ }
20
+ export interface UnsplashThemeConfig {
21
+ /** Replace the default theme set entirely. */
22
+ readonly themes?: readonly UnsplashTheme[];
23
+ /** Append to the defaults. */
24
+ readonly additionalThemes?: readonly UnsplashTheme[];
25
+ /** Theme ids to drop from the defaults. */
26
+ readonly excludeThemes?: readonly string[];
27
+ readonly defaultThemeId?: string;
28
+ /** When `false`, the `__all__` free-search pseudo-theme is not prepended. */
29
+ readonly allowFreeSearch?: boolean;
30
+ }
31
+ export interface UnsplashSourceOptions {
32
+ /** RECOMMENDED — proxy injects the `Client-ID` server-side. */
33
+ readonly proxyEndpoint?: string | URL;
34
+ /** DEV ONLY — ships the key to the browser; ignored when `proxyEndpoint` is set. */
35
+ readonly accessKey?: string;
36
+ /** Defaults to `!!(proxyEndpoint || accessKey)`; the package never bundles a key. */
37
+ readonly enabled?: boolean;
38
+ /** REQUIRED when enabled — `utm_source` for mandatory attribution. */
39
+ readonly appName: string;
40
+ readonly themes?: UnsplashThemeConfig;
41
+ /** Default 24 (clamped 1–30). */
42
+ readonly perPage?: number;
43
+ /** Throttle floor between JSON requests. Default 1200. */
44
+ readonly minRequestIntervalMs?: number;
45
+ /** Result LRU TTL. Default 300_000. */
46
+ readonly cacheTtlMs?: number;
47
+ /**
48
+ * Per-request timeout for search / topic / photo lookups (ms). A request
49
+ * that exceeds it aborts and surfaces as a retryable `PROVIDER_NETWORK`
50
+ * error, so a blocked or flaky network path (e.g. a VPN/proxy black-holing
51
+ * `api.unsplash.com`) lets the sidebar fall back to "Unsplash unavailable"
52
+ * instead of spinning. Default 15_000. Ignored if not a positive number.
53
+ */
54
+ readonly requestTimeoutMs?: number;
55
+ /** Injectable fetch for tests / SSR. */
56
+ readonly fetch?: typeof globalThis.fetch;
57
+ /** Opt-in re-host instead of hotlinking. Default false. */
58
+ readonly rehostOnPick?: boolean;
59
+ }
60
+ //# sourceMappingURL=unsplash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unsplash.d.ts","sourceRoot":"","sources":["../../src/types/unsplash.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,0CAA0C;IAC1C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,gDAAgD;IAChD,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,sDAAsD;IACtD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,GAAG,UAAU,GAAG,UAAU,CAAC;IAC7D,4BAA4B;IAC5B,QAAQ,CAAC,aAAa,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;CACxC;AAED,MAAM,WAAW,mBAAmB;IACnC,8CAA8C;IAC9C,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IAC3C,8BAA8B;IAC9B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IACrD,2CAA2C;IAC3C,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,6EAA6E;IAC7E,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;CACnC;AAED,MAAM,WAAW,qBAAqB;IACrC,+DAA+D;IAC/D,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;IACtC,oFAAoF;IACpF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,qFAAqF;IACrF,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,sEAAsE;IACtE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,mBAAmB,CAAC;IACtC,iCAAiC;IACjC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,0DAA0D;IAC1D,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IACvC,uCAAuC;IACvC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;;OAMG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,wCAAwC;IACxC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IACzC,2DAA2D;IAC3D,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;CAChC"}
@@ -0,0 +1 @@
1
+ export { };
@@ -2,11 +2,15 @@
2
2
  "use client";
3
3
  var __webpack_require__ = {};
4
4
  (()=>{
5
- __webpack_require__.d = (exports1, definition)=>{
6
- for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
7
- enumerable: true,
8
- get: definition[key]
9
- });
5
+ __webpack_require__.d = (exports1, getters, values)=>{
6
+ var define = (defs, kind)=>{
7
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
8
+ enumerable: true,
9
+ [kind]: defs[key]
10
+ });
11
+ };
12
+ define(getters, "get");
13
+ define(values, "value");
10
14
  };
11
15
  })();
12
16
  (()=>{
@@ -27,11 +31,13 @@ __webpack_require__.r(__webpack_exports__);
27
31
  __webpack_require__.d(__webpack_exports__, {
28
32
  AssetBrowser: ()=>AssetBrowser
29
33
  });
34
+ const button_namespaceObject = require("@anvilkit/ui/button");
30
35
  const card_namespaceObject = require("@anvilkit/ui/card");
31
36
  const input_namespaceObject = require("@anvilkit/ui/input");
37
+ const windowed_namespaceObject = require("@anvilkit/ui/windowed");
32
38
  const external_react_namespaceObject = require("react");
33
- const external_react_dom_namespaceObject = require("react-dom");
34
39
  const infer_kind_cjs_namespaceObject = require("../utils/infer-kind.cjs");
40
+ const external_FolderTree_cjs_namespaceObject = require("./FolderTree.cjs");
35
41
  const KIND_FILTERS = [
36
42
  "image",
37
43
  "video",
@@ -43,20 +49,13 @@ const DEFAULT_VIRTUALIZE_THRESHOLD = 50;
43
49
  const DEFAULT_ITEM_HEIGHT = 56;
44
50
  const DEFAULT_MAX_HEIGHT = 400;
45
51
  const DEFAULT_PAGE_SIZE = 100;
46
- const OVERSCAN = 4;
47
- function AssetBrowser({ assets, onInsert, onDelete, onReplace, onEdit, searchEnabled = false, pageSize = DEFAULT_PAGE_SIZE, virtualizeThreshold = DEFAULT_VIRTUALIZE_THRESHOLD, itemHeight = DEFAULT_ITEM_HEIGHT, maxHeight = DEFAULT_MAX_HEIGHT }) {
52
+ function AssetBrowser({ assets, onInsert, onDelete, onReplace, onEdit, searchEnabled = false, aboveFilters, draggableRows = false, pageSize = DEFAULT_PAGE_SIZE, virtualizeThreshold = DEFAULT_VIRTUALIZE_THRESHOLD, itemHeight = DEFAULT_ITEM_HEIGHT, maxHeight = DEFAULT_MAX_HEIGHT }) {
48
53
  const [activeIndex, setActiveIndex] = external_react_namespaceObject.useState(assets.length > 0 ? 0 : -1);
49
- const [scrollTop, setScrollTop] = external_react_namespaceObject.useState(0);
50
54
  const [query, setQuery] = external_react_namespaceObject.useState("");
51
55
  const [activeKinds, setActiveKinds] = external_react_namespaceObject.useState([]);
52
56
  const [pageLimit, setPageLimit] = external_react_namespaceObject.useState(pageSize);
53
57
  const buttonRefs = external_react_namespaceObject.useRef([]);
54
- const scrollContainerRef = external_react_namespaceObject.useRef(null);
55
- const scrollFrameRef = external_react_namespaceObject.useRef(null);
56
- const pendingScrollTopRef = external_react_namespaceObject.useRef(0);
57
- external_react_namespaceObject.useEffect(()=>()=>{
58
- if (null !== scrollFrameRef.current && "function" == typeof cancelAnimationFrame) cancelAnimationFrame(scrollFrameRef.current);
59
- }, []);
58
+ const pendingFocusRef = external_react_namespaceObject.useRef(null);
60
59
  const searchIndex = external_react_namespaceObject.useMemo(()=>{
61
60
  if (!searchEnabled) return null;
62
61
  return assets.map((asset)=>({
@@ -96,7 +95,6 @@ function AssetBrowser({ assets, onInsert, onDelete, onReplace, onEdit, searchEna
96
95
  searchEnabled
97
96
  ]);
98
97
  const total = visibleSlice.length;
99
- const isVirtualized = total > virtualizeThreshold;
100
98
  const hasMore = searchEnabled && filteredAssets.length > visibleSlice.length;
101
99
  external_react_namespaceObject.useEffect(()=>{
102
100
  if (0 === total) return void setActiveIndex(-1);
@@ -104,31 +102,20 @@ function AssetBrowser({ assets, onInsert, onDelete, onReplace, onEdit, searchEna
104
102
  }, [
105
103
  total
106
104
  ]);
105
+ function focusRow(index) {
106
+ const node = buttonRefs.current[index];
107
+ if (node) {
108
+ node.focus();
109
+ return true;
110
+ }
111
+ return false;
112
+ }
107
113
  function moveFocus(nextIndex) {
108
114
  if (0 === total) return;
109
115
  const clampedIndex = Math.max(0, Math.min(nextIndex, total - 1));
110
- if (isVirtualized && scrollContainerRef.current) {
111
- const targetTop = clampedIndex * itemHeight;
112
- const targetBottom = targetTop + itemHeight;
113
- const viewTop = scrollContainerRef.current.scrollTop;
114
- let nextScrollTop = viewTop;
115
- if (targetTop < viewTop) nextScrollTop = targetTop;
116
- else if (targetBottom > viewTop + maxHeight) nextScrollTop = targetBottom - maxHeight;
117
- if (null !== scrollFrameRef.current && "function" == typeof cancelAnimationFrame) {
118
- cancelAnimationFrame(scrollFrameRef.current);
119
- scrollFrameRef.current = null;
120
- }
121
- pendingScrollTopRef.current = nextScrollTop;
122
- (0, external_react_dom_namespaceObject.flushSync)(()=>{
123
- setActiveIndex(clampedIndex);
124
- setScrollTop(nextScrollTop);
125
- });
126
- scrollContainerRef.current.scrollTop = nextScrollTop;
127
- buttonRefs.current[clampedIndex]?.focus();
128
- return;
129
- }
116
+ pendingFocusRef.current = clampedIndex;
130
117
  setActiveIndex(clampedIndex);
131
- buttonRefs.current[clampedIndex]?.focus();
118
+ if (focusRow(clampedIndex)) pendingFocusRef.current = null;
132
119
  }
133
120
  function toggleKind(kind) {
134
121
  setActiveKinds((current)=>current.includes(kind) ? current.filter((entry)=>entry !== kind) : [
@@ -136,17 +123,16 @@ function AssetBrowser({ assets, onInsert, onDelete, onReplace, onEdit, searchEna
136
123
  kind
137
124
  ]);
138
125
  }
139
- const firstVisible = isVirtualized ? Math.max(0, Math.floor(scrollTop / itemHeight) - OVERSCAN) : 0;
140
- const lastVisible = isVirtualized ? Math.min(total - 1, Math.ceil((scrollTop + maxHeight) / itemHeight) + OVERSCAN) : total - 1;
141
- const visibleAssets = 0 === total ? [] : isVirtualized ? visibleSlice.slice(firstVisible, lastVisible + 1) : visibleSlice;
142
- function renderRow(asset, index) {
143
- return /*#__PURE__*/ external_react_namespaceObject.createElement("li", {
144
- "aria-posinset": index + 1,
145
- "aria-setsize": total,
146
- key: asset.id,
147
- role: "listitem"
148
- }, /*#__PURE__*/ external_react_namespaceObject.createElement("button", {
126
+ const renderRow = (asset, index)=>/*#__PURE__*/ external_react_namespaceObject.createElement(external_react_namespaceObject.Fragment, null, /*#__PURE__*/ external_react_namespaceObject.createElement("button", {
149
127
  "aria-label": `Insert asset ${asset.id}`,
128
+ draggable: draggableRows,
129
+ "data-asset-draggable": draggableRows ? "" : void 0,
130
+ onDragStart: draggableRows ? (event)=>{
131
+ event.dataTransfer.setData(external_FolderTree_cjs_namespaceObject.ASSET_DRAG_MIME, JSON.stringify([
132
+ asset.id
133
+ ]));
134
+ event.dataTransfer.effectAllowed = "move";
135
+ } : void 0,
150
136
  onClick: ()=>{
151
137
  onInsert(asset);
152
138
  },
@@ -181,33 +167,42 @@ function AssetBrowser({ assets, onInsert, onDelete, onReplace, onEdit, searchEna
181
167
  },
182
168
  ref: (node)=>{
183
169
  buttonRefs.current[index] = node;
170
+ if (node && pendingFocusRef.current === index) {
171
+ pendingFocusRef.current = null;
172
+ node.focus();
173
+ }
184
174
  },
185
175
  tabIndex: activeIndex === index ? 0 : -1,
186
176
  type: "button"
187
- }, /*#__PURE__*/ external_react_namespaceObject.createElement("span", null, asset.id), /*#__PURE__*/ external_react_namespaceObject.createElement("span", null, asset.meta?.mimeType ?? "unknown type")), void 0 !== onEdit ? /*#__PURE__*/ external_react_namespaceObject.createElement("button", {
177
+ }, /*#__PURE__*/ external_react_namespaceObject.createElement("span", null, asset.id), /*#__PURE__*/ external_react_namespaceObject.createElement("span", null, asset.meta?.mimeType ?? "unknown type")), void 0 !== onEdit ? /*#__PURE__*/ external_react_namespaceObject.createElement(button_namespaceObject.Button, {
188
178
  "aria-label": `Edit asset ${asset.id}`,
189
179
  "data-asset-action": "edit",
190
180
  onClick: ()=>{
191
181
  onEdit(asset);
192
182
  },
193
- type: "button"
194
- }, "Edit") : null, void 0 !== onReplace ? /*#__PURE__*/ external_react_namespaceObject.createElement("button", {
183
+ type: "button",
184
+ variant: "ghost",
185
+ size: "sm"
186
+ }, "Edit") : null, void 0 !== onReplace ? /*#__PURE__*/ external_react_namespaceObject.createElement(button_namespaceObject.Button, {
195
187
  "aria-label": `Replace asset ${asset.id}`,
196
188
  "data-asset-action": "replace",
197
189
  onClick: ()=>{
198
190
  onReplace(asset);
199
191
  },
200
- type: "button"
201
- }, "Replace") : null, void 0 !== onDelete ? /*#__PURE__*/ external_react_namespaceObject.createElement("button", {
192
+ type: "button",
193
+ variant: "ghost",
194
+ size: "sm"
195
+ }, "Replace") : null, void 0 !== onDelete ? /*#__PURE__*/ external_react_namespaceObject.createElement(button_namespaceObject.Button, {
202
196
  "aria-label": `Delete asset ${asset.id}`,
203
197
  "data-asset-action": "delete",
204
198
  onClick: ()=>{
205
199
  onDelete(asset);
206
200
  },
207
- type: "button"
201
+ type: "button",
202
+ variant: "ghost",
203
+ size: "sm"
208
204
  }, "Delete") : null);
209
- }
210
- const filterRow = searchEnabled ? /*#__PURE__*/ external_react_namespaceObject.createElement("div", {
205
+ const searchRow = searchEnabled ? /*#__PURE__*/ external_react_namespaceObject.createElement("div", {
211
206
  "data-asset-manager-filters": true
212
207
  }, /*#__PURE__*/ external_react_namespaceObject.createElement(input_namespaceObject.Input, {
213
208
  "aria-label": "Search assets",
@@ -222,7 +217,7 @@ function AssetBrowser({ assets, onInsert, onDelete, onReplace, onEdit, searchEna
222
217
  role: "group"
223
218
  }, KIND_FILTERS.map((kind)=>{
224
219
  const active = activeKinds.includes(kind);
225
- return /*#__PURE__*/ external_react_namespaceObject.createElement("button", {
220
+ return /*#__PURE__*/ external_react_namespaceObject.createElement(button_namespaceObject.Button, {
226
221
  "aria-label": `Filter ${kind} assets`,
227
222
  "aria-pressed": active,
228
223
  "data-asset-kind-filter": kind,
@@ -231,9 +226,12 @@ function AssetBrowser({ assets, onInsert, onDelete, onReplace, onEdit, searchEna
231
226
  toggleKind(kind);
232
227
  setPageLimit(pageSize);
233
228
  },
234
- type: "button"
229
+ type: "button",
230
+ variant: active ? "secondary" : "ghost",
231
+ size: "sm"
235
232
  }, kind);
236
233
  }))) : null;
234
+ const filterRow = /*#__PURE__*/ external_react_namespaceObject.createElement(external_react_namespaceObject.Fragment, null, aboveFilters, searchRow);
237
235
  if (0 === total) {
238
236
  const emptyLabel = searchEnabled && ("" !== query || activeKinds.length > 0) ? "No assets match the current filters." : "No assets uploaded yet.";
239
237
  return /*#__PURE__*/ external_react_namespaceObject.createElement(card_namespaceObject.Card, null, /*#__PURE__*/ external_react_namespaceObject.createElement(card_namespaceObject.CardHeader, null, /*#__PURE__*/ external_react_namespaceObject.createElement(card_namespaceObject.CardTitle, null, "Asset browser"), /*#__PURE__*/ external_react_namespaceObject.createElement(card_namespaceObject.CardDescription, null, "Validated assets currently registered in memory.")), /*#__PURE__*/ external_react_namespaceObject.createElement(card_namespaceObject.CardContent, null, filterRow, /*#__PURE__*/ external_react_namespaceObject.createElement("ul", {
@@ -243,58 +241,25 @@ function AssetBrowser({ assets, onInsert, onDelete, onReplace, onEdit, searchEna
243
241
  role: "listitem"
244
242
  }, emptyLabel))));
245
243
  }
246
- if (!isVirtualized) return /*#__PURE__*/ external_react_namespaceObject.createElement(card_namespaceObject.Card, null, /*#__PURE__*/ external_react_namespaceObject.createElement(card_namespaceObject.CardHeader, null, /*#__PURE__*/ external_react_namespaceObject.createElement(card_namespaceObject.CardTitle, null, "Asset browser"), /*#__PURE__*/ external_react_namespaceObject.createElement(card_namespaceObject.CardDescription, null, "Validated assets currently registered in memory.")), /*#__PURE__*/ external_react_namespaceObject.createElement(card_namespaceObject.CardContent, null, filterRow, /*#__PURE__*/ external_react_namespaceObject.createElement("ul", {
247
- "aria-label": "Assets",
248
- role: "list"
249
- }, visibleAssets.map((asset, offset)=>renderRow(asset, offset))), hasMore ? /*#__PURE__*/ external_react_namespaceObject.createElement("button", {
250
- "data-asset-action": "load-more",
251
- onClick: ()=>{
252
- setPageLimit((current)=>current + pageSize);
253
- },
254
- type: "button"
255
- }, "Load more") : null));
256
- const totalHeight = total * itemHeight;
257
- const offsetY = firstVisible * itemHeight;
258
- return /*#__PURE__*/ external_react_namespaceObject.createElement(card_namespaceObject.Card, null, /*#__PURE__*/ external_react_namespaceObject.createElement(card_namespaceObject.CardHeader, null, /*#__PURE__*/ external_react_namespaceObject.createElement(card_namespaceObject.CardTitle, null, "Asset browser"), /*#__PURE__*/ external_react_namespaceObject.createElement(card_namespaceObject.CardDescription, null, "Validated assets currently registered in memory.")), /*#__PURE__*/ external_react_namespaceObject.createElement(card_namespaceObject.CardContent, null, filterRow, /*#__PURE__*/ external_react_namespaceObject.createElement("div", {
259
- "data-asset-manager-virtual": true,
260
- onScroll: (event)=>{
261
- const next = event.currentTarget.scrollTop;
262
- if ("function" != typeof requestAnimationFrame) return void setScrollTop(next);
263
- pendingScrollTopRef.current = next;
264
- if (null !== scrollFrameRef.current) return;
265
- scrollFrameRef.current = requestAnimationFrame(()=>{
266
- scrollFrameRef.current = null;
267
- setScrollTop(pendingScrollTopRef.current);
268
- });
269
- },
270
- ref: scrollContainerRef,
271
- style: {
272
- height: maxHeight,
273
- overflowY: "auto",
274
- position: "relative"
275
- }
276
- }, /*#__PURE__*/ external_react_namespaceObject.createElement("div", {
277
- style: {
278
- height: totalHeight,
279
- position: "relative"
280
- }
281
- }, /*#__PURE__*/ external_react_namespaceObject.createElement("ul", {
244
+ return /*#__PURE__*/ external_react_namespaceObject.createElement(card_namespaceObject.Card, null, /*#__PURE__*/ external_react_namespaceObject.createElement(card_namespaceObject.CardHeader, null, /*#__PURE__*/ external_react_namespaceObject.createElement(card_namespaceObject.CardTitle, null, "Asset browser"), /*#__PURE__*/ external_react_namespaceObject.createElement(card_namespaceObject.CardDescription, null, "Validated assets currently registered in memory.")), /*#__PURE__*/ external_react_namespaceObject.createElement(card_namespaceObject.CardContent, null, filterRow, /*#__PURE__*/ external_react_namespaceObject.createElement(windowed_namespaceObject.Windowed, {
245
+ activeIndex: activeIndex >= 0 ? activeIndex : void 0,
282
246
  "aria-label": "Assets",
283
- role: "list",
284
- style: {
285
- margin: 0,
286
- padding: 0,
287
- position: "absolute",
288
- top: offsetY,
289
- left: 0,
290
- right: 0
291
- }
292
- }, visibleAssets.map((asset, offset)=>renderRow(asset, firstVisible + offset))))), hasMore ? /*#__PURE__*/ external_react_namespaceObject.createElement("button", {
247
+ as: "ul",
248
+ "data-testid": "asset-browser-virtualized",
249
+ estimateSize: itemHeight,
250
+ items: visibleSlice,
251
+ itemKey: (asset)=>asset.id,
252
+ maxHeight: maxHeight,
253
+ renderItem: renderRow,
254
+ threshold: virtualizeThreshold
255
+ }), hasMore ? /*#__PURE__*/ external_react_namespaceObject.createElement(button_namespaceObject.Button, {
293
256
  "data-asset-action": "load-more",
294
257
  onClick: ()=>{
295
258
  setPageLimit((current)=>current + pageSize);
296
259
  },
297
- type: "button"
260
+ type: "button",
261
+ variant: "outline",
262
+ size: "sm"
298
263
  }, "Load more") : null));
299
264
  }
300
265
  exports.AssetBrowser = __webpack_exports__.AssetBrowser;
@@ -1,3 +1,4 @@
1
+ import * as React from "react";
1
2
  import type { UploadResult } from "../types/types.js";
2
3
  export interface AssetBrowserProps {
3
4
  readonly assets: readonly UploadResult[];
@@ -25,6 +26,16 @@ export interface AssetBrowserProps {
25
26
  * pre-filter at the host layer) keep their previous chrome.
26
27
  */
27
28
  readonly searchEnabled?: boolean;
29
+ /**
30
+ * Optional content rendered above the filter row — typically a folder
31
+ * breadcrumb + tree + source tabs (PRD 0002 §7.4). Purely additive.
32
+ */
33
+ readonly aboveFilters?: React.ReactNode;
34
+ /**
35
+ * When `true`, asset rows are draggable carrying an asset-id payload
36
+ * (`ASSET_DRAG_MIME`) so they can be dropped onto a `FolderTree` row.
37
+ */
38
+ readonly draggableRows?: boolean;
28
39
  /**
29
40
  * Page size used by the "Load more" affordance once the visible
30
41
  * slice exceeds this number. Defaults to 100.
@@ -33,22 +44,21 @@ export interface AssetBrowserProps {
33
44
  /**
34
45
  * Threshold above which the list windows visible items. Below the
35
46
  * threshold the entire list renders inline so small libraries skip
36
- * scroll math entirely.
47
+ * scroll math entirely. Forwarded to the shared `Windowed` primitive.
37
48
  */
38
49
  readonly virtualizeThreshold?: number;
39
50
  /**
40
51
  * Pixel height of a single row when virtualizing.
41
52
  *
42
- * **Fixed-height contract:** the windowing math (visible range, scroll
43
- * offset, and keyboard-focus scroll) assumes every row is exactly
44
- * `itemHeight` tall. Rows that wrap or vary in height (long names,
45
- * thumbnails) will desync the scroll position and focus calculation.
46
- * Keep rows uniform, or raise `virtualizeThreshold` so the list renders
53
+ * **Fixed-height contract:** the windowing math assumes every row is
54
+ * roughly `itemHeight` tall. Rows that wrap or vary in height (long
55
+ * names, thumbnails) will desync the scroll-into-view calculation. Keep
56
+ * rows uniform, or raise `virtualizeThreshold` so the list renders
47
57
  * inline instead.
48
58
  */
49
59
  readonly itemHeight?: number;
50
60
  /** Pixel height of the scroll container when virtualizing. */
51
61
  readonly maxHeight?: number;
52
62
  }
53
- export declare function AssetBrowser({ assets, onInsert, onDelete, onReplace, onEdit, searchEnabled, pageSize, virtualizeThreshold, itemHeight, maxHeight, }: AssetBrowserProps): import("react/jsx-runtime").JSX.Element;
63
+ export declare function AssetBrowser({ assets, onInsert, onDelete, onReplace, onEdit, searchEnabled, aboveFilters, draggableRows, pageSize, virtualizeThreshold, itemHeight, maxHeight, }: AssetBrowserProps): import("react/jsx-runtime").JSX.Element;
54
64
  //# sourceMappingURL=AssetBrowser.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AssetBrowser.d.cts","sourceRoot":"","sources":["../../src/ui/AssetBrowser.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAa,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAWjE,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IACjD;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IAClD;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IACnD;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IAChD;;;;OAIG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC;;;;;;;;;OASG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,8DAA8D;IAC9D,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC5B;AAQD,wBAAgB,YAAY,CAAC,EAC5B,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,MAAM,EACN,aAAqB,EACrB,QAA4B,EAC5B,mBAAkD,EAClD,UAAgC,EAChC,SAA8B,GAC9B,EAAE,iBAAiB,2CAkZnB"}
1
+ {"version":3,"file":"AssetBrowser.d.cts","sourceRoot":"","sources":["../../src/ui/AssetBrowser.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAa,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAYjE,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IACjD;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IAClD;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IACnD;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IAChD;;;;OAIG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC;;;OAGG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxC;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC;;;;;;;;OAQG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,8DAA8D;IAC9D,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC5B;AAOD,wBAAgB,YAAY,CAAC,EAC5B,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,MAAM,EACN,aAAqB,EACrB,YAAY,EACZ,aAAqB,EACrB,QAA4B,EAC5B,mBAAkD,EAClD,UAAgC,EAChC,SAA8B,GAC9B,EAAE,iBAAiB,2CAqUnB"}
@@ -1,3 +1,4 @@
1
+ import * as React from "react";
1
2
  import type { UploadResult } from "../types/types.js";
2
3
  export interface AssetBrowserProps {
3
4
  readonly assets: readonly UploadResult[];
@@ -25,6 +26,16 @@ export interface AssetBrowserProps {
25
26
  * pre-filter at the host layer) keep their previous chrome.
26
27
  */
27
28
  readonly searchEnabled?: boolean;
29
+ /**
30
+ * Optional content rendered above the filter row — typically a folder
31
+ * breadcrumb + tree + source tabs (PRD 0002 §7.4). Purely additive.
32
+ */
33
+ readonly aboveFilters?: React.ReactNode;
34
+ /**
35
+ * When `true`, asset rows are draggable carrying an asset-id payload
36
+ * (`ASSET_DRAG_MIME`) so they can be dropped onto a `FolderTree` row.
37
+ */
38
+ readonly draggableRows?: boolean;
28
39
  /**
29
40
  * Page size used by the "Load more" affordance once the visible
30
41
  * slice exceeds this number. Defaults to 100.
@@ -33,22 +44,21 @@ export interface AssetBrowserProps {
33
44
  /**
34
45
  * Threshold above which the list windows visible items. Below the
35
46
  * threshold the entire list renders inline so small libraries skip
36
- * scroll math entirely.
47
+ * scroll math entirely. Forwarded to the shared `Windowed` primitive.
37
48
  */
38
49
  readonly virtualizeThreshold?: number;
39
50
  /**
40
51
  * Pixel height of a single row when virtualizing.
41
52
  *
42
- * **Fixed-height contract:** the windowing math (visible range, scroll
43
- * offset, and keyboard-focus scroll) assumes every row is exactly
44
- * `itemHeight` tall. Rows that wrap or vary in height (long names,
45
- * thumbnails) will desync the scroll position and focus calculation.
46
- * Keep rows uniform, or raise `virtualizeThreshold` so the list renders
53
+ * **Fixed-height contract:** the windowing math assumes every row is
54
+ * roughly `itemHeight` tall. Rows that wrap or vary in height (long
55
+ * names, thumbnails) will desync the scroll-into-view calculation. Keep
56
+ * rows uniform, or raise `virtualizeThreshold` so the list renders
47
57
  * inline instead.
48
58
  */
49
59
  readonly itemHeight?: number;
50
60
  /** Pixel height of the scroll container when virtualizing. */
51
61
  readonly maxHeight?: number;
52
62
  }
53
- export declare function AssetBrowser({ assets, onInsert, onDelete, onReplace, onEdit, searchEnabled, pageSize, virtualizeThreshold, itemHeight, maxHeight, }: AssetBrowserProps): import("react/jsx-runtime").JSX.Element;
63
+ export declare function AssetBrowser({ assets, onInsert, onDelete, onReplace, onEdit, searchEnabled, aboveFilters, draggableRows, pageSize, virtualizeThreshold, itemHeight, maxHeight, }: AssetBrowserProps): import("react/jsx-runtime").JSX.Element;
54
64
  //# sourceMappingURL=AssetBrowser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AssetBrowser.d.ts","sourceRoot":"","sources":["../../src/ui/AssetBrowser.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAa,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAWjE,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IACjD;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IAClD;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IACnD;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IAChD;;;;OAIG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC;;;;;;;;;OASG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,8DAA8D;IAC9D,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC5B;AAQD,wBAAgB,YAAY,CAAC,EAC5B,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,MAAM,EACN,aAAqB,EACrB,QAA4B,EAC5B,mBAAkD,EAClD,UAAgC,EAChC,SAA8B,GAC9B,EAAE,iBAAiB,2CAkZnB"}
1
+ {"version":3,"file":"AssetBrowser.d.ts","sourceRoot":"","sources":["../../src/ui/AssetBrowser.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAa,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAYjE,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IACjD;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IAClD;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IACnD;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IAChD;;;;OAIG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC;;;OAGG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxC;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC;;;;;;;;OAQG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,8DAA8D;IAC9D,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC5B;AAOD,wBAAgB,YAAY,CAAC,EAC5B,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,MAAM,EACN,aAAqB,EACrB,YAAY,EACZ,aAAqB,EACrB,QAA4B,EAC5B,mBAAkD,EAClD,UAAgC,EAChC,SAA8B,GAC9B,EAAE,iBAAiB,2CAqUnB"}