@anvilkit/plugin-asset-manager 0.1.6 → 0.1.8

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 (251) hide show
  1. package/README.md +28 -20
  2. package/dist/adapters/data-url.d.cts +13 -0
  3. package/dist/adapters/data-url.d.cts.map +1 -1
  4. package/dist/adapters/data-url.d.ts +13 -0
  5. package/dist/adapters/data-url.d.ts.map +1 -1
  6. package/dist/adapters/in-memory.d.cts +8 -1
  7. package/dist/adapters/in-memory.d.cts.map +1 -1
  8. package/dist/adapters/in-memory.d.ts +8 -1
  9. package/dist/adapters/in-memory.d.ts.map +1 -1
  10. package/dist/i18n/entry.cjs +75 -0
  11. package/dist/i18n/entry.d.cts +15 -0
  12. package/dist/i18n/entry.d.cts.map +1 -0
  13. package/dist/i18n/entry.d.ts +15 -0
  14. package/dist/i18n/entry.d.ts.map +1 -0
  15. package/dist/i18n/entry.js +29 -0
  16. package/dist/i18n/provider.cjs +49 -0
  17. package/dist/i18n/provider.d.cts +20 -0
  18. package/dist/i18n/provider.d.cts.map +1 -0
  19. package/dist/i18n/provider.d.ts +20 -0
  20. package/dist/i18n/provider.d.ts.map +1 -0
  21. package/dist/i18n/provider.js +11 -0
  22. package/dist/index.cjs +7 -0
  23. package/dist/index.d.cts +11 -3
  24. package/dist/index.d.cts.map +1 -1
  25. package/dist/index.d.ts +11 -3
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +2 -1
  28. package/dist/plugin.cjs +70 -5
  29. package/dist/plugin.d.cts +3 -2
  30. package/dist/plugin.d.cts.map +1 -1
  31. package/dist/plugin.d.ts +3 -2
  32. package/dist/plugin.d.ts.map +1 -1
  33. package/dist/plugin.js +70 -5
  34. package/dist/sources/composite-source.cjs +138 -0
  35. package/dist/sources/composite-source.d.cts +39 -0
  36. package/dist/sources/composite-source.d.cts.map +1 -0
  37. package/dist/sources/composite-source.d.ts +39 -0
  38. package/dist/sources/composite-source.d.ts.map +1 -0
  39. package/dist/sources/composite-source.js +100 -0
  40. package/dist/sources/federated-search.cjs +173 -0
  41. package/dist/sources/federated-search.d.cts +33 -0
  42. package/dist/sources/federated-search.d.cts.map +1 -0
  43. package/dist/sources/federated-search.d.ts +33 -0
  44. package/dist/sources/federated-search.d.ts.map +1 -0
  45. package/dist/sources/federated-search.js +123 -0
  46. package/dist/sources/provider.cjs +18 -0
  47. package/dist/sources/provider.d.cts +51 -0
  48. package/dist/sources/provider.d.cts.map +1 -0
  49. package/dist/sources/provider.d.ts +51 -0
  50. package/dist/sources/provider.d.ts.map +1 -0
  51. package/dist/sources/provider.js +1 -0
  52. package/dist/sources/unsplash/client.cjs +189 -0
  53. package/dist/sources/unsplash/client.d.cts +87 -0
  54. package/dist/sources/unsplash/client.d.cts.map +1 -0
  55. package/dist/sources/unsplash/client.d.ts +87 -0
  56. package/dist/sources/unsplash/client.d.ts.map +1 -0
  57. package/dist/sources/unsplash/client.js +151 -0
  58. package/dist/sources/unsplash/index.cjs +194 -0
  59. package/dist/sources/unsplash/index.d.cts +16 -0
  60. package/dist/sources/unsplash/index.d.cts.map +1 -0
  61. package/dist/sources/unsplash/index.d.ts +16 -0
  62. package/dist/sources/unsplash/index.d.ts.map +1 -0
  63. package/dist/sources/unsplash/index.js +150 -0
  64. package/dist/sources/unsplash/themes.cjs +141 -0
  65. package/dist/sources/unsplash/themes.d.cts +18 -0
  66. package/dist/sources/unsplash/themes.d.cts.map +1 -0
  67. package/dist/sources/unsplash/themes.d.ts +18 -0
  68. package/dist/sources/unsplash/themes.d.ts.map +1 -0
  69. package/dist/sources/unsplash/themes.js +93 -0
  70. package/dist/sources/unsplash/throttle-cache.cjs +86 -0
  71. package/dist/sources/unsplash/throttle-cache.d.cts +25 -0
  72. package/dist/sources/unsplash/throttle-cache.d.cts.map +1 -0
  73. package/dist/sources/unsplash/throttle-cache.d.ts +25 -0
  74. package/dist/sources/unsplash/throttle-cache.d.ts.map +1 -0
  75. package/dist/sources/unsplash/throttle-cache.js +45 -0
  76. package/dist/types/categories.cjs +18 -0
  77. package/dist/types/categories.d.cts +48 -0
  78. package/dist/types/categories.d.cts.map +1 -0
  79. package/dist/types/categories.d.ts +48 -0
  80. package/dist/types/categories.d.ts.map +1 -0
  81. package/dist/types/categories.js +1 -0
  82. package/dist/types/data-source.cjs +18 -0
  83. package/dist/types/data-source.d.cts +59 -0
  84. package/dist/types/data-source.d.cts.map +1 -0
  85. package/dist/types/data-source.d.ts +59 -0
  86. package/dist/types/data-source.d.ts.map +1 -0
  87. package/dist/types/data-source.js +1 -0
  88. package/dist/types/filter.cjs +18 -0
  89. package/dist/types/filter.d.cts +55 -0
  90. package/dist/types/filter.d.cts.map +1 -0
  91. package/dist/types/filter.d.ts +55 -0
  92. package/dist/types/filter.d.ts.map +1 -0
  93. package/dist/types/filter.js +1 -0
  94. package/dist/types/folders.cjs +42 -0
  95. package/dist/types/folders.d.cts +46 -0
  96. package/dist/types/folders.d.cts.map +1 -0
  97. package/dist/types/folders.d.ts +46 -0
  98. package/dist/types/folders.d.ts.map +1 -0
  99. package/dist/types/folders.js +4 -0
  100. package/dist/types/options.cjs +18 -0
  101. package/dist/types/options.d.cts +68 -0
  102. package/dist/types/options.d.cts.map +1 -0
  103. package/dist/types/options.d.ts +68 -0
  104. package/dist/types/options.d.ts.map +1 -0
  105. package/dist/types/options.js +1 -0
  106. package/dist/types/types.d.cts +21 -27
  107. package/dist/types/types.d.cts.map +1 -1
  108. package/dist/types/types.d.ts +21 -27
  109. package/dist/types/types.d.ts.map +1 -1
  110. package/dist/types/unsplash.cjs +18 -0
  111. package/dist/types/unsplash.d.cts +60 -0
  112. package/dist/types/unsplash.d.cts.map +1 -0
  113. package/dist/types/unsplash.d.ts +60 -0
  114. package/dist/types/unsplash.d.ts.map +1 -0
  115. package/dist/types/unsplash.js +1 -0
  116. package/dist/ui/AssetBrowser.cjs +183 -121
  117. package/dist/ui/AssetBrowser.d.cts +12 -1
  118. package/dist/ui/AssetBrowser.d.cts.map +1 -1
  119. package/dist/ui/AssetBrowser.d.ts +12 -1
  120. package/dist/ui/AssetBrowser.d.ts.map +1 -1
  121. package/dist/ui/AssetBrowser.js +183 -121
  122. package/dist/ui/AssetCommandPalette.cjs +20 -18
  123. package/dist/ui/AssetCommandPalette.d.cts.map +1 -1
  124. package/dist/ui/AssetCommandPalette.d.ts.map +1 -1
  125. package/dist/ui/AssetCommandPalette.js +20 -18
  126. package/dist/ui/AssetManagerUI.cjs +31 -17
  127. package/dist/ui/AssetManagerUI.d.cts +19 -3
  128. package/dist/ui/AssetManagerUI.d.cts.map +1 -1
  129. package/dist/ui/AssetManagerUI.d.ts +19 -3
  130. package/dist/ui/AssetManagerUI.d.ts.map +1 -1
  131. package/dist/ui/AssetManagerUI.js +31 -17
  132. package/dist/ui/DeleteAssetDialog.cjs +5 -3
  133. package/dist/ui/DeleteAssetDialog.d.cts.map +1 -1
  134. package/dist/ui/DeleteAssetDialog.d.ts.map +1 -1
  135. package/dist/ui/DeleteAssetDialog.js +5 -3
  136. package/dist/ui/DeleteFolderDialog.cjs +80 -0
  137. package/dist/ui/DeleteFolderDialog.d.cts +11 -0
  138. package/dist/ui/DeleteFolderDialog.d.cts.map +1 -0
  139. package/dist/ui/DeleteFolderDialog.d.ts +11 -0
  140. package/dist/ui/DeleteFolderDialog.d.ts.map +1 -0
  141. package/dist/ui/DeleteFolderDialog.js +42 -0
  142. package/dist/ui/EmptyFolderState.cjs +56 -0
  143. package/dist/ui/EmptyFolderState.d.cts +6 -0
  144. package/dist/ui/EmptyFolderState.d.cts.map +1 -0
  145. package/dist/ui/EmptyFolderState.d.ts +6 -0
  146. package/dist/ui/EmptyFolderState.d.ts.map +1 -0
  147. package/dist/ui/EmptyFolderState.js +18 -0
  148. package/dist/ui/FolderBreadcrumb.cjs +76 -0
  149. package/dist/ui/FolderBreadcrumb.d.cts +9 -0
  150. package/dist/ui/FolderBreadcrumb.d.cts.map +1 -0
  151. package/dist/ui/FolderBreadcrumb.d.ts +9 -0
  152. package/dist/ui/FolderBreadcrumb.d.ts.map +1 -0
  153. package/dist/ui/FolderBreadcrumb.js +38 -0
  154. package/dist/ui/FolderNameDialog.cjs +105 -0
  155. package/dist/ui/FolderNameDialog.d.cts +14 -0
  156. package/dist/ui/FolderNameDialog.d.cts.map +1 -0
  157. package/dist/ui/FolderNameDialog.d.ts +14 -0
  158. package/dist/ui/FolderNameDialog.d.ts.map +1 -0
  159. package/dist/ui/FolderNameDialog.js +67 -0
  160. package/dist/ui/FolderTree.cjs +85 -0
  161. package/dist/ui/FolderTree.d.cts +13 -0
  162. package/dist/ui/FolderTree.d.cts.map +1 -0
  163. package/dist/ui/FolderTree.d.ts +13 -0
  164. package/dist/ui/FolderTree.d.ts.map +1 -0
  165. package/dist/ui/FolderTree.js +44 -0
  166. package/dist/ui/MetadataPanel.cjs +23 -17
  167. package/dist/ui/MetadataPanel.d.cts.map +1 -1
  168. package/dist/ui/MetadataPanel.d.ts.map +1 -1
  169. package/dist/ui/MetadataPanel.js +23 -17
  170. package/dist/ui/MoveTargetPicker.cjs +87 -0
  171. package/dist/ui/MoveTargetPicker.d.cts +16 -0
  172. package/dist/ui/MoveTargetPicker.d.cts.map +1 -0
  173. package/dist/ui/MoveTargetPicker.d.ts +16 -0
  174. package/dist/ui/MoveTargetPicker.d.ts.map +1 -0
  175. package/dist/ui/MoveTargetPicker.js +49 -0
  176. package/dist/ui/ReplaceAssetDialog.cjs +19 -17
  177. package/dist/ui/ReplaceAssetDialog.d.cts +2 -1
  178. package/dist/ui/ReplaceAssetDialog.d.cts.map +1 -1
  179. package/dist/ui/ReplaceAssetDialog.d.ts +2 -1
  180. package/dist/ui/ReplaceAssetDialog.d.ts.map +1 -1
  181. package/dist/ui/ReplaceAssetDialog.js +19 -17
  182. package/dist/ui/UnsplashPanel.cjs +137 -0
  183. package/dist/ui/UnsplashPanel.d.cts +28 -0
  184. package/dist/ui/UnsplashPanel.d.cts.map +1 -0
  185. package/dist/ui/UnsplashPanel.d.ts +28 -0
  186. package/dist/ui/UnsplashPanel.d.ts.map +1 -0
  187. package/dist/ui/UnsplashPanel.js +99 -0
  188. package/dist/ui/UploadButton.cjs +12 -13
  189. package/dist/ui/UploadButton.d.cts +9 -2
  190. package/dist/ui/UploadButton.d.cts.map +1 -1
  191. package/dist/ui/UploadButton.d.ts +9 -2
  192. package/dist/ui/UploadButton.d.ts.map +1 -1
  193. package/dist/ui/UploadButton.js +12 -13
  194. package/dist/ui/index.cjs +41 -0
  195. package/dist/ui/index.d.cts +15 -0
  196. package/dist/ui/index.d.cts.map +1 -1
  197. package/dist/ui/index.d.ts +15 -0
  198. package/dist/ui/index.d.ts.map +1 -1
  199. package/dist/ui/index.js +8 -0
  200. package/dist/utils/data-source.cjs +190 -0
  201. package/dist/utils/data-source.d.cts +63 -0
  202. package/dist/utils/data-source.d.cts.map +1 -0
  203. package/dist/utils/data-source.d.ts +63 -0
  204. package/dist/utils/data-source.d.ts.map +1 -0
  205. package/dist/utils/data-source.js +149 -0
  206. package/dist/utils/errors.cjs +18 -0
  207. package/dist/utils/errors.d.cts +27 -0
  208. package/dist/utils/errors.d.cts.map +1 -1
  209. package/dist/utils/errors.d.ts +27 -0
  210. package/dist/utils/errors.d.ts.map +1 -1
  211. package/dist/utils/errors.js +16 -1
  212. package/dist/utils/folders.cjs +335 -0
  213. package/dist/utils/folders.d.cts +54 -0
  214. package/dist/utils/folders.d.cts.map +1 -0
  215. package/dist/utils/folders.d.ts +54 -0
  216. package/dist/utils/folders.d.ts.map +1 -0
  217. package/dist/utils/folders.js +297 -0
  218. package/dist/utils/header-action.cjs +1 -1
  219. package/dist/utils/header-action.d.cts.map +1 -1
  220. package/dist/utils/header-action.d.ts.map +1 -1
  221. package/dist/utils/header-action.js +1 -1
  222. package/dist/utils/registry.cjs +38 -12
  223. package/dist/utils/registry.d.cts +29 -1
  224. package/dist/utils/registry.d.cts.map +1 -1
  225. package/dist/utils/registry.d.ts +29 -1
  226. package/dist/utils/registry.d.ts.map +1 -1
  227. package/dist/utils/registry.js +31 -11
  228. package/dist/utils/resolver.cjs +5 -4
  229. package/dist/utils/resolver.d.cts.map +1 -1
  230. package/dist/utils/resolver.d.ts.map +1 -1
  231. package/dist/utils/resolver.js +5 -4
  232. package/dist/utils/studio-asset-source.cjs +13 -4
  233. package/dist/utils/studio-asset-source.d.cts +6 -1
  234. package/dist/utils/studio-asset-source.d.cts.map +1 -1
  235. package/dist/utils/studio-asset-source.d.ts +6 -1
  236. package/dist/utils/studio-asset-source.d.ts.map +1 -1
  237. package/dist/utils/studio-asset-source.js +9 -3
  238. package/dist/utils/validate-upload-result.d.cts +2 -1
  239. package/dist/utils/validate-upload-result.d.cts.map +1 -1
  240. package/dist/utils/validate-upload-result.d.ts +2 -1
  241. package/dist/utils/validate-upload-result.d.ts.map +1 -1
  242. package/dist/version.cjs +1 -1
  243. package/dist/version.d.cts +1 -1
  244. package/dist/version.d.ts +1 -1
  245. package/dist/version.js +1 -1
  246. package/i18n/messages/en.json +99 -0
  247. package/i18n/messages/ja.json +99 -0
  248. package/i18n/messages/ko.json +99 -0
  249. package/i18n/messages/zh.json +99 -0
  250. package/meta/config.json +1 -1
  251. package/package.json +19 -8
