diff --git a/.changeset/eighty-spies-beam.md b/.changeset/eighty-spies-beam.md new file mode 100644 index 000000000..1ac2b956a --- /dev/null +++ b/.changeset/eighty-spies-beam.md @@ -0,0 +1,5 @@ +--- +'@emotion/css': minor +--- + +Source code has been migrated to TypeScript. From now on type declarations will be emitted based on that, instead of being hand-written. diff --git a/.changeset/modern-tomatoes-work.md b/.changeset/modern-tomatoes-work.md new file mode 100644 index 000000000..0aace4bba --- /dev/null +++ b/.changeset/modern-tomatoes-work.md @@ -0,0 +1,5 @@ +--- +'@emotion/css': patch +--- + +Fixed `options` parameter to `createEmotion` from `@emotion/css/create-instance` incorrectly being marked as optional when it's required. diff --git a/packages/css/create-instance/package.json b/packages/css/create-instance/package.json index 203a18da1..bd294c0d3 100644 --- a/packages/css/create-instance/package.json +++ b/packages/css/create-instance/package.json @@ -2,7 +2,7 @@ "main": "dist/emotion-css-create-instance.cjs.js", "module": "dist/emotion-css-create-instance.esm.js", "umd:main": "dist/emotion-css-create-instance.umd.min.js", - "types": "../types/create-instance", + "types": "dist/emotion-css-create-instance.cjs.d.ts", "preconstruct": { "umdName": "createEmotion" } diff --git a/packages/css/package.json b/packages/css/package.json index d95f3be98..6e1a75f6e 100644 --- a/packages/css/package.json +++ b/packages/css/package.json @@ -4,7 +4,7 @@ "description": "The Next Generation of CSS-in-JS.", "main": "dist/emotion-css.cjs.js", "module": "dist/emotion-css.esm.js", - "types": "types/index.d.ts", + "types": "dist/emotion-css.cjs.d.ts", "files": [ "src", "dist", @@ -53,8 +53,8 @@ "preconstruct": { "umdName": "emotion", "entrypoints": [ - "./index.js", - "./create-instance.js" + "./index.ts", + "./create-instance.ts" ] } } diff --git a/packages/css/src/create-instance.js b/packages/css/src/create-instance.ts similarity index 52% rename from packages/css/src/create-instance.js rename to packages/css/src/create-instance.ts index 052bb18b0..2bf7cc281 100644 --- a/packages/css/src/create-instance.js +++ b/packages/css/src/create-instance.ts @@ -1,24 +1,80 @@ import createCache from '@emotion/cache' -import { serializeStyles } from '@emotion/serialize' +import { + serializeStyles, + CSSInterpolation, + Interpolation +} from '@emotion/serialize' import { insertStyles, - getRegisteredStyles - /* type EmotionCache, */ - /* type SerializedStyles */ + getRegisteredStyles, + SerializedStyles, + RegisteredCache } from '@emotion/utils' +import { EmotionCache, Options } from '@emotion/cache' +import { StyleSheet } from '@emotion/sheet' + +export type { + CSSInterpolation, + ArrayCSSInterpolation, + ComponentSelector, + CSSObject +} from '@emotion/serialize' -function insertWithoutScoping(cache, serialized /*: SerializedStyles */) { +function insertWithoutScoping( + cache: EmotionCache, + serialized: SerializedStyles +) { if (cache.inserted[serialized.name] === undefined) { return cache.insert('', serialized, cache.sheet, true) } } +export type { EmotionCache, Options } + +export interface ArrayClassNamesArg extends Array {} +export type ClassNamesArg = + | undefined + | null + | string + | boolean + | { [className: string]: boolean | null | undefined } + | ArrayClassNamesArg + +export interface CSSStyleSheet extends StyleSheet { + speedy(value: boolean): void +} + +export interface Emotion { + css(template: TemplateStringsArray, ...args: Array): string + css(...args: Array): string + cx(...classNames: Array): string + flush(): void + hydrate(ids: Array): void + injectGlobal( + template: TemplateStringsArray, + ...args: Array + ): void + injectGlobal(...args: Array): void + keyframes( + template: TemplateStringsArray, + ...args: Array + ): string + keyframes(...args: Array): string + sheet: CSSStyleSheet + cache: EmotionCache + merge(className: string): string + getRegisteredStyles( + registeredStyles: Array, + className: string + ): string +} + function merge( - registered /*: Object */, - css /*: (*) => string */, - className /*: string */ + registered: RegisteredCache, + css: Emotion['css'], + className: string ) { - const registeredStyles = [] + const registeredStyles: string[] = [] const rawClassName = getRegisteredStyles( registered, registeredStyles, @@ -31,61 +87,29 @@ function merge( return rawClassName + css(registeredStyles) } -/* -export type Interpolation = any -export type Interpolations = Array - -type CreateStyles = (...args: Interpolations) => ReturnValue - -type ClassNameArg = - | string - | boolean - | { [key: string]: boolean | void | null } - | Array - | void - | null - -declare class StyleSheet { - insert(rule: string): void; - flush(): void; - speedy(newVal: boolean): void; - tags: Array; - isSpeedy: number; - ctr: number; -} - -export type Emotion = { - css: CreateStyles, - cx: (...classNames: Array) => string, - flush: () => void, - hydrate: (ids: Array) => void, - injectGlobal: CreateStyles, - keyframes: CreateStyles, - sheet: StyleSheet, - cache: EmotionCache, - merge, - getRegisteredStyles -} -*/ - -let createEmotion = (options) /*: Emotion */ => { +let createEmotion = (options: Options): Emotion => { let cache = createCache(options) - cache.sheet.speedy = function (value /*: boolean */) { + ;(cache.sheet as CSSStyleSheet).speedy = function (value: boolean) { if (process.env.NODE_ENV !== 'production' && this.ctr !== 0) { throw new Error('speedy must be changed before any rules are inserted') } this.isSpeedy = value } + cache.compat = true - let css = (...args) => { + let css: Emotion['css'] = ( + ...args: (TemplateStringsArray | Interpolation)[] + ) => { let serialized = serializeStyles(args, cache.registered, undefined) insertStyles(cache, serialized, false) return `${cache.key}-${serialized.name}` } - let keyframes = (...args) => { + let keyframes: Emotion['keyframes'] = ( + ...args: (TemplateStringsArray | Interpolation)[] + ) => { let serialized = serializeStyles(args, cache.registered) let animation = `animation-${serialized.name}` insertWithoutScoping(cache, { @@ -95,12 +119,14 @@ let createEmotion = (options) /*: Emotion */ => { return animation } - let injectGlobal = (...args) => { + let injectGlobal: Emotion['injectGlobal'] = ( + ...args: (TemplateStringsArray | Interpolation)[] + ) => { let serialized = serializeStyles(args, cache.registered) insertWithoutScoping(cache, serialized) } - let cx = (...args) => { + let cx: Emotion['cx'] = (...args) => { return merge(cache.registered, css, classnames(args)) } return { @@ -108,7 +134,7 @@ let createEmotion = (options) /*: Emotion */ => { cx, injectGlobal, keyframes, - hydrate(ids /*: Array */) { + hydrate(ids) { ids.forEach(key => { cache.inserted[key] = true }) @@ -118,14 +144,14 @@ let createEmotion = (options) /*: Emotion */ => { cache.inserted = {} cache.sheet.flush() }, - sheet: cache.sheet, + sheet: cache.sheet as CSSStyleSheet, cache, getRegisteredStyles: getRegisteredStyles.bind(null, cache.registered), merge: merge.bind(null, cache.registered, css) } } -let classnames = args => { +let classnames = (args: ClassNamesArg[]) => { let cls = '' for (let i = 0; i < args.length; i++) { let arg = args[i] diff --git a/packages/css/src/index.js b/packages/css/src/index.ts similarity index 100% rename from packages/css/src/index.js rename to packages/css/src/index.ts diff --git a/packages/css/types/create-instance.d.ts b/packages/css/types/create-instance.d.ts index 9e560390f..e505b1993 100644 --- a/packages/css/types/create-instance.d.ts +++ b/packages/css/types/create-instance.d.ts @@ -1,55 +1,4 @@ // Definitions by: Junyoung Clare Jang // TypeScript Version: 2.8 - -import { EmotionCache, Options } from '@emotion/cache' -import { CSSInterpolation } from '@emotion/serialize' -import { StyleSheet } from '@emotion/sheet' - -export { - CSSInterpolation, - ArrayCSSInterpolation, - ComponentSelector, - CSSObject -} from '@emotion/serialize' - -export { EmotionCache, Options } - -export interface ArrayClassNamesArg extends Array {} -export type ClassNamesArg = - | undefined - | null - | string - | boolean - | { [className: string]: boolean | null | undefined } - | ArrayClassNamesArg - -export interface CSSStyleSheet extends StyleSheet { - speedy(value: boolean): void -} - -export interface Emotion { - css(template: TemplateStringsArray, ...args: Array): string - css(...args: Array): string - cx(...classNames: Array): string - flush(): void - hydrate(ids: Array): void - injectGlobal( - template: TemplateStringsArray, - ...args: Array - ): void - injectGlobal(...args: Array): void - keyframes( - template: TemplateStringsArray, - ...args: Array - ): string - keyframes(...args: Array): string - sheet: CSSStyleSheet - cache: EmotionCache - merge(className: string): string - getRegisteredStyles( - registeredStyles: Array, - className: string - ): string -} - -export default function createEmotion(options?: Options): Emotion +export * from '../create-instance' +export { default } from '../create-instance' diff --git a/packages/css/types/index.d.ts b/packages/css/types/index.d.ts index 7efec6ede..546becea7 100644 --- a/packages/css/types/index.d.ts +++ b/packages/css/types/index.d.ts @@ -1,26 +1 @@ -// Definitions by: Junyoung Clare Jang -// TypeScript Version: 2.8 - -import { Emotion } from './create-instance' - -export { - ArrayClassNamesArg, - ArrayCSSInterpolation, - ClassNamesArg, - ComponentSelector, - EmotionCache, - CSSInterpolation, - CSSObject, - CSSStyleSheet -} from './create-instance' - -export const flush: Emotion['flush'] -export const hydrate: Emotion['hydrate'] -export const cx: Emotion['cx'] -export const merge: Emotion['merge'] -export const getRegisteredStyles: Emotion['getRegisteredStyles'] -export const css: Emotion['css'] -export const injectGlobal: Emotion['injectGlobal'] -export const keyframes: Emotion['keyframes'] -export const sheet: Emotion['sheet'] -export const cache: Emotion['cache'] +export * from '..' diff --git a/packages/css/types/tests-create-instance.ts b/packages/css/types/tests-create-instance.ts index e9eb4814e..103b36aaa 100644 --- a/packages/css/types/tests-create-instance.ts +++ b/packages/css/types/tests-create-instance.ts @@ -5,7 +5,7 @@ const emotion0 = createEmotion({ key: 'bar' }) // $ExpectType Emotion const emotion1 = createEmotion({ key: 'foo', - container: document.head, + container: document.head!, nonce: 'fasefw' })