question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Drawer doesn't open or close the way I'd expect

See original GitHub issue

Disclaimer: 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 the onclick attribute or assigned via addEventListener.

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:closed
  • Created 4 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
JanMiksovskycommented, Mar 10, 2020

@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.

  • This was placed there to support the DrawerWithGrip subclass. In that subclass, a drawer is partially visible even when closed. This visible part is the grip.
  • If the user clicked inside the frame, the Drawer base class would check to see if the drawer was closed. If so, it assumed the user was clicking on the visible drawer grip, and interpret that as a request to open the drawer.
  • The presumptuous part is that Drawer should have left this behavior up to DrawerWithGrip, which could listen instead of clicks on the grip itself, rather than on the drawer frame.
  • The buggy part is that, in a completely reasonable implementation like your code sample, a 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.

0reactions
JanMiksovskycommented, Mar 14, 2020

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.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Drawers that won't open all the way - Houzz
Hello, I have a brand new dresser from Pottery Barn baby and the drawers only open about half way. It's so frustrating! I've...
Read more >
Drawer Won't Stay Closed? 3 Simple Ways You Can Make it ...
Method #2: Adjusting Your Runner and Drawer ... If your soft-close drawer won't stay closed, this method might be more well-suited. To remove...
Read more >
ActionBarDrawerToggle does not open drawer until first slide
I am using Google Design Support Library and DrawerLayout. Setup: final DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.
Read more >
What could be causing my kitchen drawers to be sliding out?
It's opening either due to gravity, or something pushing on it. Either way, solve the problem by adjusting the tracks.
Read more >
How to Fix a Kitchen Drawer Slide That Does Not Close All the ...
If your kitchen drawer will not close all the way, first empty it and try closing it again. If it still sticks, pull...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found