Skip to main content

Migrate TrapFocus from Polaris React

Remove TrapFocus around migrated Polaris overlays because the destination manages focus. Keep a custom trap only as part of a complete accessible custom dialog.


Anchor to Choose the destinationChoose the destination

Polaris ReactPolaris web componentsMigration type
TrapFocusRemove for Polaris overlays. Keep an accessible focus trap only for custom dialogs.Remove

Anchor to Map focus-trap responsibilitiesMap focus-trap responsibilities

Polaris ReactPolaris web componentsMigration notes
trapping around a modals-modalRemove the wrapper and verify focus enters, remains within, and returns to the trigger.
trapping around a popovers-popoverUse the destination interaction model instead of forcing modal behavior.
Custom dialog contentComplete accessible custom dialog implementationKeep a trap only when you also own labelling, dismissal, inert background behavior, and focus restoration.

Anchor to Migrate the call siteMigrate the call site

  1. Find every TrapFocus consumer and identify which behavior, if any, still depends on it.

  2. Migrate those dependent components or behaviors first.

  3. Delete TrapFocus and its now-unused state or helper code once it has no remaining responsibility.

  4. Verify the containing workflow without the removed layer.


Anchor to Preserve these behaviorsPreserve these behaviors

  • Any user-visible behavior that was coupled to the removed component.
  • Behavior of remaining descendants, including focus, scrolling, overlays, or context where relevant.
  • Test setup and cleanup paths that referenced the removed layer.

Anchor to Test and remove Polaris ReactTest and remove Polaris React

Test the workflows that formerly depended on TrapFocus. Verify remaining descendants render correctly and that focus, scrolling, overlays, and test setup no longer rely on the removed layer.

Don't remove @shopify/polaris while another component still imports it. Once all call sites are migrated, remove the package and its provider-level setup, then run the app's full test suite.


Migrating TrapFocus

export function TrapFocusMigrationExample() {
return (
<>
<s-button commandFor="focus-modal" command="--show">
Open dialog
</s-button>
<s-modal id="focus-modal" heading="Confirm changes">
<s-paragraph>Review the changes before continuing.</s-paragraph>
<s-button
slot="primary-action"
variant="primary"
commandFor="focus-modal"
command="--hide"
>
Continue
</s-button>
</s-modal>
</>
);
}
import {Button, Modal, TrapFocus} from '@shopify/polaris';
import {useState} from 'react';


export function TrapFocusMigrationExample() {
const [open, setOpen] = useState(false);

return (
<>
<Button onClick={() => setOpen(true)}>Open dialog</Button>
<Modal open={open} onClose={() => setOpen(false)} title="Confirm changes">
<TrapFocus trapping>
<Button onClick={() => setOpen(false)}>Continue</Button>
</TrapFocus>
</Modal>
</>
);
}

Preview


Was this page helpful?