Drawer doesn't open or close the way I'd expect
See original GitHub issueDisclaimer: I’m early-on in my exploration of web components, so it’s possible I’m missing something really obvious—sorry, if that’s the case.
For a couple days I’ve been attempting to get the <elix-drawer></elix-drawer>
to work within our Polymer or LitElement library. I’m seeing some puzzling behavior, though.
After trying it in Polymer 3 and then in a LitElement component, I created a simple HTML document to test :
<!DOCTYPE html>
<html>
<head>
<script src="./dist/bundle.js"></script>
<!-- elix/define/Drawer.js is included in the bundle above -->
<script>
function openDrawer() {
document.getElementById('drawer').opened = true;
}
function closeDrawer(event) {
document.getElementById('drawer').opened = false;
}
</script>
</head>
<body>
<elix-drawer id="drawer">
<button onclick="closeDrawer()">Close</button>
</elix-drawer>
<button onclick="openDrawer()">Open</button>
<button style="position: fixed; z-index: 100000;" onclick="closeDrawer(event)">Close</button>
</body>
</html>
In this state:
- The drawer opens when I push the Open button.
- I can close the drawer by clicking the backdrop, but not by clicking the Close button inside the drawer.
- I can close the drawer by clicking the Close button that is outside the drawer. 🤔 (I don’t really care to be able to do that, though, unfortunately.)
- In Dev Tools, if I select the button inside the drawer and call
$0.parentElement.close()
or$0.parentElement.opened = false
, it works. However, either of those fail when used in theonclick
attribute or assigned viaaddEventListener
.
Here are some things I tried while attempting to wrap the elix-drawer
with another drawer component:
Tried | Result |
---|---|
Setting opened attribute to "true" |
Drawer is “opened” initially but not visible. Clicking anywhere on the screen “closes” it, i.e. the drawer suddenly becomes visible and plays the closing animation |
Just applying the opened attribute with no value |
No noticeable result |
opened="opened" |
No noticeable result |
Using document.getElementById('drawer').open() /.close() instead of setting opened to true /false |
open() works fine, close() doesn’t. In Dev Tools I can see that the opened and aria-expanded attributes are updated, though. (To true .) |
Setting opened=false or closed=true programmatically, e.g. in LitElement’s updated() callback |
Doesn’t work—same as above |
After all this, I can’t close the drawer from within at all (e.g. by clicking a close/X button or by pressing Save), and I can’t initialize the drawer in an opened state. I like the accessibility and usability of this drawer component, and I’d rather not implement all the functionality it has built in, but I can’t really use it for anything if I can’t get these basic functions working…hopefully you can set me straight?
Issue Analytics
- State:
- Created 4 years ago
- Comments:5 (3 by maintainers)
Top GitHub Comments
@nategreen Sorry you’ve been having so much trouble with Drawer.
The root cause of both the original problem and your difficulty reproducing it appears to be that some presumptuous/buggy behavior in Drawer was recently removed.
The presumptuous/buggy behavior in Drawer was that it would treat clicks inside the frame of a closed drawer as a signal to open the drawer.
click
event on the drawer’s Close button triggers your event handler (which closes the drawer) — and then the event bubbles up to the drawer frame. The Drawer class sees the click, sees that the drawer is now closed, so it reopens the drawer. That’s a bug. The close/reopen is typically fast enough that it’s never painted in the closed state. (This is why @robbear suggested stopping propagation of the click event.)I’d noticed this presumptuous behavior (but not the buggy aspect) in recent refactoring work on Drawer. In this checkin, I removed the click handler from Drawer. The DrawerWithGrip class, it turns out, already had the desired click handler for the grip.
This fix is on #master but has not been published yet; it will go out in the next Elix release. I’m hoping to make that release in the next week or so — but let me know if you need a solution sooner.
Separately, while looking into this, I realized that the OpenCloseMixin used by Drawer makes use of an older Elix attribute pattern in which boolean attributes had “true”/“false” string values. In recent Elix work, we’ve been trying to emulate the native HTML boolean attributes, in which the presence of the attribute indicates truth and the absence represents falsehood.
So I just wanted to give you a heads up that I’ll probably fix that issue as well. It shouldn’t make any difference to code like what you show in the example:
getElementById('drawer').opened = true
will still work the same. The only difference is that the reflected attribute will appear when opened (<elix-drawer opened>
) instead of having a string value (<elix-drawer opened="true">
). Given that you’ve already hit at least two issues with Drawer, just wanted to make you aware that change was coming.Since the fix is now on master, I’m closing this. Please reopen if you see issues with what’s on master or in the eventual release.
Thanks again for filing.