@unofficialbox/box-open-elements 0.5.0 → 0.6.0

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 (219) hide show
  1. package/README.md +3 -3
  2. package/dist/components/collections/table.d.ts +57 -3
  3. package/dist/components/collections/table.js +339 -20
  4. package/dist/components/feedback/due-badge.d.ts +38 -0
  5. package/dist/components/feedback/due-badge.js +168 -0
  6. package/dist/components/feedback/due-types.d.ts +32 -0
  7. package/dist/components/feedback/due-types.js +91 -0
  8. package/dist/components/feedback/progress-steps.d.ts +51 -5
  9. package/dist/components/feedback/progress-steps.js +200 -22
  10. package/dist/components/feedback/stage-path.d.ts +44 -0
  11. package/dist/components/feedback/stage-path.js +235 -0
  12. package/dist/components/forms/select.d.ts +21 -0
  13. package/dist/components/forms/select.js +100 -3
  14. package/dist/components/forms/text-field.d.ts +21 -0
  15. package/dist/components/forms/text-field.js +100 -1
  16. package/dist/components/layout/nav-sidebar.d.ts +14 -0
  17. package/dist/components/layout/nav-sidebar.js +49 -0
  18. package/dist/components/layout/split-view.d.ts +14 -0
  19. package/dist/components/layout/split-view.js +80 -1
  20. package/dist/components/overlays/command-palette.d.ts +62 -0
  21. package/dist/components/overlays/command-palette.js +537 -0
  22. package/dist/components/overlays/command-types.d.ts +90 -0
  23. package/dist/components/overlays/command-types.js +259 -0
  24. package/dist/components/overlays/drawer.d.ts +18 -0
  25. package/dist/components/overlays/drawer.js +135 -9
  26. package/dist/components/overlays/shortcuts-overlay.d.ts +48 -0
  27. package/dist/components/overlays/shortcuts-overlay.js +385 -0
  28. package/dist/components/overlays/tooltip.js +1 -1
  29. package/dist/element-maps.d.ts +292 -0
  30. package/dist/element-maps.js +1 -0
  31. package/dist/entries/activity-density.d.ts +1 -0
  32. package/dist/entries/activity-density.js +1 -0
  33. package/dist/entries/agent-chat.d.ts +1 -0
  34. package/dist/entries/agent-chat.js +1 -0
  35. package/dist/entries/audit-log.d.ts +1 -0
  36. package/dist/entries/audit-log.js +1 -0
  37. package/dist/entries/command-palette.d.ts +1 -0
  38. package/dist/entries/command-palette.js +1 -0
  39. package/dist/entries/compare-view.d.ts +1 -0
  40. package/dist/entries/compare-view.js +1 -0
  41. package/dist/entries/diff-viewer.d.ts +1 -0
  42. package/dist/entries/diff-viewer.js +1 -0
  43. package/dist/entries/due-badge.d.ts +1 -0
  44. package/dist/entries/due-badge.js +1 -0
  45. package/dist/entries/form-wizard.d.ts +1 -0
  46. package/dist/entries/form-wizard.js +1 -0
  47. package/dist/entries/lineage-graph.d.ts +1 -0
  48. package/dist/entries/lineage-graph.js +1 -0
  49. package/dist/entries/notification-bell.d.ts +1 -0
  50. package/dist/entries/notification-bell.js +1 -0
  51. package/dist/entries/notification-inbox.d.ts +1 -0
  52. package/dist/entries/notification-inbox.js +1 -0
  53. package/dist/entries/provenance-strip.d.ts +1 -0
  54. package/dist/entries/provenance-strip.js +1 -0
  55. package/dist/entries/run-trace.d.ts +1 -0
  56. package/dist/entries/run-trace.js +1 -0
  57. package/dist/entries/shortcuts-overlay.d.ts +1 -0
  58. package/dist/entries/shortcuts-overlay.js +1 -0
  59. package/dist/entries/signature-ceremony.d.ts +1 -0
  60. package/dist/entries/signature-ceremony.js +1 -0
  61. package/dist/entries/stage-path.d.ts +1 -0
  62. package/dist/entries/stage-path.js +1 -0
  63. package/dist/entries/timeline.d.ts +1 -0
  64. package/dist/entries/timeline.js +1 -0
  65. package/dist/entries/version-graph.d.ts +1 -0
  66. package/dist/entries/version-graph.js +1 -0
  67. package/dist/entries/version-list.d.ts +1 -0
  68. package/dist/entries/version-list.js +1 -0
  69. package/dist/entries/wizard-summary.d.ts +1 -0
  70. package/dist/entries/wizard-summary.js +1 -0
  71. package/dist/entries/work-queue.d.ts +1 -0
  72. package/dist/entries/work-queue.js +1 -0
  73. package/dist/entries/workload-board.d.ts +1 -0
  74. package/dist/entries/workload-board.js +1 -0
  75. package/dist/index.d.ts +21 -0
  76. package/dist/index.js +21 -0
  77. package/dist/patterns/agent-chat/agent-chat.d.ts +75 -0
  78. package/dist/patterns/agent-chat/agent-chat.js +820 -0
  79. package/dist/patterns/agent-chat/controller.d.ts +27 -0
  80. package/dist/patterns/agent-chat/controller.js +182 -0
  81. package/dist/patterns/agent-chat/index.d.ts +3 -0
  82. package/dist/patterns/agent-chat/index.js +6 -0
  83. package/dist/patterns/agent-chat/types.d.ts +109 -0
  84. package/dist/patterns/agent-chat/types.js +1 -0
  85. package/dist/patterns/audit/activity-density.d.ts +68 -0
  86. package/dist/patterns/audit/activity-density.js +428 -0
  87. package/dist/patterns/audit/audit-log.d.ts +81 -0
  88. package/dist/patterns/audit/audit-log.js +794 -0
  89. package/dist/patterns/audit/index.d.ts +3 -0
  90. package/dist/patterns/audit/index.js +7 -0
  91. package/dist/patterns/audit/shared.d.ts +10 -0
  92. package/dist/patterns/audit/shared.js +50 -0
  93. package/dist/patterns/audit/types.d.ts +143 -0
  94. package/dist/patterns/audit/types.js +327 -0
  95. package/dist/patterns/content-explorer/actions/controller.js +12 -2
  96. package/dist/patterns/content-explorer/box-transport.js +117 -25
  97. package/dist/patterns/content-explorer/content-explorer.d.ts +13 -1
  98. package/dist/patterns/content-explorer/content-explorer.js +36 -3
  99. package/dist/patterns/content-explorer/contracts.d.ts +24 -1
  100. package/dist/patterns/content-explorer/contracts.js +68 -11
  101. package/dist/patterns/content-explorer/controller.d.ts +16 -1
  102. package/dist/patterns/content-explorer/controller.js +130 -4
  103. package/dist/patterns/content-explorer/navigation/controller.js +11 -9
  104. package/dist/patterns/content-explorer/types.d.ts +58 -1
  105. package/dist/patterns/content-picker/content-picker.d.ts +71 -0
  106. package/dist/patterns/content-picker/content-picker.js +747 -0
  107. package/dist/patterns/content-picker/controller.d.ts +38 -0
  108. package/dist/patterns/content-picker/controller.js +141 -0
  109. package/dist/patterns/content-picker/index.d.ts +3 -0
  110. package/dist/patterns/content-picker/index.js +6 -0
  111. package/dist/patterns/content-picker/types.d.ts +52 -0
  112. package/dist/patterns/content-picker/types.js +26 -0
  113. package/dist/patterns/content-sidebar/content-sidebar.d.ts +43 -0
  114. package/dist/patterns/content-sidebar/content-sidebar.js +293 -0
  115. package/dist/patterns/content-sidebar/index.d.ts +2 -0
  116. package/dist/patterns/content-sidebar/index.js +4 -0
  117. package/dist/patterns/content-sidebar/types.d.ts +18 -0
  118. package/dist/patterns/content-sidebar/types.js +20 -0
  119. package/dist/patterns/content-uploader/box-transport.d.ts +14 -0
  120. package/dist/patterns/content-uploader/box-transport.js +54 -0
  121. package/dist/patterns/content-uploader/content-uploader.d.ts +62 -0
  122. package/dist/patterns/content-uploader/content-uploader.js +559 -0
  123. package/dist/patterns/content-uploader/controller.d.ts +39 -0
  124. package/dist/patterns/content-uploader/controller.js +227 -0
  125. package/dist/patterns/content-uploader/index.d.ts +4 -0
  126. package/dist/patterns/content-uploader/index.js +8 -0
  127. package/dist/patterns/content-uploader/types.d.ts +120 -0
  128. package/dist/patterns/content-uploader/types.js +38 -0
  129. package/dist/patterns/diff/compare-view.d.ts +47 -0
  130. package/dist/patterns/diff/compare-view.js +276 -0
  131. package/dist/patterns/diff/diff-viewer.d.ts +42 -0
  132. package/dist/patterns/diff/diff-viewer.js +434 -0
  133. package/dist/patterns/diff/engine.d.ts +22 -0
  134. package/dist/patterns/diff/engine.js +276 -0
  135. package/dist/patterns/diff/index.d.ts +4 -0
  136. package/dist/patterns/diff/index.js +8 -0
  137. package/dist/patterns/diff/types.d.ts +69 -0
  138. package/dist/patterns/diff/types.js +24 -0
  139. package/dist/patterns/form-wizard/controller.d.ts +39 -0
  140. package/dist/patterns/form-wizard/controller.js +157 -0
  141. package/dist/patterns/form-wizard/form-wizard.d.ts +63 -0
  142. package/dist/patterns/form-wizard/form-wizard.js +468 -0
  143. package/dist/patterns/form-wizard/index.d.ts +4 -0
  144. package/dist/patterns/form-wizard/index.js +8 -0
  145. package/dist/patterns/form-wizard/types.d.ts +109 -0
  146. package/dist/patterns/form-wizard/types.js +83 -0
  147. package/dist/patterns/form-wizard/wizard-summary.d.ts +62 -0
  148. package/dist/patterns/form-wizard/wizard-summary.js +324 -0
  149. package/dist/patterns/internal/safe-href.d.ts +17 -0
  150. package/dist/patterns/internal/safe-href.js +17 -0
  151. package/dist/patterns/lineage/index.d.ts +3 -0
  152. package/dist/patterns/lineage/index.js +6 -0
  153. package/dist/patterns/lineage/lineage-graph.d.ts +30 -0
  154. package/dist/patterns/lineage/lineage-graph.js +434 -0
  155. package/dist/patterns/lineage/provenance-strip.d.ts +22 -0
  156. package/dist/patterns/lineage/provenance-strip.js +194 -0
  157. package/dist/patterns/lineage/types.d.ts +53 -0
  158. package/dist/patterns/lineage/types.js +49 -0
  159. package/dist/patterns/notifications/index.d.ts +3 -0
  160. package/dist/patterns/notifications/index.js +6 -0
  161. package/dist/patterns/notifications/notification-bell.d.ts +38 -0
  162. package/dist/patterns/notifications/notification-bell.js +198 -0
  163. package/dist/patterns/notifications/notification-inbox.d.ts +46 -0
  164. package/dist/patterns/notifications/notification-inbox.js +537 -0
  165. package/dist/patterns/notifications/types.d.ts +61 -0
  166. package/dist/patterns/notifications/types.js +108 -0
  167. package/dist/patterns/preview/annotation-inspector.d.ts +25 -6
  168. package/dist/patterns/preview/annotation-inspector.js +239 -94
  169. package/dist/patterns/preview/annotation-thread.d.ts +25 -5
  170. package/dist/patterns/preview/annotation-thread.js +233 -82
  171. package/dist/patterns/preview/annotation-toolbar.d.ts +20 -6
  172. package/dist/patterns/preview/annotation-toolbar.js +162 -96
  173. package/dist/patterns/preview/content-preview-adapter.d.ts +10 -1
  174. package/dist/patterns/preview/content-preview-adapter.js +26 -1
  175. package/dist/patterns/preview/preview-element.d.ts +15 -2
  176. package/dist/patterns/preview/preview-element.js +223 -52
  177. package/dist/patterns/preview/provider-adapter.d.ts +47 -0
  178. package/dist/patterns/preview/provider-adapter.js +17 -0
  179. package/dist/patterns/run/index.d.ts +2 -0
  180. package/dist/patterns/run/index.js +4 -0
  181. package/dist/patterns/run/run-trace.d.ts +40 -0
  182. package/dist/patterns/run/run-trace.js +441 -0
  183. package/dist/patterns/run/types.d.ts +66 -0
  184. package/dist/patterns/run/types.js +152 -0
  185. package/dist/patterns/signature/index.d.ts +2 -0
  186. package/dist/patterns/signature/index.js +4 -0
  187. package/dist/patterns/signature/signature-ceremony.d.ts +33 -0
  188. package/dist/patterns/signature/signature-ceremony.js +317 -0
  189. package/dist/patterns/signature/types.d.ts +68 -0
  190. package/dist/patterns/signature/types.js +89 -0
  191. package/dist/patterns/timeline/index.d.ts +2 -0
  192. package/dist/patterns/timeline/index.js +4 -0
  193. package/dist/patterns/timeline/timeline.d.ts +27 -0
  194. package/dist/patterns/timeline/timeline.js +430 -0
  195. package/dist/patterns/timeline/types.d.ts +36 -0
  196. package/dist/patterns/timeline/types.js +27 -0
  197. package/dist/patterns/versions/graph-layout.d.ts +43 -0
  198. package/dist/patterns/versions/graph-layout.js +159 -0
  199. package/dist/patterns/versions/index.d.ts +4 -0
  200. package/dist/patterns/versions/index.js +8 -0
  201. package/dist/patterns/versions/shared.d.ts +4 -0
  202. package/dist/patterns/versions/shared.js +13 -0
  203. package/dist/patterns/versions/types.d.ts +37 -0
  204. package/dist/patterns/versions/types.js +39 -0
  205. package/dist/patterns/versions/version-graph.d.ts +36 -0
  206. package/dist/patterns/versions/version-graph.js +438 -0
  207. package/dist/patterns/versions/version-list.d.ts +39 -0
  208. package/dist/patterns/versions/version-list.js +407 -0
  209. package/dist/patterns/work-queue/controller.d.ts +26 -0
  210. package/dist/patterns/work-queue/controller.js +150 -0
  211. package/dist/patterns/work-queue/index.d.ts +4 -0
  212. package/dist/patterns/work-queue/index.js +7 -0
  213. package/dist/patterns/work-queue/types.d.ts +128 -0
  214. package/dist/patterns/work-queue/types.js +45 -0
  215. package/dist/patterns/work-queue/work-queue.d.ts +48 -0
  216. package/dist/patterns/work-queue/work-queue.js +534 -0
  217. package/dist/patterns/work-queue/workload-board.d.ts +53 -0
  218. package/dist/patterns/work-queue/workload-board.js +608 -0
  219. package/package.json +89 -5