@@ -1,9 +1,12 @@
1
1
  "use client";
2
+ import { useMsg } from "@anvilkit/core/i18n";
2
3
  import { Button } from "@anvilkit/ui/button";
3
4
  import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@anvilkit/ui/dialog";
4
5
  import { Input } from "@anvilkit/ui/input";
6
+ import { Label } from "@anvilkit/ui/label";
5
7
  import * as __rspack_external_react from "react";
6
8
  function MetadataPanel({ asset, onCancel, onConfirm }) {
9
+ const msg = useMsg();
7
10
  const [name, setName] = __rspack_external_react.useState("");
8
11
  const [tagInput, setTagInput] = __rspack_external_react.useState("");
9
12
  const [tags, setTags] = __rspack_external_react.useState([]);
@@ -12,8 +15,6 @@ function MetadataPanel({ asset, onCancel, onConfirm }) {
12
15
  if (null === asset) return;
13
16
  setName(asset.name ?? "");
14
17
  setTags(asset.tags ?? []);
15
- setTagInput("");
16
- setBusy(false);
17
18
  }, [
18
19
  asset
19
20
  ]);
@@ -54,19 +55,23 @@ function MetadataPanel({ asset, onCancel, onConfirm }) {
54
55
  setBusy(false);
55
56
  }
