Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[EuiFocusTrap] Default to not trapping focus across iframes #6908

Merged
merged 5 commits into from
Jul 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@
},
"resolutions": {
"**/prismjs": "1.27.0",
"**/react": "^17.0.0"
"**/react": "^17.0.0",
"react-focus-lock": "^2.9.5"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This resolution is necessary as latest react-focus-on still points to 2.9.4 which doesn't yet have the react-focus-lock fix we need (theKashey/react-focus-lock#249). Once react-focus-on updates, we can remove this resolution

},
"pre-commit": [
"test-staged"
Expand All @@ -81,7 +82,7 @@
"react-beautiful-dnd": "^13.1.0",
"react-dropzone": "^11.5.3",
"react-element-to-jsx-string": "^14.3.4",
"react-focus-on": "^3.7.0",
"react-focus-on": "^3.9.1",
Copy link
Contributor Author

@cee-chen cee-chen Jul 10, 2023

Choose a reason for hiding this comment

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

Upgrading to 3.9.1 (from 3.9.0) should contain the fix necessary to resolve #6848 - @tkajtoch, do you think we need to write any specific tests or storybooks to ensure this is the case, or would you be OK with just merging and testing in CodeSandbox after?

"react-input-autosize": "^3.0.0",
"react-is": "^17.0.2",
"react-remove-scroll-bar": "^2.3.4",
Expand Down
26 changes: 16 additions & 10 deletions src-docs/src/views/focus_trap/focus_trap_example.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const FocusTrapExample = {
},
],
text: (
<React.Fragment>
<>
<p>
Use <strong>EuiFocusTrap</strong> to prevent keyboard-initiated
focus from leaving a defined area. Temporary flows and UX escapes
Expand All @@ -37,15 +37,21 @@ export const FocusTrapExample = {
<strong>EuiFocusTrap</strong> will maintain the tab order expected
by users.
</p>
<p>
Use <EuiCode>clickOutsideDisables</EuiCode> to disable the focus
trap when the user clicks outside the trap.
</p>
<p>
Use <EuiCode>noIsolation=false</EuiCode> when pointer events on
outside elements should be disallowed.
</p>
</React.Fragment>
<ul>
<li>
Use <EuiCode>clickOutsideDisables</EuiCode> to disable the focus
trap when the user clicks outside the trap.
</li>
<li>
Use <EuiCode>noIsolation=false</EuiCode> when pointer events on
outside elements should be disallowed.
</li>
<li>
Use <EuiCode>crossFrame=true</EuiCode> when focus should not be
allowed on other iframes on the page.
</li>
</ul>
</>
),
props: { EuiFocusTrap },
demo: <FocusTrap />,
Expand Down
76 changes: 76 additions & 0 deletions src/components/focus_trap/focus_trap.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import type { Meta, StoryObj } from '@storybook/react';
import React, { useState } from 'react';

import { EuiButton } from '../button';
import { EuiFieldText } from '../form';
import { EuiSpacer } from '../spacer';
import { EuiPanel } from '../panel';

import { EuiFocusTrap, EuiFocusTrapProps } from './focus_trap';

const meta: Meta<EuiFocusTrapProps> = {
title: 'EuiFocusTrap',
// @ts-ignore This still works for Storybook controls, even though Typescript complains
component: EuiFocusTrap,
argTypes: {
crossFrame: {
control: { type: 'boolean' },
},
},
};

export default meta;
type Story = StoryObj<EuiFocusTrapProps>;

const StatefulFocusTrap = (props: Partial<EuiFocusTrapProps>) => {
const [disabled, setDisabled] = useState(props.disabled);
return (
<>
<EuiButton size="s" onClick={() => setDisabled(!disabled)}>
Toggle focus trap
</EuiButton>
<EuiSpacer />
<EuiPanel>
<EuiFocusTrap {...props} disabled={disabled}>
Focus trap is currently {disabled ? 'disabled' : 'enabled'}
<EuiFieldText />
<EuiButton size="s">Button inside focus trap</EuiButton>
</EuiFocusTrap>
</EuiPanel>
</>
);
};

export const Playground: Story = {
render: ({ ...args }) => <StatefulFocusTrap {...args} />,
args: {
disabled: true,
},
};

export const Iframe: Story = {
render: ({ ...args }) => (
<>
<EuiFieldText placeholder="Focusable item outside iframe" />
<EuiSpacer />
<EuiPanel>
Iframe content
<iframe
title="crossFrame test"
src={`/iframe.html?id=euifocustrap--playground&crossFrame=${args.crossFrame}`}
style={{ width: '100%', height: 200 }}
sandbox="allow-forms allow-modals allow-popups allow-same-origin allow-scripts allow-downloads allow-storage-access-by-user-activation"
/>
</EuiPanel>
</>
),
args: { disabled: true, crossFrame: false },
};
1 change: 1 addition & 0 deletions src/components/focus_trap/focus_trap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export class EuiFocusTrap extends Component<EuiFocusTrapProps, State> {
returnFocus: true,
noIsolation: true,
scrollLock: false,
crossFrame: false,
gapMode: 'padding', // EUI defaults to padding because Kibana's body/layout CSS ignores `margin`
};

Expand Down
6 changes: 6 additions & 0 deletions upcoming_changelogs/6908.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
- `EuiFocusTrap` now supports configuring cross-iframe focus trapping via the `crossFrame` prop

**Breaking changes**

- `EuiFocusTrap` now defaults to *not* trapping focus across iframes

42 changes: 21 additions & 21 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -9588,10 +9588,10 @@ flush-write-stream@^1.0.0:
inherits "^2.0.1"
readable-stream "^2.0.4"

focus-lock@^0.11.2:
version "0.11.3"
resolved "https://registry.yarnpkg.com/focus-lock/-/focus-lock-0.11.3.tgz#c094e8f109d780f56038abdeec79328fd56b627f"
integrity sha512-4n0pYcPTa/uI7Q66BZna61nRT7lDhnuJ9PJr6wiDjx4uStg491ks41y7uOG+s0umaaa+hulNKSldU9aTg9/yVg==
focus-lock@^0.11.6:
version "0.11.6"
resolved "https://registry.yarnpkg.com/focus-lock/-/focus-lock-0.11.6.tgz#e8821e21d218f03e100f7dc27b733f9c4f61e683"
integrity sha512-KSuV3ur4gf2KqMNoZx3nXNVhqCkn42GuTYCX4tXPEwf0MjpFQmNMiN6m7dXaUXgIoivL6/65agoUMg4RLS0Vbg==
dependencies:
tslib "^2.0.3"

Expand Down Expand Up @@ -16502,26 +16502,26 @@ react-fast-compare@^3.1.1:
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb"
integrity sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==

react-focus-lock@^2.9.2:
version "2.9.2"
resolved "https://registry.yarnpkg.com/react-focus-lock/-/react-focus-lock-2.9.2.tgz#a57dfd7c493e5a030d87f161c96ffd082bd920f2"
integrity sha512-5JfrsOKyA5Zn3h958mk7bAcfphr24jPoMoznJ8vaJF6fUrPQ8zrtEd3ILLOK8P5jvGxdMd96OxWNjDzATfR2qw==
react-focus-lock@2.9.5, react-focus-lock@^2.9.4:
version "2.9.5"
resolved "https://registry.yarnpkg.com/react-focus-lock/-/react-focus-lock-2.9.5.tgz#8a82f4f0128cccc27b9e77a4472e8a22f1b52189"
integrity sha512-h6vrdgUbsH2HeD5I7I3Cx1PPrmwGuKYICS+kB9m+32X/9xHRrAbxgvaBpG7BFBN9h3tO+C3qX1QAVESmi4CiIA==
dependencies:
"@babel/runtime" "^7.0.0"
focus-lock "^0.11.2"
focus-lock "^0.11.6"
prop-types "^15.6.2"
react-clientside-effect "^1.2.6"
use-callback-ref "^1.3.0"
use-sidecar "^1.1.2"

react-focus-on@^3.7.0:
version "3.7.0"
resolved "https://registry.yarnpkg.com/react-focus-on/-/react-focus-on-3.7.0.tgz#bf782b51483d52d1d336b7b09cb864897af26cdf"
integrity sha512-TsCnbJr4qjqFatJ4U1N8qGSZH+FUzxJ5mJ5ta7TY2YnDmUbGGmcvZMTZgGjQ1fl6vlztsMyg6YyZlPAeeIhEUg==
react-focus-on@^3.9.1:
version "3.9.1"
resolved "https://registry.yarnpkg.com/react-focus-on/-/react-focus-on-3.9.1.tgz#449a34ebb487c458d9d5526a74214c408544cfec"
integrity sha512-IYo2j4mgNpZEJNv+/XzZs3S3xhJbR+AFop092h4OMW7sbFpIMVWxp/Z61V/gfpsgOi7VnoSFXP2bfOWWkjjtOw==
dependencies:
aria-hidden "^1.2.2"
react-focus-lock "^2.9.2"
react-remove-scroll "^2.5.5"
react-focus-lock "^2.9.4"
react-remove-scroll "^2.5.6"
react-style-singleton "^2.2.0"
tslib "^2.3.1"
use-callback-ref "^1.3.0"
Expand Down Expand Up @@ -16581,20 +16581,20 @@ react-refresh@^0.11.0:
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.11.0.tgz#77198b944733f0f1f1a90e791de4541f9f074046"
integrity sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==

react-remove-scroll-bar@^2.3.3, react-remove-scroll-bar@^2.3.4:
react-remove-scroll-bar@^2.3.4:
version "2.3.4"
resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.4.tgz#53e272d7a5cb8242990c7f144c44d8bd8ab5afd9"
integrity sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==
dependencies:
react-style-singleton "^2.2.1"
tslib "^2.0.0"

react-remove-scroll@^2.5.5:
version "2.5.5"
resolved "https://registry.yarnpkg.com/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz#1e31a1260df08887a8a0e46d09271b52b3a37e77"
integrity sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==
react-remove-scroll@^2.5.6:
version "2.5.6"
resolved "https://registry.yarnpkg.com/react-remove-scroll/-/react-remove-scroll-2.5.6.tgz#7510b8079e9c7eebe00e65a33daaa3aa29a10336"
integrity sha512-bO856ad1uDYLefgArk559IzUNeQ6SWH4QnrevIUjH+GczV56giDfl3h0Idptf2oIKxQmd1p9BN25jleKodTALg==
dependencies:
react-remove-scroll-bar "^2.3.3"
react-remove-scroll-bar "^2.3.4"
react-style-singleton "^2.2.1"
tslib "^2.1.0"
use-callback-ref "^1.3.0"
Expand Down