diff --git a/.changeset/five-balloons-sneeze.md b/.changeset/five-balloons-sneeze.md new file mode 100644 index 000000000..8eefc5f3e --- /dev/null +++ b/.changeset/five-balloons-sneeze.md @@ -0,0 +1,6 @@ +--- +'@emotion/cache': patch +'@emotion/sheet': patch +--- + +TypeScript type for the `container` option has been adjusted. It will now accept a `ShadowRoot`, or any other kind of `Node`. diff --git a/packages/cache/README.md b/packages/cache/README.md index 1429cc68b..5a3889a21 100644 --- a/packages/cache/README.md +++ b/packages/cache/README.md @@ -51,7 +51,7 @@ The prefix before class names. It will also be set as the value of the `data-emo ### `container` -`HTMLElement` +`Node` A DOM node that emotion will insert all of its style tags into. This is useful for inserting styles into iframes or windows. diff --git a/packages/cache/__tests__/__snapshots__/index.js.snap b/packages/cache/__tests__/__snapshots__/index.js.snap index 3d688782b..8c0879fc9 100644 --- a/packages/cache/__tests__/__snapshots__/index.js.snap +++ b/packages/cache/__tests__/__snapshots__/index.js.snap @@ -1,5 +1,38 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`should accept container option 1`] = ` +.emotion-0 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + color: blue; +} + + + + +
+ + + +
+
+
+
+ +`; + exports[`should accept insertionPoint option 1`] = ` diff --git a/packages/cache/__tests__/index.js b/packages/cache/__tests__/index.js index a1c8fd8db..15751f216 100644 --- a/packages/cache/__tests__/index.js +++ b/packages/cache/__tests__/index.js @@ -34,3 +34,24 @@ it('should accept insertionPoint option', () => { expect(document.head).toMatchSnapshot() }) + +it('should accept container option', () => { + const body = safeQuerySelector('body') + + body.innerHTML = ` +
+ ` + + const cache = createCache({ + key: 'test-container', + container: safeQuerySelector('#container') + }) + + render( + +
+ + ) + + expect(document.body).toMatchSnapshot() +}) diff --git a/packages/cache/src/index.js b/packages/cache/src/index.js index afde219a0..4545d8037 100644 --- a/packages/cache/src/index.js +++ b/packages/cache/src/index.js @@ -92,8 +92,7 @@ let createCache = (options: Options): EmotionCache => { } } let inserted = {} - // $FlowFixMe - let container: HTMLElement + let container: Node const nodesToHydrate = [] if (isBrowser) { container = options.container || ((document.head: any): HTMLHeadElement) @@ -250,7 +249,7 @@ let createCache = (options: Options): EmotionCache => { key, sheet: new StyleSheet({ key, - container: ((container: any): HTMLElement), + container: ((container: any): Node), nonce: options.nonce, speedy: options.speedy, prepend: options.prepend, diff --git a/packages/cache/types/index.d.ts b/packages/cache/types/index.d.ts index 032744da1..7822587db 100644 --- a/packages/cache/types/index.d.ts +++ b/packages/cache/types/index.d.ts @@ -34,7 +34,7 @@ export interface Options { nonce?: string stylisPlugins?: Array key: string - container?: HTMLElement + container?: Node speedy?: boolean /** @deprecate use `insertionPoint` instead */ prepend?: boolean diff --git a/packages/sheet/README.md b/packages/sheet/README.md index 328e78db3..e4c5ba83b 100644 --- a/packages/sheet/README.md +++ b/packages/sheet/README.md @@ -25,7 +25,7 @@ sheet.insert('html { color: hotpink; }') type Options = { nonce?: string key: string - container: HTMLElement + container: Node speedy?: boolean prepend?: boolean } diff --git a/packages/sheet/__tests__/__snapshots__/index.js.snap b/packages/sheet/__tests__/__snapshots__/index.js.snap index 21fac0955..6ecbc683d 100644 --- a/packages/sheet/__tests__/__snapshots__/index.js.snap +++ b/packages/sheet/__tests__/__snapshots__/index.js.snap @@ -271,3 +271,24 @@ exports[`StyleSheet should work if insertionPoint is last element 1`] = ` `; + +exports[`StyleSheet should work with a ShadowRoot container 1`] = ` + + + +
+ + +`; + +exports[`StyleSheet should work with a ShadowRoot container 2`] = ` +HTMLCollection [ + , +] +`; diff --git a/packages/sheet/__tests__/index.js b/packages/sheet/__tests__/index.js index 5b1b23c43..5cebf0b8c 100644 --- a/packages/sheet/__tests__/index.js +++ b/packages/sheet/__tests__/index.js @@ -105,6 +105,23 @@ describe('StyleSheet', () => { sheet.flush() }) + it('should work with a ShadowRoot container', () => { + const div = document.createElement('div') + // $FlowFixMe + document.body.appendChild(div) + const container = div.attachShadow({ mode: 'open' }) + const sheet = new StyleSheet({ ...defaultOptions, container }) + expect(sheet.container).toBe(container) + sheet.insert(rule) + expect(document.documentElement).toMatchSnapshot() + // The shadowRoot is not serialized in the snapshot, so we need to take a + // separate snapshot of the shadowRoot's children. + expect(container.children).toMatchSnapshot() + expect(sheet.tags).toHaveLength(1) + expect(sheet.tags[0].parentNode).toBe(container) + sheet.flush() + }) + it('should accept prepend option', () => { const head = safeQuerySelector('head') const otherStyle = document.createElement('style') diff --git a/packages/sheet/src/index.js b/packages/sheet/src/index.js index cd559a73a..3828c2697 100644 --- a/packages/sheet/src/index.js +++ b/packages/sheet/src/index.js @@ -42,7 +42,7 @@ function sheetForTag(tag: HTMLStyleElement): CSSStyleSheet { export type Options = { nonce?: string, key: string, - container: HTMLElement, + container: Node, speedy?: boolean, prepend?: boolean, insertionPoint?: HTMLElement @@ -66,7 +66,8 @@ export class StyleSheet { isSpeedy: boolean ctr: number tags: HTMLStyleElement[] - container: HTMLElement + // Using Node instead of HTMLElement since container may be a ShadowRoot + container: Node key: string nonce: string | void prepend: boolean | void diff --git a/packages/sheet/types/index.d.ts b/packages/sheet/types/index.d.ts index d07ebfda4..4e0c258e2 100644 --- a/packages/sheet/types/index.d.ts +++ b/packages/sheet/types/index.d.ts @@ -4,7 +4,7 @@ export interface Options { nonce?: string key: string - container: HTMLElement + container: Node speedy?: boolean /** @deprecate use `insertionPoint` instead */ prepend?: boolean @@ -15,10 +15,10 @@ export class StyleSheet { isSpeedy: boolean ctr: number tags: Array - container: HTMLElement + container: Node key: string nonce?: string - before?: Element | null + before?: ChildNode | null constructor(options?: Options) insert(rule: string): void flush(): void diff --git a/packages/sheet/types/tests.ts b/packages/sheet/types/tests.ts index 50720597d..68dcab673 100644 --- a/packages/sheet/types/tests.ts +++ b/packages/sheet/types/tests.ts @@ -51,3 +51,9 @@ styleSheet.flush() styleSheet.flush(undefined as any) // $ExpectError styleSheet.flush(...(undefined as any as Array)) + +const shadowRoot = document.createElement('div').attachShadow({ mode: 'open' }) +const shadowStyleSheet = new StyleSheet({ + key: 'abc', + container: shadowRoot +})