@anvilkit/plugin-asset-manager 0.1.7 → 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 (141) hide show
  1. package/README.md +3 -3
  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/plugin.cjs +3 -1
  23. package/dist/plugin.d.cts.map +1 -1
  24. package/dist/plugin.d.ts.map +1 -1
  25. package/dist/plugin.js +3 -1
  26. package/dist/sources/composite-source.cjs +4 -3
  27. package/dist/sources/composite-source.d.cts.map +1 -1
  28. package/dist/sources/composite-source.d.ts.map +1 -1
  29. package/dist/sources/composite-source.js +4 -3
  30. package/dist/sources/federated-search.cjs +16 -6
  31. package/dist/sources/federated-search.d.cts.map +1 -1
  32. package/dist/sources/federated-search.d.ts.map +1 -1
  33. package/dist/sources/federated-search.js +16 -6
  34. package/dist/sources/unsplash/index.cjs +6 -4
  35. package/dist/sources/unsplash/index.d.cts.map +1 -1
  36. package/dist/sources/unsplash/index.d.ts.map +1 -1
  37. package/dist/sources/unsplash/index.js +6 -4
  38. package/dist/types/types.d.cts +7 -1
  39. package/dist/types/types.d.cts.map +1 -1
  40. package/dist/types/types.d.ts +7 -1
  41. package/dist/types/types.d.ts.map +1 -1
  42. package/dist/ui/AssetBrowser.cjs +175 -134
  43. package/dist/ui/AssetBrowser.d.cts.map +1 -1
  44. package/dist/ui/AssetBrowser.d.ts.map +1 -1
  45. package/dist/ui/AssetBrowser.js +175 -134
  46. package/dist/ui/AssetCommandPalette.cjs +20 -18
  47. package/dist/ui/AssetCommandPalette.d.cts.map +1 -1
  48. package/dist/ui/AssetCommandPalette.d.ts.map +1 -1
  49. package/dist/ui/AssetCommandPalette.js +20 -18
  50. package/dist/ui/AssetManagerUI.cjs +23 -15
  51. package/dist/ui/AssetManagerUI.d.cts.map +1 -1
  52. package/dist/ui/AssetManagerUI.d.ts.map +1 -1
  53. package/dist/ui/AssetManagerUI.js +23 -15
  54. package/dist/ui/DeleteAssetDialog.cjs +5 -3
  55. package/dist/ui/DeleteAssetDialog.d.cts.map +1 -1
  56. package/dist/ui/DeleteAssetDialog.d.ts.map +1 -1
  57. package/dist/ui/DeleteAssetDialog.js +5 -3
  58. package/dist/ui/DeleteFolderDialog.cjs +6 -4
  59. package/dist/ui/DeleteFolderDialog.d.cts.map +1 -1
  60. package/dist/ui/DeleteFolderDialog.d.ts.map +1 -1
  61. package/dist/ui/DeleteFolderDialog.js +6 -4
  62. package/dist/ui/EmptyFolderState.cjs +6 -3
  63. package/dist/ui/EmptyFolderState.d.cts +1 -1
  64. package/dist/ui/EmptyFolderState.d.cts.map +1 -1
  65. package/dist/ui/EmptyFolderState.d.ts +1 -1
  66. package/dist/ui/EmptyFolderState.d.ts.map +1 -1
  67. package/dist/ui/EmptyFolderState.js +6 -3
  68. package/dist/ui/FolderBreadcrumb.cjs +7 -4
  69. package/dist/ui/FolderBreadcrumb.d.cts.map +1 -1
  70. package/dist/ui/FolderBreadcrumb.d.ts.map +1 -1
  71. package/dist/ui/FolderBreadcrumb.js +7 -4
  72. package/dist/ui/FolderNameDialog.cjs +19 -12
  73. package/dist/ui/FolderNameDialog.d.cts.map +1 -1
  74. package/dist/ui/FolderNameDialog.d.ts.map +1 -1
  75. package/dist/ui/FolderNameDialog.js +19 -12
  76. package/dist/ui/FolderTree.cjs +4 -2
  77. package/dist/ui/FolderTree.d.cts.map +1 -1
  78. package/dist/ui/FolderTree.d.ts.map +1 -1
  79. package/dist/ui/FolderTree.js +4 -2
  80. package/dist/ui/MetadataPanel.cjs +16 -13
  81. package/dist/ui/MetadataPanel.d.cts.map +1 -1
  82. package/dist/ui/MetadataPanel.d.ts.map +1 -1
  83. package/dist/ui/MetadataPanel.js +16 -13
  84. package/dist/ui/MoveTargetPicker.cjs +7 -4
  85. package/dist/ui/MoveTargetPicker.d.cts.map +1 -1
  86. package/dist/ui/MoveTargetPicker.d.ts.map +1 -1
  87. package/dist/ui/MoveTargetPicker.js +7 -4
  88. package/dist/ui/ReplaceAssetDialog.cjs +19 -17
  89. package/dist/ui/ReplaceAssetDialog.d.cts.map +1 -1
  90. package/dist/ui/ReplaceAssetDialog.d.ts.map +1 -1
  91. package/dist/ui/ReplaceAssetDialog.js +19 -17
  92. package/dist/ui/UnsplashPanel.cjs +15 -12
  93. package/dist/ui/UnsplashPanel.d.cts.map +1 -1
  94. package/dist/ui/UnsplashPanel.d.ts.map +1 -1
  95. package/dist/ui/UnsplashPanel.js +15 -12
  96. package/dist/ui/UploadButton.cjs +11 -8
  97. package/dist/ui/UploadButton.d.cts.map +1 -1
  98. package/dist/ui/UploadButton.d.ts.map +1 -1
  99. package/dist/ui/UploadButton.js +11 -8
  100. package/dist/ui/index.cjs +4 -0
  101. package/dist/ui/index.d.cts +1 -0
  102. package/dist/ui/index.d.cts.map +1 -1
  103. package/dist/ui/index.d.ts +1 -0
  104. package/dist/ui/index.d.ts.map +1 -1
  105. package/dist/ui/index.js +1 -0
  106. package/dist/utils/data-source.cjs +18 -5
  107. package/dist/utils/data-source.d.cts.map +1 -1
  108. package/dist/utils/data-source.d.ts.map +1 -1
  109. package/dist/utils/data-source.js +19 -6
  110. package/dist/utils/folders.cjs +107 -33
  111. package/dist/utils/folders.d.cts +7 -2
  112. package/dist/utils/folders.d.cts.map +1 -1
  113. package/dist/utils/folders.d.ts +7 -2
  114. package/dist/utils/folders.d.ts.map +1 -1
  115. package/dist/utils/folders.js +107 -33
  116. package/dist/utils/header-action.cjs +1 -1
  117. package/dist/utils/header-action.d.cts.map +1 -1
  118. package/dist/utils/header-action.d.ts.map +1 -1
  119. package/dist/utils/header-action.js +1 -1
  120. package/dist/utils/registry.cjs +23 -12
  121. package/dist/utils/registry.d.cts +16 -8
  122. package/dist/utils/registry.d.cts.map +1 -1
  123. package/dist/utils/registry.d.ts +16 -8
  124. package/dist/utils/registry.d.ts.map +1 -1
  125. package/dist/utils/registry.js +19 -8
  126. package/dist/utils/resolver.cjs +5 -4
  127. package/dist/utils/resolver.d.cts.map +1 -1
  128. package/dist/utils/resolver.d.ts.map +1 -1
  129. package/dist/utils/resolver.js +5 -4
  130. package/dist/utils/studio-asset-source.cjs +8 -2
  131. package/dist/utils/studio-asset-source.js +8 -2
  132. package/dist/version.cjs +1 -1
  133. package/dist/version.d.cts +1 -1
  134. package/dist/version.d.ts +1 -1
  135. package/dist/version.js +1 -1
  136. package/i18n/messages/en.json +99 -0
  137. package/i18n/messages/ja.json +99 -0
  138. package/i18n/messages/ko.json +99 -0
  139. package/i18n/messages/zh.json +99 -0
  140. package/meta/config.json +1 -1
  141. package/package.json +9 -8
