From 64ac9a54fea0e7c2aa4838cc304a3570b0637bc8 Mon Sep 17 00:00:00 2001 From: Stefan Cameron Date: Sat, 11 Dec 2021 15:35:54 -0600 Subject: [PATCH] [#539] Delay trap creation until it should be active Fixes #539 --- .changeset/neat-sheep-cheer.md | 5 +++++ src/focus-trap-react.js | 29 +++++++++++++++++++++++++---- 2 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 .changeset/neat-sheep-cheer.md diff --git a/.changeset/neat-sheep-cheer.md b/.changeset/neat-sheep-cheer.md new file mode 100644 index 00000000..8478c6f6 --- /dev/null +++ b/.changeset/neat-sheep-cheer.md @@ -0,0 +1,5 @@ +--- +'focus-trap-react': minor +--- + +Delay trap creation until it should be active. This is a change in behavior, however it should not break existing behavior. The delay now allows you to set `active=false` until you have the `focusTrapOptions` set correctly. [#539](https://github.com/focus-trap/focus-trap-react/issues/539) diff --git a/src/focus-trap-react.js b/src/focus-trap-react.js index 36703081..d2e1cead 100644 --- a/src/focus-trap-react.js +++ b/src/focus-trap-react.js @@ -172,7 +172,14 @@ class FocusTrap extends React.Component { } componentDidMount() { - this.setupFocusTrap(); + if (this.props.active) { + this.setupFocusTrap(); + } + // else, wait for later activation in case the `focusTrapOptions` will be updated + // again before the trap is activated (e.g. if waiting to know what the document + // object will be, so the Trap must be rendered, but the consumer is waiting to + // activate until they have obtained the document from a ref) + // @see https://github.com/focus-trap/focus-trap-react/issues/539 } componentDidUpdate(prevProps) { @@ -203,9 +210,23 @@ class FocusTrap extends React.Component { if (hasUnpaused) { this.focusTrap.unpause(); } - } else if (prevProps.containerElements !== this.props.containerElements) { - this.focusTrapElements = this.props.containerElements; - this.setupFocusTrap(); + } else { + // NOTE: if we're in `componentDidUpdate` and we don't have a trap yet, + // it either means it shouldn't be active, or it should be but none of + // of given `containerElements` were present in the DOM the last time + // we tried to create the trap + + if (prevProps.containerElements !== this.props.containerElements) { + this.focusTrapElements = this.props.containerElements; + } + + // don't create the trap unless it should be active in case the consumer + // is still updating `focusTrapOptions` + // @see https://github.com/focus-trap/focus-trap-react/issues/539 + if (this.props.active) { + this.updatePreviousElement(); + this.setupFocusTrap(); + } } }