Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions packages/controllers/adopted-stylesheets/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# @phase2/outline-adopted-stylesheets-controller

## 0.0.1

### Patch Changes

- Adding AdoptedStylesheets Controller
40 changes: 40 additions & 0 deletions packages/controllers/adopted-stylesheets/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# AdoptedStyleSheets Controller

The `AdoptedStyleSheets` controller is a part of the `@phase2/outline-adopted-stylesheets-controller` package. This controller helps components attach "global" document styles without duplication at the component level as well as de-duping any previous inclusions into `AdoptedStyleSheets`.

## Overview

Adopted stylesheets are a way to apply styles to a document or a shadow root. They are a part of the CSS Shadow Parts specification. You can read more about them [here](https://wicg.github.io/construct-stylesheets/).

## Methods

The `AdoptedStyleSheets` controller provides the following methods:

- `constructor(globalStyles: CSSResult)`: This method is used to create a new instance of the `AdoptedStyleSheets` controller. It takes a `CSSResult` object as a parameter, which represents the global styles to be adopted.

- `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:

```typescript
import { AdoptedStyleSheets } from '@phase2/outline-adopted-stylesheets-controller';
import { css, CSSResult } from 'lit';
import { OutlineElement } from '@phase2/outline-core';
import globalStyles from './my-component.lightDom.css.lit';

class MyComponent extends OutlineElement {
adoptedStylesheets: AdoptedStyleSheets;

connectedCallback() {
super.connectedCallback();
this.adoptedStylesheets = new AdoptedStyleSheets(globalStyles);
this.addController(this.adoptedStylesheets);
}
}
```

In the provided example, the `connectedCallback` method is utilized. This method is invoked whenever the element is inserted into the DOM. Within this method, an instance of `AdoptedStyleSheets` is created and added as a controller. This is a more efficient approach than creating the instance and adding the controller within the `constructor`. The reason for this is that it delays these operations until the element is actually inserted into the DOM. If there are many such elements that are created but not immediately added to the DOM, this approach can significantly improve the startup performance of your application. Therefore, the `connectedCallback` method is a crucial part of managing the lifecycle of a web component, especially when dealing with adopted stylesheets.
1 change: 1 addition & 0 deletions packages/controllers/adopted-stylesheets/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { AdoptedStyleSheets } from './src/adopted-stylesheets';
44 changes: 44 additions & 0 deletions packages/controllers/adopted-stylesheets/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"name": "@phase2/outline-adopted-stylesheets-controller",
"version": "0.0.1",
"description": "Controller to help with managing native AdoptedStylesheet implementations.",
"keywords": [
"outline components",
"outline design",
"CSS",
"style",
"AdoptedStylesheets"
],
"main": "index.ts",
"types": "index.ts",
"typings": "index.d.ts",
"files": [
"/dist/",
"/src/",
"!/dist/tsconfig.build.tsbuildinfo"
],
"author": "Phase2 Technology",
"repository": {
"type": "git",
"url": "https://github.com/phase2/outline.git",
"directory": "packages/controllers/adopted-stylesheets"
},
"homepage": "https://github.com/phase2/outline/tree/next/packages/controllers/adopted-stylesheets",
"license": "BSD-3-Clause",
"scripts": {
"build": "node ../../../scripts/build.js",
"package": "yarn publish"
},
"dependencies": {
"lit": "^2.3.1"
},
"devDependencies": {
"tslib": "^2.1.0"
},
"publishConfig": {
"access": "public"
},
"exports": {
".": "./index.ts"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { ReactiveController, CSSResult } from 'lit';

export class AdoptedStyleSheets implements ReactiveController {
private static styleSheetMap = new Map<string, CSSStyleSheet>();
private documentSheet: CSSStyleSheet;

constructor(globalStyles: CSSResult) {
const cssText = globalStyles.cssText;
if (!AdoptedStyleSheets.styleSheetMap.has(cssText)) {
const newSheet = new CSSStyleSheet();
newSheet.replaceSync(cssText);
AdoptedStyleSheets.styleSheetMap.set(cssText, newSheet);
}
this.documentSheet =
AdoptedStyleSheets.styleSheetMap.get(cssText) || new CSSStyleSheet();
}

hostConnected() {
if (!document.adoptedStyleSheets.includes(this.documentSheet)) {
document.adoptedStyleSheets = [
...document.adoptedStyleSheets,
this.documentSheet,
];
}
}

hostDisconnected() {
if (document.adoptedStyleSheets.includes(this.documentSheet)) {
document.adoptedStyleSheets = document.adoptedStyleSheets.filter(
sheet => sheet !== this.documentSheet
);
}
}
}
9 changes: 9 additions & 0 deletions packages/controllers/adopted-stylesheets/tsconfig.build.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "../../../tsconfig.json",
"compilerOptions": {
"rootDir": ".",
"outDir": "./dist"
},
"include": ["index.ts", "src/**/*", "tests/**/*"],
"references": [{ "path": "../../outline-core/tsconfig.build.json" }]
}