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
BsModal is closed regarding of open property which causes strange edge cases #830
Comments
This stems from the idea that the component should support both an uncontrolled as well as a controlled mode of operation. With that I basically mean who is responsible for owning the open-state of the component, see e.g. https://stackoverflow.com/questions/42522515/what-are-controlled-components-and-uncontrolled-components/42522792#42522792. I think in most cases (like 99%+) you want the uncontrolled version, where the modal shows up by default, and will be closed when user does the corresponding interaction (close button, backdrop click). So no need the prevent the closing. In that case I would like In the usually rare case that you want to control the state, the component should allow you to do that, which is the I think there is some value in what you would expect to be the default behaviour in 99%+ of the cases to just work. Take a dropdown as another example. There could be use cases where you actually want to control the opening programmatically, but in most cases the open-state can be hidden inside the component and default behaviour to show the menu when the dropdown button is clicked does not need to be controlled from the outside. Do you have ideas for a better API to unite these two modes? |
@jelhan would like to do the v3 release sooner than later. Still think this 👆 should be sorted out before the release? |
Lets not block v3 for this one as it seems to need more discussion. I'm quite sure there will be a v4 some time in the future. 😄 I like the distinction between controlled and uncontrolled mode of operation. Very helpful terms to reason about the issue. Actually I think we already support both modes but having a strange API for the controlled one:
Let me give a quick example, what I would consider broken about current implementation of controlled mode: <button onclick={{action (mut showModal) true}}>show modal</button>
<BsModal @open={{showModal}}>...</BsModal> This looks quite straight forward isn't it? But actually it's not working as expected as the modal can't be opened more than one time. You could find an Ember Twiddle to play around here: https://ember-twiddle.com/6f545b142fa78f23c9b9e3cdd419f18a?openFiles=templates.application.hbs%2C Please note that it's not that easy to fix this. Altering import { next } from '@ember/runloop';
export default Controller.extend({
actions: {
enforceModal() {
this.set('showModal', false);
next(() => {
this.set('showModal', true)
});
}
}
}); That's awful and therefore it should be considered best practice to set Speaking more technically I recommend these changes:
|
Agree 😁
Also agree here. In controlled mode you should actively prevent
Given the user is responsible as said before to manage the I think we can apply the same pattern to other components as well, which currently do not supported a controlled mode, or very limited: Dropdown, Popover, Tooltip, more? So leaving this for v4 would make even more sense, so we can introduce a coherent API pattern. |
Sounds good. Will try to pick that one up after v3 has landed. Should also add a note to documentation why {{#if showModal}}
<BsModal @onHide={{action (mut showModal) false}}> ... </BsModal>
{{/if}} But this is breaking close animation, isn't it? Would be great if we could have async |
@jelhan regarding the controlled vs uncontrolled discussion (which just kind of popped up again), I just remembered that this API choice had its root in this discussion: https://gist.github.com/simonihmig/f4cada751b89b192f608bcb83ed1c22a |
For some reason this worked as expected before the v4 glimmer rewrite. I just updated to v4.4 and now there is definitely no sane way to use @OPEN anymore. |
@tmlrd42 Could you please open a new issue for that bug? Would be helpful if you could include the code needed to reproduce the issue in a newly created application. |
Current interaction of
<BsModal>
'sopen
property and closing functionality is confusing in my opinion.The modal could be closed by clicking backdrop/close button even if
open
property staystrue
. Seeing<BsModal @open={{true}}>...</BsModal>
I would expect that these modal can't be closed at all. But actually it could by closed by a click on the backdrop. One must returnfalse
fromonHide
action to prevent a modal from being closeable or disable all possibilities to close that modal.If a modal is closed but
open
property is stilltrue
the modal could not be reopened by setting it totrue
again. It must be changed to some other value before. This is likely to cause bugs that are very difficult to debug.E.g. imagine a modal being used to show an error message if some action fails. This is most likely been implemented by setting a property bound to
<BsModal>
's@open
totrue
in that action. If the developer isn't aware of the behavior described here, he will likely not set the property tofalse
again when user closes the modal (using<BsModal>
'sonHide
oronHidden
properties). In that case the modal (and with it the error message) won't be shown again if the error reoccurs...It would be much easier to reason about
<BsModal>
and less error prune if a modal can't be closed / will always be shown if it's@open
property istrue
. A typical usage would then be<BsModal @open={{showModal}} @onHide={{action (mut showModal) false}}>
, which is much more inline with the other APIs of Ember Bootstrap and the rest of the ecosystem.This would be a breaking change. So we might want to consider it for v3.
The text was updated successfully, but these errors were encountered: