-
Notifications
You must be signed in to change notification settings - Fork 7
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
Re-implement Modal
component using HTMLDialogElement (#461)
#544
base: master
Are you sure you want to change the base?
Conversation
Update CSS properties in README.md. Done ✅ |
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.
Nice job! 👏🏻 Even with the decision of not having the closed Modal in the DOM. 👍
I just think we cannot remove the click-on-backdrop-to-close functionality.
PR updated: * Introduced
While I introduces |
Just for info, tests need to be updated in #545 as new test environment is necessary. |
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 a note regarding forms inside dialog, otherwise OK for me.
Can @adamkudrna or anybody else help me with this? I returned to this to complete the pull request but suddenly, I have all the texts inside of Modal in white even though there is no change in the code. |
I added a fix. It seems to happen only when the docs is switched to dark mode. |
b7ca42f
to
ec8d690
Compare
I have rebased and squashed it. I'm gonna perform self-review first as I have seen that documentation is not up-to-date with latest changes and then I will request review from you- |
Since rebase: I fixed submitting dialog when form fields are present. It is not working either on master. Formerly, it was part of auto focus hook which I have modified. It was also containing focus trap that it can be removed now. Now, this functionality is part of dialogOnKeyDownHandler.js. Then I have improved documentation and did minor fixes. |
I made separate commit (2514fd7) to demonstrate example with native form. Personally, I would not encourage this approach as every application differs in the way how it handles forms, state, validations and so. But it is true that it can be useful for example in that way, that native form will not be submitted until HTML validations are passing. We had 4 examples of different kind, so I added native form as fifth and atypically explained it in the example. Even though it is atypical, I would leave it there as it is only place how we can describe example with modal with creating explicit section. And we do not want to handle all possibilities in the documentation, so it compromise I think. @adamkudrna @mbohal, you can review the pull request and tell whether to include this native form example or drop it. |
I just want to mention (it will be part of commit message) that even though HTML Dialog states that it automatically focuses first focusable element in dialog, it does not work as our solution. The problem is that it autofocuses only some elements and for example states when there are only buttons and no input fields do not work. So we have to keep this functionality and we are not able to remove it! The only question is: Do we want to have autoFocus always enabled? Personally, I would suggest removing autoFocus prop and make it mandatory as native solution would automatically focuses some elements even when our autoFocus is off. |
Agreed we want to make |
…` tests (#461) `happy-dom` is used due to missing HtmlDialogElement support in `jest`. Just to mention, `happy-dom` provides partial support for dialog element, so not all test can be implemented.
I have merged PR with happy-dom into this PR. |
After discussion with @mbohal, we decided not to change our I dug deep into in again @mbohal and I found out, that with autoFocus disabled (through props, not through deleting whole functionality), our autoFocus internally forces focus on element, so it still can prevent native behavior. I had been testing it with completely removed functionality and probably cached page, so I had been obtaining wrong results before. |
…ng HTMLDialogElement (#461)
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.
Well done with beautiful demos! I only have two major requests/comments:
- Make a new "Forms" section. Forms in dialogs are a common use case. This is why I click "Request changes" here.
- Consider if we can get more out of the native functionality of the
<dialog>
. But maybe you have done an in-depth reserach and I see it wrong.
Thank you!
height: 100vh; | ||
.root[open] { | ||
display: flex; | ||
animation: fade-in theme.$animation-duration ease-out; |
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:
- add a note the animation is currently only supported in Chrome, Edge and Opera (Blink rendering engine),
- wrap the animation into
@media (prefers-reduced-motion: no-preference)
.
background: theme.$backdrop-background; | ||
animation: inherit; |
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.
+1 for inheritance. Just wrap the line into @media (prefers-reduced-motion: no-preference)
please.
this feature off, set the `autofocus` prop to `false`. | ||
|
||
- Modal **submits the form when the user presses the `Enter` key** . The primary | ||
button is clicked in this case. To turn this feature off, set the |
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 the click is just emulated, isn't it?
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.
It is not. click()
function is called directly on HTML button, it is not emulated, it's real click that also triggers its own click event. So I would not call it emulated.
@mbohal can correct me, but emulated event would be dispatchEvent(event), but not click().
`allowPrimaryActionOnEnterKey` prop to `false`. | ||
|
||
- Modal **closes when the user presses the `Escape` key**. The close button is | ||
clicked in this case. To turn this feature off, set the `allowCloseOnEscapeKey` |
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 same about "clicking" here.
@@ -225,9 +237,33 @@ React.createElement(() => { | |||
</ModalHeader> | |||
<ModalBody> | |||
<ModalContent> | |||
<FormLayout fieldLayout="horizontal"> | |||
<TextField label="Username" /> | |||
<FormLayout fieldLayout="horizontal" labelWidth="limited"> |
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.
Thanks for extending the form with new fields!
connect it with the form. | ||
</p> | ||
<p> | ||
Although we do not encourage using this approach, it is still |
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 don't we encourage the native solution? Is there something wrong when combining it with React? I'd like to see the reason mentioned here.
<Button | ||
label="Launch modal as native form" | ||
onClick={() => setModalOpen(5)} | ||
/> |
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 this section has become too long and deserves splitting into more blocks. From my experience, using the modal dialogs with forms is a frequent use case and it deserves a prominent place in the design system docs. This is how I see it:
- Create a new section called "Forms" right before the "Mouse and Keyboard Control" section.
- Explain shortly the Modal can be used with or without the native
<form>
element. If you can also tell what are the use cases, even better. - Extract the text from the last example (native form) so it's right in the document and not hidden in the demo.
- In the original section, please move the "Launch modal as dialog" example to the first place. Ever since we have the Modal component, I always click on the first button and immendiately hate myself for having to wait for the blocking modal to close 🙈.
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.
In this case, let's discuss this on Monday. We explicitly approved this on last meeting where you were supposed to be ...
TLDR; I do not encourage users to use native form behavior as it is good for plain HTML apps without JS (or with minimal JS), but not for React apps where the principles are different.
If we create Forms section, what will we do with this section? There are supported to be typical examples. If we create separate section, I would be duplicated ...
const dialogRect = dialogRef.current.getBoundingClientRect(); | ||
const isClickedOnBackdrop = dialogRef.current === e.target && ( | ||
e.clientX < dialogRect.left | ||
|| e.clientX > dialogRect.right | ||
|| e.clientY < dialogRect.top | ||
|| e.clientY > dialogRect.bottom | ||
); |
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 still need this with native dialog? The <dialog>
triggers the close
event so I was wondering if we could listen on it/use it?
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 it wasn't needed, it wouldn't be here. Neither close nor cancel event is called on backdrop click. If you want to close dialog by clicking on backdrop, you have to listen to click event and detect user clicked outside of dialog element or use different method of detection. However, this is most common approach.
It is quite hard to decide what to comment. This is default behavior/knowledge and developer is supposed to know this if he/she want to dig into it. Now, each line of each event handler is commented. But I would add docblock for each function to make it crystal clear.
@@ -4,7 +4,7 @@ const StyleLintPlugin = require('stylelint-webpack-plugin'); | |||
const TerserPlugin = require('terser-webpack-plugin'); | |||
const VisualizerPlugin = require('webpack-visualizer-plugin2'); | |||
|
|||
const MAX_DEVELOPMENT_OUTPUT_SIZE = 3300000; | |||
const MAX_DEVELOPMENT_OUTPUT_SIZE = 3400000; |
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.
Closes #461, closes #537.