diff --git a/.changeset/fifty-monkeys-shop.md b/.changeset/fifty-monkeys-shop.md new file mode 100644 index 0000000000..f45fb02760 --- /dev/null +++ b/.changeset/fifty-monkeys-shop.md @@ -0,0 +1,6 @@ +--- +'lit-element': patch +'lit': patch +--- + +Fix `CSSStyleSheet is not defined` error that would occur when importing a Lit component in Node when both static `styles` and the `@property` decorator were used. diff --git a/packages/lit-element/src/test/node-imports.ts b/packages/lit-element/src/test/node-imports.ts index 59f35e60a0..b9340f061c 100644 --- a/packages/lit-element/src/test/node-imports.ts +++ b/packages/lit-element/src/test/node-imports.ts @@ -21,13 +21,26 @@ import 'lit-element/decorators/query-assigned-elements.js'; import 'lit-element/decorators/query-assigned-nodes.js'; import 'lit-element/decorators/query-async.js'; -import {LitElement, html} from 'lit-element'; -import {customElement} from 'lit-element/decorators.js'; +import {LitElement, html, css} from 'lit-element'; +import {customElement, property} from 'lit-element/decorators.js'; @customElement('my-element') export class MyElement extends LitElement { + // Include both static styles and a @property decorator in the test. The + // @property decorator trigggers class initialization, and if there are also + // static styles, it will trigger a test for adopted stylesheets, which could + // explode if not handled with care in the node build. + static override styles = css` + p { + color: purple; + } + `; + + @property() + name = 'World'; + override render() { - return html`Hello World`; + return html`

Hello ${this.name}

`; } } diff --git a/packages/reactive-element/src/css-tag.ts b/packages/reactive-element/src/css-tag.ts index bbd00674a4..eb6e1a0334 100644 --- a/packages/reactive-element/src/css-tag.ts +++ b/packages/reactive-element/src/css-tag.ts @@ -11,10 +11,16 @@ const global = NODE_MODE ? globalThis : window; * Whether the current browser supports `adoptedStyleSheets`. */ export const supportsAdoptingStyleSheets = - global.ShadowRoot && - (global.ShadyCSS === undefined || global.ShadyCSS.nativeShadow) && - 'adoptedStyleSheets' in Document.prototype && - 'replace' in CSSStyleSheet.prototype; + // In Node mode, it doesn't really matter whether we believe adopted style + // sheets are supported or not, because styles are handled separately as part + // of SSR anyway; however if we set this to true then we avoid `instanceof + // CSSStyleSheet` checks during initialization, meaning we don't need to shim + // that global. + NODE_MODE || + (global.ShadowRoot && + (global.ShadyCSS === undefined || global.ShadyCSS.nativeShadow) && + 'adoptedStyleSheets' in Document.prototype && + 'replace' in CSSStyleSheet.prototype); /** * A CSSResult or native CSSStyleSheet. diff --git a/packages/reactive-element/src/test/node-imports.ts b/packages/reactive-element/src/test/node-imports.ts index 9d91df2af2..5d34c77f92 100644 --- a/packages/reactive-element/src/test/node-imports.ts +++ b/packages/reactive-element/src/test/node-imports.ts @@ -22,11 +22,24 @@ import '@lit/reactive-element/decorators/query-assigned-elements.js'; import '@lit/reactive-element/decorators/query-assigned-nodes.js'; import '@lit/reactive-element/decorators/query-async.js'; -import {customElement} from '@lit/reactive-element/decorators.js'; -import {ReactiveElement} from '@lit/reactive-element'; +import {customElement, property} from '@lit/reactive-element/decorators.js'; +import {ReactiveElement, css} from '@lit/reactive-element'; @customElement('my-element') -export class MyElement extends ReactiveElement {} +export class MyElement extends ReactiveElement { + // Include both static styles and a @property decorator in the test. The + // @property decorator trigggers class initialization, and if there are also + // static styles, it will trigger a test for adopted stylesheets, which could + // explode if not handled with care in the node build. + static override styles = css` + p { + color: purple; + } + `; + + @property() + name = 'World'; +} export class MyOtherElement extends ReactiveElement {} customElements.define('my-other-element', MyOtherElement);