-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
Add focus trap to the RHP (v3) #32800
Closed
kosmydel
wants to merge
16
commits into
Expensify:main
from
software-mansion-labs:@kosmydel/add-focus-trap-3
Closed
Changes from 10 commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
9de54e5
Revert "Revert "Add focus trap to the RHP (v2)""
kosmydel dff444b
update focus-trap-react
kosmydel e1691d1
fix regressions
kosmydel 09989cb
Merge branch 'main' into @kosmydel/lottie-prefetching
kosmydel b6a31da
Merge branch 'main' into @kosmydel/add-focus-trap-3
kosmydel f3817cf
fix another issues
kosmydel 7caaffa
Merge branch 'main' into @kosmydel/add-focus-trap-3
kosmydel 6d3d5e9
Merge branch 'main' into @kosmydel/add-focus-trap-3
kosmydel 3dc8501
Merge branch 'main' into @kosmydel/add-focus-trap-3
kosmydel 469188d
fix types
kosmydel b9ec1e8
address review
kosmydel 59332b3
Merge branch 'main' into @kosmydel/add-focus-trap-3
kosmydel 49a2bbe
Merge branch 'main' into @kosmydel/add-focus-trap-3
kosmydel cebcb83
Merge branch 'main' into @kosmydel/add-focus-trap-3
kosmydel 7af15e6
Merge branch 'main' into @kosmydel/add-focus-trap-3
kosmydel 14799fc
fix merge
kosmydel File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import type FocusTrapViewProps from './types'; | ||
|
||
/* | ||
* The FocusTrap is only used on web and desktop | ||
*/ | ||
function FocusTrapView({children}: FocusTrapViewProps) { | ||
return children; | ||
} | ||
|
||
FocusTrapView.displayName = 'FocusTrapView'; | ||
|
||
export default FocusTrapView; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/* | ||
* The FocusTrap is only used on web and desktop | ||
*/ | ||
import FocusTrap from 'focus-trap-react'; | ||
import React, {useRef} from 'react'; | ||
import {View} from 'react-native'; | ||
import viewRef from '@src/types/utils/viewRef'; | ||
import type FocusTrapViewProps from './types'; | ||
|
||
function FocusTrapView({isEnabled = true, isActive = true, shouldEnableAutoFocus = false, shouldReturnFocusOnDeactivate = true, ...props}: FocusTrapViewProps) { | ||
/** | ||
* Focus trap always needs a focusable element. | ||
* In case that we don't have any focusable elements in the modal, | ||
* the FocusTrap will use fallback View element using this ref. | ||
*/ | ||
const ref = useRef<HTMLDivElement>(null); | ||
|
||
return isEnabled ? ( | ||
<FocusTrap | ||
active={isActive} | ||
focusTrapOptions={{ | ||
initialFocus: () => (shouldEnableAutoFocus && ref.current) ?? false, | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
fallbackFocus: () => ref.current!, | ||
clickOutsideDeactivates: true, | ||
returnFocusOnDeactivate: shouldReturnFocusOnDeactivate, | ||
}} | ||
> | ||
<View | ||
ref={viewRef(ref)} | ||
tabIndex={0} | ||
// eslint-disable-next-line react/jsx-props-no-spreading | ||
{...props} | ||
/> | ||
</FocusTrap> | ||
) : ( | ||
props.children | ||
); | ||
} | ||
|
||
FocusTrapView.displayName = 'FocusTrapView'; | ||
|
||
export default FocusTrapView; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import type {ViewProps} from 'react-native'; | ||
import type ChildrenProps from '@src/types/utils/ChildrenProps'; | ||
|
||
type FocusTrapViewProps = ChildrenProps & { | ||
/** | ||
* Whether to enable the FocusTrap. | ||
* If the FocusTrap is disabled, we just pass the children through. | ||
*/ | ||
isEnabled?: boolean; | ||
|
||
/** | ||
* Whether to disable auto focus | ||
* It is used when the component inside the FocusTrap have their own auto focus logic | ||
*/ | ||
shouldEnableAutoFocus?: boolean; | ||
|
||
/** Whether the FocusTrap is active (listening for events) */ | ||
isActive?: boolean; | ||
|
||
/** | ||
* Whether the FocusTrap should return focus to the last focused element when it is deactivated. | ||
* The default value is True, but sometimes we have to disable it, as it causes unexpected behavior. | ||
*/ | ||
shouldReturnFocusOnDeactivate?: boolean; | ||
} & ViewProps; | ||
|
||
export default FocusTrapViewProps; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's avoid disabling this lint rule
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change was discussed here. I'm not sure if we can find a better approach. We need to pass here a function (which can't return null/undefined), but during the initial function call the
ref.current
is null.An alternative is, passing an empty string, but not sure if we have any gain from this approach: