npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@phase2/outline-adopted-stylesheets-controller

v1.0.4

Published

Controller to help with managing native AdoptedStylesheet implementations.

Downloads

445

Readme

AdoptedStylesheets Controller

Latest version for outline-adopted-stylesheets-controller Node.js version Lit 2 Lit 3

Overview

Adopted stylesheets offer a way to apply styles to a document or a shadow root, as part of the CSS Shadow Parts specification. The AdoptedStylesheets controller, a Lit Reactive Controller, is a robust tool for managing styles in web components. It provides a uniform method to manage both global and encapsulated styles, utilizing modern browser standards. This controller aids in preventing style duplication at the component level and ensures efficient style inclusion into AdoptedStylesheets. For more information on Lit Reactive Controllers, visit the Lit documentation.

Installing the AdoptedStylesheets Controller

To install the new package, use the following command, specific to your package manager:

With Yarn

For more information on using Yarn, visit the Yarn documentation.

yarn add --dev @phase2/outline-adopted-stylesheets-controller

With NPM

For more information on using NPM, visit the NPM documentation.

npm i --save-dev @phase2/outline-adopted-stylesheets-controller

With PNPM

For more information on using PNPM, visit the PNPM documentation.

pnpm add --save-dev @phase2/outline-adopted-stylesheets-controller

Methods

The AdoptedStylesheets controller provides the following methods:

  • constructor(globalStyles: CSSResult, [root: Document | ShadowRoot = document]): This method is used to create a new instance of the AdoptedStylesheets controller. It takes a CSSResult object and an optional root (either a Document or ShadowRoot) as parameters.

  • hostConnected(): This method is called when the host element is connected to the DOM. It adds the document's stylesheet to the adopted stylesheets if it is not already present.

  • hostDisconnected(): This method is called when the host element is disconnected from the DOM. It removes the document's stylesheet from the adopted stylesheets if it is present.

Usage

Here is an example of how to use the AdoptedStylesheets controller in a component. Samples will show incorporating two stylesheets, one to the document (global) and one to the shadowRoot (encapsulated).

Importing the package

import { AdoptedStylesheets } from '@phase2/outline-adopted-stylesheets-controller';

Importing your stylesheet(s)

import globalStyles from './styles/global-styles.css?inline';
import encapsulatedStyles from './styles/encapsulated-styles.css?inline';

CSS Structure

The globalStyles and encapsulatedStyles are imported from their respective CSS files. These stylesheets are used to style the web component and the document respectively.

  • globalStyles: This stylesheet is used to style the entire document.

  • encapsulatedStyles: This stylesheet is used to style the web component itself.

By separating the styles into global and encapsulated stylesheets, you can manage the styles in a more organized and efficient way. It also allows for better encapsulation and control over the styles, as you can decide which styles should be applied globally and which should be scoped to the web component.

CSSStyleSheet instead of CSSResultGroup

The ?inline flag is used when importing stylesheets in modern bundlers like Vite and Webpack. This flag tells the bundler to import the contents of the CSS file as a string, which can then be used directly in JavaScript or TypeScript code. This is particularly useful when working with web components, as it allows for the dynamic inclusion of styles.

The benefit of using the CSSStyleSheet type over the Lit-specific CSSResultGroup is that CSSStyleSheet is a web standard, while CSSResultGroup is specific to Lit. By using CSSStyleSheet, you're leveraging browser-native capabilities, which can lead to better performance and compatibility.

Attaching a global stylesheet

This snippet shows setting up both the global and encapsulated instance properties.

export class MyComponent extends LitElement {
  GlobalStylesheets: AdoptedStylesheets | undefined = new AdoptedStylesheets(globalStyles, document);
  
  EncapsulatedStylesheets: AdoptedStylesheets | undefined;
}

Above, the definition of GlobalStylesheets is calling the controller, and attaching immediately. Read on to understand why EncapsulatedStylesheets must be assigned differently and is only instantiated here.

Attaching an encapsulated stylesheet via createRenderRoot

Because of the methods by which Adopted Stylesheets work, we must ensure that we have a shadowRoot prior to attaching styles to it. This may seem overly verbose compared to using static styles = css'', however, static styles is a Lit-ism, and in turn has us using the "Lit way" to attach our encapsulated styles, and "this way" to attach global ones. This consolidation is purposeful to ensure we are utilizing the same, modern, browser standards based methods when possible.

createRenderRoot() {
  const root = super.createRenderRoot();
  this.EncapsulatedStylesheets = this.shadowRoot
    ? new AdoptedStylesheets(this, encapsulatedStyles, this.shadowRoot)
    : undefined;
  return root;
}

The createRenderRoot method is used here for a very specific reason. In Lit, the createRenderRoot method is used to specify the container to which the template is rendered. By default, Lit renders the template into the component's Shadow DOM. This is done by returning this.shadowRoot in the createRenderRoot method, which is the default behavior.

In this specific case, we are using createRenderRoot to adopt stylesheets into the shadow root of the component. This is done by creating a new instance of the AdoptedStylesheets class and assigning it to this.EncapsulatedStylesheets. The AdoptedStylesheets class is a controller that manages CSS stylesheets that are adopted into the document or a shadow root. By adopting the stylesheets into the shadow root, we ensure that the styles are scoped to this component and do not leak out to the rest of the page.

This could not be achieved with other lifecycle methods in Lit. The createRenderRoot method is the only method that gives us direct access to the shadow root before the template is rendered, which is necessary for adopting the stylesheets. Other lifecycle methods like connectedCallback, disconnectedCallback, updated, firstUpdated, etc., are called at different stages of the component's lifecycle and do not give us the opportunity to adopt the stylesheets into the shadow root before the template is rendered.

Additional Information

For more information about adopted stylesheets and their usage in web components, refer to the following resources: