๐Ÿ•Ž 8 Days of Web Components Tips

In honour of Hannukah this year, I undertook to write 8 web components tips, one for each night of the festival. Tonight is the 8th and final night of the festival. The mystics said that this night combines and contains aspects of each of the seven pre…


This content originally appeared on DEV Community and was authored by Benny Powers ๐Ÿ‡ฎ๐Ÿ‡ฑ๐Ÿ‡จ๐Ÿ‡ฆ

In honour of Hannukah this year, I undertook to write 8 web components tips, one for each night of the festival. Tonight is the 8th and final night of the festival. The mystics said that this night combines and contains aspects of each of the seven previous nights, so I'd like to share a compilation of those tips with the dev community.

Wishing you and yours a fully Lit Hannukah!

1st night: Adding Controllers via TypeScript Decorators ๐Ÿ•ฏ

Did you know you can add reactive controllers to an element via a class or field decorator? You don't even need to assign it to an instance property!

/**
 * Adds a given class to a ReactiveElement when it upgrades
 */
export function classy(classString: string): ClassDecorator {
  return function(klass) {
    if (!isReactiveElementClass(klass))
      throw new Error(`@classy may only decorate ReactiveElements.`);

    klass.addInitializer(instance => {
      // Define and add an ad-hoc controller!
      // Look, mah! No instance property!
      instance.addController({
        hostConnected() {
          instance.classList.add(classString);
        },
      });
    });
  };
}

@customElement('pirsumei-nissa') @classy('al-hanissim')
export class PirsumeiNissa extends LitElement {}

2nd night: Adding Controllers Inside Other Controllers ๐Ÿ•ฏ๐Ÿ•ฏ

Like a delicious sufganya (traditional holiday donut) with many fillings, a Lit component can have multiple reactive controllers, and controllers can even add other controllers

export class MutationController<E extends ReactiveElement> implements ReactiveController {
  private logger: Logger;

  mo = new MutationObserver(this.onMutation);

  constructor(public host: E, public options?: Options<E>) {
    // Add another controller
    this.logger = new Logger(this.host);
    host.addController(this);
  }

  onMutation(records: MutationRecord[]) {
    this.logger.log('Mutation', records);
    this.options?.onMutation?.(records)
  }

  hostConnected() {
    this.mo.observe(this.host, this.options?.init ?? { attributes: true, childList: true });
  }

  hostDisconnected() {
    this.mo.disconnect();
  }
}

3rd night: Web Component Context API ๐Ÿ•ฏ๐Ÿ•ฏ๐Ÿ•ฏ

Did you know web components can have context? The protocol is based on composed events. Define providers & consumers, & share data across the DOM.

https://github.com/webcomponents-cg/community-protocols/blob/main/proposals/context.md

4th night: Using SASS, PostCSS, etc. ๐Ÿ•ฏ๐Ÿ•ฏ๐Ÿ•ฏ๐Ÿ•ฏ

Building #webcomponents with #SASS? (You probably don't need it but if you can't resistโ€ฆ) you can develop using a buildless workflow with Web Dev Server and esbuild-plugin-lit-css

Want to use #PostCSS instead for sweet-sweet future CSS syntax? No problem

5th night: Stacking Slots ๐Ÿ•ฏ๐Ÿ•ฏ๐Ÿ•ฏ๐Ÿ•ฏ๐Ÿ•ฏ

Who doesn't like a piping hot stack of latkes?

Stack slots to toggle component states. Adding content into the outer slot automatically 'disables' the inner slot

State management in HTML! ๐Ÿคฏ

Check out @westbrook 's blog on the topic:

6th night: Better TypeScript Imports ๐Ÿ•ฏ๐Ÿ•ฏ๐Ÿ•ฏ๐Ÿ•ฏ๐Ÿ•ฏ๐Ÿ•ฏ

In #TypeScript 4.5, if you set preserveValueImports, you can import the class definitions of your element dependencies without worrying that TS will elide the side-effecting value.

import { LitElement } from 'lit';
import { customElement, property } from 'lit/decorators.js';

@customElement('lit-candle')
export class LitCandle extends LitElement {
  @property({ type: Boolean }) lit = false;

  render() {
    return this.lit ? '๐Ÿ•ฏ' : ' ';
  }
}
import { LitElement, html } from 'lit';
import { customElement, property, query } from 'lit/decorators.js';
import { LitCandle } from './lit-candle.js';

@customElement('lit-menorah')
export class LitMenorah extends LitElement {
  @property({ type: Number }) night = 6;

  // Although the value of `LitCandle` isn't used, only the type
  // with `preserveValueImports`, TS 4.5 won't strip the import
  // So you can be sure that `<lit-candle>` will upgrade
  @query('lit-candle') candles: NodeListOf<LitCandle>;

  render() {
    return Array.from({ length: 8 }, (_, i) => html`
      <lit-candle ?lit="${(i + 1) <= this.night}"></lit-candle>
    `);
  }
}

live demo

7th night: GraphQL Web Components ๐Ÿ•ฏ๐Ÿ•ฏ๐Ÿ•ฏ๐Ÿ•ฏ๐Ÿ•ฏ๐Ÿ•ฏ๐Ÿ•ฏ

