How to check a dialog component is on top of dialogs? - reactjs

i am coding a Dialog component, and it will allow to close by pressing the Esc key on the keyboard and it works fine.
The problem I have is when using multiple Dialogs on top of each other, when I press Esc they all get closed while I just want to close the top Dialog one by one.
The point is know the dialog isOnTop or isNotOnTop and blocking keyboard event. I have tried using props drilling to check if DialogB is opened then DialogA isNotOnTop and prevent to closing but with more complex components this method seems difficult.
Can anyone give me some suggestions on how to implement my idea in a better way? I'm a newbie with reactjs, thanks.
This is how the idea looklike: youtube
Below code is written on codesanbox.

I played around a bit. I used zustand.js to store all the opened dialogs.
Every dialog has its own identifier/index. When pressing ESC the dialog checks the open dialogs in the store against its own identifier, like that only the last dialog closes. I used a Set(), so the dialogs are always unique.
I hope that helps.
Here's your modified sandbox.
edit:
(Answering your comment)
This happens because right now the code checks the identifier against the size of the Set. To fix replace this line
if (dialogs.size === identifier && event.keyCode === escapeKeyNumber) {
with
if ([...dialogs].pop() === identifier && event.keyCode === escapeKeyNumber) {
this compares the last entry of the set with the identifier instead of the size of the set.
modified sandbox

Related

Don't show the Next or Done buttons in the Android VKB

How can I prevent the showing of the Next or Done buttons of the Android VKB in a Codename One app?
Currently, for my app, they are a mess: the next button of the VKB doesn't focus the next field, but the previous. After tons of trials, I didn't find a way to make them working correctly (but there are fine on iOS and on the Simulator). I also tried to override the Layout.overridesTabIndices(com.codename1.ui.Container) and Layout.getChildrenInTraversalOrder(com.codename1.ui.Container) methods in the Form, but nothing changed on Android.
I supposed two possible causes: the use of a Form inside a Form or, more probably, the fact that I replace all the TextFields and Pickers in the same Form (and other components). Maybe the fact that the inner Form is deeply changed results in a confusion for the Android mapping of the "next" button.
That's why my request: because I didn't find a way to make the "next" button useful, I'm asking how I can avoid that it's been shown.
Thank you
Nesting forms would probably mess with the focus traversal/tab order.
Normally you should be able to override public TabIterator getTabIterator(Component start) to return a blank iterator. I'd suggest doing the same for both the parent and child form to disable the "next" feature.

Pressing tab key closes Material UI Dialog that is opened from a submenu

I need to create a menubar with a number of menus that have submenus. When I open a dialog from a top level menu item, everything works as desired/expected. BUT when I open a dialog from a submenu, pressing the tab key closes the dialog.
I've tried several different ways of implementing the nested menus and settled on the approach discussed here: https://github.com/mui-org/material-ui/issues/11723
I've created sample code to demonstrate the problem here:
https://codesandbox.io/s/loving-heisenberg-rvwwb
You'll see this is forked from the submenu example I found on GitHub. There were a few things I changed because I wasn't sure how to add the opening of a dialog from that example, so I'm not sure the way I did it is correct.
The problem is that Tab is triggering close of the parent Menu which then causes the Dialog to be unmounted. You could use state to prevent the parent Menu from closing whenever the Dialog is open, but that leaves a different problem. Regardless of whether the parent Menu closes, when a Tab occurs it calls event.preventDefault() which then prevents the Tab from changing the focus location (the default browser behavior).
You can fix this by having the Dialog stop propagation of the Tab key event. This prevents Menu from receiving it, so Menu won't try to close itself and it won't call event.preventDefault(). I can't guarantee that this won't introduce some new issues, but this fixes the issue described.
const stopPropagationForTab = (event) => {
if (event.key === "Tab") {
event.stopPropagation();
}
};
<Dialog
onKeyDown={stopPropagationForTab}
In my fork of your sandbox, I upgraded the Material-UI version from 1.2 to 4.0 just because I wanted to make sure the issues weren't related to aspects that have changed. This threw off some of the styling, but the main behavior being addressed seemed to work the same in both versions.
A different way to handle this problem would be to rework the code such that the Dialog is no longer a child of the Menu. Then clicking a menu item that opens a Dialog would set state at the top-level for closing all the menus and opening the Dialog. This would probably be a better way to handle this, but it is a bigger change to the code structure.

Use of the Validate button in the Codename One Component Inspector Tree

Does the Validate button in the Codename One Component Inspector Tree do a check of UI?
I've never seen a message, a log, a dialog or anything else clicking on it. What is the way to use it?
Right now it only checks for nested scrollables, the goal is to add additional checks for common pitfalls but this wasn't implemented yet. See: https://www.codenameone.com/blog/validate-owner-badges-imageviewer-picker-range.html

TestRecorder with MaterialCommand in Toolbar

In a test-class, is there any way to invoke Buttons inside the toolbar, without a name (""), which were added like this?
getToolbar().addMaterialCommandToRightBar("", FontImage.MATERIAL_PICTURE_AS_PDF, e -> createPDF());
Or can I somehow tell the test-class to show a specific form ?(which is happening when I click the button without a label).
The test recorder is not generating any code in that case. It seems that it is only working with buttons, which have a non-empty String as name, as they are simply invoked by
clickButtonByLabel("Label");
The test recorder was written before the Toolbar existed, we tried to update it for the Toolbar recently but this proved to be pretty difficult.
We have this issue that covers this bug. As a workaround you can post the command directly in the code of the test.

NVDA screen reader reads clickable word on text

Any idea why NVDA reads clickable word when tabbing through text in html example:
<h1 tabindex="1"> testing </h1>
NVDA will read clickable testing
In first place remember that tabindex are not a good practice in a11y, and also headers don't need a tabindex NVDA provides a header navigation with the H key. About the clickable I can say from my experience is a known issue for NVDA, if you check that in other SR (Voice over or Chromebox) should be read properly
Short answer:
the tabindex attribute implies functionality to some screenreaders.
Long answer:
Two primary ways that a screen reader user will navigate your webpage are by skipping through interactive elements or by headings. Interactive elements are things like links, buttons, form fields and any other piece of functionality that the user will initiate on your page. These are navigated by using the 'tab' key.
The other primary way they will navigate your page is by headings. In fact, a survey from webaim lists headings overwhelmingly as the primary method of navigating a page to find information (source). In your example, you have given the heading a tabindex which will give the impression that it has some functionality or interactivity to it. To my understanding, both JAWS and NVDA will read out 'clickable' on elements that have a tabindex, as they could easily (and typically would) have some javascript click handlers that are not evident from the screenreader.
Answer:
It's because of attribute tabindex which makes this element keyboard focusable. One can focus it by pressing TAB key on a keyboard.
Hint #1: Attribute tabindex with value above 0 should be generally avoided!
Don't use tabindex="1", tabindex="2" and so on. Only tabindex="0" or tabindex="-1" can be useful in some cases. Otherwise you can create a complete mess for a user experience.
Read more:
Google: Using a tabindex greater than 0 is considered an anti-pattern.
WebAIM (accessibility): This is almost always a bad idea.
MDN: Avoid using tabindex values greater than 0.
Hint #2: Generally no need to make focusable elements that a user cannot interact with.
As in specific case no sense to make a heading element keyboard focusable if a user cannot interact with it.
If you are concerned about screen reader users have no worries as they read non focusable content just fine. A quote from Accessibility Developer Guide: As opposed to keyboard only users, screen reader users usually do not use the Tab key to read a page! Read the "Screen readers browse and focus modes" to know the difference between navigation using Arrow keys and Tab key.
But... Exception to the rule exists
Exception to the rule exists and it's probably a good idea in cases where developers set tabindex="-1" to headings which they want the focus to be moved programmatically for the purpose of accessibility. Such cases are for example fresh content update with AJAX in single page applications. The focus would be moved to a heading for a user to get aware of the content update and to be able to start from there. Also it can be useful when currently focused content is about to get removed from the DOM (a.g. deleting currently focused table entry) or moving a focus to an error summary heading after a form submit trial etc.
In my case (VoiceOver on MacOS), it seems that H1 is announced as clickable only on Firefox. On Chrome, it's announced correctly.
This leads me to believe it's a Firefox bug.

Resources