@anvilkit/plugin-asset-manager 0.1.6 → 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 (209) hide show
  1. package/README.md +26 -18
  2. package/dist/index.cjs +7 -0
  3. package/dist/index.d.cts +11 -3
  4. package/dist/index.d.cts.map +1 -1
  5. package/dist/index.d.ts +11 -3
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +2 -1
  8. package/dist/plugin.cjs +67 -4
  9. package/dist/plugin.d.cts +3 -2
  10. package/dist/plugin.d.cts.map +1 -1
  11. package/dist/plugin.d.ts +3 -2
  12. package/dist/plugin.d.ts.map +1 -1
  13. package/dist/plugin.js +67 -4
  14. package/dist/sources/composite-source.cjs +137 -0
  15. package/dist/sources/composite-source.d.cts +39 -0
  16. package/dist/sources/composite-source.d.cts.map +1 -0
  17. package/dist/sources/composite-source.d.ts +39 -0
  18. package/dist/sources/composite-source.d.ts.map +1 -0
  19. package/dist/sources/composite-source.js +99 -0
  20. package/dist/sources/federated-search.cjs +163 -0
  21. package/dist/sources/federated-search.d.cts +33 -0
  22. package/dist/sources/federated-search.d.cts.map +1 -0
  23. package/dist/sources/federated-search.d.ts +33 -0
  24. package/dist/sources/federated-search.d.ts.map +1 -0
  25. package/dist/sources/federated-search.js +113 -0
  26. package/dist/sources/provider.cjs +18 -0
  27. package/dist/sources/provider.d.cts +51 -0
  28. package/dist/sources/provider.d.cts.map +1 -0
  29. package/dist/sources/provider.d.ts +51 -0
  30. package/dist/sources/provider.d.ts.map +1 -0
  31. package/dist/sources/provider.js +1 -0
  32. package/dist/sources/unsplash/client.cjs +189 -0
  33. package/dist/sources/unsplash/client.d.cts +87 -0
  34. package/dist/sources/unsplash/client.d.cts.map +1 -0
  35. package/dist/sources/unsplash/client.d.ts +87 -0
  36. package/dist/sources/unsplash/client.d.ts.map +1 -0
  37. package/dist/sources/unsplash/client.js +151 -0
  38. package/dist/sources/unsplash/index.cjs +192 -0
  39. package/dist/sources/unsplash/index.d.cts +16 -0
  40. package/dist/sources/unsplash/index.d.cts.map +1 -0
  41. package/dist/sources/unsplash/index.d.ts +16 -0
  42. package/dist/sources/unsplash/index.d.ts.map +1 -0
  43. package/dist/sources/unsplash/index.js +148 -0
  44. package/dist/sources/unsplash/themes.cjs +141 -0
  45. package/dist/sources/unsplash/themes.d.cts +18 -0
  46. package/dist/sources/unsplash/themes.d.cts.map +1 -0
  47. package/dist/sources/unsplash/themes.d.ts +18 -0
  48. package/dist/sources/unsplash/themes.d.ts.map +1 -0
  49. package/dist/sources/unsplash/themes.js +93 -0
  50. package/dist/sources/unsplash/throttle-cache.cjs +86 -0
  51. package/dist/sources/unsplash/throttle-cache.d.cts +25 -0
  52. package/dist/sources/unsplash/throttle-cache.d.cts.map +1 -0
  53. package/dist/sources/unsplash/throttle-cache.d.ts +25 -0
  54. package/dist/sources/unsplash/throttle-cache.d.ts.map +1 -0
  55. package/dist/sources/unsplash/throttle-cache.js +45 -0
  56. package/dist/types/categories.cjs +18 -0
  57. package/dist/types/categories.d.cts +48 -0
  58. package/dist/types/categories.d.cts.map +1 -0
  59. package/dist/types/categories.d.ts +48 -0
  60. package/dist/types/categories.d.ts.map +1 -0
  61. package/dist/types/categories.js +1 -0
  62. package/dist/types/data-source.cjs +18 -0
  63. package/dist/types/data-source.d.cts +59 -0
  64. package/dist/types/data-source.d.cts.map +1 -0
  65. package/dist/types/data-source.d.ts +59 -0
  66. package/dist/types/data-source.d.ts.map +1 -0
  67. package/dist/types/data-source.js +1 -0
  68. package/dist/types/filter.cjs +18 -0
  69. package/dist/types/filter.d.cts +55 -0
  70. package/dist/types/filter.d.cts.map +1 -0
  71. package/dist/types/filter.d.ts +55 -0
  72. package/dist/types/filter.d.ts.map +1 -0
  73. package/dist/types/filter.js +1 -0
  74. package/dist/types/folders.cjs +42 -0
  75. package/dist/types/folders.d.cts +46 -0
  76. package/dist/types/folders.d.cts.map +1 -0
  77. package/dist/types/folders.d.ts +46 -0
  78. package/dist/types/folders.d.ts.map +1 -0
  79. package/dist/types/folders.js +4 -0
  80. package/dist/types/options.cjs +18 -0
  81. package/dist/types/options.d.cts +68 -0
  82. package/dist/types/options.d.cts.map +1 -0
  83. package/dist/types/options.d.ts +68 -0
  84. package/dist/types/options.d.ts.map +1 -0
  85. package/dist/types/options.js +1 -0
  86. package/dist/types/types.d.cts +15 -27
  87. package/dist/types/types.d.cts.map +1 -1
  88. package/dist/types/types.d.ts +15 -27
  89. package/dist/types/types.d.ts.map +1 -1
  90. package/dist/types/unsplash.cjs +18 -0
  91. package/dist/types/unsplash.d.cts +60 -0
  92. package/dist/types/unsplash.d.cts.map +1 -0
  93. package/dist/types/unsplash.d.ts +60 -0
  94. package/dist/types/unsplash.d.ts.map +1 -0
  95. package/dist/types/unsplash.js +1 -0
  96. package/dist/ui/AssetBrowser.cjs +33 -12
  97. package/dist/ui/AssetBrowser.d.cts +12 -1
  98. package/dist/ui/AssetBrowser.d.cts.map +1 -1
  99. package/dist/ui/AssetBrowser.d.ts +12 -1
  100. package/dist/ui/AssetBrowser.d.ts.map +1 -1
  101. package/dist/ui/AssetBrowser.js +33 -12
  102. package/dist/ui/AssetManagerUI.cjs +8 -2
  103. package/dist/ui/AssetManagerUI.d.cts +19 -3
  104. package/dist/ui/AssetManagerUI.d.cts.map +1 -1
  105. package/dist/ui/AssetManagerUI.d.ts +19 -3
  106. package/dist/ui/AssetManagerUI.d.ts.map +1 -1
  107. package/dist/ui/AssetManagerUI.js +8 -2
  108. package/dist/ui/DeleteFolderDialog.cjs +78 -0
  109. package/dist/ui/DeleteFolderDialog.d.cts +11 -0
  110. package/dist/ui/DeleteFolderDialog.d.cts.map +1 -0
  111. package/dist/ui/DeleteFolderDialog.d.ts +11 -0
  112. package/dist/ui/DeleteFolderDialog.d.ts.map +1 -0
  113. package/dist/ui/DeleteFolderDialog.js +40 -0
  114. package/dist/ui/EmptyFolderState.cjs +53 -0
  115. package/dist/ui/EmptyFolderState.d.cts +6 -0
  116. package/dist/ui/EmptyFolderState.d.cts.map +1 -0
  117. package/dist/ui/EmptyFolderState.d.ts +6 -0
  118. package/dist/ui/EmptyFolderState.d.ts.map +1 -0
  119. package/dist/ui/EmptyFolderState.js +15 -0
  120. package/dist/ui/FolderBreadcrumb.cjs +73 -0
  121. package/dist/ui/FolderBreadcrumb.d.cts +9 -0
  122. package/dist/ui/FolderBreadcrumb.d.cts.map +1 -0
  123. package/dist/ui/FolderBreadcrumb.d.ts +9 -0
  124. package/dist/ui/FolderBreadcrumb.d.ts.map +1 -0
  125. package/dist/ui/FolderBreadcrumb.js +35 -0
  126. package/dist/ui/FolderNameDialog.cjs +98 -0
  127. package/dist/ui/FolderNameDialog.d.cts +14 -0
  128. package/dist/ui/FolderNameDialog.d.cts.map +1 -0
  129. package/dist/ui/FolderNameDialog.d.ts +14 -0
  130. package/dist/ui/FolderNameDialog.d.ts.map +1 -0
  131. package/dist/ui/FolderNameDialog.js +60 -0
  132. package/dist/ui/FolderTree.cjs +83 -0
  133. package/dist/ui/FolderTree.d.cts +13 -0
  134. package/dist/ui/FolderTree.d.cts.map +1 -0
  135. package/dist/ui/FolderTree.d.ts +13 -0
  136. package/dist/ui/FolderTree.d.ts.map +1 -0
  137. package/dist/ui/FolderTree.js +42 -0
  138. package/dist/ui/MetadataPanel.cjs +7 -4
  139. package/dist/ui/MetadataPanel.d.cts.map +1 -1
  140. package/dist/ui/MetadataPanel.d.ts.map +1 -1
  141. package/dist/ui/MetadataPanel.js +7 -4
  142. package/dist/ui/MoveTargetPicker.cjs +84 -0
  143. package/dist/ui/MoveTargetPicker.d.cts +16 -0
  144. package/dist/ui/MoveTargetPicker.d.cts.map +1 -0
  145. package/dist/ui/MoveTargetPicker.d.ts +16 -0
  146. package/dist/ui/MoveTargetPicker.d.ts.map +1 -0
  147. package/dist/ui/MoveTargetPicker.js +46 -0
  148. package/dist/ui/ReplaceAssetDialog.d.cts +2 -1
  149. package/dist/ui/ReplaceAssetDialog.d.cts.map +1 -1
  150. package/dist/ui/ReplaceAssetDialog.d.ts +2 -1
  151. package/dist/ui/ReplaceAssetDialog.d.ts.map +1 -1
  152. package/dist/ui/UnsplashPanel.cjs +134 -0
  153. package/dist/ui/UnsplashPanel.d.cts +28 -0
  154. package/dist/ui/UnsplashPanel.d.cts.map +1 -0
  155. package/dist/ui/UnsplashPanel.d.ts +28 -0
  156. package/dist/ui/UnsplashPanel.d.ts.map +1 -0
  157. package/dist/ui/UnsplashPanel.js +96 -0
  158. package/dist/ui/UploadButton.cjs +1 -5
  159. package/dist/ui/UploadButton.d.cts +9 -2
  160. package/dist/ui/UploadButton.d.cts.map +1 -1
  161. package/dist/ui/UploadButton.d.ts +9 -2
  162. package/dist/ui/UploadButton.d.ts.map +1 -1
  163. package/dist/ui/UploadButton.js +1 -5
  164. package/dist/ui/index.cjs +37 -0
  165. package/dist/ui/index.d.cts +14 -0
  166. package/dist/ui/index.d.cts.map +1 -1
  167. package/dist/ui/index.d.ts +14 -0
  168. package/dist/ui/index.d.ts.map +1 -1
  169. package/dist/ui/index.js +7 -0
  170. package/dist/utils/data-source.cjs +177 -0
  171. package/dist/utils/data-source.d.cts +63 -0
  172. package/dist/utils/data-source.d.cts.map +1 -0
  173. package/dist/utils/data-source.d.ts +63 -0
  174. package/dist/utils/data-source.d.ts.map +1 -0
  175. package/dist/utils/data-source.js +136 -0
  176. package/dist/utils/errors.cjs +18 -0
  177. package/dist/utils/errors.d.cts +27 -0
  178. package/dist/utils/errors.d.cts.map +1 -1
  179. package/dist/utils/errors.d.ts +27 -0
  180. package/dist/utils/errors.d.ts.map +1 -1
  181. package/dist/utils/errors.js +16 -1
  182. package/dist/utils/folders.cjs +261 -0
  183. package/dist/utils/folders.d.cts +49 -0
  184. package/dist/utils/folders.d.cts.map +1 -0
  185. package/dist/utils/folders.d.ts +49 -0
  186. package/dist/utils/folders.d.ts.map +1 -0
  187. package/dist/utils/folders.js +223 -0
  188. package/dist/utils/registry.cjs +27 -12
  189. package/dist/utils/registry.d.cts +21 -1
  190. package/dist/utils/registry.d.cts.map +1 -1
  191. package/dist/utils/registry.d.ts +21 -1
  192. package/dist/utils/registry.d.ts.map +1 -1
  193. package/dist/utils/registry.js +20 -11
  194. package/dist/utils/studio-asset-source.cjs +5 -2
  195. package/dist/utils/studio-asset-source.d.cts +6 -1
  196. package/dist/utils/studio-asset-source.d.cts.map +1 -1
  197. package/dist/utils/studio-asset-source.d.ts +6 -1
  198. package/dist/utils/studio-asset-source.d.ts.map +1 -1
  199. package/dist/utils/studio-asset-source.js +1 -1
  200. package/dist/utils/validate-upload-result.d.cts +2 -1
  201. package/dist/utils/validate-upload-result.d.cts.map +1 -1
  202. package/dist/utils/validate-upload-result.d.ts +2 -1
  203. package/dist/utils/validate-upload-result.d.ts.map +1 -1
  204. package/dist/version.cjs +1 -1
  205. package/dist/version.d.cts +1 -1
  206. package/dist/version.d.ts +1 -1
  207. package/dist/version.js +1 -1
  208. package/meta/config.json +1 -1
  209. package/package.json +12 -2
@@ -31,11 +31,13 @@ __webpack_require__.r(__webpack_exports__);
31
31
  __webpack_require__.d(__webpack_exports__, {
32
32
  AssetBrowser: ()=>AssetBrowser
33
33
  });
34
+ const button_namespaceObject = require("@anvilkit/ui/button");
34
35
  const card_namespaceObject = require("@anvilkit/ui/card");
35
36
  const input_namespaceObject = require("@anvilkit/ui/input");
36
37
  const windowed_namespaceObject = require("@anvilkit/ui/windowed");
37
38
  const external_react_namespaceObject = require("react");
38
39
  const infer_kind_cjs_namespaceObject = require("../utils/infer-kind.cjs");
40
+ const external_FolderTree_cjs_namespaceObject = require("./FolderTree.cjs");
39
41
  const KIND_FILTERS = [
40
42
  "image",
41
43
  "video",
@@ -47,7 +49,7 @@ const DEFAULT_VIRTUALIZE_THRESHOLD = 50;
47
49
  const DEFAULT_ITEM_HEIGHT = 56;
48
50
  const DEFAULT_MAX_HEIGHT = 400;
49
51
  const DEFAULT_PAGE_SIZE = 100;
50
- 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 }) {
51
53
  const [activeIndex, setActiveIndex] = external_react_namespaceObject.useState(assets.length > 0 ? 0 : -1);
52
54
  const [query, setQuery] = external_react_namespaceObject.useState("");
53
55
  const [activeKinds, setActiveKinds] = external_react_namespaceObject.useState([]);
@@ -123,6 +125,14 @@ function AssetBrowser({ assets, onInsert, onDelete, onReplace, onEdit, searchEna
123
125
  }
124
126
  const renderRow = (asset, index)=>/*#__PURE__*/ external_react_namespaceObject.createElement(external_react_namespaceObject.Fragment, null, /*#__PURE__*/ external_react_namespaceObject.createElement("button", {
125
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,
126
136
  onClick: ()=>{
127
137
  onInsert(asset);
128
138
  },
@@ -164,29 +174,35 @@ function AssetBrowser({ assets, onInsert, onDelete, onReplace, onEdit, searchEna
164
174
  },
165
175
  tabIndex: activeIndex === index ? 0 : -1,
166
176
  type: "button"
167
- }, /*#__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, {
168
178
  "aria-label": `Edit asset ${asset.id}`,
169
179
  "data-asset-action": "edit",
170
180
  onClick: ()=>{
171
181
  onEdit(asset);
172
182
  },
173
- type: "button"
174
- }, "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, {
175
187
  "aria-label": `Replace asset ${asset.id}`,
176
188
  "data-asset-action": "replace",
177
189
  onClick: ()=>{
178
190
  onReplace(asset);
179
191
  },
180
- type: "button"
181
- }, "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, {
182
196
  "aria-label": `Delete asset ${asset.id}`,
183
197
  "data-asset-action": "delete",
184
198
  onClick: ()=>{
185
199
  onDelete(asset);
186
200
  },
187
- type: "button"
201
+ type: "button",
202
+ variant: "ghost",
203
+ size: "sm"
188
204
  }, "Delete") : null);
189
- const filterRow = searchEnabled ? /*#__PURE__*/ external_react_namespaceObject.createElement("div", {
205
+ const searchRow = searchEnabled ? /*#__PURE__*/ external_react_namespaceObject.createElement("div", {
190
206
  "data-asset-manager-filters": true
191
207
  }, /*#__PURE__*/ external_react_namespaceObject.createElement(input_namespaceObject.Input, {
192
208
  "aria-label": "Search assets",
@@ -201,7 +217,7 @@ function AssetBrowser({ assets, onInsert, onDelete, onReplace, onEdit, searchEna
201
217
  role: "group"
202
218
  }, KIND_FILTERS.map((kind)=>{
203
219
  const active = activeKinds.includes(kind);
204
- return /*#__PURE__*/ external_react_namespaceObject.createElement("button", {
220
+ return /*#__PURE__*/ external_react_namespaceObject.createElement(button_namespaceObject.Button, {
205
221
  "aria-label": `Filter ${kind} assets`,
206
222
  "aria-pressed": active,
207
223
  "data-asset-kind-filter": kind,
@@ -210,9 +226,12 @@ function AssetBrowser({ assets, onInsert, onDelete, onReplace, onEdit, searchEna
210
226
  toggleKind(kind);
211
227
  setPageLimit(pageSize);
212
228
  },
213
- type: "button"
229
+ type: "button",
230
+ variant: active ? "secondary" : "ghost",
231
+ size: "sm"
214
232
  }, kind);
215
233
  }))) : null;
234
+ const filterRow = /*#__PURE__*/ external_react_namespaceObject.createElement(external_react_namespaceObject.Fragment, null, aboveFilters, searchRow);
216
235
  if (0 === total) {
217
236
  const emptyLabel = searchEnabled && ("" !== query || activeKinds.length > 0) ? "No assets match the current filters." : "No assets uploaded yet.";
218
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", {
@@ -233,12 +252,14 @@ function AssetBrowser({ assets, onInsert, onDelete, onReplace, onEdit, searchEna
233
252
  maxHeight: maxHeight,
234
253
  renderItem: renderRow,
235
254
  threshold: virtualizeThreshold
236
- }), hasMore ? /*#__PURE__*/ external_react_namespaceObject.createElement("button", {
255
+ }), hasMore ? /*#__PURE__*/ external_react_namespaceObject.createElement(button_namespaceObject.Button, {
237
256
  "data-asset-action": "load-more",
238
257
  onClick: ()=>{
239
258
  setPageLimit((current)=>current + pageSize);
240
259
  },
241
- type: "button"
260
+ type: "button",
261
+ variant: "outline",
262
+ size: "sm"
242
263
  }, "Load more") : null));
243
264
  }
244
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.
@@ -49,5 +60,5 @@ export interface AssetBrowserProps {
49
60
  /** Pixel height of the scroll container when virtualizing. */
50
61
  readonly maxHeight?: number;
51
62
  }
52
- 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;
53
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;;;;;;;;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,QAA4B,EAC5B,mBAAkD,EAClD,UAAgC,EAChC,SAA8B,GAC9B,EAAE,iBAAiB,2CAuSnB"}
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.
@@ -49,5 +60,5 @@ export interface AssetBrowserProps {
49
60
  /** Pixel height of the scroll container when virtualizing. */
50
61
  readonly maxHeight?: number;
51
62
  }
52
- 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;
53
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;;;;;;;;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,QAA4B,EAC5B,mBAAkD,EAClD,UAAgC,EAChC,SAA8B,GAC9B,EAAE,iBAAiB,2CAuSnB"}
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"}
@@ -1,8 +1,10 @@
1
1
  "use client";
2
+ import { Button } from "@anvilkit/ui/button";
2
3
  import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@anvilkit/ui/card";
3
4
  import { Input } from "@anvilkit/ui/input";
4
5
  import { Windowed } from "@anvilkit/ui/windowed";
5
6
  import { inferAssetKind } from "../utils/infer-kind.js";
7
+ import { ASSET_DRAG_MIME } from "./FolderTree.js";
6
8
  import * as __rspack_external_react from "react";
7
9
  const KIND_FILTERS = [
8
10
  "image",
@@ -15,7 +17,7 @@ const DEFAULT_VIRTUALIZE_THRESHOLD = 50;
15
17
  const DEFAULT_ITEM_HEIGHT = 56;
16
18
  const DEFAULT_MAX_HEIGHT = 400;
17
19
  const DEFAULT_PAGE_SIZE = 100;
18
- 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 }) {
20
+ 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 }) {
19
21
  const [activeIndex, setActiveIndex] = __rspack_external_react.useState(assets.length > 0 ? 0 : -1);
20
22
  const [query, setQuery] = __rspack_external_react.useState("");
21
23
  const [activeKinds, setActiveKinds] = __rspack_external_react.useState([]);
@@ -91,6 +93,14 @@ function AssetBrowser({ assets, onInsert, onDelete, onReplace, onEdit, searchEna
91
93
  }
92
94
  const renderRow = (asset, index)=>/*#__PURE__*/ __rspack_external_react.createElement(__rspack_external_react.Fragment, null, /*#__PURE__*/ __rspack_external_react.createElement("button", {
93
95
  "aria-label": `Insert asset ${asset.id}`,
96
+ draggable: draggableRows,
97
+ "data-asset-draggable": draggableRows ? "" : void 0,
98
+ onDragStart: draggableRows ? (event)=>{
99
+ event.dataTransfer.setData(ASSET_DRAG_MIME, JSON.stringify([
100
+ asset.id
101
+ ]));
102
+ event.dataTransfer.effectAllowed = "move";
103
+ } : void 0,
94
104
  onClick: ()=>{
95
105
  onInsert(asset);
96
106
  },
@@ -132,29 +142,35 @@ function AssetBrowser({ assets, onInsert, onDelete, onReplace, onEdit, searchEna
132
142
  },
133
143
  tabIndex: activeIndex === index ? 0 : -1,
134
144
  type: "button"
135
- }, /*#__PURE__*/ __rspack_external_react.createElement("span", null, asset.id), /*#__PURE__*/ __rspack_external_react.createElement("span", null, asset.meta?.mimeType ?? "unknown type")), void 0 !== onEdit ? /*#__PURE__*/ __rspack_external_react.createElement("button", {
145
+ }, /*#__PURE__*/ __rspack_external_react.createElement("span", null, asset.id), /*#__PURE__*/ __rspack_external_react.createElement("span", null, asset.meta?.mimeType ?? "unknown type")), void 0 !== onEdit ? /*#__PURE__*/ __rspack_external_react.createElement(Button, {
136
146
  "aria-label": `Edit asset ${asset.id}`,
137
147
  "data-asset-action": "edit",
138
148
  onClick: ()=>{
139
149
  onEdit(asset);
140
150
  },
141
- type: "button"
142
- }, "Edit") : null, void 0 !== onReplace ? /*#__PURE__*/ __rspack_external_react.createElement("button", {
151
+ type: "button",
152
+ variant: "ghost",
153
+ size: "sm"
154
+ }, "Edit") : null, void 0 !== onReplace ? /*#__PURE__*/ __rspack_external_react.createElement(Button, {
143
155
  "aria-label": `Replace asset ${asset.id}`,
144
156
  "data-asset-action": "replace",
145
157
  onClick: ()=>{
146
158
  onReplace(asset);
147
159
  },
148
- type: "button"
149
- }, "Replace") : null, void 0 !== onDelete ? /*#__PURE__*/ __rspack_external_react.createElement("button", {
160
+ type: "button",
161
+ variant: "ghost",
162
+ size: "sm"
163
+ }, "Replace") : null, void 0 !== onDelete ? /*#__PURE__*/ __rspack_external_react.createElement(Button, {
150
164
  "aria-label": `Delete asset ${asset.id}`,
151
165
  "data-asset-action": "delete",
152
166
  onClick: ()=>{
153
167
  onDelete(asset);
154
168
  },
155
- type: "button"
169
+ type: "button",
170
+ variant: "ghost",
171
+ size: "sm"
156
172
  }, "Delete") : null);
157
- const filterRow = searchEnabled ? /*#__PURE__*/ __rspack_external_react.createElement("div", {
173
+ const searchRow = searchEnabled ? /*#__PURE__*/ __rspack_external_react.createElement("div", {
158
174
  "data-asset-manager-filters": true
159
175
  }, /*#__PURE__*/ __rspack_external_react.createElement(Input, {
160
176
  "aria-label": "Search assets",
@@ -169,7 +185,7 @@ function AssetBrowser({ assets, onInsert, onDelete, onReplace, onEdit, searchEna
169
185
  role: "group"
170
186
  }, KIND_FILTERS.map((kind)=>{
171
187
  const active = activeKinds.includes(kind);
172
- return /*#__PURE__*/ __rspack_external_react.createElement("button", {
188
+ return /*#__PURE__*/ __rspack_external_react.createElement(Button, {
173
189
  "aria-label": `Filter ${kind} assets`,
174
190
  "aria-pressed": active,
175
191
  "data-asset-kind-filter": kind,
@@ -178,9 +194,12 @@ function AssetBrowser({ assets, onInsert, onDelete, onReplace, onEdit, searchEna
178
194
  toggleKind(kind);
179
195
  setPageLimit(pageSize);
180
196
  },
181
- type: "button"
197
+ type: "button",
198
+ variant: active ? "secondary" : "ghost",
199
+ size: "sm"
182
200
  }, kind);
183
201
  }))) : null;
202
+ const filterRow = /*#__PURE__*/ __rspack_external_react.createElement(__rspack_external_react.Fragment, null, aboveFilters, searchRow);
184
203
  if (0 === total) {
185
204
  const emptyLabel = searchEnabled && ("" !== query || activeKinds.length > 0) ? "No assets match the current filters." : "No assets uploaded yet.";
186
205
  return /*#__PURE__*/ __rspack_external_react.createElement(Card, null, /*#__PURE__*/ __rspack_external_react.createElement(CardHeader, null, /*#__PURE__*/ __rspack_external_react.createElement(CardTitle, null, "Asset browser"), /*#__PURE__*/ __rspack_external_react.createElement(CardDescription, null, "Validated assets currently registered in memory.")), /*#__PURE__*/ __rspack_external_react.createElement(CardContent, null, filterRow, /*#__PURE__*/ __rspack_external_react.createElement("ul", {
@@ -201,12 +220,14 @@ function AssetBrowser({ assets, onInsert, onDelete, onReplace, onEdit, searchEna
201
220
  maxHeight: maxHeight,
202
221
  renderItem: renderRow,
203
222
  threshold: virtualizeThreshold
204
- }), hasMore ? /*#__PURE__*/ __rspack_external_react.createElement("button", {
223
+ }), hasMore ? /*#__PURE__*/ __rspack_external_react.createElement(Button, {
205
224
  "data-asset-action": "load-more",
206
225
  onClick: ()=>{
207
226
  setPageLimit((current)=>current + pageSize);
208
227
  },
209
- type: "button"
228
+ type: "button",
229
+ variant: "outline",
230
+ size: "sm"
210
231
  }, "Load more") : null));
211
232
  }
212
233
  export { AssetBrowser };
@@ -41,7 +41,7 @@ const external_DeleteAssetDialog_cjs_namespaceObject = require("./DeleteAssetDia
41
41
  const external_MetadataPanel_cjs_namespaceObject = require("./MetadataPanel.cjs");
42
42
  const external_ReplaceAssetDialog_cjs_namespaceObject = require("./ReplaceAssetDialog.cjs");
43
43
  const external_UploadButton_cjs_namespaceObject = require("./UploadButton.cjs");
44
- function AssetManagerUI({ acceptedMimeTypes, allowMixedScriptHostnames, dataUrlAllowlistOptIn, maxFileSize, onAssetInserted, registry, searchEnabled = true, uploader }) {
44
+ function AssetManagerUI({ acceptedMimeTypes, allowMixedScriptHostnames, aboveFilters, dataUrlAllowlistOptIn, draggableRows, maxFileSize, onAssetInserted, registry, searchEnabled = true, uploader }) {
45
45
  const [assets, setAssets] = external_react_namespaceObject.useState(()=>registry.list());
46
46
  const [progress, setProgress] = external_react_namespaceObject.useState(null);
47
47
  const [pendingDelete, setPendingDelete] = external_react_namespaceObject.useState(null);
@@ -135,7 +135,13 @@ function AssetManagerUI({ acceptedMimeTypes, allowMixedScriptHostnames, dataUrlA
135
135
  onReplace: (asset)=>{
136
136
  setPendingReplace(asset);
137
137
  },
138
- searchEnabled: searchEnabled
138
+ searchEnabled: searchEnabled,
139
+ ...void 0 !== aboveFilters ? {
140
+ aboveFilters
141
+ } : {},
142
+ ...void 0 !== draggableRows ? {
143
+ draggableRows
144
+ } : {}
139
145
  }), /*#__PURE__*/ external_react_namespaceObject.createElement(external_DeleteAssetDialog_cjs_namespaceObject.DeleteAssetDialog, {
140
146
  asset: pendingDelete,
141
147
  onCancel: ()=>{
@@ -1,5 +1,13 @@
1
- import type { AssetManagerOptions, AssetRegistry, UploadResult } from "../types/types.js";
2
- export interface AssetManagerUIProps extends Pick<AssetManagerOptions, "acceptedMimeTypes" | "maxFileSize" | "uploader" | "dataUrlAllowlistOptIn" | "allowMixedScriptHostnames"> {
1
+ import * as React from "react";
2
+ import type { AssetManagerOptions } from "../types/options.js";
3
+ import type { AssetRegistry, UploadAdapter, UploadResult } from "../types/types.js";
4
+ export interface AssetManagerUIProps extends Pick<AssetManagerOptions, "acceptedMimeTypes" | "maxFileSize" | "dataUrlAllowlistOptIn" | "allowMixedScriptHostnames"> {
5
+ /**
6
+ * Binary uploader. Required at the UI boundary even though
7
+ * `AssetManagerOptions.uploader` is optional — the plugin passes the
8
+ * resolved (defaulted) uploader.
9
+ */
10
+ readonly uploader: UploadAdapter;
3
11
  readonly registry: AssetRegistry;
4
12
  readonly onAssetInserted?: (asset: UploadResult) => void;
5
13
  /**
@@ -10,6 +18,14 @@ export interface AssetManagerUIProps extends Pick<AssetManagerOptions, "accepted
10
18
  * chrome can opt out.
11
19
  */
12
20
  readonly searchEnabled?: boolean;
21
+ /**
22
+ * Optional content rendered above the browser's filter row — e.g. a
23
+ * `FolderBreadcrumb` + `FolderTree` for folder navigation (PRD 0002 §7.4).
24
+ * The host wires these to the resolved data source / composite source.
25
+ */
26
+ readonly aboveFilters?: React.ReactNode;
27
+ /** Make asset rows draggable so they can be dropped onto a `FolderTree`. */
28
+ readonly draggableRows?: boolean;
13
29
  }
14
- export declare function AssetManagerUI({ acceptedMimeTypes, allowMixedScriptHostnames, dataUrlAllowlistOptIn, maxFileSize, onAssetInserted, registry, searchEnabled, uploader, }: AssetManagerUIProps): import("react/jsx-runtime").JSX.Element;
30
+ export declare function AssetManagerUI({ acceptedMimeTypes, allowMixedScriptHostnames, aboveFilters, dataUrlAllowlistOptIn, draggableRows, maxFileSize, onAssetInserted, registry, searchEnabled, uploader, }: AssetManagerUIProps): import("react/jsx-runtime").JSX.Element;
15
31
  //# sourceMappingURL=AssetManagerUI.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AssetManagerUI.d.cts","sourceRoot":"","sources":["../../src/ui/AssetManagerUI.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACX,mBAAmB,EACnB,aAAa,EACb,YAAY,EACZ,MAAM,mBAAmB,CAAC;AAS3B,MAAM,WAAW,mBAChB,SAAQ,IAAI,CACX,mBAAmB,EACjB,mBAAmB,GACnB,aAAa,GACb,UAAU,GACV,uBAAuB,GACvB,2BAA2B,CAC7B;IACD,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IACzD;;;;;;OAMG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,wBAAgB,cAAc,CAAC,EAC9B,iBAAiB,EACjB,yBAAyB,EACzB,qBAAqB,EACrB,WAAW,EACX,eAAe,EACf,QAAQ,EACR,aAAoB,EACpB,QAAQ,GACR,EAAE,mBAAmB,2CAiKrB"}
1
+ {"version":3,"file":"AssetManagerUI.d.cts","sourceRoot":"","sources":["../../src/ui/AssetManagerUI.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EACX,aAAa,EACb,aAAa,EACb,YAAY,EACZ,MAAM,mBAAmB,CAAC;AAS3B,MAAM,WAAW,mBAChB,SAAQ,IAAI,CACX,mBAAmB,EACjB,mBAAmB,GACnB,aAAa,GACb,uBAAuB,GACvB,2BAA2B,CAC7B;IACD;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IACzD;;;;;;OAMG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxC,4EAA4E;IAC5E,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,wBAAgB,cAAc,CAAC,EAC9B,iBAAiB,EACjB,yBAAyB,EACzB,YAAY,EACZ,qBAAqB,EACrB,aAAa,EACb,WAAW,EACX,eAAe,EACf,QAAQ,EACR,aAAoB,EACpB,QAAQ,GACR,EAAE,mBAAmB,2CAmKrB"}
@@ -1,5 +1,13 @@
1
- import type { AssetManagerOptions, AssetRegistry, UploadResult } from "../types/types.js";
2
- export interface AssetManagerUIProps extends Pick<AssetManagerOptions, "acceptedMimeTypes" | "maxFileSize" | "uploader" | "dataUrlAllowlistOptIn" | "allowMixedScriptHostnames"> {
1
+ import * as React from "react";
2
+ import type { AssetManagerOptions } from "../types/options.js";
3
+ import type { AssetRegistry, UploadAdapter, UploadResult } from "../types/types.js";
4
+ export interface AssetManagerUIProps extends Pick<AssetManagerOptions, "acceptedMimeTypes" | "maxFileSize" | "dataUrlAllowlistOptIn" | "allowMixedScriptHostnames"> {
5
+ /**
6
+ * Binary uploader. Required at the UI boundary even though
7
+ * `AssetManagerOptions.uploader` is optional — the plugin passes the
8
+ * resolved (defaulted) uploader.
9
+ */
10
+ readonly uploader: UploadAdapter;
3
11
  readonly registry: AssetRegistry;
4
12
  readonly onAssetInserted?: (asset: UploadResult) => void;
5
13
  /**
@@ -10,6 +18,14 @@ export interface AssetManagerUIProps extends Pick<AssetManagerOptions, "accepted
10
18
  * chrome can opt out.
11
19
  */
12
20
  readonly searchEnabled?: boolean;
21
+ /**
22
+ * Optional content rendered above the browser's filter row — e.g. a
23
+ * `FolderBreadcrumb` + `FolderTree` for folder navigation (PRD 0002 §7.4).
24
+ * The host wires these to the resolved data source / composite source.
25
+ */
26
+ readonly aboveFilters?: React.ReactNode;
27
+ /** Make asset rows draggable so they can be dropped onto a `FolderTree`. */
28
+ readonly draggableRows?: boolean;
13
29
  }
14
- export declare function AssetManagerUI({ acceptedMimeTypes, allowMixedScriptHostnames, dataUrlAllowlistOptIn, maxFileSize, onAssetInserted, registry, searchEnabled, uploader, }: AssetManagerUIProps): import("react/jsx-runtime").JSX.Element;
30
+ export declare function AssetManagerUI({ acceptedMimeTypes, allowMixedScriptHostnames, aboveFilters, dataUrlAllowlistOptIn, draggableRows, maxFileSize, onAssetInserted, registry, searchEnabled, uploader, }: AssetManagerUIProps): import("react/jsx-runtime").JSX.Element;
15
31
  //# sourceMappingURL=AssetManagerUI.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AssetManagerUI.d.ts","sourceRoot":"","sources":["../../src/ui/AssetManagerUI.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACX,mBAAmB,EACnB,aAAa,EACb,YAAY,EACZ,MAAM,mBAAmB,CAAC;AAS3B,MAAM,WAAW,mBAChB,SAAQ,IAAI,CACX,mBAAmB,EACjB,mBAAmB,GACnB,aAAa,GACb,UAAU,GACV,uBAAuB,GACvB,2BAA2B,CAC7B;IACD,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IACzD;;;;;;OAMG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,wBAAgB,cAAc,CAAC,EAC9B,iBAAiB,EACjB,yBAAyB,EACzB,qBAAqB,EACrB,WAAW,EACX,eAAe,EACf,QAAQ,EACR,aAAoB,EACpB,QAAQ,GACR,EAAE,mBAAmB,2CAiKrB"}
1
+ {"version":3,"file":"AssetManagerUI.d.ts","sourceRoot":"","sources":["../../src/ui/AssetManagerUI.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EACX,aAAa,EACb,aAAa,EACb,YAAY,EACZ,MAAM,mBAAmB,CAAC;AAS3B,MAAM,WAAW,mBAChB,SAAQ,IAAI,CACX,mBAAmB,EACjB,mBAAmB,GACnB,aAAa,GACb,uBAAuB,GACvB,2BAA2B,CAC7B;IACD;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IACzD;;;;;;OAMG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxC,4EAA4E;IAC5E,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,wBAAgB,cAAc,CAAC,EAC9B,iBAAiB,EACjB,yBAAyB,EACzB,YAAY,EACZ,qBAAqB,EACrB,aAAa,EACb,WAAW,EACX,eAAe,EACf,QAAQ,EACR,aAAoB,EACpB,QAAQ,GACR,EAAE,mBAAmB,2CAmKrB"}
@@ -9,7 +9,7 @@ import { MetadataPanel } from "./MetadataPanel.js";
9
9
  import { ReplaceAssetDialog } from "./ReplaceAssetDialog.js";
10
10
  import { UploadButton } from "./UploadButton.js";
11
11
  import * as __rspack_external_react from "react";
12
- function AssetManagerUI({ acceptedMimeTypes, allowMixedScriptHostnames, dataUrlAllowlistOptIn, maxFileSize, onAssetInserted, registry, searchEnabled = true, uploader }) {
12
+ function AssetManagerUI({ acceptedMimeTypes, allowMixedScriptHostnames, aboveFilters, dataUrlAllowlistOptIn, draggableRows, maxFileSize, onAssetInserted, registry, searchEnabled = true, uploader }) {
13
13
  const [assets, setAssets] = __rspack_external_react.useState(()=>registry.list());
14
14
  const [progress, setProgress] = __rspack_external_react.useState(null);
15
15
  const [pendingDelete, setPendingDelete] = __rspack_external_react.useState(null);
@@ -103,7 +103,13 @@ function AssetManagerUI({ acceptedMimeTypes, allowMixedScriptHostnames, dataUrlA
103
103
  onReplace: (asset)=>{
104
104
  setPendingReplace(asset);
105
105
  },
106
- searchEnabled: searchEnabled
106
+ searchEnabled: searchEnabled,
107
+ ...void 0 !== aboveFilters ? {
108
+ aboveFilters
109
+ } : {},
110
+ ...void 0 !== draggableRows ? {
111
+ draggableRows
112
+ } : {}
107
113
  }), /*#__PURE__*/ __rspack_external_react.createElement(DeleteAssetDialog, {
108
114
  asset: pendingDelete,
109
115
  onCancel: ()=>{
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ "use client";
3
+ var __webpack_require__ = {};
4
+ (()=>{
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");
14
+ };
15
+ })();
16
+ (()=>{
17
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
18
+ })();
19
+ (()=>{
20
+ __webpack_require__.r = (exports1)=>{
21
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
22
+ value: 'Module'
23
+ });
24
+ Object.defineProperty(exports1, '__esModule', {
25
+ value: true
26
+ });
27
+ };
28
+ })();
29
+ var __webpack_exports__ = {};
30
+ __webpack_require__.r(__webpack_exports__);
31
+ __webpack_require__.d(__webpack_exports__, {
32
+ DeleteFolderDialog: ()=>DeleteFolderDialog
33
+ });
34
+ const button_namespaceObject = require("@anvilkit/ui/button");
35
+ const dialog_namespaceObject = require("@anvilkit/ui/dialog");
36
+ const external_react_namespaceObject = require("react");
37
+ function DeleteFolderDialog({ folder, onConfirm, onCancel }) {
38
+ const [busy, setBusy] = external_react_namespaceObject.useState(false);
39
+ async function confirm(cascade) {
40
+ if (null === folder || busy) return;
41
+ setBusy(true);
42
+ try {
43
+ await onConfirm(folder, cascade);
44
+ } finally{
45
+ setBusy(false);
46
+ }
47
+ }
48
+ const open = null !== folder;
49
+ const assetCount = folder?.counts.assets ?? 0;
50
+ return /*#__PURE__*/ external_react_namespaceObject.createElement(dialog_namespaceObject.Dialog, {
51
+ open: open,
52
+ onOpenChange: (next)=>{
53
+ if (!next && !busy) onCancel();
54
+ }
55
+ }, /*#__PURE__*/ external_react_namespaceObject.createElement(dialog_namespaceObject.DialogContent, null, /*#__PURE__*/ external_react_namespaceObject.createElement(dialog_namespaceObject.DialogHeader, null, /*#__PURE__*/ external_react_namespaceObject.createElement(dialog_namespaceObject.DialogTitle, null, "Delete folder?"), /*#__PURE__*/ external_react_namespaceObject.createElement(dialog_namespaceObject.DialogDescription, null, "“", folder?.name, "” will be removed. By default its contents move up to the parent folder — nothing is deleted. Choose “Delete contents” to remove its ", assetCount, " ", 1 === assetCount ? "asset" : "assets", " too.")), /*#__PURE__*/ external_react_namespaceObject.createElement(dialog_namespaceObject.DialogFooter, null, /*#__PURE__*/ external_react_namespaceObject.createElement(button_namespaceObject.Button, {
56
+ type: "button",
57
+ variant: "outline",
58
+ disabled: busy,
59
+ onClick: onCancel
60
+ }, "Cancel"), /*#__PURE__*/ external_react_namespaceObject.createElement(button_namespaceObject.Button, {
61
+ type: "button",
62
+ variant: "outline",
63
+ disabled: busy || null === folder,
64
+ onClick: ()=>void confirm(false)
65
+ }, busy ? "Removing…" : "Remove folder"), /*#__PURE__*/ external_react_namespaceObject.createElement(button_namespaceObject.Button, {
66
+ type: "button",
67
+ variant: "destructive",
68
+ disabled: busy || null === folder,
69
+ onClick: ()=>void confirm(true)
70
+ }, "Delete contents"))));
71
+ }
72
+ exports.DeleteFolderDialog = __webpack_exports__.DeleteFolderDialog;
73
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
74
+ "DeleteFolderDialog"
75
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
76
+ Object.defineProperty(exports, '__esModule', {
77
+ value: true
78
+ });
@@ -0,0 +1,11 @@
1
+ import type { AssetFolder } from "../types/folders.js";
2
+ export interface DeleteFolderDialogProps {
3
+ /** Folder to delete. `null` ⇒ closed. */
4
+ readonly folder: AssetFolder | null;
5
+ /** Confirm. `cascade=false` reparents children to the parent (default, safe);
6
+ * `cascade=true` also deletes the descendant assets. */
7
+ readonly onConfirm: (folder: AssetFolder, cascade: boolean) => void | Promise<void>;
8
+ readonly onCancel: () => void;
9
+ }
10
+ export declare function DeleteFolderDialog({ folder, onConfirm, onCancel, }: DeleteFolderDialogProps): import("react/jsx-runtime").JSX.Element;
11
+ //# sourceMappingURL=DeleteFolderDialog.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DeleteFolderDialog.d.cts","sourceRoot":"","sources":["../../src/ui/DeleteFolderDialog.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,MAAM,WAAW,uBAAuB;IACvC,yCAAyC;IACzC,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IACpC;6DACyD;IACzD,QAAQ,CAAC,SAAS,EAAE,CACnB,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,OAAO,KACZ,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED,wBAAgB,kBAAkB,CAAC,EAClC,MAAM,EACN,SAAS,EACT,QAAQ,GACR,EAAE,uBAAuB,2CA6DzB"}
@@ -0,0 +1,11 @@
1
+ import type { AssetFolder } from "../types/folders.js";
2
+ export interface DeleteFolderDialogProps {
3
+ /** Folder to delete. `null` ⇒ closed. */
4
+ readonly folder: AssetFolder | null;
5
+ /** Confirm. `cascade=false` reparents children to the parent (default, safe);
6
+ * `cascade=true` also deletes the descendant assets. */
7
+ readonly onConfirm: (folder: AssetFolder, cascade: boolean) => void | Promise<void>;
8
+ readonly onCancel: () => void;
9
+ }
10
+ export declare function DeleteFolderDialog({ folder, onConfirm, onCancel, }: DeleteFolderDialogProps): import("react/jsx-runtime").JSX.Element;
11
+ //# sourceMappingURL=DeleteFolderDialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DeleteFolderDialog.d.ts","sourceRoot":"","sources":["../../src/ui/DeleteFolderDialog.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,MAAM,WAAW,uBAAuB;IACvC,yCAAyC;IACzC,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IACpC;6DACyD;IACzD,QAAQ,CAAC,SAAS,EAAE,CACnB,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,OAAO,KACZ,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED,wBAAgB,kBAAkB,CAAC,EAClC,MAAM,EACN,SAAS,EACT,QAAQ,GACR,EAAE,uBAAuB,2CA6DzB"}
@@ -0,0 +1,40 @@
1
+ "use client";
2
+ import { Button } from "@anvilkit/ui/button";
3
+ import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@anvilkit/ui/dialog";
4
+ import * as __rspack_external_react from "react";
5
+ function DeleteFolderDialog({ folder, onConfirm, onCancel }) {
6
+ const [busy, setBusy] = __rspack_external_react.useState(false);
7
+ async function confirm(cascade) {
8
+ if (null === folder || busy) return;
9
+ setBusy(true);
10
+ try {
11
+ await onConfirm(folder, cascade);
12
+ } finally{
13
+ setBusy(false);
14
+ }
15
+ }
16
+ const open = null !== folder;
17
+ const assetCount = folder?.counts.assets ?? 0;
18
+ return /*#__PURE__*/ __rspack_external_react.createElement(Dialog, {
19
+ open: open,
20
+ onOpenChange: (next)=>{
21
+ if (!next && !busy) onCancel();
22
+ }
23
+ }, /*#__PURE__*/ __rspack_external_react.createElement(DialogContent, null, /*#__PURE__*/ __rspack_external_react.createElement(DialogHeader, null, /*#__PURE__*/ __rspack_external_react.createElement(DialogTitle, null, "Delete folder?"), /*#__PURE__*/ __rspack_external_react.createElement(DialogDescription, null, "“", folder?.name, "” will be removed. By default its contents move up to the parent folder — nothing is deleted. Choose “Delete contents” to remove its ", assetCount, " ", 1 === assetCount ? "asset" : "assets", " too.")), /*#__PURE__*/ __rspack_external_react.createElement(DialogFooter, null, /*#__PURE__*/ __rspack_external_react.createElement(Button, {
24
+ type: "button",
25
+ variant: "outline",
26
+ disabled: busy,
27
+ onClick: onCancel
28
+ }, "Cancel"), /*#__PURE__*/ __rspack_external_react.createElement(Button, {
29
+ type: "button",
30
+ variant: "outline",
31
+ disabled: busy || null === folder,
32
+ onClick: ()=>void confirm(false)
33
+ }, busy ? "Removing…" : "Remove folder"), /*#__PURE__*/ __rspack_external_react.createElement(Button, {
34
+ type: "button",
35
+ variant: "destructive",
36
+ disabled: busy || null === folder,
37
+ onClick: ()=>void confirm(true)
38
+ }, "Delete contents"))));
39
+ }
40
+ export { DeleteFolderDialog };