-
Notifications
You must be signed in to change notification settings - Fork 3k
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
fix: prevent parent view scroll when press space bar and arrow #56435
base: main
Are you sure you want to change the base?
fix: prevent parent view scroll when press space bar and arrow #56435
Conversation
@DylanDylann Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button] |
src/CONST.ts
Outdated
shortcutKey: 'Space', | ||
modifiers: [], | ||
trigger: { | ||
DEFAULT: {input: ' '}, |
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.
- Do we need to add some options for IOS/MACOS platform?
- Please use constant like keyInputLeftArrow, keyInputRightArrow instead of hardcode
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.
- I see that the input value is the same for iOS/macOS, so I don't think it's necessary to add it.
- Same answer as below: KeyCommand does not have a space input. Can I update the name to keyInputSpace = ' ' instead?
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.
I see that the input value is the same for iOS/macOS
@linhvovan29546 Could you give an reference to this point?
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.
I don't have a reference, but I've tested pressing space, and the useKeyboardShortcut returns a callback
src/libs/KeyboardShortcut/index.ts
Outdated
@@ -42,7 +42,7 @@ const keyInputUpArrow = KeyCommand?.constants?.keyInputUpArrow?.toString() ?? 'k | |||
const keyInputDownArrow = KeyCommand?.constants?.keyInputDownArrow?.toString() ?? 'keyInputDownArrow'; | |||
const keyInputLeftArrow = KeyCommand?.constants?.keyInputLeftArrow?.toString() ?? 'keyInputLeftArrow'; | |||
const keyInputRightArrow = KeyCommand?.constants?.keyInputRightArrow?.toString() ?? 'keyInputRightArrow'; | |||
|
|||
const keySpace = ' '; |
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.
Please using constant as above definition
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.
KeyCommand
does not have a space input. Can I update the name to keyInputSpace = ' '
instead?
const keyboardShortcutSpaceCallback = useCallback(() => { | ||
if (!scrollViewRef.current) { | ||
return; | ||
} | ||
const scrollableElement = scrollViewRef.current as HTMLDivElement; | ||
// If the popover menu is scrollable, allow scrolling with the space bar instead of preventing it. | ||
const clientHeight = scrollableElement.clientHeight; | ||
const scrollTop = scrollableElement.scrollTop; | ||
const scrollHeight = scrollableElement.scrollHeight; | ||
const remainingScrollSpace = scrollHeight - clientHeight - scrollTop; | ||
|
||
scrollableElement.scrollBy(0, Math.min(clientHeight, remainingScrollSpace)); | ||
}, []); |
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.
I think we only need e.preventDefault in this callback, right?
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.
By default, we called e.preventDefault in KeyboardShortcut.subscribe
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.
Why do we need to call scrollableElement.scrollBy
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.
The PopoverMenu
supports scrolling if shouldUseScrollView
is true
. However, preventing the space key will also prevent scrolling within the PopOverMenu
. To avoid this, I handle scrolling manually instead. Wdyt?
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.
@linhvovan29546 Could you help to point out a specific case that has shouldUseScrollView
is true? I think it will be weird when there are 2 scrolling in the same time. Thus, to make it simpler, should we call e.preventDefault only when shouldUseScrollView is false?
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.
If we call e.preventDefault only when shouldUseScrollView is false, the issue still exists. For example, see the case below. Note: I have set shouldUseScrollView
to true for testing
Screen.Recording.2025-02-11.at.3.11.01.PM.mov
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.
I have an idea based on useBottomTabIsFocused. I'll update it
I've updated and replied to the review change. |
src/hooks/useScrollEnabled/index.ts
Outdated
const useScrollEnabled: UseScrollEnabled = () => { | ||
const isFocused = useIsFocused(); | ||
const prevIsFocused = usePrevious(isFocused); | ||
return !(prevIsFocused && !isFocused); |
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.
return !(prevIsFocused && !isFocused); | |
return !prevIsFocused || isFocused); |
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.
More readable
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.
My code is not working when isFocused re-renders twice, causing !(prevIsFocused && !isFocused) to return true even when the screen is not focused. I'll revert to the previous code.
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.
@DylanDylann I noticed that isFocused remains false when calling const isFocused = useIsFocused(); inside the bottom tab, which causes scrolling to be disabled. Do you have any ideas on how to fix this?
const keyboardShortcutSpaceCallback = useCallback(() => { | ||
if (!scrollViewRef.current) { | ||
return; | ||
} | ||
const scrollableElement = scrollViewRef.current as HTMLDivElement; | ||
// If the popover menu is scrollable, allow scrolling with the space bar instead of preventing it. | ||
const clientHeight = scrollableElement.clientHeight; | ||
const scrollTop = scrollableElement.scrollTop; | ||
const scrollHeight = scrollableElement.scrollHeight; | ||
const remainingScrollSpace = scrollHeight - clientHeight - scrollTop; | ||
|
||
scrollableElement.scrollBy(0, Math.min(clientHeight, remainingScrollSpace)); | ||
}, []); |
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.
@linhvovan29546 Could you help to point out a specific case that has shouldUseScrollView
is true? I think it will be weird when there are 2 scrolling in the same time. Thus, to make it simpler, should we call e.preventDefault only when shouldUseScrollView is false?
Explanation of Change
Fixed Issues
$ #55832
PROPOSAL: #55832 (comment)
Tests
Precond: User has a long Workspace list
Precond: User has a long list
We can apply this test to other lists as well
Offline tests
Same Test above
QA Steps
Same Test above
PR Author Checklist
### Fixed Issues
section aboveTests
sectionOffline steps
sectionQA steps
sectiontoggleReport
and notonIconClick
)src/languages/*
files and using the translation methodSTYLE.md
) were followedAvatar
, I verified the components usingAvatar
are working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG)
)Avatar
is modified, I verified thatAvatar
is working as expected in all cases)Design
label and/or tagged@Expensify/design
so the design team can review the changes.ScrollView
component to make it scrollable when more elements are added to the page.main
branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTest
steps.Screenshots/Videos
Android: Native
This change only apply for web and desktop
Android: mWeb Chrome
Screen.Recording.2025-02-10.at.8.52.20.PM.mov
iOS: Native
This change only apply for web and desktop
iOS: mWeb Safari
Screen.Recording.2025-02-10.at.7.14.19.PM.mov
MacOS: Chrome / Safari
Screen.Recording.2025-02-06.at.7.41.49.AM.mov
Screen.Recording.2025-02-06.at.7.44.16.AM.mov
Screen.Recording.2025-02-06.at.7.44.51.AM.mov
MacOS: Desktop
Screen.Recording.2025-02-06.at.7.48.23.AM.mov