56
57
  }
58
+ function handleCancel() {
59
+ setTagInput("");
60
+ onCancel();
61
+ }
57
62
  function handleOpenChange(nextOpen) {
58
- if (!nextOpen && !busy) onCancel();
63
+ if (!nextOpen && !busy) handleCancel();
59
64
  }
60
65
  const open = null !== asset;
61
66
  const mimeType = asset?.meta?.mimeType;
62
67
  return /*#__PURE__*/ __rspack_external_react.createElement(Dialog, {
63
68
  open: open,
64
69
  onOpenChange: handleOpenChange
65
- }, /*#__PURE__*/ __rspack_external_react.createElement(DialogContent, null, /*#__PURE__*/ __rspack_external_react.createElement(DialogHeader, null, /*#__PURE__*/ __rspack_external_react.createElement(DialogTitle, null, "Edit asset"), /*#__PURE__*/ __rspack_external_react.createElement(DialogDescription, null, asset?.id, mimeType ? ` (${mimeType})` : "")), /*#__PURE__*/ __rspack_external_react.createElement("div", {
70
+ }, /*#__PURE__*/ __rspack_external_react.createElement(DialogContent, null, /*#__PURE__*/ __rspack_external_react.createElement(DialogHeader, null, /*#__PURE__*/ __rspack_external_react.createElement(DialogTitle, null, msg("assetManager.dialog.editTitle")), /*#__PURE__*/ __rspack_external_react.createElement(DialogDescription, null, asset?.id, mimeType ? ` (${mimeType})` : "")), /*#__PURE__*/ __rspack_external_react.createElement("div", {
66
71
  "data-asset-manager-metadata": true
67
- }, /*#__PURE__*/ __rspack_external_react.createElement("label", {
72
+ }, /*#__PURE__*/ __rspack_external_react.createElement(Label, {
68
73
  htmlFor: "asset-metadata-name"
69
- }, "Name"), /*#__PURE__*/ __rspack_external_react.createElement(Input, {
74
+ }, msg("assetManager.form.nameLabel")), /*#__PURE__*/ __rspack_external_react.createElement(Input, {
70
75
  id: "asset-metadata-name",
71
76
  value: name,
72
77
  onChange: (event)=>{
@@ -76,21 +81,22 @@ function MetadataPanel({ asset, onCancel, onConfirm }) {
76
81
  disabled: busy
77
82
  }), /*#__PURE__*/ __rspack_external_react.createElement("div", {
78
83
  "data-asset-manager-tag-editor": true
79
- }, /*#__PURE__*/ __rspack_external_react.createElement("label", {
84
+ }, /*#__PURE__*/ __rspack_external_react.createElement(Label, {
80
85
  htmlFor: "asset-metadata-tag-input"
81
- }, "Tags"), /*#__PURE__*/ __rspack_external_react.createElement("ul", {
82
- "aria-label": "Current tags",
83
- role: "list"
86
+ }, msg("assetManager.form.tagsLabel")), /*#__PURE__*/ __rspack_external_react.createElement("ul", {
87
+ "aria-label": msg("assetManager.form.tagsListLabel")
84
88
  }, tags.map((tag)=>/*#__PURE__*/ __rspack_external_react.createElement("li", {
85
89
  key: tag
86
- }, /*#__PURE__*/ __rspack_external_react.createElement("span", null, tag), /*#__PURE__*/ __rspack_external_react.createElement("button", {
87
- "aria-label": `Remove tag ${tag}`,
90
+ }, /*#__PURE__*/ __rspack_external_react.createElement("span", null, tag), /*#__PURE__*/ __rspack_external_react.createElement(Button, {
91
+ "aria-label": msg("assetManager.form.removeTag").replace("{tag}", tag),
88
92
  "data-asset-action": "remove-tag",
89
93
  disabled: busy,
90
94
  onClick: ()=>{
91
95
  removeTag(tag);
92
96
  },
93
- type: "button"
97
+ type: "button",
98
+ variant: "ghost",
99
+ size: "icon-xs"
94
100
  }, "\xd7")))), /*#__PURE__*/ __rspack_external_react.createElement(Input, {
95
101
  id: "asset-metadata-tag-input",
96
102
  value: tagInput,
@@ -98,17 +104,17 @@ function MetadataPanel({ asset, onCancel, onConfirm }) {
98
104
  setTagInput(event.target.value);
99
105
  },
100
106
  onKeyDown: handleTagKeyDown,
101
- placeholder: "Add a tag and press Enter",
107
+ placeholder: msg("assetManager.form.addTagPlaceholder"),
102
108
  disabled: busy
103
109
  }))), /*#__PURE__*/ __rspack_external_react.createElement(DialogFooter, null, /*#__PURE__*/ __rspack_external_react.createElement(Button, {
104
110
  disabled: busy,
105
- onClick: onCancel,
111
+ onClick: handleCancel,
106
112
  type: "button",
107
113
  variant: "outline"
108
- }, "Cancel"), /*#__PURE__*/ __rspack_external_react.createElement(Button, {
114
+ }, msg("assetManager.button.cancel")), /*#__PURE__*/ __rspack_external_react.createElement(Button, {
109
115
  disabled: busy || null === asset,
110
116
  onClick: handleConfirm,
111
117
  type: "button"
112
- }, busy ? "Saving…" : "Save"))));
118
+ }, busy ? msg("assetManager.dialog.saveProgress") : msg("assetManager.button.save")))));
113
119
  }
114
120
  export { MetadataPanel };
@@ -0,0 +1,87 @@
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
+ MoveTargetPicker: ()=>MoveTargetPicker
33
+ });
34
+ const i18n_namespaceObject = require("@anvilkit/core/i18n");
35
+ const button_namespaceObject = require("@anvilkit/ui/button");
36
+ const dialog_namespaceObject = require("@anvilkit/ui/dialog");
37
+ const external_react_namespaceObject = require("react");
38
+ function MoveTargetPicker({ open, onOpenChange, folders, onPick, rootLabel }) {
39
+ const msg = (0, i18n_namespaceObject.useMsg)();
40
+ const resolvedRootLabel = rootLabel ?? msg("assetManager.folder.root");
41
+ const [busy, setBusy] = external_react_namespaceObject.useState(false);
42
+ async function pick(folderId) {
43
+ if (busy) return;
44
+ setBusy(true);
45
+ try {
46
+ await onPick(folderId);
47
+ onOpenChange(false);
48
+ } finally{
49
+ setBusy(false);
50
+ }
51
+ }
52
+ return /*#__PURE__*/ external_react_namespaceObject.createElement(dialog_namespaceObject.Dialog, {
53
+ open: open,
54
+ onOpenChange: (next)=>{
55
+ if (!busy) onOpenChange(next);
56
+ }
57
+ }, /*#__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, msg("assetManager.dialog.moveTitle"))), /*#__PURE__*/ external_react_namespaceObject.createElement("ul", {
58
+ "aria-label": msg("assetManager.dialog.moveTitle"),
59
+ "data-testid": "ak-move-target-picker",
60
+ className: "flex max-h-72 flex-col gap-1 overflow-auto"
61
+ }, /*#__PURE__*/ external_react_namespaceObject.createElement("li", null, /*#__PURE__*/ external_react_namespaceObject.createElement(button_namespaceObject.Button, {
62
+ type: "button",
63
+ variant: "ghost",
64
+ size: "sm",
65
+ className: "w-full justify-start",
66
+ "data-move-target": "root",
67
+ disabled: busy,
68
+ onClick: ()=>void pick(null)
69
+ }, resolvedRootLabel)), folders.map((folder)=>/*#__PURE__*/ external_react_namespaceObject.createElement("li", {
70
+ key: folder.id
71
+ }, /*#__PURE__*/ external_react_namespaceObject.createElement(button_namespaceObject.Button, {
72
+ type: "button",
73
+ variant: "ghost",
74
+ size: "sm",
75
+ className: "w-full justify-start",
76
+ "data-move-target": folder.id,
77
+ disabled: busy,
78
+ onClick: ()=>void pick(folder.id)
79
+ }, folder.name))))));
80
+ }
81
+ exports.MoveTargetPicker = __webpack_exports__.MoveTargetPicker;
82
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
83
+ "MoveTargetPicker"
84
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
85
+ Object.defineProperty(exports, '__esModule', {
86
+ value: true
87
+ });
@@ -0,0 +1,16 @@
1
+ import type { AssetFolder } from "../types/folders.js";
2
+ /**
3
+ * Keyboard-accessible move-target picker — the a11y fallback for drag-to-folder.
4
+ * Renders, inside a focus-trapping `<Dialog>`, a labelled `<ul>` of Tab-focusable
5
+ * folder `<Button>`s plus a root option (no roving-tabindex listbox; each option
6
+ * is an individually focusable, Enter/Space-activatable button).
7
+ */
8
+ export interface MoveTargetPickerProps {
9
+ readonly open: boolean;
10
+ readonly onOpenChange: (open: boolean) => void;
11
+ readonly folders: readonly AssetFolder[];
12
+ readonly onPick: (folderId: string | null) => void | Promise<void>;
13
+ readonly rootLabel?: string;
14
+ }
15
+ export declare function MoveTargetPicker({ open, onOpenChange, folders, onPick, rootLabel, }: MoveTargetPickerProps): import("react/jsx-runtime").JSX.Element;
16
+ //# sourceMappingURL=MoveTargetPicker.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MoveTargetPicker.d.cts","sourceRoot":"","sources":["../../src/ui/MoveTargetPicker.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/C,QAAQ,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,CAAC;IACzC,QAAQ,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,wBAAgB,gBAAgB,CAAC,EAChC,IAAI,EACJ,YAAY,EACZ,OAAO,EACP,MAAM,EACN,SAAS,GACT,EAAE,qBAAqB,2CAgEvB"}
@@ -0,0 +1,16 @@
1
+ import type { AssetFolder } from "../types/folders.js";
2
+ /**
3
+ * Keyboard-accessible move-target picker — the a11y fallback for drag-to-folder.
4
+ * Renders, inside a focus-trapping `<Dialog>`, a labelled `<ul>` of Tab-focusable
5
+ * folder `<Button>`s plus a root option (no roving-tabindex listbox; each option
6
+ * is an individually focusable, Enter/Space-activatable button).
7
+ */
8
+ export interface MoveTargetPickerProps {
9
+ readonly open: boolean;
10
+ readonly onOpenChange: (open: boolean) => void;
11
+ readonly folders: readonly AssetFolder[];
12
+ readonly onPick: (folderId: string | null) => void | Promise<void>;
13
+ readonly rootLabel?: string;
14
+ }
15
+ export declare function MoveTargetPicker({ open, onOpenChange, folders, onPick, rootLabel, }: MoveTargetPickerProps): import("react/jsx-runtime").JSX.Element;
16
+ //# sourceMappingURL=MoveTargetPicker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MoveTargetPicker.d.ts","sourceRoot":"","sources":["../../src/ui/MoveTargetPicker.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/C,QAAQ,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,CAAC;IACzC,QAAQ,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,wBAAgB,gBAAgB,CAAC,EAChC,IAAI,EACJ,YAAY,EACZ,OAAO,EACP,MAAM,EACN,SAAS,GACT,EAAE,qBAAqB,2CAgEvB"}
@@ -0,0 +1,49 @@
1
+ "use client";
2
+ import { useMsg } from "@anvilkit/core/i18n";
3
+ import { Button } from "@anvilkit/ui/button";
4
+ import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@anvilkit/ui/dialog";
5
+ import * as __rspack_external_react from "react";
6
+ function MoveTargetPicker({ open, onOpenChange, folders, onPick, rootLabel }) {
7
+ const msg = useMsg();
8
+ const resolvedRootLabel = rootLabel ?? msg("assetManager.folder.root");
9
+ const [busy, setBusy] = __rspack_external_react.useState(false);
10
+ async function pick(folderId) {
11
+ if (busy) return;
12
+ setBusy(true);
13
+ try {
14
+ await onPick(folderId);
15
+ onOpenChange(false);
16
+ } finally{
17
+ setBusy(false);
18
+ }
19
+ }
20
+ return /*#__PURE__*/ __rspack_external_react.createElement(Dialog, {
21
+ open: open,
22
+ onOpenChange: (next)=>{
23
+ if (!busy) onOpenChange(next);
24
+ }
25
+ }, /*#__PURE__*/ __rspack_external_react.createElement(DialogContent, null, /*#__PURE__*/ __rspack_external_react.createElement(DialogHeader, null, /*#__PURE__*/ __rspack_external_react.createElement(DialogTitle, null, msg("assetManager.dialog.moveTitle"))), /*#__PURE__*/ __rspack_external_react.createElement("ul", {
26
+ "aria-label": msg("assetManager.dialog.moveTitle"),
27
+ "data-testid": "ak-move-target-picker",
28
+ className: "flex max-h-72 flex-col gap-1 overflow-auto"
29
+ }, /*#__PURE__*/ __rspack_external_react.createElement("li", null, /*#__PURE__*/ __rspack_external_react.createElement(Button, {
30
+ type: "button",
31
+ variant: "ghost",
32
+ size: "sm",
33
+ className: "w-full justify-start",
34
+ "data-move-target": "root",
35
+ disabled: busy,
36
+ onClick: ()=>void pick(null)
37
+ }, resolvedRootLabel)), folders.map((folder)=>/*#__PURE__*/ __rspack_external_react.createElement("li", {
38
+ key: folder.id
39
+ }, /*#__PURE__*/ __rspack_external_react.createElement(Button, {
40
+ type: "button",
41
+ variant: "ghost",
42
+ size: "sm",
43
+ className: "w-full justify-start",
44
+ "data-move-target": folder.id,
45
+ disabled: busy,
46
+ onClick: ()=>void pick(folder.id)
47
+ }, folder.name))))));
48
+ }
49
+ export { MoveTargetPicker };
@@ -31,11 +31,13 @@ __webpack_require__.r(__webpack_exports__);
31
31
  __webpack_require__.d(__webpack_exports__, {
32
32
  ReplaceAssetDialog: ()=>ReplaceAssetDialog
33
33
  });
34
+ const i18n_namespaceObject = require("@anvilkit/core/i18n");
34
35
  const button_namespaceObject = require("@anvilkit/ui/button");
35
36
  const dialog_namespaceObject = require("@anvilkit/ui/dialog");
36
37
  const external_react_namespaceObject = require("react");
37
38
  const external_plugin_cjs_namespaceObject = require("../plugin.cjs");
38
39
  function ReplaceAssetDialog({ acceptedMimeTypes, asset, maxFileSize, onCancel, onConfirm }) {
40
+ const msg = (0, i18n_namespaceObject.useMsg)();
39
41
  const inputRef = external_react_namespaceObject.useRef(null);
40
42
  const [selectedFile, setSelectedFile] = external_react_namespaceObject.useState(null);
41
43
  const [error, setError] = external_react_namespaceObject.useState(null);
@@ -43,15 +45,10 @@ function ReplaceAssetDialog({ acceptedMimeTypes, asset, maxFileSize, onCancel, o
43
45
  const acceptAttr = external_react_namespaceObject.useMemo(()=>acceptedMimeTypes?.join(","), [
44
46
  acceptedMimeTypes
45
47
  ]);
46
- external_react_namespaceObject.useEffect(()=>{
47
- if (null === asset) {
48
- setSelectedFile(null);
49
- setError(null);
50
- setBusy(false);
51
- }
52
- }, [
53
- asset
54
- ]);
48
+ function resetPicker() {
49
+ setSelectedFile(null);
50
+ setError(null);
51
+ }
55
52
  function handleFileChange(event) {
56
53
  const file = event.target.files?.[0];
57
54
  event.target.value = "";
@@ -73,22 +70,27 @@ function ReplaceAssetDialog({ acceptedMimeTypes, asset, maxFileSize, onCancel, o
73
70
  setBusy(true);
74
71
  try {
75
72
  await onConfirm(asset, selectedFile);
73
+ resetPicker();
76
74
  } catch (err) {
77
75
  setError(err instanceof Error ? err.message : String(err));
78
76
  } finally{
79
77
  setBusy(false);
80
78
  }
81
79
  }
80
+ function handleCancel() {
81
+ resetPicker();
82
+ onCancel();
83
+ }
82
84
  function handleOpenChange(nextOpen) {
83
- if (!nextOpen && !busy) onCancel();
85
+ if (!nextOpen && !busy) handleCancel();
84
86
  }
85
87
  const open = null !== asset;
86
88
  const label = asset?.name ?? asset?.id ?? "";
87
89
  return /*#__PURE__*/ external_react_namespaceObject.createElement(dialog_namespaceObject.Dialog, {
88
90
  open: open,
89
91
  onOpenChange: handleOpenChange
90
- }, /*#__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, "Replace asset?"), /*#__PURE__*/ external_react_namespaceObject.createElement(dialog_namespaceObject.DialogDescription, null, label ? `Pick a file to replace ${label} with. Existing asset:// references will resolve to the new bytes.` : "Pick a file to replace this asset with.")), /*#__PURE__*/ external_react_namespaceObject.createElement("input", {
91
- "aria-label": "Replacement file",
92
+ }, /*#__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, msg("assetManager.dialog.replaceTitle")), /*#__PURE__*/ external_react_namespaceObject.createElement(dialog_namespaceObject.DialogDescription, null, label ? msg("assetManager.dialog.replaceDescription").replace("{label}", label) : msg("assetManager.dialog.replaceDescriptionGeneric"))), /*#__PURE__*/ external_react_namespaceObject.createElement("input", {
93
+ "aria-label": msg("assetManager.dialog.replaceFileLabel"),
92
94
  "data-testid": "replace-asset-file-input",
93
95
  hidden: true,
94
96
  onChange: handleFileChange,
@@ -104,22 +106,22 @@ function ReplaceAssetDialog({ acceptedMimeTypes, asset, maxFileSize, onCancel, o
104
106
  variant: "outline",
105
107
  onClick: ()=>inputRef.current?.click(),
106
108
  disabled: busy
107
- }, selectedFile ? "Choose a different file" : "Choose file"), /*#__PURE__*/ external_react_namespaceObject.createElement("p", {
109
+ }, selectedFile ? msg("assetManager.dialog.chooseFileDifferent") : msg("assetManager.dialog.chooseFile")), /*#__PURE__*/ external_react_namespaceObject.createElement("p", {
108
110
  "aria-live": "polite",
109
111
  role: "status"
110
- }, selectedFile ? `Selected: ${selectedFile.name}` : "No file selected."), error ? /*#__PURE__*/ external_react_namespaceObject.createElement("p", {
112
+ }, selectedFile ? msg("assetManager.dialog.fileSelected").replace("{name}", selectedFile.name) : msg("assetManager.dialog.noFileSelected")), error ? /*#__PURE__*/ external_react_namespaceObject.createElement("p", {
111
113
  "data-asset-manager-replace-error": true,
112
114
  role: "alert"
113
115
  }, error) : null), /*#__PURE__*/ external_react_namespaceObject.createElement(dialog_namespaceObject.DialogFooter, null, /*#__PURE__*/ external_react_namespaceObject.createElement(button_namespaceObject.Button, {
114
116
  type: "button",
115
117
  variant: "outline",
116
- onClick: onCancel,
118
+ onClick: handleCancel,
117
119
  disabled: busy
118
- }, "Cancel"), /*#__PURE__*/ external_react_namespaceObject.createElement(button_namespaceObject.Button, {
120
+ }, msg("assetManager.button.cancel")), /*#__PURE__*/ external_react_namespaceObject.createElement(button_namespaceObject.Button, {
119
121
  type: "button",
120
122
  onClick: handleConfirm,
121
123
  disabled: busy || null === asset || null === selectedFile
122
- }, busy ? "Replacing…" : "Replace"))));
124
+ }, busy ? msg("assetManager.dialog.replaceProgress") : msg("assetManager.button.replace")))));
123
125
  }
