Skip to content

Remove findDOMNode usage from Modal and Popover#46123

Merged
ravicious merged 11 commits intomasterfrom
r7s/refactor-modal
Sep 9, 2024
Merged

Remove findDOMNode usage from Modal and Popover#46123
ravicious merged 11 commits intomasterfrom
r7s/refactor-modal

Conversation

@ravicious
Copy link
Copy Markdown
Member

@ravicious ravicious commented Sep 2, 2024

e counterpart: https://github.com/gravitational/teleport.e/pull/4970

findDOMNode is going to be deprecated in React 19. I was able to replace all uses of it in Modal and Popover by using regular React refs, since findDOMNode was used there mostly to get a DOM node and then read or write some stuff on it.

I removed some functionality from Modal, e.g. the ability to pass a custom container (if you didn't want to put your modal directly in document.body) because it was not used anywhere in the project and it let me simplify the code a little bit. I also removed some extra abstractions that I deemed not to be necessary. Everything is explained in individual commit messages.

The work on removing findDOMNode is not done, there's still a couple of callsites that use it. However, @bl-nero wants to work on the Popover component, so I'm pushing this PR for review so that he can branch off this work.

It was not used within the app anyway
@ravicious ravicious added the no-changelog Indicates that a PR does not require a changelog entry label Sep 2, 2024
@ravicious ravicious force-pushed the r7s/refactor-modal branch 3 times, most recently from 782ef74 to f40b724 Compare September 2, 2024 16:19
The only situation where they'd be needed if we were handling some nodes
between iframes, but we don't use <iframe> even once in our code.
Calls to those functions can be replaced with document and window.

https://stackoverflow.com/questions/9845043/when-node-ownerdocument-is-not-window-document
https://stackoverflow.com/questions/9183555/whats-the-point-of-document-defaultview
Initially I wanted to just remove the container prop, but as I sat down
to it, I realized that the whole Portal component is not necessary as
we can just replace it with calling createPortal directly.

The onRendered prop of Portal was never used, rendering the handleRendered
function unnecessary.

Similarly, handlePortalRef was set to the ref prop on Portal. This
function sets mountNode, but after we replaced ownerDocument with document,
it's mountNode is no longer being used.
dialogRef used to point at the child of StyledModal. To get rid of
findDOMNode, we replaced it by taking children directly from the ref
set on StyledModal.
@ravicious ravicious changed the title Remove findDOMNode usage Remove findDOMNode usage from Modal and Popover Sep 5, 2024
@ravicious ravicious marked this pull request as ready for review September 5, 2024 16:18
@ravicious ravicious requested a review from bl-nero September 5, 2024 16:18
@ravicious ravicious removed the request for review from gzdunek September 5, 2024 16:19
Comment thread web/packages/design/src/Modal/Modal.tsx Outdated
* The `reason` parameter can optionally be used to control the response to `onClose`.
*/
onClose?: (
event: React.UIEvent,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Depending on whether it was due to a click or keypress, the handler gets either a React event, or a native event (look how the event handlers are attached).

Comment thread web/packages/design/src/Modal/Modal.tsx
Comment thread web/packages/design/src/Modal/Modal.tsx
Comment thread web/packages/design/src/Modal/Modal.tsx Outdated
modalCss?: StyleFunction<any>;
children?: React.ReactElement;
/**
* Properties applied to the [`Backdrop`](/api/backdrop/) element.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This link is quite possibly some relic of the forked third-party library, can we remove it?

Comment thread web/packages/design/src/Modal/Modal.tsx Outdated
*
* invisible: Boolean - allows backdrop to keep bg color of parent eg: popup menu
*/
BackdropProps?: object;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider extracting { invisible: boolean } from StyledBackdrop props and using it here. Then we can remove the "invisible: Boolean" comment from here and apply it directly as a documentation to the invisible field on the backdrop props.

Comment thread web/packages/design/src/Modal/Modal.tsx
@ravicious ravicious requested a review from bl-nero September 6, 2024 15:22
@ravicious ravicious added this pull request to the merge queue Sep 9, 2024
Merged via the queue into master with commit 50ad928 Sep 9, 2024
@ravicious ravicious deleted the r7s/refactor-modal branch September 9, 2024 12:52
@ravicious
Copy link
Copy Markdown
Member Author

@bl-nero I have to backport this because it's causing problems with certain modals, like the one to delete a notification rule (https://localhost:9002/?path=/story/teleporte-accessrequests-notificationroutingrules--create-and-view-valid-rule, "View" next to a notification rule and then click on the trash icon in the top right). The code goes into an infinite loop when focusing on the dialog el. See the thread on Slack.

mvbrock pushed a commit that referenced this pull request Sep 10, 2024
* Remove disablePortal prop

It was not used within the app anyway

* Get rid of ownerDocument and ownerWindow

The only situation where they'd be needed if we were handling some nodes
between iframes, but we don't use <iframe> even once in our code.
Calls to those functions can be replaced with document and window.

https://stackoverflow.com/questions/9845043/when-node-ownerdocument-is-not-window-document
https://stackoverflow.com/questions/9183555/whats-the-point-of-document-defaultview

* Remove container prop for Modal, replace Portal with createPortal

Initially I wanted to just remove the container prop, but as I sat down
to it, I realized that the whole Portal component is not necessary as
we can just replace it with calling createPortal directly.

The onRendered prop of Portal was never used, rendering the handleRendered
function unnecessary.

Similarly, handlePortalRef was set to the ref prop on Portal. This
function sets mountNode, but after we replaced ownerDocument with document,
it's mountNode is no longer being used.

* Refactor Modal to use TypeScript

* Remove RootRef

dialogRef used to point at the child of StyledModal. To get rid of
findDOMNode, we replaced it by taking children directly from the ref
set on StyledModal.

* Remove findDOMNode from Popover

* Fix types for mouse & keyboard events

* Insert whitespace between prop type declarations

* Remove link from BackdropProps comment

* Extract type for BackdropProps

* Add JSDoc for children prop
mvbrock pushed a commit that referenced this pull request Sep 10, 2024
* Remove disablePortal prop

It was not used within the app anyway

* Get rid of ownerDocument and ownerWindow

The only situation where they'd be needed if we were handling some nodes
between iframes, but we don't use <iframe> even once in our code.
Calls to those functions can be replaced with document and window.

https://stackoverflow.com/questions/9845043/when-node-ownerdocument-is-not-window-document
https://stackoverflow.com/questions/9183555/whats-the-point-of-document-defaultview

* Remove container prop for Modal, replace Portal with createPortal

Initially I wanted to just remove the container prop, but as I sat down
to it, I realized that the whole Portal component is not necessary as
we can just replace it with calling createPortal directly.

The onRendered prop of Portal was never used, rendering the handleRendered
function unnecessary.

Similarly, handlePortalRef was set to the ref prop on Portal. This
function sets mountNode, but after we replaced ownerDocument with document,
it's mountNode is no longer being used.

* Refactor Modal to use TypeScript

* Remove RootRef

dialogRef used to point at the child of StyledModal. To get rid of
findDOMNode, we replaced it by taking children directly from the ref
set on StyledModal.

* Remove findDOMNode from Popover

* Fix types for mouse & keyboard events

* Insert whitespace between prop type declarations

* Remove link from BackdropProps comment

* Extract type for BackdropProps

* Add JSDoc for children prop
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-changelog Indicates that a PR does not require a changelog entry size/sm ui

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants