Skip to content

Commit fd4332f

Browse files
authored
Merge pull request #424 from phase2/feature/adopted-stylesheets
Controller: `@phase2/outline-adopted-stylesheets-controller`
2 parents b08e21f + 01a874f commit fd4332f

File tree

6 files changed

+135
-0
lines changed

6 files changed

+135
-0
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# @phase2/outline-adopted-stylesheets-controller
2+
3+
## 0.0.1
4+
5+
### Patch Changes
6+
7+
- Adding AdoptedStylesheets Controller
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# AdoptedStyleSheets Controller
2+
3+
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`.
4+
5+
## Overview
6+
7+
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/).
8+
9+
## Methods
10+
11+
The `AdoptedStyleSheets` controller provides the following methods:
12+
13+
- `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.
14+
15+
- `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.
16+
17+
- `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.
18+
19+
## Usage
20+
21+
Here is an example of how to use the `AdoptedStyleSheets` controller in a component:
22+
23+
```typescript
24+
import { AdoptedStyleSheets } from '@phase2/outline-adopted-stylesheets-controller';
25+
import { css, CSSResult } from 'lit';
26+
import { OutlineElement } from '@phase2/outline-core';
27+
import globalStyles from './my-component.lightDom.css.lit';
28+
29+
class MyComponent extends OutlineElement {
30+
adoptedStylesheets: AdoptedStyleSheets;
31+
32+
connectedCallback() {
33+
super.connectedCallback();
34+
this.adoptedStylesheets = new AdoptedStyleSheets(globalStyles);
35+
this.addController(this.adoptedStylesheets);
36+
}
37+
}
38+
```
39+
40+
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.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { AdoptedStyleSheets } from './src/adopted-stylesheets';
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"name": "@phase2/outline-adopted-stylesheets-controller",
3+
"version": "0.0.1",
4+
"description": "Controller to help with managing native AdoptedStylesheet implementations.",
5+
"keywords": [
6+
"outline components",
7+
"outline design",
8+
"CSS",
9+
"style",
10+
"AdoptedStylesheets"
11+
],
12+
"main": "index.ts",
13+
"types": "index.ts",
14+
"typings": "index.d.ts",
15+
"files": [
16+
"/dist/",
17+
"/src/",
18+
"!/dist/tsconfig.build.tsbuildinfo"
19+
],
20+
"author": "Phase2 Technology",
21+
"repository": {
22+
"type": "git",
23+
"url": "https://github.com/phase2/outline.git",
24+
"directory": "packages/controllers/adopted-stylesheets"
25+
},
26+
"homepage": "https://github.com/phase2/outline/tree/next/packages/controllers/adopted-stylesheets",
27+
"license": "BSD-3-Clause",
28+
"scripts": {
29+
"build": "node ../../../scripts/build.js",
30+
"package": "yarn publish"
31+
},
32+
"dependencies": {
33+
"lit": "^2.3.1"
34+
},
35+
"devDependencies": {
36+
"tslib": "^2.1.0"
37+
},
38+
"publishConfig": {
39+
"access": "public"
40+
},
41+
"exports": {
42+
".": "./index.ts"
43+
}
44+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { ReactiveController, CSSResult } from 'lit';
2+
3+
export class AdoptedStyleSheets implements ReactiveController {
4+
private static styleSheetMap = new Map<string, CSSStyleSheet>();
5+
private documentSheet: CSSStyleSheet;
6+
7+
constructor(globalStyles: CSSResult) {
8+
const cssText = globalStyles.cssText;
9+
if (!AdoptedStyleSheets.styleSheetMap.has(cssText)) {
10+
const newSheet = new CSSStyleSheet();
11+
newSheet.replaceSync(cssText);
12+
AdoptedStyleSheets.styleSheetMap.set(cssText, newSheet);
13+
}
14+
this.documentSheet =
15+
AdoptedStyleSheets.styleSheetMap.get(cssText) || new CSSStyleSheet();
16+
}
17+
18+
hostConnected() {
19+
if (!document.adoptedStyleSheets.includes(this.documentSheet)) {
20+
document.adoptedStyleSheets = [
21+
...document.adoptedStyleSheets,
22+
this.documentSheet,
23+
];
24+
}
25+
}
26+
27+
hostDisconnected() {
28+
if (document.adoptedStyleSheets.includes(this.documentSheet)) {
29+
document.adoptedStyleSheets = document.adoptedStyleSheets.filter(
30+
sheet => sheet !== this.documentSheet
31+
);
32+
}
33+
}
34+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"extends": "../../../tsconfig.json",
3+
"compilerOptions": {
4+
"rootDir": ".",
5+
"outDir": "./dist"
6+
},
7+
"include": ["index.ts", "src/**/*", "tests/**/*"],
8+
"references": [{ "path": "../../outline-core/tsconfig.build.json" }]
9+
}

0 commit comments

Comments
 (0)