124
126
  exports.ReplaceAssetDialog = __webpack_exports__.ReplaceAssetDialog;
125
127
  for(var __rspack_i in __webpack_exports__)if (-1 === [
@@ -1,4 +1,5 @@
1
- import type { AssetManagerOptions, UploadResult } from "../types/types.js";
1
+ import type { AssetManagerOptions } from "../types/options.js";
2
+ import type { UploadResult } from "../types/types.js";
2
3
  export interface ReplaceAssetDialogProps extends Pick<AssetManagerOptions, "acceptedMimeTypes" | "maxFileSize"> {
3
4
  /** Asset to replace. `null` closes the dialog. */
4
5
  readonly asset: UploadResult | null;
@@ -1 +1 @@
1
- {"version":3,"file":"ReplaceAssetDialog.d.cts","sourceRoot":"","sources":["../../src/ui/ReplaceAssetDialog.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAE3E,MAAM,WAAW,uBAChB,SAAQ,IAAI,CAAC,mBAAmB,EAAE,mBAAmB,GAAG,aAAa,CAAC;IACtE,kDAAkD;IAClD,QAAQ,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;IACpC;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED,wBAAgB,kBAAkB,CAAC,EAClC,iBAAiB,EACjB,KAAK,EACL,WAAW,EACX,QAAQ,EACR,SAAS,GACT,EAAE,uBAAuB,2CAuHzB"}
1
+ {"version":3,"file":"ReplaceAssetDialog.d.cts","sourceRoot":"","sources":["../../src/ui/ReplaceAssetDialog.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,MAAM,WAAW,uBAChB,SAAQ,IAAI,CAAC,mBAAmB,EAAE,mBAAmB,GAAG,aAAa,CAAC;IACtE,kDAAkD;IAClD,QAAQ,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;IACpC;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED,wBAAgB,kBAAkB,CAAC,EAClC,iBAAiB,EACjB,KAAK,EACL,WAAW,EACX,QAAQ,EACR,SAAS,GACT,EAAE,uBAAuB,2CAuIzB"}
@@ -1,4 +1,5 @@
1
- import type { AssetManagerOptions, UploadResult } from "../types/types.js";
1
+ import type { AssetManagerOptions } from "../types/options.js";
2
+ import type { UploadResult } from "../types/types.js";
2
3
  export interface ReplaceAssetDialogProps extends Pick<AssetManagerOptions, "acceptedMimeTypes" | "maxFileSize"> {
3
4
  /** Asset to replace. `null` closes the dialog. */
4
5
  readonly asset: UploadResult | null;
@@ -1 +1 @@
1
- {"version":3,"file":"ReplaceAssetDialog.d.ts","sourceRoot":"","sources":["../../src/ui/ReplaceAssetDialog.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAE3E,MAAM,WAAW,uBAChB,SAAQ,IAAI,CAAC,mBAAmB,EAAE,mBAAmB,GAAG,aAAa,CAAC;IACtE,kDAAkD;IAClD,QAAQ,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;IACpC;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED,wBAAgB,kBAAkB,CAAC,EAClC,iBAAiB,EACjB,KAAK,EACL,WAAW,EACX,QAAQ,EACR,SAAS,GACT,EAAE,uBAAuB,2CAuHzB"}
1
+ {"version":3,"file":"ReplaceAssetDialog.d.ts","sourceRoot":"","sources":["../../src/ui/ReplaceAssetDialog.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,MAAM,WAAW,uBAChB,SAAQ,IAAI,CAAC,mBAAmB,EAAE,mBAAmB,GAAG,aAAa,CAAC;IACtE,kDAAkD;IAClD,QAAQ,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;IACpC;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED,wBAAgB,kBAAkB,CAAC,EAClC,iBAAiB,EACjB,KAAK,EACL,WAAW,EACX,QAAQ,EACR,SAAS,GACT,EAAE,uBAAuB,2CAuIzB"}
@@ -1,9 +1,11 @@
1
1
  "use client";
2
+ import { useMsg } from "@anvilkit/core/i18n";
2
3
  import { Button } from "@anvilkit/ui/button";
3
4
  import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@anvilkit/ui/dialog";
4
5
  import { validateSelectedFile } from "../plugin.js";
5
6
  import * as __rspack_external_react from "react";
6
7
  function ReplaceAssetDialog({ acceptedMimeTypes, asset, maxFileSize, onCancel, onConfirm }) {
8
+ const msg = useMsg();
7
9
  const inputRef = __rspack_external_react.useRef(null);
8
10
  const [selectedFile, setSelectedFile] = __rspack_external_react.useState(null);
9
11
  const [error, setError] = __rspack_external_react.useState(null);
@@ -11,15 +13,10 @@ function ReplaceAssetDialog({ acceptedMimeTypes, asset, maxFileSize, onCancel, o
11
13
  const acceptAttr = __rspack_external_react.useMemo(()=>acceptedMimeTypes?.join(","), [
12
14
  acceptedMimeTypes
13
15
  ]);
14
- __rspack_external_react.useEffect(()=>{
15
- if (null === asset) {
16
- setSelectedFile(null);
17
- setError(null);
18
- setBusy(false);
19
- }
20
- }, [
21
- asset
22
- ]);
16
+ function resetPicker() {
17
+ setSelectedFile(null);
18
+ setError(null);
19
+ }
23
20
  function handleFileChange(event) {
24
21
  const file = event.target.files?.[0];
25
22
  event.target.value = "";
@@ -41,22 +38,27 @@ function ReplaceAssetDialog({ acceptedMimeTypes, asset, maxFileSize, onCancel, o
41
38
  setBusy(true);
42
39
  try {
43
40
  await onConfirm(asset, selectedFile);
41
+ resetPicker();
44
42
  } catch (err) {
45
43
  setError(err instanceof Error ? err.message : String(err));
46
44
  } finally{
47
45
  setBusy(false);
48
46
  }
49
47
  }
48
+ function handleCancel() {
49
+ resetPicker();
50
+ onCancel();
51
+ }
50
52
  function handleOpenChange(nextOpen) {
51
- if (!nextOpen && !busy) onCancel();
53
+ if (!nextOpen && !busy) handleCancel();
52
54
  }
53
55
  const open = null !== asset;
54
56
  const label = asset?.name ?? asset?.id ?? "";
55
57
  return /*#__PURE__*/ __rspack_external_react.createElement(Dialog, {
56
58
  open: open,
57
59
  onOpenChange: handleOpenChange
58
- }, /*#__PURE__*/ __rspack_external_react.createElement(DialogContent, null, /*#__PURE__*/ __rspack_external_react.createElement(DialogHeader, null, /*#__PURE__*/ __rspack_external_react.createElement(DialogTitle, null, "Replace asset?"), /*#__PURE__*/ __rspack_external_react.createElement(DialogDescription, null, label ? `Pick a file to replace ${label} with. Existing asset:// references will resolve to the new bytes.` : "Pick a file to replace this asset with.")), /*#__PURE__*/ __rspack_external_react.createElement("input", {
59
- "aria-label": "Replacement file",
60
+ }, /*#__PURE__*/ __rspack_external_react.createElement(DialogContent, null, /*#__PURE__*/ __rspack_external_react.createElement(DialogHeader, null, /*#__PURE__*/ __rspack_external_react.createElement(DialogTitle, null, msg("assetManager.dialog.replaceTitle")), /*#__PURE__*/ __rspack_external_react.createElement(DialogDescription, null, label ? msg("assetManager.dialog.replaceDescription").replace("{label}", label) : msg("assetManager.dialog.replaceDescriptionGeneric"))), /*#__PURE__*/ __rspack_external_react.createElement("input", {
61
+ "aria-label": msg("assetManager.dialog.replaceFileLabel"),
60
62
  "data-testid": "replace-asset-file-input",
61
63
  hidden: true,
62
64
  onChange: handleFileChange,
@@ -72,21 +74,21 @@ function ReplaceAssetDialog({ acceptedMimeTypes, asset, maxFileSize, onCancel, o
72
74
  variant: "outline",
73
75
  onClick: ()=>inputRef.current?.click(),
74
76
  disabled: busy
75
- }, selectedFile ? "Choose a different file" : "Choose file"), /*#__PURE__*/ __rspack_external_react.createElement("p", {
77
+ }, selectedFile ? msg("assetManager.dialog.chooseFileDifferent") : msg("assetManager.dialog.chooseFile")), /*#__PURE__*/ __rspack_external_react.createElement("p", {
76
78
  "aria-live": "polite",
77
79
  role: "status"
78
- }, selectedFile ? `Selected: ${selectedFile.name}` : "No file selected."), error ? /*#__PURE__*/ __rspack_external_react.createElement("p", {
80
+ }, selectedFile ? msg("assetManager.dialog.fileSelected").replace("{name}", selectedFile.name) : msg("assetManager.dialog.noFileSelected")), error ? /*#__PURE__*/ __rspack_external_react.createElement("p", {
79
81
  "data-asset-manager-replace-error": true,
80
82
  role: "alert"
81
83
  }, error) : null), /*#__PURE__*/ __rspack_external_react.createElement(DialogFooter, null, /*#__PURE__*/ __rspack_external_react.createElement(Button, {
82
84
  type: "button",
83
85
  variant: "outline",
84
- onClick: onCancel,
86
+ onClick: handleCancel,
85
87
  disabled: busy
86
- }, "Cancel"), /*#__PURE__*/ __rspack_external_react.createElement(Button, {
88
+ }, msg("assetManager.button.cancel")), /*#__PURE__*/ __rspack_external_react.createElement(Button, {
87
89
  type: "button",
88
90
  onClick: handleConfirm,
89
91
  disabled: busy || null === asset || null === selectedFile
90
- }, busy ? "Replacing…" : "Replace"))));
92
+ }, busy ? msg("assetManager.dialog.replaceProgress") : msg("assetManager.button.replace")))));
91
93
  }
92
94
  export { ReplaceAssetDialog };
@@ -0,0 +1,137 @@
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
+ UnsplashPanel: ()=>UnsplashPanel
33
+ });
34
+ const i18n_namespaceObject = require("@anvilkit/core/i18n");
35
+ const button_namespaceObject = require("@anvilkit/ui/button");
36
+ const input_namespaceObject = require("@anvilkit/ui/input");
37
+ const external_react_namespaceObject = require("react");
38
+ function UnsplashPanel({ themes, activeThemeId, onThemeChange, query, onQueryChange, results, status, onPick, onLoadMore, themeLabel, skeletonCount = 12 }) {
39
+ const msg = (0, i18n_namespaceObject.useMsg)();
40
+ const resolvedThemeLabel = themeLabel ?? ((key)=>msg(key));
41
+ if ("disabled" === status) return /*#__PURE__*/ external_react_namespaceObject.createElement("div", {
42
+ role: "status",
43
+ "data-testid": "ak-unsplash-disabled",
44
+ className: "flex flex-col items-center gap-2 p-6 text-center text-sm text-[var(--ak-studio-muted-fg)]"
45
+ }, /*#__PURE__*/ external_react_namespaceObject.createElement("p", null, msg("assetManager.unsplash.disabled")));
46
+ return /*#__PURE__*/ external_react_namespaceObject.createElement("div", {
47
+ "data-testid": "ak-unsplash-panel",
48
+ className: "flex flex-col gap-2"
49
+ }, /*#__PURE__*/ external_react_namespaceObject.createElement("span", {
50
+ role: "status",
51
+ "aria-live": "polite",
52
+ "data-testid": "ak-unsplash-status",
53
+ className: "sr-only"
54
+ }, "loading" === status ? msg("assetManager.unsplash.loading") : ""), /*#__PURE__*/ external_react_namespaceObject.createElement(input_namespaceObject.Input, {
55
+ value: query,
56
+ placeholder: msg("assetManager.unsplash.searchPlaceholder"),
57
+ "data-testid": "ak-unsplash-search",
58
+ onChange: (event)=>onQueryChange(event.currentTarget.value)
59
+ }), themes.length > 0 ? /*#__PURE__*/ external_react_namespaceObject.createElement("div", {
60
+ role: "group",
61
+ "aria-label": msg("assetManager.unsplash.themesLabel"),
62
+ "data-testid": "ak-unsplash-themes",
63
+ className: "flex flex-wrap gap-1"
64
+ }, themes.map((theme)=>/*#__PURE__*/ external_react_namespaceObject.createElement(button_namespaceObject.Button, {
65
+ key: theme.id,
66
+ type: "button",
67
+ size: "sm",
68
+ variant: theme.id === activeThemeId ? "secondary" : "ghost",
69
+ "aria-pressed": theme.id === activeThemeId,
70
+ "data-theme-id": theme.id,
71
+ onClick: ()=>onThemeChange(theme.id === activeThemeId ? void 0 : theme.id)
72
+ }, resolvedThemeLabel(theme.label)))) : null, "rateLimited" === status ? /*#__PURE__*/ external_react_namespaceObject.createElement("p", {
73
+ role: "alert",
74
+ "data-testid": "ak-unsplash-rate-limited",
75
+ className: "text-sm"
76
+ }, msg("assetManager.unsplash.rateLimited")) : null, "error" === status ? /*#__PURE__*/ external_react_namespaceObject.createElement("p", {
77
+ role: "alert",
78
+ "data-testid": "ak-unsplash-error",
79
+ className: "text-sm"
80
+ }, msg("assetManager.unsplash.error")) : null, "loading" === status && 0 === results.length ? /*#__PURE__*/ external_react_namespaceObject.createElement("ul", {
81
+ "data-testid": "ak-unsplash-skeletons",
82
+ className: "grid grid-cols-3 gap-2",
83
+ "aria-hidden": "true"
84
+ }, Array.from({
85
+ length: skeletonCount
86
+ }, (_, index)=>/*#__PURE__*/ external_react_namespaceObject.createElement("li", {
87
+ key: `skeleton-${index}`,
88
+ className: "aspect-square animate-pulse rounded bg-[var(--ak-studio-muted,#e5e7eb)]"
89
+ }))) : 0 === results.length && "idle" === status ? /*#__PURE__*/ external_react_namespaceObject.createElement("p", {
90
+ "data-testid": "ak-unsplash-empty",
91
+ className: "p-4 text-center text-sm"
92
+ }, msg("assetManager.unsplash.empty")) : /*#__PURE__*/ external_react_namespaceObject.createElement("ul", {
93
+ "data-testid": "ak-unsplash-results",
94
+ className: "grid grid-cols-3 gap-2"
95
+ }, results.map((result)=>/*#__PURE__*/ external_react_namespaceObject.createElement("li", {
96
+ key: result.id,
97
+ className: "flex flex-col gap-0.5"
98
+ }, /*#__PURE__*/ external_react_namespaceObject.createElement("button", {
99
+ type: "button",
100
+ "data-unsplash-id": result.id,
101
+ "aria-label": msg("assetManager.unsplash.insert").replace("{photographer}", result.photographerName),
102
+ className: "overflow-hidden rounded",
103
+ onClick: ()=>void onPick(result.id)
104
+ }, /*#__PURE__*/ external_react_namespaceObject.createElement("img", {
105
+ src: result.thumbnailUrl,
106
+ alt: "",
107
+ className: "aspect-square w-full object-cover",
108
+ loading: "lazy"
109
+ })), /*#__PURE__*/ external_react_namespaceObject.createElement("p", {
110
+ className: "truncate text-[10px] text-[var(--ak-studio-muted-fg)]"
111
+ }, /*#__PURE__*/ external_react_namespaceObject.createElement("a", {
112
+ href: result.photographerUrl,
113
+ target: "_blank",
114
+ rel: "noreferrer noopener",
115
+ className: "underline"
116
+ }, result.photographerName), " ", "\xb7", " ", /*#__PURE__*/ external_react_namespaceObject.createElement("a", {
117
+ href: result.unsplashUrl,
118
+ target: "_blank",
119
+ rel: "noreferrer noopener",
120
+ className: "underline"
121
+ }, "Unsplash"))))), onLoadMore && results.length > 0 ? /*#__PURE__*/ external_react_namespaceObject.createElement("div", {
122
+ className: "flex justify-center"
123
+ }, /*#__PURE__*/ external_react_namespaceObject.createElement(button_namespaceObject.Button, {
124
+ type: "button",
125
+ variant: "outline",
126
+ size: "sm",
127
+ disabled: "loading" === status,
128
+ onClick: onLoadMore
129
+ }, msg("assetManager.button.loadMore"))) : null);
130
+ }
131
+ exports.UnsplashPanel = __webpack_exports__.UnsplashPanel;
132
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
133
+ "UnsplashPanel"
134
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
135
+ Object.defineProperty(exports, '__esModule', {
136
+ value: true
137
+ });