Skip to content

Commit

Permalink
Allow for pre-pending style tags to container element (emotion-js#1473)
Browse files Browse the repository at this point in the history
* Add prepend option to createCache

* changeset

* Simplify implementation a little bit

* Add test

* Tweak changeset

* Add new prepend option to TS types

* Add type for prepend in createCache options as well
  • Loading branch information
jcharry authored and Andarist committed Nov 25, 2019
1 parent b600be5 commit b3868a5
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 4 deletions.
6 changes: 6 additions & 0 deletions .changeset/gorgeous-steaks-report.md
@@ -0,0 +1,6 @@
---
'@emotion/cache': minor
'@emotion/sheet': minor
---

Accept new `prepend` option to allow for adding style tags at the beginning of the specified DOM container.
6 changes: 6 additions & 0 deletions packages/cache/README.md
Expand Up @@ -56,3 +56,9 @@ The prefix before class names. It will also be set as the value of the `data-emo
`HTMLElement`

A DOM node that emotion will insert all of its style tags into. This is useful for inserting styles into iframes.

### `prepend`

`boolean`

A string representing whether to prepend rather than append style tags into the specified container DOM node.
6 changes: 4 additions & 2 deletions packages/cache/src/index.js
Expand Up @@ -19,7 +19,8 @@ export type Options = {
prefix?: PrefixOption,
key?: string,
container?: HTMLElement,
speedy?: boolean
speedy?: boolean,
prepend?: boolean
}

let rootServerStylisCache = {}
Expand Down Expand Up @@ -240,7 +241,8 @@ let createCache = (options?: Options): EmotionCache => {
key,
container,
nonce: options.nonce,
speedy: options.speedy
speedy: options.speedy,
prepend: options.prepend
}),
nonce: options.nonce,
inserted,
Expand Down
1 change: 1 addition & 0 deletions packages/cache/types/index.d.ts
Expand Up @@ -12,6 +12,7 @@ export interface Options {
key?: string
container?: HTMLElement
speedy?: boolean
prepend?: boolean
}

export default function createCache(options?: Options): EmotionCache
23 changes: 23 additions & 0 deletions packages/sheet/__tests__/__snapshots__/index.js.snap
@@ -1,5 +1,28 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`StyleSheet should accept prepend option 1`] = `
<html>
<head>
<style
data-emotion=""
>
html { color: hotpink; }
</style>
<style
data-emotion=""
>
* { box-sizing: border-box; }
</style>
<style
id="other"
/>
</head>
<body />
</html>
`;

exports[`StyleSheet should insert a rule into the DOM when not in speedy 1`] = `
<html>
<head>
Expand Down
16 changes: 16 additions & 0 deletions packages/sheet/__tests__/index.js
Expand Up @@ -3,6 +3,7 @@ import { safeQuerySelector } from 'test-utils'
import { StyleSheet } from '@emotion/sheet'

const rule = 'html { color: hotpink; }'
const rule2 = '* { box-sizing: border-box; }'

let defaultOptions = {
key: '',
Expand Down Expand Up @@ -110,4 +111,19 @@ describe('StyleSheet', () => {
expect(sheet.tags[0].sheet.cssRules[0]).toBeInstanceOf(window.CSSImportRule)
sheet.flush()
})

it('should accept prepend option', () => {
const head = safeQuerySelector('head')
const otherStyle = document.createElement('style')
otherStyle.setAttribute('id', 'other')
head.appendChild(otherStyle)

const sheet = new StyleSheet({ ...defaultOptions, prepend: true })
sheet.insert(rule)
sheet.insert(rule2)
expect(document.documentElement).toMatchSnapshot()

sheet.flush()
head.removeChild(otherStyle)
})
})
7 changes: 5 additions & 2 deletions packages/sheet/src/index.js
Expand Up @@ -43,7 +43,8 @@ export type Options = {
nonce?: string,
key: string,
container: HTMLElement,
speedy?: boolean
speedy?: boolean,
prepend?: boolean
}

function createStyleElement(options: {
Expand All @@ -66,6 +67,7 @@ export class StyleSheet {
container: HTMLElement
key: string
nonce: string | void
prepend: boolean | void
before: Element | null
constructor(options: Options) {
this.isSpeedy =
Expand All @@ -78,6 +80,7 @@ export class StyleSheet {
// key is the value of the data-emotion attribute, it's used to identify different sheets
this.key = options.key
this.container = options.container
this.prepend = options.prepend
this.before = null
}
insert(rule: string) {
Expand All @@ -88,7 +91,7 @@ export class StyleSheet {
let tag = createStyleElement(this)
let before
if (this.tags.length === 0) {
before = this.before
before = this.prepend ? this.container.firstChild : this.before
} else {
before = this.tags[this.tags.length - 1].nextSibling
}
Expand Down
1 change: 1 addition & 0 deletions packages/sheet/types/index.d.ts
Expand Up @@ -6,6 +6,7 @@ export interface Options {
key: string
container: HTMLElement
speedy?: boolean
prepend?: boolean
}

export class StyleSheet {
Expand Down

0 comments on commit b3868a5

Please sign in to comment.