Skip to content

Commit

Permalink
Only conditionally render most of content action dropdown and workaro…
Browse files Browse the repository at this point in the history
…und for tippy warning (#2422)

* Avoid destroyed tippy warning

Tippy doesn't remove its onDocumentPress listener when destroyed.
Instead the listener removes itself after calling hide for hideOnClick.

It doesn't look like there is a way to reliable work around this.

This skips the warning for the first hide call on a destroyed tippy
instance.

Cleanup is only performed after at least ten tippy instances have been
created.

* Hide tooltips for elements that are no longer connected to the document

* Only render action modals after first show

* Only render action dropdown after first show

* Modals fix for quick unmount

Modals use `await import("bootstrap/js/dist/modal")` when being mounted.
This means its possible that the component unmounts before the promise
resolves.

* bind() dropdown toggle click handler

* Modal mixin
  • Loading branch information
matc-pub authored Apr 13, 2024
1 parent 6e33395 commit fdeb924
Show file tree
Hide file tree
Showing 7 changed files with 504 additions and 456 deletions.
48 changes: 11 additions & 37 deletions src/shared/components/common/confirmation-modal.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
import { Component, RefObject, createRef, linkEvent } from "inferno";
import {
Component,
InfernoNode,
RefObject,
createRef,
linkEvent,
} from "inferno";
import { I18NextService } from "../../services";
import type { Modal } from "bootstrap";
import { Spinner } from "./icon";
import { LoadingEllipses } from "./loading-ellipses";
import { modalMixin } from "../mixins/modal-mixin";

interface ConfirmationModalProps {
children?: InfernoNode;
onYes: () => Promise<void>;
onNo: () => void;
message: string;
Expand All @@ -22,13 +30,14 @@ async function handleYes(i: ConfirmationModal) {
i.setState({ loading: false });
}

@modalMixin
export default class ConfirmationModal extends Component<
ConfirmationModalProps,
ConfirmationModalState
> {
readonly modalDivRef: RefObject<HTMLDivElement>;
readonly yesButtonRef: RefObject<HTMLButtonElement>;
modal: Modal;
modal?: Modal;
state: ConfirmationModalState = {
loading: false,
};
Expand All @@ -38,41 +47,6 @@ export default class ConfirmationModal extends Component<

this.modalDivRef = createRef();
this.yesButtonRef = createRef();

this.handleShow = this.handleShow.bind(this);
}

async componentDidMount() {
this.modalDivRef.current?.addEventListener(
"shown.bs.modal",
this.handleShow,
);

const Modal = (await import("bootstrap/js/dist/modal")).default;
this.modal = new Modal(this.modalDivRef.current!);

if (this.props.show) {
this.modal.show();
}
}

componentWillUnmount() {
this.modalDivRef.current?.removeEventListener(
"shown.bs.modal",
this.handleShow,
);

this.modal.dispose();
}

componentDidUpdate({ show: prevShow }: ConfirmationModalProps) {
if (!!prevShow !== !!this.props.show) {
if (this.props.show) {
this.modal.show();
} else {
this.modal.hide();
}
}
}

render() {
Expand Down
Loading

0 comments on commit fdeb924

Please sign in to comment.