#3483485 Multi select
Closes #3483485
- This MR allows a user to CMD+click to select multiple components (what happens for windows/linux users TBC - but I think the meta key refers to CTRL).
- This MR does not yet allow you to do anything once you have selected multiple components (drag, copy, save as section). That is coming later.
In addition to adding the "multi-select" concept a fairly fundamental change to the source of truth for the currently selected component had to be made to accommodate it the more complex functionality.
TLDR: the Redux state selection.items
is now the source of truth for the currently selected component.
In head, before this MR, the selectedComponent
is used for things such as which component to draw a border around and also which props form to display.
In the first iteration of selecting components we attempted to have a 2-way sync between the component/:componentId
router parameter and a selectedComponent
redux state. The idea was that updating the URL would set the state and updating the state would set the URL.
Short version: this proved really complex and unstable and lead to infinite loops etc. so we scrapped it.
It was then decided that the source of truth for the currently selected component would be the component/:componentId
router param. Everywhere that needed to know the selected component would query the URL params. A 1-way sync was introduced to replace the 2-way sync and so updating the URL would set a _readOnlySelectedComponent
in the Redux state. Updating the state directly was discouraged and doing so would not update the URL. The value existed in state for one reason - so that extensions could check the currently selected component as we had already written a way for extensions to access our redux store values.
Now, in this MR
We have added a further complexity. Now there can be more than one selected component! The URL param is no longer sufficient (and I don't think it would be desirable for a user to copy/paste a url that contains the multi-selection). Multi-selection is a bit more transient than when you have a single component selected (and therefore want to see its props form or whatever else).
So things had to change.
- The source of truth for the selected component is now the redux store.
- The value in redux has been updated from
_readOnly...
toselection
which has a consecutive property and an array of items - Adding an item to the selection using the commands from
useComponentSelection
will update the state and handle updates to the URL as required. - On page load, if there is a component/:componentId in the URL, the state will be updated accordingly (in
ui/src/hooks/useSyncParamsToState.ts
)
The below table shows how the URL is updated based on changing the number of selected components (either adding to or removing from the selection)
No. of components selected | URL | |
---|---|---|
From |
To |
|
0 | 1 | /:componentId added to URL |
1 | 2 | /:componentId removed from URL |
1 | 0 | /:componentId removed from URL |
2 | 1 | remaining item's /:componentId added to URL |
2 | 3+ | No change to URL |
-
CMD+Click can add more components to the multi selection -
CMD+Click on a multi-selected item will remove it from the selection. -
Focusing a different region will clear the multi-selection -
Highlight multi-selected components in preview -
Hight multi-selected components in layers -
Display multi-selection status in right hand panel -
Detect 'type' of selection (consecutive components or not) -
Prevent "invalid" selection - selecting both a child and a parent at the same time