stencil-constructible-style
TypeScript icon, indicating that this package has built-in type declarations

2.0.0 • Public • Published

stencil-constructible-style

Built With Stencil

What is it?

stencil-constructible-style is a decorator for Stencil components that gives you the ability to add dynamic styles as constructible stylesheets, with a fallback for non-supported browsers.

* Requires @stencil/core@1.0.0-alpha.15 or later

Why? Don't Stencil do this already?

Yes, for your .css-files they do. But what if your style depends on some variables? Then you end up having to write <style> tags in your render function. Or if you host your code from a CDN, such as unpkg.com? Then the assets folder will not be on a relative URL, as it would be relative to the website your web components are being used on (getAssetPath to the rescue!).

How to use it?

import { Component, Element, getAssetPath } from "@stencil/core";
import { ConstructibleStyle } from "stencil-constructible-style";

@Component({...})
export class MyComponent {
  // A componentWillLoad is required, even if it's empty.
  componentWillLoad() {}

  @ConstructibleStyle() styles = `
    .classIcon { background: url(${ getAssetPath("../assets/class-icon.png") }); }
  `;
}

You can also set the ConstructibleStyle to a function in case you want to avoid running it for every instance of the component. The above would be:

@ConstructibleStyle() styles = () => `
  .classIcon { background: url(${ getAssetPath("../assets/class-icon.png") }); }
`;

Caching

The stylesheet, once constructed, is cached statically per component and therefore won't be recreated when new instances of the component are created. This could be a problem if you have variables that affects that stylesheet. That's where the cacheKeyProperty option comes in.

import { Component, Element, getAssetPath } from "@stencil/core";
import { ConstructibleStyle } from "stencil-constructible-style";

@Component({...})
export class MyComponent {
  @Prop() myClass: string;

  // A componentWillLoad is required, even if it's empty.
  componentWillLoad() {}

  @ConstructibleStyle({ cacheKeyProperty: "myClass" }) styles = `
    .classIcon { background: url(${ getAssetPath(`../assets/${ this.myClass }-icon.png`) }); }
  `;
}

ConstructibleStyle runs after your componentWillLoad, so if you have multiple variables that affects your styles and want them all to be relevant in your key, you can prepare a unique key during componentWillLoad.

@Component({...})
export class MyComponent {
  @Prop() myClass: string;
  @Prop() mode: string;

  private cacheKey: string;

  componentWillLoad() {
    this.cacheKey = `${ this.myClass }-${ this.mode }`;
  }

  @ConstructibleStyle({ cacheKeyProperty: "cacheKey" }) styles = `
    .classIcon { background: url(${ getAssetPath(`../assets/${ this.myClass }-${ this.mode }-icon.png`) }); }
  `;
}

Why is componentWillLoad required?

StencilJS does heavy optimizations. If none of your components have a componentWillLoad StencilJS will simply remove the code that calls that function from the output, and hence @ConstructibleStyle will never execute. Since the decorator has no knowledge about other components however, a warning will be issued to the console if a component that uses @ConstructibleStyle does not have a componentWillLoad.

What about browsers that don't suppot Constructible Stylesheets?

If new CSSStyleSheet() can't be called (same check that Stencil itself uses), the decorator will fall back to render a <style> element to the end of your rendered output.

Package Sidebar

Install

npm i stencil-constructible-style

Weekly Downloads

2

Version

2.0.0

License

MIT

Unpacked Size

16.7 kB

Total Files

6

Last publish

Collaborators

  • bodinaren