简体   繁体   中英

Cannot access “custom-style” resources in Polymer Element

I am writing a basic Polymer Component that should be able also to change its style at the change of a property.

When I try to change the theme file, I use the id to retrieve it but I always get null.

Here is my code:

[other polymer imports]
<link rel="import" href="/themes/my-theme.html" id="current_theme"/>

<dom-module id="my-app">
 <template>
  <style>
  :host{
    font-family: 'Roboto', 'Noto', sans-serif;
    -webkit-font-smoothing: antialiased;
  }

  :host ::content app-header{
    background: var(--app-primary-color);
    color: var(--app-text-color);
  }

  :host ::content user-app-toolbar{
    background: var(--app-primary-color);
    color: var(--app-text-color);
  }
  ...
</style>

...
<script>
Polymer({
  is: 'my-app',

  properties: {
    state: {
      type: String,
      reflectToAttribute: true,
      observer: '_stateChanged',
    },
   },
  _stateChanged: function(page) {
    // get theme file
    theme.href = '/theme/red.html';
   }
 });
 </script>
 </template>
</dom-module>

my-theme.html

<style is="custom-style">
  my-app {
   --app-primary-color: grey;
   --app-secondary-color: black;
   --app-text-color: white;
 }
</style>

The problem is how to implement the "get theme file". I tried many things:

  • document.querySelector('#current_theme'): [returns null, I think it is because it uses the main document and not the one of the element]
  • Polymer(dom).querySelector('current_theme'): [undefined]
  • this.$$["current_theme"] [undefined]

Any idea of how to do this?

PS: the idea of changing the theme in this way is taken from this stack overflow question

Static

You need to put a style tag with your theme id (Polymer 2.0)

<link rel="import" href="/themes/my-theme.html"/>

<dom-module id="my-app">
  <template>
    <style include="my-theme-xxx"></style>
    <style>
      :host{
      ...

my-theme.html

<dom-module id="my-theme-xxx"><template><style>
    my-app {
    --app-primary-color: grey;
    --app-secondary-color: black;
    --app-text-color: white;
    }
</style></template></dom-module>

Dynamic

Yet I found only this way to change element css by theme dynamicaly.

<link rel="import" href="my-css.html">

<dom-module id="my-app">
  <template>
    <style include="my-css"></style>
    <button class="btn-primary-dark">Dark button</button>
    <button class="btn-primary-light">Light button</button>
    <button class="btn-primary-default">Default button</button>
    <br><br>
    <button on-click="setTheme1">Set theme 1</button>
    <button on-click="setTheme2">Set theme 2</button>
  </template>
  <script>
    class MyApp extends Polymer.Element {
      static get is() { return 'my-app'; }

      // Dynamicaly change vars
      setTheme1() {
        Polymer.updateStyles({
          '--dark-primary-color' : '#689F38',
          '--default-primary-color' : '#8BC34A',
          '--light-primary-color' : '#DCEDC8',
          '--text-primary-color' : '#212121'
        });
      }
      setTheme2() {
        Polymer.updateStyles({
          '--dark-primary-color' : '#1f8f37',
          '--default-primary-color' : '#818bbf',
          '--light-primary-color' : '#f0e82f',
          '--text-primary-color' : '#333333'
        });
      }

    }
    window.customElements.define(MyApp.is, MyApp);
  </script>
</dom-module>

my-css.html

<dom-module id="my-css">
  <template>
    <style>
      .btn-primary-dark {
          background-color: var(--dark-primary-color);
          color: var(--secondary-text-color);
      }
      .btn-primary-light {
          background-color: var(--light-primary-color);
          color: var(--secondary-text-color);
      }
      .btn-primary-default {
          background-color: var(--default-primary-color);
          color: var(--secondary-text-color);
      }
    </style>
  </template>
</dom-module>

Digging into documentation of Polymer I found this quote from this official Polymer doc page

Note: You should only use custom-style to define styles for the main document. To define styles for an element's local DOM, just use a < style> block.

And moreover, from this older documentation

Frequently you want to define custom property values at the document level, to set a theme for an entire application, for example. Because custom properties aren't built into most browsers yet, you need to use a special custom-style tag to define custom properties outside of a Polymer element. Try adding the following code inside the tag of your index.html file

Moving the my-theme.html into the index.html page, I am able to retrieve it from my polymer element using

document.querySelector('#current_theme')

Beside this, I am not able to change the theme dynamically. But since the title of the question was about accessing the resource, I solved the problem moving it. As craPkit said, I am not sure what I was trying to do is actually possible.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM