[$250] mWeb – Chat – Blue frame appears around + button when open conversation link URL in a new tab
If you haven’t already, check out our contributing guidelines for onboarding and email [email protected] to request to join our Slack channel!
Version Number: 9.0.11-2 Reproducible in staging?: Y Reproducible in production?: N If this was caught during regression testing, add the test name, ID and link from TestRail: N/A Issue reported by: Applause - Internal Team
Action Performed:
- Go to https://staging.new.expensify.com/
- Log in with Gmail account
- Open any chat and copy URL
- Open new tab and paste URL
Expected Result:
Chat opens without blue frame around + button
Actual Result:
Chat opens with blue frame around + button
Workaround:
Unknown
Platforms:
Which of our officially supported platforms is this issue occurring on?
- [ ] Android: Native
- [x] Android: mWeb Chrome
- [ ] iOS: Native
- [ ] iOS: mWeb Safari
- [ ] MacOS: Chrome / Safari
- [ ] MacOS: Desktop
Screenshots/Videos
Add any screenshot/video evidence
https://github.com/user-attachments/assets/369832a2-8e5f-4180-b1c0-e23e7f9d8299
Upwork Automation - Do Not Edit
- Upwork Job URL: https://www.upwork.com/jobs/~011ced2d499965abe3
- Upwork Job ID: 1816181351346781688
- Last Price Increase: 2024-08-21
- Automatic offers:
- tsa321 | Contributor | 103953960
Issue Owner
Current Issue Owner: @sobitneupane
Triggered auto assignment to @srikarparsi (DeployBlockerCash), see https://stackoverflowteams.com/c/expensify/questions/9980/ for more details.
:wave: Friendly reminder that deploy blockers are time-sensitive ⏱ issues! Check out the open `StagingDeployCash` deploy checklist to see the list of PRs included in this release, then work quickly to do one of the following:
- Identify the pull request that introduced this issue and revert it.
- Find someone who can quickly fix the issue.
- Fix the issue yourself.
We think that this bug might be related to #vip-vsp
Issue is not reproducible on Production:
https://github.com/user-attachments/assets/80605f58-1968-445c-aa67-9a1b290d0f6b
Possibly related to https://github.com/Expensify/App/pull/45743 (?) Anyway, doesn't look like something worth blocking for – going to demote.
Job added to Upwork: https://www.upwork.com/jobs/~011ced2d499965abe3
Triggered auto assignment to Contributor-plus team member for initial proposal review - @sobitneupane (External)
Hi @tsa321 @hoangzinh, if you have a second, do you think you could check if this issue is related to https://github.com/Expensify/App/pull/45743
@srikarparsi, I have tried reverting my PR, but this issue is still reproducible.
Edited by proposal-police: This proposal was edited at 2024-08-13 12:48:11 UTC.
Proposal
Please re-state the problem that we are trying to solve in this issue.
Blue border appears on + button when user open report by url
What is the root cause of that problem?
We use focusTrap to maintain tab navigation. When a user visits a page via URL, focusTrap initially focuses on the tabbable element, causing the blue border to appear. This issue is not limited to the report page; it occurs on several other pages as well, such as the About page, Profile page, Workspace List page, and briefly in the display name field, etc
What changes do you think we should make in order to solve the problem?
We can disable the blue border using CSS styling when the page loads. We can then enable the blue border only when the user presses the Tab key. If any other key is pressed, we should disable the blue border again. The code could be:
let sheet;
const mangaeFocusedElementBlueBorder = () => {
if (!document?.body) {
return;
}
sheet = document.createElement('style');
sheet.innerHTML = '[tabindex="0"]:focus{box-shadow: none; outline: none;}'
document.body.appendChild(sheet);
window.addEventListener('keydown', (e) => {
if (e.key === 'Tab' || e.key === 'Shift') {
if (e.key === 'Tab' && !!sheet.parentNode) {
sheet.parentNode.removeChild(sheet);
}
} else if (!sheet.parentNode) {
document.body.appendChild(sheet);
}
}, true);
}
We could place it in the Accessbility library
For the css selector, we could use *:focus instead of [tabindex="0"]:focus
What alternative solutions did you explore? (Optional)
In the FocusTrapForScreen option:
https://github.com/Expensify/App/blob/59741d821263569f72a8c6a6ab7c03825e7acda4/src/components/FocusTrap/FocusTrapForScreen/index.web.tsx#L44-L45
we could add an onActivate property with the function: () => document?.activeElement?.blur(). Then, in initialFocus:
https://github.com/Expensify/App/blob/59741d821263569f72a8c6a6ab7c03825e7acda4/src/components/FocusTrap/FocusTrapForScreen/index.web.tsx#L49-L59
we should always return false there.
The focus trap already listens for the focus event and will check whether the focused element is inside the element to which it is attached (in this case, inside the screen) and will automatically move the focus inside the screen if it is outside.
What alternative solutions did you explore? (2)
To also fix this in strict mode, we could add activeElementRef and include onActivate and onDeactivate options in focusTrapOptions. In onActivate, we store the current active element in the ref, then blur it; in onDeactivate, we focus that element or if don't want to return the we don't need the onDeactivate callback. We must also set initialFocus and setReturnFocus to always return false. I have created a test branch to highlight the code changes.
Thanks for your proposal @tsa321
Can you please elaborate the root cause section of your proposal?
When a user visits a page via URL, focusTrap initially focuses on the tabbable element, causing the blue border to appear.
Can you please link the code which implements above feature? Let's try to investigate more on the root cause.
Why is the issue limited to some pages only?
@sobitneupane,
Here:
https://github.com/Expensify/App/blob/08bb00b2dc515bb1da2e70f9b9eae9d522c3be50/src/components/FocusTrap/FocusTrapForScreen/index.web.tsx#L45-L54
In the initialFocus of focusTrap, if the return value is false, the focusTrap will not automatically focus on a tabbable element inside the screen. However, if the return value is undefined, the focusTrap will focus on an element inside it.
(Assuming the return value of initialFocus is undefined.) When a user opens a page by clicking a button, the blue border won't appear. However, when the user refreshes the page or opens it by pressing a keyboard key (for example, pressing Enter on a button), the blue border will appear. This is the default behavior of web browsers for tab navigation.
@sobitneupane, @srikarparsi Uh oh! This issue is overdue by 2 days. Don't forget to update your issues!
Hi @sobitneupane, any updates here?
There is a bug in #46075 that seems to have the same cause as this one. Let's fix them together in this one.
Thanks for the update @tsa321
This PR adds the focus trap in the app.
Will your proposal resolve https://github.com/Expensify/App/issues/46075 issue as well? What is RCA for https://github.com/Expensify/App/issues/46075?
Are there any other ways to show the outline only if interacted through keyboard? If I am not wrong, focus-visible outlines only if interaction is made through keyboard.
📣 It's been a week! Do we have any satisfactory proposals yet? Do we need to adjust the bounty for this issue? 💸
@sobitneupane
Will your proposal resolve the issue at https://github.com/Expensify/App/issues/46075 as well? What is the root cause analysis (RCA) for https://github.com/Expensify/App/issues/46075?
Yes, my proposal will address that issue as well. The root cause analysis (RCA) for #46075 indicates that the blue border only appears when something is typed in the search box, but it won't appear if you immediately click on the concierge chat without typing. This issue could be related to browser behavior involving typing.
Are there any other ways to show the outline only if interacted with through the keyboard? If I’m not mistaken,
focus-visibleoutlines only appear with keyboard interaction.
Currently, browser behavior for focus is similar to focus-visible. Before focus-visible, the browser use focus behavior, the browser would show the blue border even on mouse clicks. However, with focus-visible, the blue border only appears if the event prior to the focus is from keyboard interaction or other criteria (which is not from mouse click). If the event is from a mouse click or other criteria, the blue border will not be displayed.
Thanks for the update @tsa321
Your proposal will probably solve the issue. . However, I believe we should avoid a workaround if possible. The change was introduced by this PR, authored by @adamgrzybowski and @jnowakow
@adamgrzybowski @jnowakow, any suggestions?
📣 It's been a week! Do we have any satisfactory proposals yet? Do we need to adjust the bounty for this issue? 💸
Hey @sobitneupane, @jnowakow who was the main creator of PR for Focus Trap is currently OOO. From my point of view, I can only agree that we should avoid workarounds, but I currently have no alternative.
@sobitneupane, @srikarparsi Uh oh! This issue is overdue by 2 days. Don't forget to update your issues!
Thanks @adamgrzybowski
@sobitneupane, @srikarparsi Whoops! This issue is 2 days overdue. Let's get this updated quick!
Waiting for proposal.
Proposal
updated on alternative solution.
@sobitneupane In the FocusTrapForScreen option:
https://github.com/Expensify/App/blob/59741d821263569f72a8c6a6ab7c03825e7acda4/src/components/FocusTrap/FocusTrapForScreen/index.web.tsx#L44-L45
we could add an onActivate property with the function: () => document?.activeElement?.blur(). Then, in initialFocus:
https://github.com/Expensify/App/blob/59741d821263569f72a8c6a6ab7c03825e7acda4/src/components/FocusTrap/FocusTrapForScreen/index.web.tsx#L49-L59
we should always return false there.
The focus trap already listens for the focus event and will check whether the focused element is outside the element to which it is attached (in this case, inside the screen) and will automatically move the focus inside the screen if it is outside.
Thanks for the update @tsa321
The change you suggested might recreate some issue, https://github.com/Expensify/App/pull/39520 PR is trying to solve. For example: Focus remains on the report when navigated to RHP with keyboard.
https://github.com/user-attachments/assets/612a6320-02f6-424a-bb8e-691a4c45823d
@sobitneupane by adding onActivate property to in focusTrap option: () => document?.activeElement?.blur() the active element will be document body.
the blue border won't show up in the report
@tsa321, I tried but It didn't work for me. I might have missed something. Is it working on your end?
@sobitneupane it is working as expected for me:
https://github.com/user-attachments/assets/05680e08-1c6e-461c-80c9-3bb565082ac0
The code change is :
in FocusTrapForScreen/index.web.tsx :
focusTrapOptions={{
+ onActivate: () => {
+ document?.activeElement?.blur();
+ },
trapStack: sharedTrapStack,
allowOutsideClick: true,
fallbackFocus: document.body,
delayInitialFocus: CONST.ANIMATED_TRANSITION,
initialFocus: (focusTrapContainers) => {
- if (!canFocusInputOnScreenFocus()) {
- return false;
- }
- const isFocusedElementInsideContainer = focusTrapContainers?.some((container) => container.contains(document.activeElement));
- if (isFocusedElementInsideContainer) {
- return false;
- }
- return undefined;
+ return false;
},
- setReturnFocus: (element) => {
- if (document.activeElement && document.activeElement !== document.body) {
- return false;
- }
- return element;
- },
...(focusTrapSettings?.focusTrapOptions ?? {}),
}}
The removal of setReturnFocus is to make the focus return to last focused element in previous screen, it is optional.