Looking to add #GraphQL to your frontend? Give Apollo Elements a try. Use Apollo reactive controllers with lit+others, or try a 'functional' library like atomic

import { ApolloQueryController } from '@apollo-elements/core';
import { LitElement, html } from 'lit';
import { customElement } from 'lit/decorators.js';
import { HelloQuery } from './Hello.query.graphql';

@customElement('hello-query')
export class HelloQueryElement extends LitElement {
  query = new ApolloQueryController(this, HelloQuery);

  render() {
    return html`
      <article class=${classMap({ skeleton: this.query.loading })}>
        <p id="error" ?hidden=${!this.query.error}>${this.query.error?.message}</p>
        <p>
          ${this.query.data?.greeting ?? 'Hello'},
          ${this.query.data?.name ?? 'Friend'}
        </p>
      </article>
    `;
  }
}

8th night: Component Interop ๐Ÿ•ฏ๐Ÿ•ฏ๐Ÿ•ฏ๐Ÿ•ฏ๐Ÿ•ฏ๐Ÿ•ฏ๐Ÿ•ฏ๐Ÿ•ฏ

You don't need to use only #lit components in your #lit app

Mix old-school #Polymer 3 components with #vue js web components. Put #stencil js Microsoft's #FAST UI on the same page

It's your party!

<!DOCTYPE html>
<head>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.0.0-beta.61/dist/themes/light.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ionic/core/css/ionic.bundle.css"/>
  <script type="module" src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.0.0-beta.61/dist/shoelace.js"></script>
  <script type="module" src="https://cdn.jsdelivr.net/npm/@ionic/core/dist/ionic/ionic.esm.js"></script>
  <script type="module" src="https://unpkg.com/@microsoft/fast-components"></script>
  <script type="module" src="https://unpkg.com/@patternfly/pfe-datetime@1.12.2/dist/pfe-datetime.js?module"></script>
  <script type="module" src="https://unpkg.com/@material/mwc-button?module"></script>
</head>
<body>
  <sl-card>
    <pfe-datetime slot="header" type="relative" datetime="Mon Jan 2 15:04:05 EST 2010"></pfe-datetime>
    <ion-img slot="image" src="https://placekitten.com/300/200"></ion-img>
    <fast-progress-ring min="0" max="100" value="75"></fast-progress-ring>
    <mwc-button slot="footer">More Info</mwc-button>
  </sl-card>
</body>


This content originally appeared on DEV Community and was authored by Benny Powers ๐Ÿ‡ฎ๐Ÿ‡ฑ๐Ÿ‡จ๐Ÿ‡ฆ


Print Share Comment Cite Upload Translate Updates
APA

Benny Powers ๐Ÿ‡ฎ๐Ÿ‡ฑ๐Ÿ‡จ๐Ÿ‡ฆ | Sciencx (2021-12-05T18:10:05+00:00) ๐Ÿ•Ž 8 Days of Web Components Tips. Retrieved from https://www.scien.cx/2021/12/05/%f0%9f%95%8e-8-days-of-web-components-tips/

MLA
" » ๐Ÿ•Ž 8 Days of Web Components Tips." Benny Powers ๐Ÿ‡ฎ๐Ÿ‡ฑ๐Ÿ‡จ๐Ÿ‡ฆ | Sciencx - Sunday December 5, 2021, https://www.scien.cx/2021/12/05/%f0%9f%95%8e-8-days-of-web-components-tips/
HARVARD
Benny Powers ๐Ÿ‡ฎ๐Ÿ‡ฑ๐Ÿ‡จ๐Ÿ‡ฆ | Sciencx Sunday December 5, 2021 » ๐Ÿ•Ž 8 Days of Web Components Tips., viewed ,<https://www.scien.cx/2021/12/05/%f0%9f%95%8e-8-days-of-web-components-tips/>
VANCOUVER
Benny Powers ๐Ÿ‡ฎ๐Ÿ‡ฑ๐Ÿ‡จ๐Ÿ‡ฆ | Sciencx - » ๐Ÿ•Ž 8 Days of Web Components Tips. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/12/05/%f0%9f%95%8e-8-days-of-web-components-tips/
CHICAGO
" » ๐Ÿ•Ž 8 Days of Web Components Tips." Benny Powers ๐Ÿ‡ฎ๐Ÿ‡ฑ๐Ÿ‡จ๐Ÿ‡ฆ | Sciencx - Accessed . https://www.scien.cx/2021/12/05/%f0%9f%95%8e-8-days-of-web-components-tips/
IEEE
" » ๐Ÿ•Ž 8 Days of Web Components Tips." Benny Powers ๐Ÿ‡ฎ๐Ÿ‡ฑ๐Ÿ‡จ๐Ÿ‡ฆ | Sciencx [Online]. Available: https://www.scien.cx/2021/12/05/%f0%9f%95%8e-8-days-of-web-components-tips/. [Accessed: ]
rf:citation
» ๐Ÿ•Ž 8 Days of Web Components Tips | Benny Powers ๐Ÿ‡ฎ๐Ÿ‡ฑ๐Ÿ‡จ๐Ÿ‡ฆ | Sciencx | https://www.scien.cx/2021/12/05/%f0%9f%95%8e-8-days-of-web-components-tips/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.