@@ -20,11 +20,13 @@ const createInitialState = (config) => ({
20
20
  totalCount: null,
21
21
  },
22
22
  selectedItemIds: [],
23
+ sort: null,
23
24
  view: createInitialExplorerViewState(),
24
25
  });
25
26
  export class ContentExplorerController extends Controller {
26
27
  config;
27
28
  activeLoadRequestId = 0;
29
+ activeLoadAbortController = null;
28
30
  actionsController;
29
31
  collectionController;
30
32
  navigationController;
@@ -104,11 +106,21 @@ export class ContentExplorerController extends Controller {
104
106
  if (!this.state.connected) {
105
107
  return;
106
108
  }
109
+ // Invalidate and abort any in-flight load, then reset the sub-controllers
110
+ // BEFORE snapshotting their state so the facade and navigation agree on
111
+ // being back at the root.
112
+ this.activeLoadRequestId += 1;
113
+ this.activeLoadAbortController?.abort();
114
+ this.activeLoadAbortController = null;
115
+ this.collectionController.reset();
116
+ this.navigationController.reset();
107
117
  this.setState({
108
118
  ...this.state,
119
+ availableActionsByItemId: {},
109
120
  breadcrumbs: [],
110
121
  connected: false,
111
- currentFolder: this.navigationController.getState().currentFolder,
122
+ currentFolder: null,
123
+ currentFolderId: this.config.rootFolderId,
112
124
  error: null,
113
125
  items: [],
114
126
  loading: false,
@@ -116,9 +128,6 @@ export class ContentExplorerController extends Controller {
116
128
  selectedItemIds: [],
117
129
  view: createInitialExplorerViewState(),
118
130
  });
119
- this.activeLoadRequestId += 1;
120
- this.collectionController.reset();
121
- this.navigationController.reset();
122
131
  this.emit("viewChanged", { view: this.state.view });
123
132
  this.emit("disconnected", undefined);
124
133
  }
@@ -259,6 +268,108 @@ export class ContentExplorerController extends Controller {
259
268
  await this.navigateTo(item.id);
260
269
  }
261
270
  }
271
+ async setSort(sortOrSortBy, direction) {
272
+ const sort = sortOrSortBy === null
273
+ ? null
274
+ : typeof sortOrSortBy === "string"
275
+ ? { sortBy: sortOrSortBy, direction: direction ?? "ASC" }
276
+ : sortOrSortBy;
277
+ const current = this.state.sort;
278
+ if (current?.sortBy === sort?.sortBy && current?.direction === sort?.direction) {
279
+ return;
280
+ }
281
+ this.setState({
282
+ ...this.state,
283
+ sort,
284
+ });
285
+ this.emit("sortChanged", { sort });
286
+ if (this.state.connected) {
287
+ this.collectionController.reset();
288
+ await this.reload();
289
+ }
290
+ }
291
+ /** Create a folder in the current folder, then refresh the collection. */
292
+ async createFolder(name) {
293
+ const createFolder = this.config.transport.createFolder;
294
+ if (!createFolder) {
295
+ throw new Error("Explorer transport does not support folder creation");
296
+ }
297
+ const trimmed = name.trim();
298
+ if (!trimmed || !this.state.connected) {
299
+ return null;
300
+ }
301
+ return this.runMutation("create-folder", undefined, async () => {
302
+ const item = await createFolder({
303
+ parentFolderId: this.state.currentFolderId,
304
+ name: trimmed,
305
+ token: this.config.token,
306
+ language: this.config.language,
307
+ });
308
+ this.emit("itemMutated", { kind: "create-folder", item, itemId: item.id });
309
+ return item;
310
+ });
311
+ }
312
+ /** Rename an item in the current collection, then refresh. */
313
+ async renameItem(itemId, name) {
314
+ const renameItem = this.config.transport.renameItem;
315
+ if (!renameItem) {
316
+ throw new Error("Explorer transport does not support rename");
317
+ }
318
+ const item = this.state.items.find(entry => entry.id === itemId);
319
+ const trimmed = name.trim();
320
+ if (!item || !trimmed || !this.state.connected) {
321
+ return null;
322
+ }
323
+ return this.runMutation("rename", itemId, async () => {
324
+ const renamed = await renameItem({
325
+ itemId,
326
+ itemType: item.type,
327
+ name: trimmed,
328
+ token: this.config.token,
329
+ language: this.config.language,
330
+ });
331
+ this.emit("itemMutated", { kind: "rename", item: renamed, itemId });
332
+ return renamed;
333
+ });
334
+ }
335
+ /** Delete an item from the current collection, then refresh. */
336
+ async deleteItem(itemId) {
337
+ const deleteItem = this.config.transport.deleteItem;
338
+ if (!deleteItem) {
339
+ throw new Error("Explorer transport does not support delete");
340
+ }
341
+ const item = this.state.items.find(entry => entry.id === itemId);
342
+ if (!item || !this.state.connected) {
343
+ return false;
344
+ }
345
+ const result = await this.runMutation("delete", itemId, async () => {
346
+ await deleteItem({
347
+ itemId,
348
+ itemType: item.type,
349
+ token: this.config.token,
350
+ language: this.config.language,
351
+ });
352
+ this.emit("itemMutated", { kind: "delete", itemId });
353
+ return true;
354
+ });
355
+ return result ?? false;
356
+ }
357
+ async runMutation(kind, itemId, perform) {
358
+ try {
359
+ const result = await perform();
360
+ await this.reload();
361
+ return result;
362
+ }
363
+ catch (error) {
364
+ const message = error instanceof Error ? error.message : `Explorer ${kind} failed`;
365
+ this.setState({
366
+ ...this.state,
367
+ error: { code: "mutation_failed", message },
368
+ });
369
+ this.emit("mutationFailed", { kind, message, ...(itemId ? { itemId } : {}) });
370
+ return null;
371
+ }
372
+ }
262
373
  async reload() {
263
374
  await this.loadPage({ append: false });
264
375
  }
@@ -277,6 +388,11 @@ export class ContentExplorerController extends Controller {
277
388
  }
278
389
  const requestId = this.activeLoadRequestId + 1;
279
390
  this.activeLoadRequestId = requestId;
391
+ // Abort the superseded in-flight request so the transport can cancel its
392
+ // network work; the requestId guard already discards its response.
393
+ this.activeLoadAbortController?.abort();
394
+ const abortController = typeof AbortController === "function" ? new AbortController() : null;
395
+ this.activeLoadAbortController = abortController;
280
396
  this.setState({
281
397
  ...this.state,
282
398
  error: null,
@@ -284,6 +400,7 @@ export class ContentExplorerController extends Controller {
284
400
  this.collectionController.startLoading();
285
401
  const pagination = this.collectionController.getState().pagination;
286
402
  const requestOffset = append ? (pagination.nextOffset ?? this.collectionController.getState().items.length) : 0;
403
+ const sort = this.state.sort;
287
404
  try {
288
405
  if (this.state.view.mode === "search") {
289
406
  const searchItems = this.config.transport.searchItems;
@@ -296,8 +413,10 @@ export class ContentExplorerController extends Controller {
296
413
  ancestorFolderId: this.state.view.searchAncestorFolderId ?? undefined,
297
414
  limit: pagination.limit,
298
415
  offset: requestOffset,
416
+ ...(sort ? { sortBy: sort.sortBy, sortDirection: sort.direction } : {}),
299
417
  token: this.config.token,
300
418
  language: this.config.language,
419
+ ...(abortController ? { signal: abortController.signal } : {}),
301
420
  });
302
421
  this.applyLoadedSearch(requestId, result, append);
303
422
  return;
@@ -306,14 +425,21 @@ export class ContentExplorerController extends Controller {
306
425
  folderId: this.state.currentFolderId,
307
426
  limit: pagination.limit,
308
427
  offset: requestOffset,
428
+ ...(sort ? { sortBy: sort.sortBy, sortDirection: sort.direction } : {}),
309
429
  token: this.config.token,
310
430
  language: this.config.language,
431
+ ...(abortController ? { signal: abortController.signal } : {}),
311
432
  });
312
433
  this.applyLoadedFolder(requestId, result, append);
313
434
  }
314
435
  catch (error) {
315
436
  this.applyLoadFailure(requestId, error, append);
316
437
  }
438
+ finally {
439
+ if (this.activeLoadAbortController === abortController) {
440
+ this.activeLoadAbortController = null;
441
+ }
442
+ }
317
443
  }
318
444
  applyLoadedSearch(requestId, result, append) {
319
445
  if (requestId !== this.activeLoadRequestId) {
@@ -18,15 +18,17 @@ export class ExplorerNavigationController extends Controller {
18
18
  if (folderId === this.state.currentFolderId) {
19
19
  return null;
20
20
  }
21
- const nextFolder = {
22
- id: folderId,
23
- name: folderId,
24
- type: "folder",
25
- };
26
- const nextBreadcrumbs = [
27
- ...this.state.breadcrumbs.filter(crumb => crumb.id !== folderId),
28
- nextFolder,
29
- ];
21
+ // Navigating to a crumb already in the trail truncates back to it (a
22
+ // breadcrumb is a path, so an ancestor click must drop its descendants);
23
+ // navigating anywhere else appends a provisional crumb that the loaded
24
+ // folder's real metadata replaces via applyLoadedFolder.
25
+ const existingIndex = this.state.breadcrumbs.findIndex(crumb => crumb.id === folderId);
26
+ const nextFolder = existingIndex >= 0
27
+ ? { ...this.state.breadcrumbs[existingIndex], type: "folder" }
28
+ : { id: folderId, name: folderId, type: "folder" };
29
+ const nextBreadcrumbs = existingIndex >= 0
30
+ ? this.state.breadcrumbs.slice(0, existingIndex + 1)
31
+ : [...this.state.breadcrumbs, nextFolder];
30
32
  this.setState({
31
33
  breadcrumbs: nextBreadcrumbs,
32
34
  currentFolder: nextFolder,
@@ -65,6 +65,21 @@ export interface ExplorerItemAction {
65
65
  id: string;
66
66
  itemTypes?: ExplorerItem["type"][];
67
67
  label: string;
68
+ /**
69
+ * Permission flag an item must not explicitly deny for this action to be
70
+ * enabled. An item with the flag `false` gets the action `disabled`; an item
71
+ * without permission data keeps it enabled (permissions unknown ≠ denied).
72
+ */
73
+ requiresPermission?: keyof ExplorerItemPermissions;
74
+ /** Resolved availability — populated by the actions controller, not authored. */
75
+ disabled?: boolean;
76
+ }
77
+ /** Sort field vocabulary mirroring box-ui-elements' ContentExplorer. */
78
+ export type ExplorerSortBy = "name" | "date" | "size";
79
+ export type ExplorerSortDirection = "ASC" | "DESC";
80
+ export interface ExplorerSortState {
81
+ sortBy: ExplorerSortBy;
82
+ direction: ExplorerSortDirection;
68
83
  }
69
84
  export interface ExplorerFolder {
70
85
  id: string;
@@ -83,6 +98,8 @@ export interface ExplorerTransportRequest {
83
98
  folderId: string;
84
99
  limit?: number;
85
100
  offset?: number;
101
+ sortBy?: ExplorerSortBy;
102
+ sortDirection?: ExplorerSortDirection;
86
103
  token: string;
87
104
  language?: string;
88
105
  signal?: AbortSignal;
@@ -92,10 +109,32 @@ export interface ExplorerSearchRequest {
92
109
  ancestorFolderId?: string;
93
110
  limit?: number;
94
111
  offset?: number;
112
+ sortBy?: ExplorerSortBy;
113
+ sortDirection?: ExplorerSortDirection;
114
+ token: string;
115
+ language?: string;
116
+ signal?: AbortSignal;
117
+ }
118
+ /** Shared shape for the mutation requests a transport may support. */
119
+ export interface ExplorerMutationContext {
95
120
  token: string;
96
121
  language?: string;
97
122
  signal?: AbortSignal;
98
123
  }
124
+ export interface ExplorerCreateFolderRequest extends ExplorerMutationContext {
125
+ parentFolderId: string;
126
+ name: string;
127
+ }
128
+ export interface ExplorerRenameItemRequest extends ExplorerMutationContext {
129
+ itemId: string;
130
+ itemType: ExplorerItem["type"];
131
+ name: string;
132
+ }
133
+ export interface ExplorerDeleteItemRequest extends ExplorerMutationContext {
134
+ itemId: string;
135
+ itemType: ExplorerItem["type"];
136
+ }
137
+ export type ExplorerMutationKind = "create-folder" | "rename" | "delete";
99
138
  export interface ExplorerPaginationState {
100
139
  hasMoreItems: boolean;
101
140
  limit: number;
@@ -124,6 +163,9 @@ export interface ExplorerSearchResult {
124
163
  export interface ExplorerTransport {
125
164
  loadFolderItems(request: ExplorerTransportRequest): Promise<ExplorerTransportResult>;
126
165
  searchItems?(request: ExplorerSearchRequest): Promise<ExplorerSearchResult>;
166
+ createFolder?(request: ExplorerCreateFolderRequest): Promise<ExplorerItem>;
167
+ renameItem?(request: ExplorerRenameItemRequest): Promise<ExplorerItem>;
168
+ deleteItem?(request: ExplorerDeleteItemRequest): Promise<void>;
127
169
  }
128
170
  export interface ExplorerFetchLike {
129
171
  (input: string | URL | Request, init?: RequestInit): Promise<Response>;
@@ -139,7 +181,7 @@ export interface ExplorerSessionConfig {
139
181
  transport: ExplorerTransport;
140
182
  }
141
183
  export interface ExplorerErrorState {
142
- code: "load_failed";
184
+ code: "load_failed" | "mutation_failed";
143
185
  message: string;
144
186
  }
145
187
  export interface ExplorerState {
@@ -153,6 +195,7 @@ export interface ExplorerState {
153
195
  loading: boolean;
154
196
  pagination: ExplorerPaginationState;
155
197
  selectedItemIds: string[];
198
+ sort: ExplorerSortState | null;
156
199
  view: ExplorerViewState;
157
200
  }
158
201
  export interface ExplorerEvents {
@@ -198,6 +241,9 @@ export interface ExplorerEvents {
198
241
  selectionChanged: {
199
242
  selectedItemIds: string[];
200
243
  };
244
+ sortChanged: {
245
+ sort: ExplorerSortState | null;
246
+ };
201
247
  viewChanged: {
202
248
  view: ExplorerViewState;
203
249
  };
@@ -206,4 +252,15 @@ export interface ExplorerEvents {
206
252
  items: ExplorerItem[];
207
253
  pagination: ExplorerPaginationState;
208
254
  };
255
+ itemMutated: {
256
+ kind: ExplorerMutationKind;
257
+ /** Present for create-folder and rename; absent for delete. */
258
+ item?: ExplorerItem;
259
+ itemId: string;
260
+ };
261
+ mutationFailed: {
262
+ kind: ExplorerMutationKind;
263
+ message: string;
264
+ itemId?: string;
265
+ };
209
266
  }
@@ -0,0 +1,71 @@
1
+ import { ContentPickerController } from "./controller.js";
2
+ import type { PickerItemType, PickerState } from "./types.js";
3
+ import type { ExplorerItem, ExplorerState, ExplorerTransport } from "../content-explorer/types.js";
4
+ import { BaseElement } from "../../core/index.js";
5
+ export declare class ContentPicker extends BaseElement {
6
+ static readonly tagName: string;
7
+ static get observedAttributes(): string[];
8
+ private controller;
9
+ private pendingStart;
10
+ private focusItemId;
11
+ /**
12
+ * Set when a rebuild destroyed in-element focus before its target existed
13
+ * (e.g. navigation is still loading the next folder); the next update keeps
14
+ * trying to restore until a target renders.
15
+ */
16
+ private pendingFocusRestore;
17
+ private unsubscribeFns;
18
+ private transportValue;
19
+ get language(): string | null;
20
+ set language(value: string | null);
21
+ get pageSize(): number | undefined;
22
+ set pageSize(value: number | undefined);
23
+ get rootFolderId(): string | null;
24
+ set rootFolderId(value: string | null);
25
+ get token(): string | null;
26
+ set token(value: string | null);
27
+ get maxSelectable(): number | undefined;
28
+ set maxSelectable(value: number | undefined);
29
+ /** Comma-separated in markup, e.g. `extensions="pdf,docx"`. */
30
+ get extensions(): string[];
31
+ set extensions(value: string[]);
32
+ /** Comma-separated in markup, e.g. `selectable-types="file,web_link"`. */
33
+ get selectableTypes(): PickerItemType[];
34
+ set selectableTypes(value: PickerItemType[]);
35
+ get chooseLabel(): string;
36
+ set chooseLabel(value: string);
37
+ get cancelLabel(): string;
38
+ set cancelLabel(value: string);
39
+ get transport(): ExplorerTransport | null;
40
+ set transport(value: ExplorerTransport | null);
41
+ get state(): Readonly<PickerState> | null;
42
+ get explorerState(): Readonly<ExplorerState> | null;
43
+ /** The live session controller. Null until configured and connected. */
44
+ get pickerController(): ContentPickerController | null;
45
+ attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
46
+ connectedCallback(): void;
47
+ disconnectedCallback(): void;
48
+ navigateTo(folderId: string): Promise<void>;
49
+ search(query: string): Promise<void>;
50
+ clearSearch(): Promise<void>;
51
+ loadNextPage(): Promise<void>;
52
+ togglePick(itemId: string): void;
53
+ clearPicks(): void;
54
+ choose(): ExplorerItem[] | null;
55
+ cancel(): void;
56
+ private updateStringAttribute;
57
+ private scheduleStart;
58
+ private startController;
59
+ private readConfig;
60
+ private subscribeToController;
61
+ private teardownController;
62
+ /**
63
+ * Only interactive rows (pickable items and navigable folders) participate
64
+ * in keyboard navigation — disabled rows cannot take focus, so including
65
+ * them would strand arrow-key movement and the roving tab stop.
66
+ */
67
+ private getFocusableItemIds;
68
+ protected renderTemplate(): void;
69
+ protected update(): void;
70
+ private isFocusInsideHost;
71
+ }