Skip to content

Commit

Permalink
Convert @emotion/primitives-core to TypeScript (#2818)
Browse files Browse the repository at this point in the history
* [wip] primitives-core TS migration

* Finish converting primitives-core to TS

* Update yarn.lock?

* Implement @Andarist's feedback for primitives-core TS migration

* Fix regression
  • Loading branch information
srmagura authored Jul 31, 2022
1 parent 945169b commit 8546dd0
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 48 deletions.
1 change: 1 addition & 0 deletions packages/primitives-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
},
"devDependencies": {
"@emotion/react": "11.9.3",
"@types/css-to-react-native": "^3.0.0",
"react": "16.14.0"
},
"homepage": "https://emotion.sh",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import transform from 'css-to-react-native'
import transform, { Style } from 'css-to-react-native'
import { AbstractStyleSheet } from './types'
import { interleave } from './utils'

// this is for handleInterpolation
// they're reset on every call to css
// this is done so we don't create a new
// handleInterpolation function on every css call
let styles
let generated = {}
let styles: unknown[] | undefined
let generated: Record<string, unknown> = {}
let buffer = ''
let lastType
let lastType: string | undefined

function handleInterpolation(
interpolation,
i /*: number */,
arr /*: Array<*> */
this: unknown,
interpolation: any,
i: number,
arr: any[]
) {
let type = typeof interpolation

Expand Down Expand Up @@ -44,7 +46,7 @@ function handleInterpolation(
if (lastType === 'string' && (isRnStyle || isIrrelevant)) {
let converted = convertStyles(buffer)
if (converted !== undefined) {
styles.push(converted)
styles!.push(converted)
}
buffer = ''
}
Expand All @@ -58,13 +60,13 @@ function handleInterpolation(
if (arr.length - 1 === i) {
let converted = convertStyles(buffer)
if (converted !== undefined) {
styles.push(converted)
styles!.push(converted)
}
buffer = ''
}
}
if (isRnStyle) {
styles.push(interpolation)
styles!.push(interpolation)
}
if (Array.isArray(interpolation)) {
interpolation.forEach(handleInterpolation, this)
Expand All @@ -74,10 +76,10 @@ function handleInterpolation(

// Use platform specific StyleSheet method for creating the styles.
// This enables us to use the css``/css({}) in any environment (Native | Sketch | Web)
export function createCss(StyleSheet /*: Object */) {
return function css(...args) {
export function createCss(StyleSheet: AbstractStyleSheet) {
return function css(this: unknown, ...args: any[]) {
const prevBuffer = buffer
let vals
let vals: any[]

// these are declared earlier
// this is done so we don't create a new
Expand All @@ -89,7 +91,7 @@ export function createCss(StyleSheet /*: Object */) {
if (args[0] == null || args[0].raw === undefined) {
vals = args
} else {
vals = interleave(args)
vals = interleave(args as [any, ...any[]])
}

try {
Expand All @@ -111,7 +113,7 @@ export function createCss(StyleSheet /*: Object */) {

let propertyValuePattern = /\s*([^\s]+)\s*:\s*(.+?)\s*$/

function convertPropertyValue(style) {
function convertPropertyValue(this: [string, string][], style: string): void {
// Get prop name and prop value
let match = propertyValuePattern.exec(style)
// match[2] will be " " in cases where there is no value
Expand All @@ -121,14 +123,14 @@ function convertPropertyValue(style) {
// be the whole string so we remove it
match.shift()
// yes i know this looks funny
this.push(match)
this.push(match as unknown as [string, string])
}
}

function convertStyles(str /*: string */) {
function convertStyles(str: string): Style | undefined {
if (str.trim() === '') return

const stylePairs = []
const stylePairs: [string, string][] = []

const parsedString = str.split(';')

Expand All @@ -137,9 +139,9 @@ function convertStyles(str /*: string */) {
try {
return transform(stylePairs)
} catch (error) {
const msg = error.message
const msg = (error as { message?: string } | undefined)?.message

if (msg.includes('Failed to parse declaration')) {
if (msg && msg.includes('Failed to parse declaration')) {
const values = msg
.replace('Failed to parse declaration ', '')
.replace(/"/g, '')
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,35 @@ import * as React from 'react'
import { interleave } from './utils'
import { ThemeContext } from '@emotion/react'
import { createCss } from './css'
import { AbstractStyleSheet } from './types'

let testOmitPropsOnComponent = prop => prop !== 'theme' && prop !== 'as'
let testOmitPropsOnComponent = (prop: string) =>
prop !== 'theme' && prop !== 'as'

/*
type CreateStyledOptions = {
getShouldForwardProp: (cmp: React.ElementType) => (prop: string) => boolean
interface CreateStyledOptions {
getShouldForwardProp(cmp: React.ElementType): (prop: string) => boolean
}

type StyledOptions = {
shouldForwardProp?: (prop: string) => boolean
interface StyledOptions {
shouldForwardProp?(prop: string): boolean
}

type StyledProps = Record<string, unknown> & {
as?: React.ElementType
}
*/

export function createStyled(
StyleSheet /*: Object */,
{
getShouldForwardProp = () => testOmitPropsOnComponent
} /*: CreateStyledOptions */ = {}
StyleSheet: AbstractStyleSheet,
options?: CreateStyledOptions
) {
const getShouldForwardProp =
options?.getShouldForwardProp ?? (() => testOmitPropsOnComponent)

const css = createCss(StyleSheet)

return function createEmotion(
component /*: React.ElementType */,
options /* ?: StyledOptions */
component: React.ElementType,
options?: StyledOptions
) {
let shouldForwardProp =
options && options.shouldForwardProp
Expand All @@ -35,17 +40,17 @@ export function createStyled(
shouldForwardProp || getShouldForwardProp(component)
let shouldUseAs = !defaultShouldForwardProp('as')

return function createStyledComponent(...rawStyles) {
let styles
return function createStyledComponent(...rawStyles: any[]) {
let styles: any[]

if (rawStyles[0] == null || rawStyles[0].raw === undefined) {
styles = rawStyles
} else {
styles = interleave(rawStyles)
styles = interleave(rawStyles as [any, ...any[]])
}

// do we really want to use the same infra as the web since it only really uses theming?
let Styled = React.forwardRef((props, ref) => {
let Styled = React.forwardRef<unknown, StyledProps>((props, ref) => {
const finalTag = (shouldUseAs && props.as) || component

let mergedProps = props
Expand All @@ -62,7 +67,7 @@ export function createStyled(
? getShouldForwardProp(finalTag)
: defaultShouldForwardProp

let newProps = {}
let newProps: Record<string, unknown> = {}

for (let key in props) {
if (shouldUseAs && key === 'as') continue
Expand All @@ -77,17 +82,26 @@ export function createStyled(

return React.createElement(finalTag, newProps)
})
Styled.withComponent = (newComponent /*: React.ElementType */) =>
createEmotion(newComponent)(...styles)

Styled.displayName = `emotion(${getDisplayName(component)})`

return Styled
const withComponent = (newComponent: React.ElementType) =>
createEmotion(newComponent)(...styles)

const castedStyled = Styled as typeof Styled & {
withComponent: typeof withComponent
}

castedStyled.withComponent = withComponent

return castedStyled
}
}
}

const getDisplayName = primitive =>
const getDisplayName = (
primitive: string | { displayName?: string; name?: string }
) =>
typeof primitive === 'string'
? primitive
: primitive.displayName || primitive.name || 'Styled'
10 changes: 10 additions & 0 deletions packages/primitives-core/src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
type NamedStyles<T> = { [P in keyof T]: unknown }

// This is based on the StyleSheet type from @types/react-native
export interface AbstractStyleSheet {
create<T extends NamedStyles<T> | NamedStyles<any>>(
styles: T | NamedStyles<T>
): T

flatten(style?: unknown[]): unknown
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
export function interleave(vals /*: Array */) {
export function interleave(
vals: [TemplateStringsArray, ...unknown[]]
): unknown[] {
let strings = vals[0]
let finalArray = [strings[0]]
let finalArray: unknown[] = [strings[0]]
for (let i = 1, len = vals.length; i < len; i++) {
finalArray.push(vals[i])
if (strings[i] !== undefined) {
Expand Down
18 changes: 14 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5880,6 +5880,11 @@
resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.10.tgz#61cc8469849e5bcdd0c7044122265c39cec10cf4"
integrity sha512-C7srjHiVG3Ey1nR6d511dtDkCEjxuN9W1HWAEjGq8kpcwmNM6JJkpC0xvabM7BXTG2wDq8Eu33iH9aQKa7IvLQ==

"@types/css-to-react-native@^3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@types/css-to-react-native/-/css-to-react-native-3.0.0.tgz#63831e79c3855f78981217c745fb4bd7c8733d05"
integrity sha512-MjLLf4YKMQYKnZ7xPZisizAiC8C5EQUKSLeimtApbc82WJDDN0TQBCY+HhWJHsSQ8Le4509aD/O7MWV73jJykQ==

"@types/debug@^0.0.30":
version "0.0.30"
resolved "https://registry.yarnpkg.com/@types/debug/-/debug-0.0.30.tgz#dc1e40f7af3b9c815013a7860e6252f6352a84df"
Expand Down Expand Up @@ -9168,11 +9173,16 @@ caniuse-api@^3.0.0:
lodash.memoize "^4.1.2"
lodash.uniq "^4.5.0"

caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001010:
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001010:
version "1.0.30001012"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001012.tgz#653ec635e815b9e0fb801890923b0c2079eb34ec"
integrity sha512-7RR4Uh04t9K1uYRWzOJmzplgEOAXbfK72oVNokCdMzA67trrhPzy93ahKk1AWHiA0c58tD2P+NHqxrA8FZ+Trg==

caniuse-lite@^1.0.30000844:
version "1.0.30001373"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001373.tgz#2dc3bc3bfcb5d5a929bec11300883040d7b4b4be"
integrity sha512-pJYArGHrPp3TUqQzFYRmP/lwJlj8RCbVe3Gd3eJQkAV8SAC6b19XS9BjMvRdvaS8RMkaTN8ZhoHP6S1y8zzwEQ==

caniuse-lite@^1.0.30001109:
version "1.0.30001204"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001204.tgz#256c85709a348ec4d175e847a3b515c66e79f2aa"
Expand Down Expand Up @@ -11874,9 +11884,9 @@ ejs@^3.1.6:
jake "^10.6.1"

electron-to-chromium@^1.3.47:
version "1.3.212"
resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.212.tgz#15d81ba96edb8ae6f937cde0fdb18c1c3c2bfec5"
integrity sha512-H8z5Smi1s1u1zGegEBfbxUAzrxyk1JoRHHHrlNGfhxv3sTb+p/Jz7JDvrR4196Q/Ip8r4+XwWcLvKrUjFKoJAg==
version "1.4.206"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.206.tgz#580ff85b54d7ec0c05f20b1e37ea0becdd7b0ee4"
integrity sha512-h+Fadt1gIaQ06JaIiyqPsBjJ08fV5Q7md+V8bUvQW/9OvXfL2LRICTz2EcnnCP7QzrFTS6/27MRV6Bl9Yn97zA==

elegant-spinner@^1.0.1:
version "1.0.1"
Expand Down

0 comments on commit 8546dd0

Please sign in to comment.