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
+})