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.

setVisible(false) on PolymerTemplate does not work if the PolymerTemplate is within a component with a shadow root.

See original GitHub issue

Description of the bug

When building apps using PolymerTemplate, polymerTemplate.setVisible(false) does not work. Normally setVisible(false) applies the hidden="true" attribute, and Vaadin has the generic CSS rule available :host([hidden]) { display: none !important; } which hides the component. Things break if the component you try to hide is within another component that uses a shadow root. The attribute is added correctly, but the CSS is not applied. If you have for example a VerticalLayout within a component that has a shadow root, then setVisible() works correctly, so the bug has so far only appeared with PolymerTemplate

Minimal reproducible example

Expected behavior

VisibilityBug.java

package com.vaadin.tutorial.crm.ui;

import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.html.Paragraph;
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.Route;

@Route("visibility-bug")
public class VisibilityBug extends VerticalLayout {

    boolean isVisible = true;

    public VisibilityBug() {
        VerticalLayout verticalLayout1 = new VerticalLayout(new Span("Hello VerticalLayout"));
        MyTemplateOuter template1 = new MyTemplateOuter();

        Button button1 = new Button("Toggle visibility when no shadow doms are present", e -> {
            isVisible = !isVisible;
            verticalLayout1.setVisible(isVisible);
            template1.setVisible(isVisible);
        });
        add(button1, verticalLayout1, template1);

        add(new Paragraph());

        MyTemplateOuter template2 = new MyTemplateOuter();

        Button button2 = new Button("Toggle visibility when a shadow dom is present", e -> {
            isVisible = !isVisible;
            template2.setInnerVisibilities(isVisible);
        });
        add(button2, template2);
    }
}

MyTempalteOuter.java

package com.vaadin.tutorial.crm.ui;

import com.vaadin.flow.component.Tag;
import com.vaadin.flow.component.dependency.JsModule;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.polymertemplate.Id;
import com.vaadin.flow.component.polymertemplate.PolymerTemplate;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.templatemodel.TemplateModel;

@Tag("my-template-outer")
@JsModule("./src/views/my-template-outer.js")
public class MyTemplateOuter extends PolymerTemplate<MyTemplateOuter.MyTemplateOuterModel> {

    @Id("vl") private VerticalLayout vl;

    @Id("inner") private MyTemplateInner innerTemplate;

    public MyTemplateOuter() { }
    public interface MyTemplateOuterModel extends TemplateModel {}
    public void setInnerVisibilities(boolean visible){
        vl.setVisible(visible);
        innerTemplate.setVisible(visible);
    }
}

MyTemplateInner.java

package com.vaadin.tutorial.crm.ui;

import com.vaadin.flow.component.Tag;
import com.vaadin.flow.component.dependency.JsModule;
import com.vaadin.flow.component.polymertemplate.PolymerTemplate;
import com.vaadin.flow.templatemodel.TemplateModel;

@Tag("my-template-inner")
@JsModule("./src/views/my-template-inner.js")
public class MyTemplateInner extends PolymerTemplate<MyTemplateInner.MyTemplateInnerModel> {
    public MyTemplateInner() {}
    public interface MyTemplateInnerModel extends TemplateModel {}
}

my-template-outer.js

import {html, PolymerElement} from '@polymer/polymer/polymer-element.js';
import './my-template-inner.js';
import '@vaadin/vaadin-ordered-layout/src/vaadin-vertical-layout.js';

class MyTemplateOuter extends PolymerElement {

    static get template() {
        return html`
<style include="shared-styles">
                :host {
                    display: block;
                    height: 100%;
                    border: 1px solid black;
                    padding: 10px;
                }
            </style>
            <vaadin-vertical-layout id="vl">
              <span>Hello inner VerticalLayout</span>
            </vaadin-vertical-layout>
            <my-template-inner id="inner"></my-template-inner>
`;
    }

    static get is() {
        return 'my-template-outer';
    }

    static get properties() {
        return {
            // Declare your properties here.
        };
    }
}
customElements.define(MyTemplateOuter.is, MyTemplateOuter);

my-template-inner.js

import {html, PolymerElement} from '@polymer/polymer/polymer-element.js';

class MyTemplateInner extends PolymerElement {

    static get template() {
        return html`
<style include="shared-styles">
                :host {
                    display: block;
                    height: 100%;
                }
            </style>
<div>Hello template inner</div>
`;
    }

    static get is() {
        return 'my-template-inner';
    }

    static get properties() {
        return {
            // Declare your properties here.
        };
    }
}

customElements.define(MyTemplateInner.is, MyTemplateInner);

Actual behavior

A PolymerTemplate stays visible after setVisible(false) if that PolymerTemplate is within a shadow root. hidden="true" is applied but not the CSS

vaadin-template-visibility

Expected behavior

A component that you call setVisible(false) on should be hidden

Versions:

- Vaadin / Flow version: 14.1.21
- Java version: Corretto 11
- OS version: Windows 10

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:2
  • Comments:22 (17 by maintainers)

github_iconTop GitHub Comments

1reaction
Legiothcommented, May 28, 2020

This is always a problem within my application as MainView is a PolymerTemplate along with my custom components

My recommended workaround for those situations would be to include [hidden] { display: none; } as a style in each template. You can create your own subclass (either server-side for PolymerTemplate or client-side for PolymerElement) that would automatically apply the style and use that one consistently throughout the application so that you wouldn’t have to separately include the extra style separately in each template.

You can indeed remove the prioritization if you conclude that the workaround is good enough for you.

0reactions
plekucommented, Sep 15, 2020

So we agreed on going with 1) with both keeping hidden and additionally setting style display: none;.

Once this lands to 18, the designer tutorial needs to be updated.

Read more comments on GitHub >

github_iconTop Results From Across the Web

What happens between setVisible() and a component being ...
When you add/remove components from a visible GUI you need to use revalidate() and repaint() on the parent container. I know you are...
Read more >
Basic Features | Using Vaadin Components | Flow
You can set a component as invisible using the component.setVisible(false) ) method. Invisible components: Are no longer displayed in the UI.
Read more >
8 SHADOW ROOT MISTAKES & HOW TO FIX THEM
Mistake #1: Shadow rooting every client. Not every client needs a shadow root. According to Sharon Mudavanhu (@yogacolourist), she prefers to do ......
Read more >
Component Basic Features - 《Vaadin 10 Documentation》
Component have common features that can be used regardless of the component. ... setVisible(false) ) is not shown on the UI. In addition ......
Read more >
29 Shadow Root Hair Highlight Ideas for 2022
There's also lots of room for customization with shadow roots—your root can be as soft or as strong as you like—so don't be...
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