Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow for pre-pending style tags to container element #1473

Merged
merged 8 commits into from Nov 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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