diff --git a/packages/ui-modal/src/Modal/v1/index.tsx b/packages/ui-modal/src/Modal/v1/index.tsx index 366541e29e..ec2e14026a 100644 --- a/packages/ui-modal/src/Modal/v1/index.tsx +++ b/packages/ui-modal/src/Modal/v1/index.tsx @@ -107,6 +107,14 @@ class Modal extends Component { componentDidUpdate(prevProps: ModalProps) { if (this.props.open !== prevProps.open) { this.setState({ transitioning: true, open: !!this.props.open }) + // When closing, release focus from the Dialog. + // The Dialog stays open so its content can fade out, but the + // Transition marks the exiting subtree aria-hidden -- keeping focus inside + // it would hide a focused element from assistive tech resulting in a + // console warning + if (prevProps.open && !this.props.open) { + this._content?.blur() + } } this.props.makeStyles?.() } @@ -284,31 +292,31 @@ class Modal extends Component { onOpen={this.handlePortalOpen} data-cid="Modal" > - + this.setState({ bodyScrollAriaLabel: txt }) + }} > - - this.setState({ bodyScrollAriaLabel: txt }) - }} + {constrain === 'parent' ? ( @@ -317,8 +325,8 @@ class Modal extends Component { ) : ( this.renderDialog(passthroughProps) )} - - + + ) } diff --git a/packages/ui-modal/src/Modal/v2/README.md b/packages/ui-modal/src/Modal/v2/README.md index 27e3f7d192..b690729e49 100644 --- a/packages/ui-modal/src/Modal/v2/README.md +++ b/packages/ui-modal/src/Modal/v2/README.md @@ -618,16 +618,14 @@ You can do this with the `insertAt` prop or a theme override: type: code --- + themeOverride={{ + components: { + Mask: { + zIndex: 555 + } + } + }} +> ``` diff --git a/packages/ui-modal/src/Modal/v2/index.tsx b/packages/ui-modal/src/Modal/v2/index.tsx index f301d08c3a..37950b4c2a 100644 --- a/packages/ui-modal/src/Modal/v2/index.tsx +++ b/packages/ui-modal/src/Modal/v2/index.tsx @@ -106,6 +106,14 @@ class Modal extends Component { componentDidUpdate(prevProps: ModalProps) { if (this.props.open !== prevProps.open) { this.setState({ transitioning: true, open: !!this.props.open }) + // When closing, release focus from the Dialog. + // The Dialog stays open so its content can fade out, but the + // Transition marks the exiting subtree aria-hidden -- keeping focus inside + // it would hide a focused element from assistive tech resulting in a + // console warning + if (prevProps.open && !this.props.open) { + this._content?.blur() + } } this.props.makeStyles?.() } @@ -205,8 +213,7 @@ class Modal extends Component { | keyof ModalPropsForTransition | 'constrain' | 'overflow' - >, - open?: boolean + > ) { const { onDismiss, @@ -225,7 +232,7 @@ class Modal extends Component { { onOpen={this.handlePortalOpen} data-cid="Modal" > - + this.setState({ bodyScrollAriaLabel: txt }) + }} > - - this.setState({ bodyScrollAriaLabel: txt }) - }} + {constrain === 'parent' ? ( - {this.renderDialog(passthroughProps, open)} + {this.renderDialog(passthroughProps)} ) : ( - this.renderDialog(passthroughProps, open) + this.renderDialog(passthroughProps) )} - - + + ) } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4fd8f8bb6c..83d0917a36 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8495,6 +8495,11 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + baseline-browser-mapping@2.10.38: + resolution: {integrity: sha512-31/02mVB4yuQU6adKk5SlY6m+mxDwUq5KZkyYgnLrrKl7TEm1+3PyDtDBz2kOv/wxZz41GHsvV1A/u6RmiyBvw==} + engines: {node: '>=6.0.0'} + hasBin: true + basic-auth@2.0.1: resolution: {integrity: sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==} engines: {node: '>= 0.8'} @@ -8571,6 +8576,11 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + browserslist@4.28.4: + resolution: {integrity: sha512-MTc8i/x9jBQd1iMw2CFGS+rwMa07eYjLR0CCTLDACl9xhxy+nIs3KeML/biicXtk9JrZ6dnnTatmc7ErPXIxqw==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + buffer-alloc-unsafe@1.1.0: resolution: {integrity: sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==} @@ -8679,6 +8689,9 @@ packages: caniuse-lite@1.0.30001784: resolution: {integrity: sha512-WU346nBTklUV9YfUl60fqRbU5ZqyXlqvo1SgigE1OAXK5bFL8LL9q1K7aap3N739l4BvNqnkm3YrGHiY9sfUQw==} + caniuse-lite@1.0.30001799: + resolution: {integrity: sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw==} + capture-stack-trace@1.0.2: resolution: {integrity: sha512-X/WM2UQs6VMHUtjUDnZTRI+i1crWteJySFzr9UpGoQa4WQffXVTTXuekjl7TjZRlcF2XfjgITT0HxZ9RnxeT0w==} engines: {node: '>=0.10.0'} @@ -9483,6 +9496,9 @@ packages: electron-to-chromium@1.5.331: resolution: {integrity: sha512-IbxXrsTlD3hRodkLnbxAPP4OuJYdWCeM3IOdT+CpcMoIwIoDfCmRpEtSPfwBXxVkg9xmBeY7Lz2Eo2TDn/HC3Q==} + electron-to-chromium@1.5.378: + resolution: {integrity: sha512-VinvOAuuPmdD1guEgGv5f2Qp7/vlfqOrUOMYNnOD4wj3pit8kRsQHzfIf6teyUGWo15Tg5+bOJaRunvyltpVWQ==} + emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} @@ -11686,6 +11702,10 @@ packages: node-releases@2.0.37: resolution: {integrity: sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==} + node-releases@2.0.49: + resolution: {integrity: sha512-f06bl1D+8ZDkn2oOQQKAh5/otFWqVnM1Q5oerA8Pex7UfT66Tx4IPHIqVVFKqFT3FUtaDstdgkM7yT7JWhqxfw==} + engines: {node: '>=18'} + nopt@8.1.0: resolution: {integrity: sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==} engines: {node: ^18.17.0 || >=20.5.0} @@ -17462,6 +17482,8 @@ snapshots: baseline-browser-mapping@2.10.13: {} + baseline-browser-mapping@2.10.38: {} + basic-auth@2.0.1: dependencies: safe-buffer: 5.1.2 @@ -17566,6 +17588,14 @@ snapshots: node-releases: 2.0.37 update-browserslist-db: 1.2.3(browserslist@4.28.2) + browserslist@4.28.4: + dependencies: + baseline-browser-mapping: 2.10.38 + caniuse-lite: 1.0.30001799 + electron-to-chromium: 1.5.378 + node-releases: 2.0.49 + update-browserslist-db: 1.2.3(browserslist@4.28.4) + buffer-alloc-unsafe@1.1.0: {} buffer-alloc@1.2.0: @@ -17710,6 +17740,8 @@ snapshots: caniuse-lite@1.0.30001784: {} + caniuse-lite@1.0.30001799: {} + capture-stack-trace@1.0.2: {} case@1.6.3: {} @@ -18606,6 +18638,8 @@ snapshots: electron-to-chromium@1.5.331: {} + electron-to-chromium@1.5.378: {} + emoji-regex@10.6.0: {} emoji-regex@8.0.0: {} @@ -21366,6 +21400,8 @@ snapshots: node-releases@2.0.37: {} + node-releases@2.0.49: {} + nopt@8.1.0: dependencies: abbrev: 3.0.1 @@ -23516,6 +23552,12 @@ snapshots: escalade: 3.2.0 picocolors: 1.1.1 + update-browserslist-db@1.2.3(browserslist@4.28.4): + dependencies: + browserslist: 4.28.4 + escalade: 3.2.0 + picocolors: 1.1.1 + update-notifier@2.5.0: dependencies: boxen: 1.3.0 @@ -23825,7 +23867,7 @@ snapshots: '@webassemblyjs/wasm-parser': 1.14.1 acorn: 8.17.0 acorn-import-phases: 1.0.4(acorn@8.17.0) - browserslist: 4.28.2 + browserslist: 4.28.4 chrome-trace-event: 1.0.4 enhanced-resolve: 5.24.0 es-module-lexer: 2.1.0 @@ -23864,7 +23906,7 @@ snapshots: '@webassemblyjs/wasm-parser': 1.14.1 acorn: 8.17.0 acorn-import-phases: 1.0.4(acorn@8.17.0) - browserslist: 4.28.2 + browserslist: 4.28.4 chrome-trace-event: 1.0.4 enhanced-resolve: 5.24.0 es-module-lexer: 2.1.0