-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[1545] Extract selection and setSelection in a hook
Bug: #1545 Signed-off-by: Guillaume Coutable <guillaume.coutable@obeo.fr>
- Loading branch information
1 parent
01ac013
commit e262c60
Showing
105 changed files
with
881 additions
and
936 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
= ADR-123 - Improve frontend selection support | ||
|
||
== Context | ||
|
||
Selection handling is currently managed by the `Workbench` frontend component, which is only part (although the main one) of the project edition view/page (EditProjectView). | ||
Actions of the EditProjectView which are not part of the workbench (for example in the navbar and its menu) should also be able to read and set the selection. | ||
|
||
== Decision | ||
|
||
We will extract selection handling from `Workbench(Machine).tsx` into a custom hook. | ||
This will simplify the Workbench state machine. | ||
|
||
It will also isolate selection handling implementation and enable a lot of simplications where we used to drill down `selection` and/or `setSelection` using props. | ||
Components which need to read/set the selection will be able to do so using: | ||
|
||
[source,js] | ||
---- | ||
const {selection, setSelection} = useSelection(); | ||
---- | ||
|
||
Some components (notably the workbench itself) need to be able to react to selection changes. | ||
They can do this with a `useEffect()` which reacts to changes in the selection value: | ||
|
||
[source,js] | ||
---- | ||
const {selection} = useSelection(); | ||
useEffect(() => { | ||
/* handle the new selection value */ | ||
}, [selection]); | ||
---- | ||
|
||
Components which used to get the selection and/or setSelection callback as part of their props just to pass them to their children will be simplified. | ||
|
||
The state needed for the new hook will be handled by the `SelectionContext` and it will be possible to initialize the selection. | ||
|
||
[source,js] | ||
---- | ||
export const SelectionContext = React.createContext(undefined); | ||
export const SelectionContextProvider = ({ initialSelection, children }) => { | ||
const [state, setState] = useState({ | ||
selection: initialSelection ?? { entries: [] }, | ||
}); | ||
const setSelection = useCallback((selection: Selection) => { | ||
setState((prevState) => ({ ...prevState, selection })); | ||
}, []); | ||
return ( | ||
<SelectionContext.Provider | ||
value={{ selection: state.selection, setSelection }}> | ||
{children} | ||
</SelectionContext.Provider> | ||
); | ||
} | ||
---- | ||
|
||
The `SelectionContextProvider` will be used as the parent of the `Workbench` and the `Project Navbar` in `EditProjectView`: | ||
|
||
[source,js] | ||
---- | ||
return ( | ||
<SelectionContextProvider initialSelection={initialSelection}> | ||
{navbar} | ||
{main} | ||
<Snackbar /> | ||
</SelectionContextProvider> | ||
); | ||
---- | ||
|
||
This makes sense because the selection is relative to a particular project/editing context. | ||
|
||
== Status | ||
|
||
Work in progress |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
49 changes: 49 additions & 0 deletions
49
packages/core/frontend/sirius-components-core/src/selection/SelectionContext.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2023 Obeo. | ||
* This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Public License v2.0 | ||
* which accompanies this distribution, and is available at | ||
* https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Obeo - initial API and implementation | ||
*******************************************************************************/ | ||
|
||
import React, { useCallback, useState } from 'react'; | ||
import { Representation } from '../workbench/Workbench.types'; | ||
import { | ||
Selection, | ||
SelectionContextProviderProps, | ||
SelectionContextProviderState, | ||
SelectionContextValue, | ||
SelectionEntry, | ||
} from './SelectionContext.types'; | ||
|
||
const defaultValue: SelectionContextValue = { | ||
selection: { entries: [] }, | ||
setSelection: () => {}, | ||
}; | ||
|
||
export const SelectionContext = React.createContext<SelectionContextValue>(defaultValue); | ||
|
||
const isRepresentation = (selectionEntry: SelectionEntry): selectionEntry is Representation => | ||
selectionEntry.kind.startsWith('siriusComponents://representation'); | ||
|
||
export const SelectionContextProvider = ({ initialSelection, children }: SelectionContextProviderProps) => { | ||
const [state, setState] = useState<SelectionContextProviderState>({ | ||
selection: initialSelection ?? { entries: [] }, | ||
}); | ||
|
||
const setSelection = useCallback((selection: Selection) => { | ||
const selectedRepresentation = selection.entries.filter(isRepresentation); | ||
setState((prevState) => ({ ...prevState, selection, selectedRepresentation })); | ||
}, []); | ||
|
||
return ( | ||
<SelectionContext.Provider value={{ selection: state.selection, setSelection }}> | ||
{children} | ||
</SelectionContext.Provider> | ||
); | ||
}; |
36 changes: 36 additions & 0 deletions
36
packages/core/frontend/sirius-components-core/src/selection/SelectionContext.types.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2023 Obeo. | ||
* This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Public License v2.0 | ||
* which accompanies this distribution, and is available at | ||
* https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Obeo - initial API and implementation | ||
*******************************************************************************/ | ||
|
||
export interface Selection { | ||
entries: SelectionEntry[]; | ||
} | ||
|
||
export interface SelectionEntry { | ||
id: string; | ||
label: string; | ||
kind: string; | ||
} | ||
|
||
export interface SelectionContextValue { | ||
selection: Selection; | ||
setSelection: (selection: Selection) => void; | ||
} | ||
|
||
export interface SelectionContextProviderProps { | ||
initialSelection: Selection | null; | ||
children: React.ReactNode; | ||
} | ||
|
||
export interface SelectionContextProviderState { | ||
selection: Selection; | ||
} |
22 changes: 22 additions & 0 deletions
22
packages/core/frontend/sirius-components-core/src/selection/useSelection.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2023 Obeo. | ||
* This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Public License v2.0 | ||
* which accompanies this distribution, and is available at | ||
* https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Obeo - initial API and implementation | ||
*******************************************************************************/ | ||
|
||
import { useContext } from 'react'; | ||
import { SelectionContext } from './SelectionContext'; | ||
import { UseSelectionValue } from './useSelection.types'; | ||
|
||
export const useSelection = (): UseSelectionValue => { | ||
const { selection, setSelection } = useContext<UseSelectionValue>(SelectionContext); | ||
|
||
return { selection, setSelection }; | ||
}; |
20 changes: 20 additions & 0 deletions
20
packages/core/frontend/sirius-components-core/src/selection/useSelection.types.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2023 Obeo. | ||
* This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Public License v2.0 | ||
* which accompanies this distribution, and is available at | ||
* https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Obeo - initial API and implementation | ||
*******************************************************************************/ | ||
|
||
import { Selection } from './SelectionContext.types'; | ||
|
||
export interface UseSelectionValue { | ||
selection: Selection; | ||
|
||
setSelection: (selection: Selection) => void; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.