As we need to display menu on the top of UI, I created React context that can handle rendering menu items.
The diff introduces the context that provides function allowing to render items in portal.
Rendering in the portal is not used yet. It will be in the following diffs.
Details
No behavior change in web app. Empty portal div should appear in DOM as a child of react-root div. The portal can be tested after introducing rendering in one of the following diffs.
Diff Detail
- Repository
- rCOMM Comm
- Lint
Lint Not Applicable - Unit
Tests Not Applicable
Event Timeline
web/menu-portal-provider.react.js | ||
---|---|---|
13 ↗ | (On Diff #10188) | Is it necessary to expose this ref via context? And if it's necessary, we need to have a more concrete type. (The fact that mixed works here suggests that it is not used anywhere) |
34–39 ↗ | (On Diff #10188) | You can use a shorthand |
51–56 ↗ | (On Diff #10188) | It might be easier to have a useRenderInMenuPortal that returns just renderInMenuPortal function |
web/menu-portal-provider.react.js | ||
---|---|---|
13–14 ↗ | (On Diff #10188) | I think we should avoid having any writeable properties in a context type. The risk is that a consumer of the context could directly modify some of these properties. Agree with all of @palys-swm's comments:
On top of those comments, let's make sure to set every field here as $ReadOnly, including any nested fields |
web/menu-portal.css | ||
---|---|---|
1 ↗ | (On Diff #10188) | It is supposed to remain in top left corner of the page (so the portal content could be styled with relative position to the .portal div using JS calculated coordinates) |
web/menu-portal-provider.react.js | ||
---|---|---|
28 ↗ | (On Diff #10355) | Do we actually need ReactDOM.createPortal here? My understanding is that it's only necessary for "brownfield" apps where the "portal" is outside of the root React component. But in our case, we have a "greenfield" app where pretty much the whole thing (and certainly <div ref={portalRef} className={css.portal}></div> below) is inside the root React component. So we can use a pseudo-portal (eg. portal design, but not an actual portal), similar to how @benschac refactored the Modal component recently. Let me know if I'm missing something here! |
web/menu-portal-provider.react.js | ||
---|---|---|
28 ↗ | (On Diff #10355) | Good point. The initial idea was to use the context providing the ref for portal, and executing createPortal from components deep inside the root. However, after the changes, the logic for writing into the portal was moved into the context itself, which seems to have no sense. |
Follow review comments & introduce setMenuPosition function into context.
The reason is that previous solution required changing renedered menu object every time browser window resizes (because the position calculated in JS was kept in the menu itself).
Right now, the position updates (like on window resize) don't require changing passed menu object, which improves performance and prevents recreating all callbacks dependent on menu object (in Menu component)
Added closeMenu and currentMenu into context, to simplify Menu compoenent in the following diff.
web/menu-provider.react.js | ||
---|---|---|
46 ↗ | (On Diff #10818) | Should this take the symbol instead of menuToClose? Pro: we will be consistent with other logic, and we can protect a potential case where the React.Node is out-of-sync (the symbol for a component will always be the same across render cycles). Con: we can't pass a callback to setMenu that looks at the old value of oldMenu – we will need to have this React.useCallback take currentOpenMenu as a dependency |
web/menu-provider.react.js | ||
---|---|---|
46 ↗ | (On Diff #10818) | I think, the current solution is better, as we don't have any dependencies in the callback. |