aws-amplify / aws-amplify/amplify-ui
Expose additional internals and dispatch state
- Dominant language
- TypeScript
- Stars
- 1.1k
- Forks
- 347
- Avg merge
- 18h 29m
- Merged PRs (30d)
- 9
Description
### On which framework/platform would you like to see this feature implemented?
React
### Which UI component is this feature-request for?
Storage
### Please describe your feature-request in detail.
There's a number of internals I found inspecting code that would make integration with custom additions for my purposes much easier. I'd like to have them available in state or event callbacks, etc.
The features I want to implement are:
- When only one storage location is available, ensure the user doesn't even have to select it and never leaves it.
- After creating a folder, or uploading a new folder, include 'View' button action in the success message
- I'd like to be able to add other custom actions as well, like 'Process' that receives the state details so they can automatically kick off actions against the uploaded folder.
- Context menu
- I'd like to add my own context items, potentially enabled or disabled by selections and receiving that state when the action is clicked.
- I'm promoting some items out of the context menu (like Upload)
- I'm adding my own promoted items (like Process)
### Please describe a solution you'd like.
Here's my current work around. If we could get these into easily viewed controlled mode state, or other callbacks it would be lovely.
Based on everything we've worked through in this session:
---
## Amplify StorageBrowser internals we work around
### 1. Selected items (`locationItems` / `dataItems`)
**Not exposed**: Checkbox selection state lives in an internal `locationItemsDispatch` store. `onValueChange` only carries `{ actionType, location }`.
**Our workaround**: `StorageBrowserDataTable` scans `rows` for `checked=true` checkbox cells on every render and derives `selectedItems` in context via `SELECTED_ITEMS_CHANGED`.
---
### 2. Action exit internal cleanup (`RESET_FILE_ITEMS`)
**Not exposed**: `onActionExit` on each view dispatches two internal stores — `RESET_ACTION_TYPE` (store) and `RESET_FILE_ITEMS` (fileItemsDispatch). Only the first propagates externally via `onValueChange`. Calling `setStorageBrowserValue({ actionType: undefined })` from outside skips `RESET_FILE_ITEMS`.
**Our workaround**: Success message renders the real `storageBrowser.StorageBrowser.UploadView.Exit` / `CreateFolderView.Exit` composable so Amplify runs its own cleanup. `postExitNavigationRef` holds the target path and `onStorageBrowserValueChange` applies it once Amplify's exit event propagates externally.
---
### 3. `useControlsContext` / `onActionExit` not exported
**Not exposed**: The controls context hook (which gives access to `onActionExit`, `onActionSelect`, etc.) is internal. `ActionExitControl` composable is attached to view objects but not exported from `@aws-amplify/ui-react-storage/browser`.
**Our workaround**: Access exit composables via `storageBrowser.StorageBrowser.UploadView.Exit` and `CreateFolderView.Exit` (they are attached to the view objects, not independently exported).
---
### 4. Transient empty location on delete exit
**Not exposed/undocumented**: When exiting `DeleteView`, Amplify intermittently emits `{ actionType: undefined, location: undefined }` instead of preserving the current location.
**Our workaround**: In `onStorageBrowserValueChange`, when transitioning out of `delete` with an empty location, we preserve `current.location` to prevent the user being dropped to the location-selection screen.
---
### 5. Empty path on single-location action transitions
**Not exposed/undocumented**: When Amplify emits `CHANGE_ACTION_TYPE` for `upload`, `createFolder`, or `delete` in single-location mode, the emitted `location.path` is sometimes `""` even when the user is already navigated into a subfolder.
**Our workaround**: In `onStorageBrowserValueChange`, when entering one of those actions with `path === ""` but `current.location.path` is non-empty, we preserve the current path.
---
### 6. No `onExit` callback contract in `createStorageBrowser` options
**Not exposed at the right level**: `onExit` exists as a prop on the standalone view components (`UploadView`, `CreateFolderView`) but is not available via `createStorageBrowser`'s `options` object, so there's no clean way to hook navigation post-exit without rendering the composables directly.
**Our workaround**: Combine the real Exit composable rendering (#2, #3) with the `postExitNavigationRef` pattern to sequence navigation after internal cleanup.
---
### Summary table
| Gap | Workaround location |
|---|---|
| Selected items state | `StorageBrowserDataTable` row scan → `SELECTED_ITEMS_CHANGED` |
| `RESET_FILE_ITEMS` on exit | Render real `UploadView.Exit` / `CreateFolderView.Exit` composable |
| `useControlsContext` not exported | Access via `storageBrowser.StorageBrowser.*View.Exit` |
| Delete exit drops location | `onStorageBrowserValueChange` null-location guard |
| Empty path on action transition | `onStorageBrowserValueChange` empty-path preservation |
| No `onExit` in `createStorageBrowser` options | `postExitNavigationRef` + composable exit rendering |
### We love contributors! Is this something you'd be interested in working on?
- [ ] 👋 I may be able to implement this feature request.
- [ ] ⚠️ This feature might incur a breaking change.
Contributor guide
Research direction
Start by reading the StorageBrowser internals described in the issue, especially locationItemsDispatch, fileItemsDispatch, useControlsContext, ActionExitControl, and the onStorageBrowserValueChange workarounds. Reproduce the single-location, action-exit, delete-exit, selection, and context-menu cases before determining which state or callback contracts are missing. Done requires a decided, supported API scope rather than exposing every internal directly.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript
- Domain
- frontend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100