@@ -1,4 +1,5 @@
1
1
  "use client";
2
+ import { useMsg } from "@anvilkit/core/i18n";
2
3
  import { Button } from "@anvilkit/ui/button";
3
4
  import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@anvilkit/ui/card";
4
5
  import { Input } from "@anvilkit/ui/input";
@@ -17,11 +18,121 @@ const DEFAULT_VIRTUALIZE_THRESHOLD = 50;
17
18
  const DEFAULT_ITEM_HEIGHT = 56;
18
19
  const DEFAULT_MAX_HEIGHT = 400;
19
20
  const DEFAULT_PAGE_SIZE = 100;
21
+ function AssetFilterRow({ query, onQueryChange, activeKinds, onToggleKind }) {
22
+ const msg = useMsg();
23
+ return /*#__PURE__*/ __rspack_external_react.createElement("div", {
24
+ "data-asset-manager-filters": true
25
+ }, /*#__PURE__*/ __rspack_external_react.createElement(Input, {
26
+ "aria-label": msg("assetManager.browser.searchLabel"),
27
+ onChange: (event)=>{
28
+ onQueryChange(event.target.value);
29
+ },
30
+ placeholder: msg("assetManager.browser.searchPlaceholder"),
31
+ value: query
32
+ }), /*#__PURE__*/ __rspack_external_react.createElement("div", {
33
+ "aria-label": msg("assetManager.browser.filterLabel"),
34
+ role: "group"
35
+ }, KIND_FILTERS.map((kind)=>{
36
+ const active = activeKinds.includes(kind);
37
+ return /*#__PURE__*/ __rspack_external_react.createElement(Button, {
38
+ "aria-label": msg("assetManager.browser.filterByKind").replace("{kind}", kind),
39
+ "aria-pressed": active,
40
+ "data-asset-kind-filter": kind,
41
+ key: kind,
42
+ onClick: ()=>{
43
+ onToggleKind(kind);
44
+ },
45
+ type: "button",
46
+ variant: active ? "secondary" : "ghost",
47
+ size: "sm"
48
+ }, msg(`assetManager.kind.${kind}`));
49
+ })));
50
+ }
51
+ const AssetBrowser_AssetRow = /*#__PURE__*/ __rspack_external_react.memo(function({ asset, index, isActive, total, draggableRows, onInsert, onEdit, onReplace, onDelete, onFocusRow, onMoveFocus, registerRow }) {
52
+ const msg = useMsg();
53
+ return /*#__PURE__*/ __rspack_external_react.createElement(__rspack_external_react.Fragment, null, /*#__PURE__*/ __rspack_external_react.createElement("button", {
54
+ "aria-label": msg("assetManager.browser.insert").replace("{id}", asset.id),
55
+ draggable: draggableRows,
56
+ "data-asset-draggable": draggableRows ? "" : void 0,
57
+ onDragStart: draggableRows ? (event)=>{
58
+ event.dataTransfer.setData(ASSET_DRAG_MIME, JSON.stringify([
59
+ asset.id
60
+ ]));
61
+ event.dataTransfer.effectAllowed = "move";
62
+ } : void 0,
63
+ onClick: ()=>{
64
+ onInsert(asset);
65
+ },
66
+ onFocus: ()=>{
67
+ onFocusRow(index);
68
+ },
69
+ onKeyDown: (event)=>{
70
+ if ("ArrowDown" === event.key) {
71
+ event.preventDefault();
72
+ onMoveFocus(index + 1);
73
+ return;
74
+ }
75
+ if ("ArrowUp" === event.key) {
76
+ event.preventDefault();
77
+ onMoveFocus(index - 1);
78
+ return;
79
+ }
80
+ if ("Home" === event.key) {
81
+ event.preventDefault();
82
+ onMoveFocus(0);
83
+ return;
84
+ }
85
+ if ("End" === event.key) {
86
+ event.preventDefault();
87
+ onMoveFocus(total - 1);
88
+ return;
89
+ }
90
+ if ("Enter" === event.key || " " === event.key) {
91
+ event.preventDefault();
92
+ onInsert(asset);
93
+ }
94
+ },
95
+ ref: (node)=>{
96
+ registerRow(index, node);
97
+ },
98
+ tabIndex: isActive ? 0 : -1,
99
+ type: "button"
100
+ }, /*#__PURE__*/ __rspack_external_react.createElement("span", null, asset.id), /*#__PURE__*/ __rspack_external_react.createElement("span", null, asset.meta?.mimeType ?? msg("assetManager.browser.unknownMime"))), void 0 !== onEdit ? /*#__PURE__*/ __rspack_external_react.createElement(Button, {
101
+ "aria-label": msg("assetManager.browser.edit").replace("{id}", asset.id),
102
+ "data-asset-action": "edit",
103
+ onClick: ()=>{
104
+ onEdit(asset);
105
+ },
106
+ type: "button",
107
+ variant: "ghost",
108
+ size: "sm"
109
+ }, msg("assetManager.button.edit")) : null, void 0 !== onReplace ? /*#__PURE__*/ __rspack_external_react.createElement(Button, {
110
+ "aria-label": msg("assetManager.browser.replace").replace("{id}", asset.id),
111
+ "data-asset-action": "replace",
112
+ onClick: ()=>{
113
+ onReplace(asset);
114
+ },
115
+ type: "button",
116
+ variant: "ghost",
117
+ size: "sm"
118
+ }, msg("assetManager.button.replace")) : null, void 0 !== onDelete ? /*#__PURE__*/ __rspack_external_react.createElement(Button, {
119
+ "aria-label": msg("assetManager.browser.delete").replace("{id}", asset.id),
120
+ "data-asset-action": "delete",
121
+ onClick: ()=>{
122
+ onDelete(asset);
123
+ },
124
+ type: "button",
125
+ variant: "ghost",
126
+ size: "sm"
127
+ }, msg("assetManager.button.delete")) : null);
128
+ });
20
129
  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 }) {
130
+ const msg = useMsg();
21
131
  const [activeIndex, setActiveIndex] = __rspack_external_react.useState(assets.length > 0 ? 0 : -1);
22
132
  const [query, setQuery] = __rspack_external_react.useState("");
23
133
  const [activeKinds, setActiveKinds] = __rspack_external_react.useState([]);
24
- const [pageLimit, setPageLimit] = __rspack_external_react.useState(pageSize);
134
+ const [extraPages, setExtraPages] = __rspack_external_react.useState(0);
135
+ const pageLimit = pageSize * (extraPages + 1);
25
136
  const buttonRefs = __rspack_external_react.useRef([]);
26
137
  const pendingFocusRef = __rspack_external_react.useRef(null);
27
138
  const searchIndex = __rspack_external_react.useMemo(()=>{
@@ -45,8 +156,9 @@ function AssetBrowser({ assets, onInsert, onDelete, onReplace, onEdit, searchEna
45
156
  const lower = query.trim().toLowerCase();
46
157
  const hasKindFilter = activeKinds.length > 0;
47
158
  if ("" === lower && !hasKindFilter) return assets;
159
+ const activeKindSet = hasKindFilter ? new Set(activeKinds) : null;
48
160
  const result = [];
49
- for (const entry of searchIndex)if (!hasKindFilter || activeKinds.includes(entry.kind)) {
161
+ for (const entry of searchIndex)if (!activeKindSet || activeKindSet.has(entry.kind)) {
50
162
  if ("" === lower || entry.haystack.includes(lower)) result.push(entry.asset);
51
163
  }
52
164
  return result;
@@ -64,154 +176,83 @@ function AssetBrowser({ assets, onInsert, onDelete, onReplace, onEdit, searchEna
64
176
  ]);
65
177
  const total = visibleSlice.length;
66
178
  const hasMore = searchEnabled && filteredAssets.length > visibleSlice.length;
67
- __rspack_external_react.useEffect(()=>{
68
- if (0 === total) return void setActiveIndex(-1);
69
- setActiveIndex((currentIndex)=>currentIndex >= 0 && currentIndex < total ? currentIndex : 0);
70
- }, [
71
- total
72
- ]);
73
- function focusRow(index) {
179
+ const effectiveActiveIndex = 0 === total ? -1 : activeIndex >= 0 && activeIndex < total ? activeIndex : 0;
180
+ const focusRow = __rspack_external_react.useCallback((index)=>{
74
181
  const node = buttonRefs.current[index];
75
182
  if (node) {
76
183
  node.focus();
77
184
  return true;
78
185
  }
79
186
  return false;
80
- }
81
- function moveFocus(nextIndex) {
187
+ }, []);
188
+ const moveFocus = __rspack_external_react.useCallback((nextIndex)=>{
82
189
  if (0 === total) return;
83
190
  const clampedIndex = Math.max(0, Math.min(nextIndex, total - 1));
84
191
  pendingFocusRef.current = clampedIndex;
85
192
  setActiveIndex(clampedIndex);
86
193
  if (focusRow(clampedIndex)) pendingFocusRef.current = null;
87
- }
88
- function toggleKind(kind) {
194
+ }, [
195
+ total,
196
+ focusRow
197
+ ]);
198
+ const registerRow = __rspack_external_react.useCallback((index, node)=>{
199
+ buttonRefs.current[index] = node;
200
+ if (node && pendingFocusRef.current === index) {
201
+ pendingFocusRef.current = null;
202
+ node.focus();
203
+ }
204
+ }, []);
205
+ const changeQuery = __rspack_external_react.useCallback((value)=>{
206
+ setQuery(value);
207
+ setExtraPages(0);
208
+ }, []);
209
+ const toggleKind = __rspack_external_react.useCallback((kind)=>{
89
210
  setActiveKinds((current)=>current.includes(kind) ? current.filter((entry)=>entry !== kind) : [
90
211
  ...current,
91
212
  kind
92
213
  ]);
93
- }
94
- const renderRow = (asset, index)=>/*#__PURE__*/ __rspack_external_react.createElement(__rspack_external_react.Fragment, null, /*#__PURE__*/ __rspack_external_react.createElement("button", {
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,
104
- onClick: ()=>{
105
- onInsert(asset);
106
- },
107
- onFocus: ()=>{
108
- setActiveIndex(index);
109
- },
110
- onKeyDown: (event)=>{
111
- if ("ArrowDown" === event.key) {
112
- event.preventDefault();
113
- moveFocus(index + 1);
114
- return;
115
- }
116
- if ("ArrowUp" === event.key) {
117
- event.preventDefault();
118
- moveFocus(index - 1);
119
- return;
120
- }
121
- if ("Home" === event.key) {
122
- event.preventDefault();
123
- moveFocus(0);
124
- return;
125
- }
126
- if ("End" === event.key) {
127
- event.preventDefault();
128
- moveFocus(total - 1);
129
- return;
130
- }
131
- if ("Enter" === event.key || " " === event.key) {
132
- event.preventDefault();
133
- onInsert(asset);
134
- }
135
- },
136
- ref: (node)=>{
137
- buttonRefs.current[index] = node;
138
- if (node && pendingFocusRef.current === index) {
139
- pendingFocusRef.current = null;
140
- node.focus();
141
- }
142
- },
143
- tabIndex: activeIndex === index ? 0 : -1,
144
- type: "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, {
146
- "aria-label": `Edit asset ${asset.id}`,
147
- "data-asset-action": "edit",
148
- onClick: ()=>{
149
- onEdit(asset);
150
- },
151
- type: "button",
152
- variant: "ghost",
153
- size: "sm"
154
- }, "Edit") : null, void 0 !== onReplace ? /*#__PURE__*/ __rspack_external_react.createElement(Button, {
155
- "aria-label": `Replace asset ${asset.id}`,
156
- "data-asset-action": "replace",
157
- onClick: ()=>{
158
- onReplace(asset);
159
- },
160
- type: "button",
161
- variant: "ghost",
162
- size: "sm"
163
- }, "Replace") : null, void 0 !== onDelete ? /*#__PURE__*/ __rspack_external_react.createElement(Button, {
164
- "aria-label": `Delete asset ${asset.id}`,
165
- "data-asset-action": "delete",
166
- onClick: ()=>{
167
- onDelete(asset);
168
- },
169
- type: "button",
170
- variant: "ghost",
171
- size: "sm"
172
- }, "Delete") : null);
173
- const searchRow = searchEnabled ? /*#__PURE__*/ __rspack_external_react.createElement("div", {
174
- "data-asset-manager-filters": true
175
- }, /*#__PURE__*/ __rspack_external_react.createElement(Input, {
176
- "aria-label": "Search assets",
177
- onChange: (event)=>{
178
- setQuery(event.target.value);
179
- setPageLimit(pageSize);
180
- },
181
- placeholder: "Search by name, tag, or MIME",
182
- value: query
183
- }), /*#__PURE__*/ __rspack_external_react.createElement("div", {
184
- "aria-label": "Asset kind filters",
185
- role: "group"
186
- }, KIND_FILTERS.map((kind)=>{
187
- const active = activeKinds.includes(kind);
188
- return /*#__PURE__*/ __rspack_external_react.createElement(Button, {
189
- "aria-label": `Filter ${kind} assets`,
190
- "aria-pressed": active,
191
- "data-asset-kind-filter": kind,
192
- key: kind,
193
- onClick: ()=>{
194
- toggleKind(kind);
195
- setPageLimit(pageSize);
196
- },
197
- type: "button",
198
- variant: active ? "secondary" : "ghost",
199
- size: "sm"
200
- }, kind);
201
- }))) : null;
214
+ setExtraPages(0);
215
+ }, []);
216
+ const renderRow = __rspack_external_react.useCallback((asset, index)=>/*#__PURE__*/ __rspack_external_react.createElement(AssetBrowser_AssetRow, {
217
+ asset: asset,
218
+ draggableRows: draggableRows,
219
+ index: index,
220
+ isActive: effectiveActiveIndex === index,
221
+ onDelete: onDelete,
222
+ onEdit: onEdit,
223
+ onFocusRow: setActiveIndex,
224
+ onInsert: onInsert,
225
+ onMoveFocus: moveFocus,
226
+ onReplace: onReplace,
227
+ registerRow: registerRow,
228
+ total: total
229
+ }), [
230
+ draggableRows,
231
+ effectiveActiveIndex,
232
+ moveFocus,
233
+ onDelete,
234
+ onEdit,
235
+ onInsert,
236
+ onReplace,
237
+ registerRow,
238
+ total
239
+ ]);
240
+ const searchRow = searchEnabled ? /*#__PURE__*/ __rspack_external_react.createElement(AssetFilterRow, {
241
+ activeKinds: activeKinds,
242
+ onQueryChange: changeQuery,
243
+ onToggleKind: toggleKind,
244
+ query: query
245
+ }) : null;
202
246
  const filterRow = /*#__PURE__*/ __rspack_external_react.createElement(__rspack_external_react.Fragment, null, aboveFilters, searchRow);
203
247
  if (0 === total) {
204
- const emptyLabel = searchEnabled && ("" !== query || activeKinds.length > 0) ? "No assets match the current filters." : "No assets uploaded yet.";
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", {
206
- "aria-label": "Assets",
207
- role: "list"
208
- }, /*#__PURE__*/ __rspack_external_react.createElement("li", {
209
- role: "listitem"
210
- }, emptyLabel))));
248
+ const emptyLabel = searchEnabled && ("" !== query || activeKinds.length > 0) ? msg("assetManager.browser.emptyFiltered") : msg("assetManager.browser.empty");
249
+ return /*#__PURE__*/ __rspack_external_react.createElement(Card, null, /*#__PURE__*/ __rspack_external_react.createElement(CardHeader, null, /*#__PURE__*/ __rspack_external_react.createElement(CardTitle, null, msg("assetManager.browser.title")), /*#__PURE__*/ __rspack_external_react.createElement(CardDescription, null, msg("assetManager.browser.subtitle"))), /*#__PURE__*/ __rspack_external_react.createElement(CardContent, null, filterRow, /*#__PURE__*/ __rspack_external_react.createElement("ul", {
250
+ "aria-label": msg("assetManager.browser.assetsLabel")
251
+ }, /*#__PURE__*/ __rspack_external_react.createElement("li", null, emptyLabel))));
211
252
  }
212
- 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(Windowed, {
213
- activeIndex: activeIndex >= 0 ? activeIndex : void 0,
214
- "aria-label": "Assets",
253
+ return /*#__PURE__*/ __rspack_external_react.createElement(Card, null, /*#__PURE__*/ __rspack_external_react.createElement(CardHeader, null, /*#__PURE__*/ __rspack_external_react.createElement(CardTitle, null, msg("assetManager.browser.title")), /*#__PURE__*/ __rspack_external_react.createElement(CardDescription, null, msg("assetManager.browser.subtitle"))), /*#__PURE__*/ __rspack_external_react.createElement(CardContent, null, filterRow, /*#__PURE__*/ __rspack_external_react.createElement(Windowed, {
254
+ activeIndex: effectiveActiveIndex >= 0 ? effectiveActiveIndex : void 0,
255
+ "aria-label": msg("assetManager.browser.assetsLabel"),
215
256
  as: "ul",
216
257
  "data-testid": "asset-browser-virtualized",
217
258
  estimateSize: itemHeight,
@@ -223,11 +264,11 @@ function AssetBrowser({ assets, onInsert, onDelete, onReplace, onEdit, searchEna
223
264
  }), hasMore ? /*#__PURE__*/ __rspack_external_react.createElement(Button, {
224
265
  "data-asset-action": "load-more",
225
266
  onClick: ()=>{
226
- setPageLimit((current)=>current + pageSize);
267
+ setExtraPages((current)=>current + 1);
227
268
  },
228
269
  type: "button",
229
270
  variant: "outline",
230
271
  size: "sm"
231
- }, "Load more") : null));
272
+ }, msg("assetManager.button.loadMore")) : null));
232
273
  }
233
274
  export { AssetBrowser };
@@ -31,12 +31,14 @@ __webpack_require__.r(__webpack_exports__);
31
31
  __webpack_require__.d(__webpack_exports__, {
32
32
  AssetCommandPalette: ()=>AssetCommandPalette
33
33
  });
34
+ const i18n_namespaceObject = require("@anvilkit/core/i18n");
34
35
  const dialog_namespaceObject = require("@anvilkit/ui/dialog");
35
36
  const input_namespaceObject = require("@anvilkit/ui/input");
36
37
  const external_react_namespaceObject = require("react");
37
38
  const infer_kind_cjs_namespaceObject = require("../utils/infer-kind.cjs");
38
39
  const DEFAULT_MAX_RESULTS = 20;
39
40
  function AssetCommandPalette({ registry, open, onOpenChange, onSelect, maxResults = DEFAULT_MAX_RESULTS }) {
41
+ const msg = (0, i18n_namespaceObject.useMsg)();
40
42
  const [query, setQuery] = external_react_namespaceObject.useState("");
41
43
  const [results, setResults] = external_react_namespaceObject.useState([]);
42
44
  const [activeIndex, setActiveIndex] = external_react_namespaceObject.useState(0);
@@ -53,17 +55,21 @@ function AssetCommandPalette({ registry, open, onOpenChange, onSelect, maxResult
53
55
  registry,
54
56
  maxResults
55
57
  ]);
56
- const queryRef = external_react_namespaceObject.useRef(query);
57
- queryRef.current = query;
58
+ const onRegistryChange = external_react_namespaceObject.useEffectEvent(()=>{
59
+ refresh(query);
60
+ });
58
61
  external_react_namespaceObject.useEffect(()=>{
59
62
  if (!open) return;
60
- setQuery("");
61
63
  queueMicrotask(()=>{
62
64
  inputRef.current?.focus();
63
65
  });
64
66
  }, [
65
67
  open
66
68
  ]);
69
+ function emitOpenChange(nextOpen) {
70
+ if (!nextOpen) setQuery("");
71
+ onOpenChange(nextOpen);
72
+ }
67
73
  external_react_namespaceObject.useEffect(()=>{
68
74
  if (!open) return;
69
75
  refresh(query);
@@ -74,14 +80,10 @@ function AssetCommandPalette({ registry, open, onOpenChange, onSelect, maxResult
74
80
  ]);
75
81
  external_react_namespaceObject.useEffect(()=>{
76
82
  if (!open) return;
77
- const unsubscribe = registry.subscribe(()=>{
78
- refresh(queryRef.current);
79
- });
80
- return unsubscribe;
83
+ return registry.subscribe(onRegistryChange);
81
84
  }, [
82
85
  open,
83
- registry,
84
- refresh
86
+ registry
85
87
  ]);
86
88
  function handleKeyDown(event) {
87
89
  if ("ArrowDown" === event.key) {
@@ -99,39 +101,39 @@ function AssetCommandPalette({ registry, open, onOpenChange, onSelect, maxResult
99
101
  const picked = results[activeIndex];
100
102
  if (void 0 !== picked) {
101
103
  onSelect(picked);
102
- onOpenChange(false);
104
+ emitOpenChange(false);
103
105
  }
104
106
  }
105
107
  }
106
108
  return /*#__PURE__*/ external_react_namespaceObject.createElement(dialog_namespaceObject.Dialog, {
107
109
  open: open,
108
- onOpenChange: onOpenChange
109
- }, /*#__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, "Find an asset"), /*#__PURE__*/ external_react_namespaceObject.createElement(dialog_namespaceObject.DialogDescription, null, "Search by name, id, MIME type, or tag.")), /*#__PURE__*/ external_react_namespaceObject.createElement(input_namespaceObject.Input, {
110
- "aria-label": "Asset search query",
110
+ onOpenChange: emitOpenChange
111
+ }, /*#__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.palette.title")), /*#__PURE__*/ external_react_namespaceObject.createElement(dialog_namespaceObject.DialogDescription, null, msg("assetManager.palette.subtitle"))), /*#__PURE__*/ external_react_namespaceObject.createElement(input_namespaceObject.Input, {
112
+ "aria-label": msg("assetManager.palette.searchLabel"),
111
113
  onChange: (event)=>{
112
114
  setQuery(event.target.value);
113
115
  },
114
116
  onKeyDown: handleKeyDown,
115
- placeholder: "Type to search…",
117
+ placeholder: msg("assetManager.palette.searchPlaceholder"),
116
118
  ref: inputRef,
117
119
  value: query
118
120
  }), /*#__PURE__*/ external_react_namespaceObject.createElement("ul", {
119
- "aria-label": "Asset results",
121
+ "aria-label": msg("assetManager.palette.resultsLabel"),
120
122
  "data-asset-manager-palette-results": true,
121
123
  ref: listRef,
122
124
  role: "listbox"
123
125
  }, 0 === results.length ? /*#__PURE__*/ external_react_namespaceObject.createElement("li", {
124
126
  role: "presentation"
125
- }, "No matches.") : results.map((asset, index)=>/*#__PURE__*/ external_react_namespaceObject.createElement("li", {
127
+ }, msg("assetManager.palette.noMatches")) : results.map((asset, index)=>/*#__PURE__*/ external_react_namespaceObject.createElement("li", {
126
128
  "aria-selected": index === activeIndex,
127
129
  key: asset.id,
128
130
  role: "option"
129
131
  }, /*#__PURE__*/ external_react_namespaceObject.createElement("button", {
130
- "aria-label": `Insert asset ${asset.id}`,
132
+ "aria-label": msg("assetManager.browser.insert").replace("{id}", asset.id),
131
133
  "data-active": index === activeIndex ? "true" : void 0,
132
134
  onClick: ()=>{
133
135
  onSelect(asset);
134
- onOpenChange(false);
136
+ emitOpenChange(false);
135
137
  },
136
138
  onMouseEnter: ()=>{
137
139
  setActiveIndex(index);
@@ -1 +1 @@
1
- {"version":3,"file":"AssetCommandPalette.d.cts","sourceRoot":"","sources":["../../src/ui/AssetCommandPalette.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGrE,MAAM,WAAW,wBAAwB;IACxC,6CAA6C;IAC7C,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,mEAAmE;IACnE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,6EAA6E;IAC7E,QAAQ,CAAC,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/C;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IACjD;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC7B;AAID,wBAAgB,mBAAmB,CAAC,EACnC,QAAQ,EACR,IAAI,EACJ,YAAY,EACZ,QAAQ,EACR,UAAgC,GAChC,EAAE,wBAAwB,2CAiI1B"}
1
+ {"version":3,"file":"AssetCommandPalette.d.cts","sourceRoot":"","sources":["../../src/ui/AssetCommandPalette.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGrE,MAAM,WAAW,wBAAwB;IACxC,6CAA6C;IAC7C,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,mEAAmE;IACnE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,6EAA6E;IAC7E,QAAQ,CAAC,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/C;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IACjD;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC7B;AAID,wBAAgB,mBAAmB,CAAC,EACnC,QAAQ,EACR,IAAI,EACJ,YAAY,EACZ,QAAQ,EACR,UAAgC,GAChC,EAAE,wBAAwB,2CA6I1B"}
@@ -1 +1 @@
1
- {"version":3,"file":"AssetCommandPalette.d.ts","sourceRoot":"","sources":["../../src/ui/AssetCommandPalette.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGrE,MAAM,WAAW,wBAAwB;IACxC,6CAA6C;IAC7C,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,mEAAmE;IACnE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,6EAA6E;IAC7E,QAAQ,CAAC,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/C;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IACjD;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC7B;AAID,wBAAgB,mBAAmB,CAAC,EACnC,QAAQ,EACR,IAAI,EACJ,YAAY,EACZ,QAAQ,EACR,UAAgC,GAChC,EAAE,wBAAwB,2CAiI1B"}
1
+ {"version":3,"file":"AssetCommandPalette.d.ts","sourceRoot":"","sources":["../../src/ui/AssetCommandPalette.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGrE,MAAM,WAAW,wBAAwB;IACxC,6CAA6C;IAC7C,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,mEAAmE;IACnE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,6EAA6E;IAC7E,QAAQ,CAAC,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/C;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IACjD;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC7B;AAID,wBAAgB,mBAAmB,CAAC,EACnC,QAAQ,EACR,IAAI,EACJ,YAAY,EACZ,QAAQ,EACR,UAAgC,GAChC,EAAE,wBAAwB,2CA6I1B"}
@@ -1,10 +1,12 @@
1
1
  "use client";
2
+ import { useMsg } from "@anvilkit/core/i18n";
2
3
  import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "@anvilkit/ui/dialog";
3
4
  import { Input } from "@anvilkit/ui/input";
4
5
  import { inferAssetKind } from "../utils/infer-kind.js";
5
6
  import * as __rspack_external_react from "react";
6
7
  const DEFAULT_MAX_RESULTS = 20;
7
8
  function AssetCommandPalette({ registry, open, onOpenChange, onSelect, maxResults = DEFAULT_MAX_RESULTS }) {
9
+ const msg = useMsg();
8
10
  const [query, setQuery] = __rspack_external_react.useState("");
9
11
  const [results, setResults] = __rspack_external_react.useState([]);
10
12
  const [activeIndex, setActiveIndex] = __rspack_external_react.useState(0);
@@ -21,17 +23,21 @@ function AssetCommandPalette({ registry, open, onOpenChange, onSelect, maxResult
21
23
  registry,
22
24
  maxResults
23
25
  ]);
24
- const queryRef = __rspack_external_react.useRef(query);
25
- queryRef.current = query;
26
+ const onRegistryChange = __rspack_external_react.useEffectEvent(()=>{
27
+ refresh(query);
28
+ });
26
29
  __rspack_external_react.useEffect(()=>{
27
30
  if (!open) return;
28
- setQuery("");
29
31
  queueMicrotask(()=>{
30
32
  inputRef.current?.focus();
31
33
  });
32
34
  }, [
33
35
  open
34
36
  ]);
37
+ function emitOpenChange(nextOpen) {
38
+ if (!nextOpen) setQuery("");
39
+ onOpenChange(nextOpen);
40
+ }
35
41
  __rspack_external_react.useEffect(()=>{
36
42
  if (!open) return;
37
43
  refresh(query);
@@ -42,14 +48,10 @@ function AssetCommandPalette({ registry, open, onOpenChange, onSelect, maxResult
42
48
  ]);
43
49
  __rspack_external_react.useEffect(()=>{
44
50
  if (!open) return;
45
- const unsubscribe = registry.subscribe(()=>{
46
- refresh(queryRef.current);
47
- });
48
- return unsubscribe;
51
+ return registry.subscribe(onRegistryChange);
49
52
  }, [
50
53
  open,
51
- registry,
52
- refresh
54
+ registry
53
55
  ]);
54
56
  function handleKeyDown(event) {
55
57
  if ("ArrowDown" === event.key) {
@@ -67,39 +69,39 @@ function AssetCommandPalette({ registry, open, onOpenChange, onSelect, maxResult
67
69
  const picked = results[activeIndex];
68
70
  if (void 0 !== picked) {
69
71
  onSelect(picked);
70
- onOpenChange(false);
72
+ emitOpenChange(false);
71
73
  }
72
74
  }
73
75
  }
74
76
  return /*#__PURE__*/ __rspack_external_react.createElement(Dialog, {
75
77
  open: open,
76
- onOpenChange: onOpenChange
77
- }, /*#__PURE__*/ __rspack_external_react.createElement(DialogContent, null, /*#__PURE__*/ __rspack_external_react.createElement(DialogHeader, null, /*#__PURE__*/ __rspack_external_react.createElement(DialogTitle, null, "Find an asset"), /*#__PURE__*/ __rspack_external_react.createElement(DialogDescription, null, "Search by name, id, MIME type, or tag.")), /*#__PURE__*/ __rspack_external_react.createElement(Input, {
78
- "aria-label": "Asset search query",
78
+ onOpenChange: emitOpenChange
79
+ }, /*#__PURE__*/ __rspack_external_react.createElement(DialogContent, null, /*#__PURE__*/ __rspack_external_react.createElement(DialogHeader, null, /*#__PURE__*/ __rspack_external_react.createElement(DialogTitle, null, msg("assetManager.palette.title")), /*#__PURE__*/ __rspack_external_react.createElement(DialogDescription, null, msg("assetManager.palette.subtitle"))), /*#__PURE__*/ __rspack_external_react.createElement(Input, {
80
+ "aria-label": msg("assetManager.palette.searchLabel"),
79
81
  onChange: (event)=>{
80
82
  setQuery(event.target.value);
81
83
  },
82
84
  onKeyDown: handleKeyDown,
83
- placeholder: "Type to search…",
85
+ placeholder: msg("assetManager.palette.searchPlaceholder"),
84
86
  ref: inputRef,
85
87
  value: query
86
88
  }), /*#__PURE__*/ __rspack_external_react.createElement("ul", {
87
- "aria-label": "Asset results",
89
+ "aria-label": msg("assetManager.palette.resultsLabel"),
88
90
  "data-asset-manager-palette-results": true,
89
91
  ref: listRef,
90
92
  role: "listbox"
91
93
  }, 0 === results.length ? /*#__PURE__*/ __rspack_external_react.createElement("li", {
92
94
  role: "presentation"
93
- }, "No matches.") : results.map((asset, index)=>/*#__PURE__*/ __rspack_external_react.createElement("li", {
95
+ }, msg("assetManager.palette.noMatches")) : results.map((asset, index)=>/*#__PURE__*/ __rspack_external_react.createElement("li", {
94
96
  "aria-selected": index === activeIndex,
95
97
  key: asset.id,
96
98
  role: "option"
97
99
  }, /*#__PURE__*/ __rspack_external_react.createElement("button", {
98
- "aria-label": `Insert asset ${asset.id}`,
100
+ "aria-label": msg("assetManager.browser.insert").replace("{id}", asset.id),
99
101
  "data-active": index === activeIndex ? "true" : void 0,
100
102
  onClick: ()=>{
101
103
  onSelect(asset);
102
- onOpenChange(false);
104
+ emitOpenChange(false);
103
105
  },
104
106
  onMouseEnter: ()=>{
105
107
  setActiveIndex(index);