javascripthtmlpolymercustom-elementlit-element

paper-dropdown-menu not working in a lit-element


Edit: Turns out, it helps if you import paper-listbox before using it in another element. For some reason I thought it was being imported as a dependency on another element I was importing, but no. As soon as I added the explicit import, it began working correctly. Original question follows.

To start, this problem only happens when using paper-dropdown-menu (with paper-listbox inside) in a lit-element. We're using the component in almost the exact same way in multiple PolymerElement(s) with no issues.

Basically, I'm seeing two issues with paper-dropdown-menu. The first is that it never displays a value of any type, whether the label attribute or an actual selected value, nor does its value property ever change, even when the paper-listbox inside has a set value. The second problem is that it appears to be impossible to select any value from the dropdown menu - you can click on them, but the list doesn't close, and the selected option name doesn't show up in the menu's text display.

Due to the nature of the issues, it appears as though the problem is that the paper-dropdown-menu and the paper-listbox inside of it aren't communicating properly... but I'll be damned if I can figure out why.

Here's the markup in question from the element's render method:

    <paper-dropdown-menu id="homepageSelect">
        <paper-listbox slot="dropdown-content" 
            attr-for-selected="item-value" 
            selected="${state.homepage}"
            label="Select a homepage"
            @selected-changed="_homepageChanged">
    
            ${state.homepageOptions.map(o => html`
                <paper-item item-value="${o.value}">${o.name}</paper-item>
            `)}
    
        </paper-listbox>
    </paper-dropdown-menu> 

And the mock data we're using:

    {
        "title": "Boss of you",
        "fullName": "J Jonah Jameson",
        "username": "jjj",
        "client": "Daily Bugle",
        "homepage": "http://sampledomain.com/",
        "homepageOptions": [{
            "name": "FrontPage",
            "value": "http://sampledomain.com/"
        }, {
            "name": "Editorials",
            "value": "http://sampledomain.com/opinion"
        }, {
            "name": "Metro",
            "value": "http://sampledomain.com/metro"
        }],
        "groups": [{
            "name": "Admin",
            "description": "Administers the whole shebang"
        }, {
            "name": "Power users",
            "description": "Like regular users, but powerful"
        }, {
            "name": "Gen pop",
            "description": "Down in the weeds"
        }],
        "changePasswordUrl": "https://change.password.now",
        "email": "test@email.com",
        "phoneWork": "404-555-1234",
        "phoneCell": "404-555-4321",
        "phoneHome": "404-123-5555",
        "address": {
            "address1": "1234 Boulevard St",
            "address2": "Ste 1",
            "city": "Atlanta",
            "state": "GA",
            "zip": "30303",
            "country": "USA",
            "type": "Office"
        }
    }

I'd put up a screenshot of how it looks, but just imagine a dropdown with nothing selected, and you've got it. Clicking it actually does display the internal paper-listbox, but the list does not close on click, nor does the clicked value ever make it up to the paper-dropdown-menu element.

Anyone have any idea what's going on? Theoretically, a PolymerElement should be able to run inside of any form of HTML markup - the fact that it's within a lit-element shouldn't make a difference, and doesn't for every other component we're using. Nevertheless, this component, using this pattern, works in PolymerElement but does not work here, and I don't understand why.


Solution

  • It never displays a value of any type, whether the label attribute or an actual selected value, nor does its value property ever change, even when the paper-listbox inside has a set value

    Inside of the template you're referencing state. If state is a property of the element then you have to reference it with this. (unless it's a variable you defined in the part of the render() function you didn't paste here). This may be the cause of the missing values.

    The missing label is because you put the label attribute in <paper-listbox> while it should be in <paper-dropdown-menu>.

    It appears to be impossible to select any value from the dropdown menu - you can click on them, but the list doesn't close, and the selected option name doesn't show up in the menu's text display.

    The name not showing up should be the same as the previous point. I tried your example locally and the list actually doesn't close because of an error with the animations. This happens because the dropdown uses some Web Animations API features that have to be polyfilled:

    $ npm install web-animations-js
    
    <script src="node_modules/web-animations-js/web-animations-next-lite.min.js"></script>
    

    Also, you're passing a string to @selected-changed (à la Polymer) while you should use interpolation:

    @selected-change=${e => this. _homepageChanged(e)}
    
    or
    
    @selected-change=${this. _homepageChanged.bind(this)}
    

    This way everything seems to work correctly:

    example