Initial commit: Crypto trader application

This commit is contained in:
2025-12-25 20:20:40 -05:00
commit 07a04c1bb8
47895 changed files with 2042266 additions and 0 deletions
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) Emotion team and other contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+48
View File
@@ -0,0 +1,48 @@
# @emotion/react
> Simple styling in React.
## Install
```bash
yarn add @emotion/react
```
## Usage
```jsx
/** @jsx jsx */
import { jsx, css, Global, ClassNames } from '@emotion/react'
render(
<div css={{ color: 'hotpink' }}>
<div
css={css`
color: green;
`}
/>
<Global
styles={{
body: {
margin: 0,
padding: 0
}
}}
/>
<ClassNames>
{({ css, cx }) => (
<div
className={cx(
'some-class',
css`
color: yellow;
`
)}
/>
)}
</ClassNames>
</div>
)
```
More documentation is available at [https://emotion.sh](https://emotion.sh).
+10
View File
@@ -0,0 +1,10 @@
{
"main": "dist/emotion-react-_isolated-hnrs.cjs.js",
"module": "dist/emotion-react-_isolated-hnrs.esm.js",
"umd:main": "dist/emotion-react-_isolated-hnrs.umd.min.js",
"types": "dist/emotion-react-_isolated-hnrs.cjs.d.ts",
"sideEffects": false,
"preconstruct": {
"umdName": "emotionHoistNonReactStatics"
}
}
+10
View File
@@ -0,0 +1,10 @@
{
"main": "dist/emotion-react-jsx-dev-runtime.cjs.js",
"module": "dist/emotion-react-jsx-dev-runtime.esm.js",
"umd:main": "dist/emotion-react-jsx-dev-runtime.umd.min.js",
"types": "dist/emotion-react-jsx-dev-runtime.cjs.d.ts",
"sideEffects": false,
"preconstruct": {
"umdName": "emotionReactJSXDevRuntime"
}
}
+10
View File
@@ -0,0 +1,10 @@
{
"main": "dist/emotion-react-jsx-runtime.cjs.js",
"module": "dist/emotion-react-jsx-runtime.esm.js",
"umd:main": "dist/emotion-react-jsx-runtime.umd.min.js",
"types": "dist/emotion-react-jsx-runtime.cjs.d.ts",
"sideEffects": false,
"preconstruct": {
"umdName": "emotionReactJSXRuntime"
}
}
+1
View File
@@ -0,0 +1 @@
export * from './macro.js'
+1
View File
@@ -0,0 +1 @@
export * from '@emotion/react'
+1
View File
@@ -0,0 +1 @@
module.exports = require('@emotion/babel-plugin').macros.core
+318
View File
@@ -0,0 +1,318 @@
{
"name": "@emotion/react",
"version": "11.14.0",
"main": "dist/emotion-react.cjs.js",
"module": "dist/emotion-react.esm.js",
"types": "dist/emotion-react.cjs.d.ts",
"exports": {
".": {
"types": {
"import": "./dist/emotion-react.cjs.mjs",
"default": "./dist/emotion-react.cjs.js"
},
"development": {
"edge-light": {
"module": "./dist/emotion-react.development.edge-light.esm.js",
"import": "./dist/emotion-react.development.edge-light.cjs.mjs",
"default": "./dist/emotion-react.development.edge-light.cjs.js"
},
"worker": {
"module": "./dist/emotion-react.development.edge-light.esm.js",
"import": "./dist/emotion-react.development.edge-light.cjs.mjs",
"default": "./dist/emotion-react.development.edge-light.cjs.js"
},
"workerd": {
"module": "./dist/emotion-react.development.edge-light.esm.js",
"import": "./dist/emotion-react.development.edge-light.cjs.mjs",
"default": "./dist/emotion-react.development.edge-light.cjs.js"
},
"browser": {
"module": "./dist/emotion-react.browser.development.esm.js",
"import": "./dist/emotion-react.browser.development.cjs.mjs",
"default": "./dist/emotion-react.browser.development.cjs.js"
},
"module": "./dist/emotion-react.development.esm.js",
"import": "./dist/emotion-react.development.cjs.mjs",
"default": "./dist/emotion-react.development.cjs.js"
},
"edge-light": {
"module": "./dist/emotion-react.edge-light.esm.js",
"import": "./dist/emotion-react.edge-light.cjs.mjs",
"default": "./dist/emotion-react.edge-light.cjs.js"
},
"worker": {
"module": "./dist/emotion-react.edge-light.esm.js",
"import": "./dist/emotion-react.edge-light.cjs.mjs",
"default": "./dist/emotion-react.edge-light.cjs.js"
},
"workerd": {
"module": "./dist/emotion-react.edge-light.esm.js",
"import": "./dist/emotion-react.edge-light.cjs.mjs",
"default": "./dist/emotion-react.edge-light.cjs.js"
},
"browser": {
"module": "./dist/emotion-react.browser.esm.js",
"import": "./dist/emotion-react.browser.cjs.mjs",
"default": "./dist/emotion-react.browser.cjs.js"
},
"module": "./dist/emotion-react.esm.js",
"import": "./dist/emotion-react.cjs.mjs",
"default": "./dist/emotion-react.cjs.js"
},
"./jsx-runtime": {
"types": {
"import": "./jsx-runtime/dist/emotion-react-jsx-runtime.cjs.mjs",
"default": "./jsx-runtime/dist/emotion-react-jsx-runtime.cjs.js"
},
"development": {
"edge-light": {
"module": "./jsx-runtime/dist/emotion-react-jsx-runtime.development.edge-light.esm.js",
"import": "./jsx-runtime/dist/emotion-react-jsx-runtime.development.edge-light.cjs.mjs",
"default": "./jsx-runtime/dist/emotion-react-jsx-runtime.development.edge-light.cjs.js"
},
"worker": {
"module": "./jsx-runtime/dist/emotion-react-jsx-runtime.development.edge-light.esm.js",
"import": "./jsx-runtime/dist/emotion-react-jsx-runtime.development.edge-light.cjs.mjs",
"default": "./jsx-runtime/dist/emotion-react-jsx-runtime.development.edge-light.cjs.js"
},
"workerd": {
"module": "./jsx-runtime/dist/emotion-react-jsx-runtime.development.edge-light.esm.js",
"import": "./jsx-runtime/dist/emotion-react-jsx-runtime.development.edge-light.cjs.mjs",
"default": "./jsx-runtime/dist/emotion-react-jsx-runtime.development.edge-light.cjs.js"
},
"browser": {
"module": "./jsx-runtime/dist/emotion-react-jsx-runtime.browser.development.esm.js",
"import": "./jsx-runtime/dist/emotion-react-jsx-runtime.browser.development.cjs.mjs",
"default": "./jsx-runtime/dist/emotion-react-jsx-runtime.browser.development.cjs.js"
},
"module": "./jsx-runtime/dist/emotion-react-jsx-runtime.development.esm.js",
"import": "./jsx-runtime/dist/emotion-react-jsx-runtime.development.cjs.mjs",
"default": "./jsx-runtime/dist/emotion-react-jsx-runtime.development.cjs.js"
},
"edge-light": {
"module": "./jsx-runtime/dist/emotion-react-jsx-runtime.edge-light.esm.js",
"import": "./jsx-runtime/dist/emotion-react-jsx-runtime.edge-light.cjs.mjs",
"default": "./jsx-runtime/dist/emotion-react-jsx-runtime.edge-light.cjs.js"
},
"worker": {
"module": "./jsx-runtime/dist/emotion-react-jsx-runtime.edge-light.esm.js",
"import": "./jsx-runtime/dist/emotion-react-jsx-runtime.edge-light.cjs.mjs",
"default": "./jsx-runtime/dist/emotion-react-jsx-runtime.edge-light.cjs.js"
},
"workerd": {
"module": "./jsx-runtime/dist/emotion-react-jsx-runtime.edge-light.esm.js",
"import": "./jsx-runtime/dist/emotion-react-jsx-runtime.edge-light.cjs.mjs",
"default": "./jsx-runtime/dist/emotion-react-jsx-runtime.edge-light.cjs.js"
},
"browser": {
"module": "./jsx-runtime/dist/emotion-react-jsx-runtime.browser.esm.js",
"import": "./jsx-runtime/dist/emotion-react-jsx-runtime.browser.cjs.mjs",
"default": "./jsx-runtime/dist/emotion-react-jsx-runtime.browser.cjs.js"
},
"module": "./jsx-runtime/dist/emotion-react-jsx-runtime.esm.js",
"import": "./jsx-runtime/dist/emotion-react-jsx-runtime.cjs.mjs",
"default": "./jsx-runtime/dist/emotion-react-jsx-runtime.cjs.js"
},
"./_isolated-hnrs": {
"types": {
"import": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.cjs.mjs",
"default": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.cjs.js"
},
"development": {
"edge-light": {
"module": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.development.edge-light.esm.js",
"import": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.development.edge-light.cjs.mjs",
"default": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.development.edge-light.cjs.js"
},
"worker": {
"module": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.development.edge-light.esm.js",
"import": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.development.edge-light.cjs.mjs",
"default": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.development.edge-light.cjs.js"
},
"workerd": {
"module": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.development.edge-light.esm.js",
"import": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.development.edge-light.cjs.mjs",
"default": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.development.edge-light.cjs.js"
},
"browser": {
"module": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.browser.development.esm.js",
"import": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.browser.development.cjs.mjs",
"default": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.browser.development.cjs.js"
},
"module": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.development.esm.js",
"import": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.development.cjs.mjs",
"default": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.development.cjs.js"
},
"edge-light": {
"module": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.edge-light.esm.js",
"import": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.edge-light.cjs.mjs",
"default": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.edge-light.cjs.js"
},
"worker": {
"module": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.edge-light.esm.js",
"import": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.edge-light.cjs.mjs",
"default": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.edge-light.cjs.js"
},
"workerd": {
"module": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.edge-light.esm.js",
"import": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.edge-light.cjs.mjs",
"default": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.edge-light.cjs.js"
},
"browser": {
"module": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.browser.esm.js",
"import": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.browser.cjs.mjs",
"default": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.browser.cjs.js"
},
"module": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.esm.js",
"import": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.cjs.mjs",
"default": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.cjs.js"
},
"./jsx-dev-runtime": {
"types": {
"import": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.cjs.mjs",
"default": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.cjs.js"
},
"development": {
"edge-light": {
"module": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.development.edge-light.esm.js",
"import": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.development.edge-light.cjs.mjs",
"default": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.development.edge-light.cjs.js"
},
"worker": {
"module": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.development.edge-light.esm.js",
"import": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.development.edge-light.cjs.mjs",
"default": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.development.edge-light.cjs.js"
},
"workerd": {
"module": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.development.edge-light.esm.js",
"import": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.development.edge-light.cjs.mjs",
"default": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.development.edge-light.cjs.js"
},
"browser": {
"module": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.browser.development.esm.js",
"import": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.browser.development.cjs.mjs",
"default": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.browser.development.cjs.js"
},
"module": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.development.esm.js",
"import": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.development.cjs.mjs",
"default": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.development.cjs.js"
},
"edge-light": {
"module": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.edge-light.esm.js",
"import": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.edge-light.cjs.mjs",
"default": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.edge-light.cjs.js"
},
"worker": {
"module": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.edge-light.esm.js",
"import": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.edge-light.cjs.mjs",
"default": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.edge-light.cjs.js"
},
"workerd": {
"module": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.edge-light.esm.js",
"import": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.edge-light.cjs.mjs",
"default": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.edge-light.cjs.js"
},
"browser": {
"module": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.browser.esm.js",
"import": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.browser.cjs.mjs",
"default": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.browser.cjs.js"
},
"module": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.esm.js",
"import": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.cjs.mjs",
"default": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.cjs.js"
},
"./package.json": "./package.json",
"./types/css-prop": "./types/css-prop.d.ts",
"./macro": {
"types": {
"import": "./macro.d.mts",
"default": "./macro.d.ts"
},
"default": "./macro.js"
}
},
"imports": {
"#is-development": {
"development": "./src/conditions/true.ts",
"default": "./src/conditions/false.ts"
},
"#is-browser": {
"edge-light": "./src/conditions/false.ts",
"workerd": "./src/conditions/false.ts",
"worker": "./src/conditions/false.ts",
"browser": "./src/conditions/true.ts",
"default": "./src/conditions/is-browser.ts"
}
},
"files": [
"src",
"dist",
"jsx-runtime",
"jsx-dev-runtime",
"_isolated-hnrs",
"types/css-prop.d.ts",
"macro.*"
],
"sideEffects": false,
"author": "Emotion Contributors",
"license": "MIT",
"scripts": {
"test:typescript": "dtslint types"
},
"dependencies": {
"@babel/runtime": "^7.18.3",
"@emotion/babel-plugin": "^11.13.5",
"@emotion/cache": "^11.14.0",
"@emotion/serialize": "^1.3.3",
"@emotion/use-insertion-effect-with-fallbacks": "^1.2.0",
"@emotion/utils": "^1.4.2",
"@emotion/weak-memoize": "^0.4.0",
"hoist-non-react-statics": "^3.3.1"
},
"peerDependencies": {
"react": ">=16.8.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
},
"devDependencies": {
"@definitelytyped/dtslint": "0.0.112",
"@emotion/css": "11.13.5",
"@emotion/css-prettifier": "1.2.0",
"@emotion/server": "11.11.0",
"@emotion/styled": "11.14.0",
"@types/hoist-non-react-statics": "^3.3.5",
"html-tag-names": "^1.1.2",
"react": "16.14.0",
"svg-tag-names": "^1.1.1",
"typescript": "^5.4.5"
},
"repository": "https://github.com/emotion-js/emotion/tree/main/packages/react",
"publishConfig": {
"access": "public"
},
"umd:main": "dist/emotion-react.umd.min.js",
"preconstruct": {
"entrypoints": [
"./index.ts",
"./jsx-runtime.ts",
"./jsx-dev-runtime.ts",
"./_isolated-hnrs.ts"
],
"umdName": "emotionReact",
"exports": {
"extra": {
"./types/css-prop": "./types/css-prop.d.ts",
"./macro": {
"types": {
"import": "./macro.d.mts",
"default": "./macro.d.ts"
},
"default": "./macro.js"
}
}
}
}
}
+15
View File
@@ -0,0 +1,15 @@
// this file isolates this package that is not tree-shakeable
// and allows it to be dropped - if it stays unused
// it happens thanks to sideEffects: false in our package.json
import hoistNonReactStatics from 'hoist-non-react-statics'
// have to wrap it in a proxy function because Rollup is too damn smart
// and if this module doesn't actually contain any logic of its own
// then Rollup just use 'hoist-non-react-statics' directly in other chunks
export default <
T extends React.ComponentType<any>,
S extends React.ComponentType<any>
>(
targetComponent: T,
sourceComponent: S
) => hoistNonReactStatics(targetComponent, sourceComponent)
+180
View File
@@ -0,0 +1,180 @@
import * as React from 'react'
import {
EmotionCache,
getRegisteredStyles,
insertStyles,
registerStyles,
SerializedStyles
} from '@emotion/utils'
import { CSSInterpolation, serializeStyles } from '@emotion/serialize'
import isDevelopment from '#is-development'
import { withEmotionCache } from './context'
import { Theme, ThemeContext } from './theming'
import { useInsertionEffectAlwaysWithSyncFallback } from '@emotion/use-insertion-effect-with-fallbacks'
import isBrowser from '#is-browser'
export interface ArrayClassNamesArg extends Array<ClassNamesArg> {}
export type ClassNamesArg =
| undefined
| null
| string
| boolean
| { [className: string]: boolean | null | undefined }
| ArrayClassNamesArg
let classnames = (args: ArrayClassNamesArg): string => {
let len = args.length
let i = 0
let cls = ''
for (; i < len; i++) {
let arg = args[i]
if (arg == null) continue
let toAdd
switch (typeof arg) {
case 'boolean':
break
case 'object': {
if (Array.isArray(arg)) {
toAdd = classnames(arg)
} else {
if (
isDevelopment &&
arg.styles !== undefined &&
arg.name !== undefined
) {
console.error(
'You have passed styles created with `css` from `@emotion/react` package to the `cx`.\n' +
'`cx` is meant to compose class names (strings) so you should convert those styles to a class name by passing them to the `css` received from <ClassNames/> component.'
)
}
toAdd = ''
for (const k in arg) {
if (arg[k] && k) {
toAdd && (toAdd += ' ')
toAdd += k
}
}
}
break
}
default: {
toAdd = arg
}
}
if (toAdd) {
cls && (cls += ' ')
cls += toAdd
}
}
return cls
}
function merge(
registered: EmotionCache['registered'],
css: ClassNamesContent['css'],
className: string
) {
const registeredStyles: string[] = []
const rawClassName = getRegisteredStyles(
registered,
registeredStyles,
className
)
if (registeredStyles.length < 2) {
return className
}
return rawClassName + css(registeredStyles)
}
const Insertion = ({
cache,
serializedArr
}: {
cache: EmotionCache
serializedArr: SerializedStyles[]
}) => {
let rules = useInsertionEffectAlwaysWithSyncFallback(() => {
let rules = ''
for (let i = 0; i < serializedArr.length; i++) {
let res = insertStyles(cache, serializedArr[i], false)
if (!isBrowser && res !== undefined) {
rules += res
}
}
if (!isBrowser) {
return rules
}
})
if (!isBrowser && rules!.length !== 0) {
return (
<style
{...{
[`data-emotion`]: `${cache.key} ${serializedArr
.map(serialized => serialized.name)
.join(' ')}`,
dangerouslySetInnerHTML: { __html: rules! },
nonce: cache.sheet.nonce
}}
/>
)
}
return null
}
export interface ClassNamesContent {
css(template: TemplateStringsArray, ...args: Array<CSSInterpolation>): string
css(...args: Array<CSSInterpolation>): string
cx(...args: Array<ClassNamesArg>): string
theme: Theme
}
export interface ClassNamesProps {
children(content: ClassNamesContent): React.ReactNode
}
export const ClassNames = /* #__PURE__ */ withEmotionCache<ClassNamesProps>(
(props, cache) => {
let hasRendered = false
let serializedArr: SerializedStyles[] = []
let css: ClassNamesContent['css'] = (...args) => {
if (hasRendered && isDevelopment) {
throw new Error('css can only be used during render')
}
let serialized = serializeStyles(args, cache.registered)
serializedArr.push(serialized)
// registration has to happen here as the result of this might get consumed by `cx`
registerStyles(cache, serialized, false)
return `${cache.key}-${serialized.name}`
}
let cx = (...args: Array<ClassNamesArg>) => {
if (hasRendered && isDevelopment) {
throw new Error('cx can only be used during render')
}
return merge(cache.registered, css, classnames(args))
}
let content = {
css,
cx,
theme: React.useContext(ThemeContext)
}
let ele = props.children(content)
hasRendered = true
return (
<>
<Insertion cache={cache} serializedArr={serializedArr} />
{ele}
</>
)
}
)
if (isDevelopment) {
ClassNames.displayName = 'EmotionClassNames'
}
+1
View File
@@ -0,0 +1 @@
export default false
+1
View File
@@ -0,0 +1 @@
export default typeof document !== 'undefined'
+1
View File
@@ -0,0 +1 @@
export default true
+72
View File
@@ -0,0 +1,72 @@
import * as React from 'react'
import { useContext, forwardRef } from 'react'
import createCache, { EmotionCache } from '@emotion/cache'
import isDevelopment from '#is-development'
import isBrowser from '#is-browser'
let EmotionCacheContext =
/* #__PURE__ */ React.createContext<EmotionCache | null>(
// we're doing this to avoid preconstruct's dead code elimination in this one case
// because this module is primarily intended for the browser and node
// but it's also required in react native and similar environments sometimes
// and we could have a special build just for that
// but this is much easier and the native packages
// might use a different theme context in the future anyway
typeof HTMLElement !== 'undefined'
? /* #__PURE__ */ createCache({ key: 'css' })
: null
)
if (isDevelopment) {
EmotionCacheContext.displayName = 'EmotionCacheContext'
}
export let CacheProvider = EmotionCacheContext.Provider
export let __unsafe_useEmotionCache = function useEmotionCache() {
return useContext(EmotionCacheContext)
}
let withEmotionCache = function withEmotionCache<Props, RefType = any>(
func: (
props: React.PropsWithoutRef<Props>,
context: EmotionCache,
ref?: React.ForwardedRef<RefType>
) => React.ReactNode
):
| React.FC<React.PropsWithoutRef<Props> & React.RefAttributes<RefType>>
| React.ForwardRefExoticComponent<
React.PropsWithoutRef<Props> & React.RefAttributes<RefType>
> {
return forwardRef<RefType, Props>((props, ref) => {
// the cache will never be null in the browser
let cache = useContext(EmotionCacheContext)!
return func(props, cache, ref)
})
}
if (!isBrowser) {
withEmotionCache = function withEmotionCache(func) {
return (props: Parameters<typeof func>[0]) => {
let cache = useContext(EmotionCacheContext)
if (cache === null) {
// yes, we're potentially creating this on every render
// it doesn't actually matter though since it's only on the server
// so there will only every be a single render
// that could change in the future because of suspense and etc. but for now,
// this works and i don't want to optimise for a future thing that we aren't sure about
cache = createCache({ key: 'css' })
return (
<EmotionCacheContext.Provider value={cache}>
{func(props, cache)}
</EmotionCacheContext.Provider>
)
} else {
return func(props, cache)
}
}
}
}
export { withEmotionCache }
+14
View File
@@ -0,0 +1,14 @@
import type { SerializedStyles } from '@emotion/utils'
import type { CSSInterpolation } from '@emotion/serialize'
import { serializeStyles } from '@emotion/serialize'
function css(
template: TemplateStringsArray,
...args: CSSInterpolation[]
): SerializedStyles
function css(...args: CSSInterpolation[]): SerializedStyles
function css(...args: CSSInterpolation[]) {
return serializeStyles(args)
}
export default css
+193
View File
@@ -0,0 +1,193 @@
import * as React from 'react'
import { withEmotionCache } from './context'
import { Theme, ThemeContext } from './theming'
import {
EmotionCache,
getRegisteredStyles,
insertStyles,
registerStyles,
SerializedStyles
} from '@emotion/utils'
import { hasOwn } from './utils'
import { Interpolation, serializeStyles } from '@emotion/serialize'
import isDevelopment from '#is-development'
import isBrowser from '#is-browser'
import { getLabelFromStackTrace } from './get-label-from-stack-trace'
import { useInsertionEffectAlwaysWithSyncFallback } from '@emotion/use-insertion-effect-with-fallbacks'
const typePropName = '__EMOTION_TYPE_PLEASE_DO_NOT_USE__'
const labelPropName = '__EMOTION_LABEL_PLEASE_DO_NOT_USE__'
interface EmotionProps {
css: Interpolation<Theme>
[typePropName]: React.ElementType
[labelPropName]?: string
[key: string]: unknown
}
export const createEmotionProps = (
type: React.ElementType,
props: { css: Interpolation<Theme> }
): EmotionProps => {
if (
isDevelopment &&
typeof props.css === 'string' &&
// check if there is a css declaration
props.css.indexOf(':') !== -1
) {
throw new Error(
`Strings are not allowed as css prop values, please wrap it in a css template literal from '@emotion/react' like this: css\`${props.css}\``
)
}
let newProps = {} as EmotionProps
for (let key in props) {
if (hasOwn.call(props, key)) {
newProps[key] = props[key as keyof typeof props]
}
}
newProps[typePropName] = type
// Runtime labeling is an opt-in feature because:
// - It causes hydration warnings when using Safari and SSR
// - It can degrade performance if there are a huge number of elements
//
// Even if the flag is set, we still don't compute the label if it has already
// been determined by the Babel plugin.
if (
isDevelopment &&
typeof globalThis !== 'undefined' &&
!!(globalThis as any).EMOTION_RUNTIME_AUTO_LABEL &&
!!props.css &&
(typeof props.css !== 'object' ||
!('name' in props.css) ||
typeof props.css.name !== 'string' ||
props.css.name.indexOf('-') === -1)
) {
const label = getLabelFromStackTrace(new Error().stack)
if (label) newProps[labelPropName] = label
}
return newProps
}
const Insertion = ({
cache,
serialized,
isStringTag
}: {
cache: EmotionCache
serialized: SerializedStyles
isStringTag: boolean
}) => {
registerStyles(cache, serialized, isStringTag)
const rules = useInsertionEffectAlwaysWithSyncFallback(() =>
insertStyles(cache, serialized, isStringTag)
)
if (!isBrowser && rules !== undefined) {
let serializedNames = serialized.name
let next = serialized.next
while (next !== undefined) {
serializedNames += ' ' + next.name
next = next.next
}
return (
<style
{...{
[`data-emotion`]: `${cache.key} ${serializedNames}`,
dangerouslySetInnerHTML: { __html: rules },
nonce: cache.sheet.nonce
}}
/>
)
}
return null
}
let Emotion = /* #__PURE__ */ withEmotionCache<EmotionProps>(
(props, cache, ref) => {
let cssProp = props.css as EmotionProps['css']
// so that using `css` from `emotion` and passing the result to the css prop works
// not passing the registered cache to serializeStyles because it would
// make certain babel optimisations not possible
if (
typeof cssProp === 'string' &&
cache.registered[cssProp] !== undefined
) {
cssProp = cache.registered[cssProp]
}
let WrappedComponent = props[
typePropName
] as EmotionProps[typeof typePropName]
let registeredStyles = [cssProp]
let className = ''
if (typeof props.className === 'string') {
className = getRegisteredStyles(
cache.registered,
registeredStyles,
props.className
)
} else if (props.className != null) {
className = `${props.className} `
}
let serialized = serializeStyles(
registeredStyles,
undefined,
React.useContext(ThemeContext)
)
if (isDevelopment && serialized.name.indexOf('-') === -1) {
let labelFromStack = props[labelPropName]
if (labelFromStack) {
serialized = serializeStyles([
serialized,
'label:' + labelFromStack + ';'
])
}
}
className += `${cache.key}-${serialized.name}`
const newProps: Record<string, unknown> = {}
for (let key in props) {
if (
hasOwn.call(props, key) &&
key !== 'css' &&
key !== typePropName &&
(!isDevelopment || key !== labelPropName)
) {
newProps[key] = props[key]
}
}
newProps.className = className
if (ref) {
newProps.ref = ref
}
return (
<>
<Insertion
cache={cache}
serialized={serialized}
isStringTag={typeof WrappedComponent === 'string'}
/>
<WrappedComponent {...newProps} />
</>
)
}
)
if (isDevelopment) {
Emotion.displayName = 'EmotionCssPropInternal'
}
export default Emotion
+55
View File
@@ -0,0 +1,55 @@
const getLastPart = (functionName: string): string => {
// The match may be something like 'Object.createEmotionProps' or
// 'Loader.prototype.render'
const parts = functionName.split('.')
return parts[parts.length - 1]
}
const getFunctionNameFromStackTraceLine = (
line: string
): string | undefined => {
// V8
let match = /^\s+at\s+([A-Za-z0-9$.]+)\s/.exec(line)
if (match) return getLastPart(match[1])
// Safari / Firefox
match = /^([A-Za-z0-9$.]+)@/.exec(line)
if (match) return getLastPart(match[1])
return undefined
}
const internalReactFunctionNames = /* #__PURE__ */ new Set([
'renderWithHooks',
'processChild',
'finishClassComponent',
'renderToString'
])
// These identifiers come from error stacks, so they have to be valid JS
// identifiers, thus we only need to replace what is a valid character for JS,
// but not for CSS.
const sanitizeIdentifier = (identifier: string) =>
identifier.replace(/\$/g, '-')
export const getLabelFromStackTrace = (stackTrace: string | undefined) => {
if (!stackTrace) return undefined
const lines = stackTrace.split('\n')
for (let i = 0; i < lines.length; i++) {
const functionName = getFunctionNameFromStackTraceLine(lines[i])
// The first line of V8 stack traces is just "Error"
if (!functionName) continue
// If we reach one of these, we have gone too far and should quit
if (internalReactFunctionNames.has(functionName)) break
// The component name is the first function in the stack that starts with an
// uppercase letter
if (/^[A-Z]/.test(functionName)) return sanitizeIdentifier(functionName)
}
return undefined
}
+147
View File
@@ -0,0 +1,147 @@
import * as React from 'react'
import isDevelopment from '#is-development'
import { withEmotionCache } from './context'
import { Theme, ThemeContext } from './theming'
import { insertStyles } from '@emotion/utils'
import { Options as SheetOptions, StyleSheet } from '@emotion/sheet'
import isBrowser from '#is-browser'
import { useInsertionEffectWithLayoutFallback } from '@emotion/use-insertion-effect-with-fallbacks'
import { Interpolation, serializeStyles } from '@emotion/serialize'
export interface GlobalProps {
styles: Interpolation<Theme>
}
let warnedAboutCssPropForGlobal = false
// maintain place over rerenders.
// initial render from browser, insertBefore context.sheet.tags[0] or if a style hasn't been inserted there yet, appendChild
// initial client-side render from SSR, use place of hydrating tag
export let Global = /* #__PURE__ */ withEmotionCache<GlobalProps>(
(props, cache) => {
if (
isDevelopment &&
!warnedAboutCssPropForGlobal && // check for className as well since the user is
// probably using the custom createElement which
// means it will be turned into a className prop
// I don't really want to add it to the type since it shouldn't be used
(('className' in props && props.className) ||
('css' in props && props.css))
) {
console.error(
"It looks like you're using the css prop on Global, did you mean to use the styles prop instead?"
)
warnedAboutCssPropForGlobal = true
}
let styles = props.styles
let serialized = serializeStyles(
[styles],
undefined,
React.useContext(ThemeContext)
)
if (!isBrowser) {
let serializedNames = serialized.name
let serializedStyles = serialized.styles
let next = serialized.next
while (next !== undefined) {
serializedNames += ' ' + next.name
serializedStyles += next.styles
next = next.next
}
let shouldCache = cache.compat === true
let rules = cache.insert(
``,
{ name: serializedNames, styles: serializedStyles },
cache.sheet,
shouldCache
)
if (shouldCache) {
return null
}
return (
<style
{...{
[`data-emotion`]: `${cache.key}-global ${serializedNames}`,
dangerouslySetInnerHTML: { __html: rules! },
nonce: cache.sheet.nonce
}}
/>
)
}
// yes, i know these hooks are used conditionally
// but it is based on a constant that will never change at runtime
// it's effectively like having two implementations and switching them out
// so it's not actually breaking anything
let sheetRef = React.useRef<
[sheet: StyleSheet, isRehydrating: boolean] | undefined
>()
useInsertionEffectWithLayoutFallback(() => {
const key = `${cache.key}-global`
// use case of https://github.com/emotion-js/emotion/issues/2675
let sheet = new (cache.sheet.constructor as {
new (options: SheetOptions): StyleSheet
})({
key,
nonce: cache.sheet.nonce,
container: cache.sheet.container,
speedy: cache.sheet.isSpeedy
})
let rehydrating = false
let node: HTMLStyleElement | null = document.querySelector(
`style[data-emotion="${key} ${serialized.name}"]`
)
if (cache.sheet.tags.length) {
sheet.before = cache.sheet.tags[0]
}
if (node !== null) {
rehydrating = true
// clear the hash so this node won't be recognizable as rehydratable by other <Global/>s
node.setAttribute('data-emotion', key)
sheet.hydrate([node])
}
sheetRef.current = [sheet, rehydrating]
return () => {
sheet.flush()
}
}, [cache])
useInsertionEffectWithLayoutFallback(() => {
let sheetRefCurrent = sheetRef.current!
let [sheet, rehydrating] = sheetRefCurrent
if (rehydrating) {
sheetRefCurrent[1] = false
return
}
if (serialized.next !== undefined) {
// insert keyframes
insertStyles(cache, serialized.next, true)
}
if (sheet.tags.length) {
// if this doesn't exist then it will be null so the style element will be appended
let element = sheet.tags[sheet.tags.length - 1].nextElementSibling
sheet.before = element
sheet.flush()
}
cache.insert(``, serialized, sheet, false)
}, [cache, serialized.name])
return null
}
)
if (isDevelopment) {
Global.displayName = 'EmotionGlobal'
}
+63
View File
@@ -0,0 +1,63 @@
import isDevelopment from '#is-development'
import pkg from '../package.json'
export type { EmotionCache } from '@emotion/cache'
export type {
ArrayInterpolation,
ComponentSelector,
CSSObject,
FunctionInterpolation,
Interpolation,
Keyframes,
SerializedStyles
} from '@emotion/serialize'
export {
withEmotionCache,
CacheProvider,
__unsafe_useEmotionCache
} from './context'
export { jsx } from './jsx'
export { jsx as createElement } from './jsx'
export { Global } from './global'
export type { GlobalProps } from './global'
export { keyframes } from './keyframes'
export { ClassNames } from './class-names'
export type {
ClassNamesArg,
ClassNamesContent,
ClassNamesProps,
ArrayClassNamesArg
} from './class-names'
export { ThemeContext, useTheme, ThemeProvider, withTheme } from './theming'
export type { Theme, ThemeProviderProps, WithTheme } from './theming'
export { default as css } from './css'
export type { DistributiveOmit, PropsOf } from './types'
declare const global: Record<string, unknown>
declare const jest: unknown
declare const vi: unknown
if (isDevelopment) {
const isBrowser = typeof document !== 'undefined'
// #1727, #2905 for some reason Jest and Vitest evaluate modules twice if some consuming module gets mocked
const isTestEnv = typeof jest !== 'undefined' || typeof vi !== 'undefined'
if (isBrowser && !isTestEnv) {
// globalThis has wide browser support - https://caniuse.com/?search=globalThis, Node.js 12 and later
const globalContext: Record<string, unknown> =
typeof globalThis !== 'undefined'
? globalThis // eslint-disable-line no-undef
: isBrowser
? window
: global
const globalKey = `__EMOTION_REACT_${pkg.version.split('.')[0]}__`
if (globalContext[globalKey]) {
console.warn(
'You are loading @emotion/react when it is already loaded. Running ' +
'multiple instances may cause problems. This can happen if multiple ' +
'versions are used, or if multiple builds of the same version are ' +
'used.'
)
}
globalContext[globalKey] = true
}
}
+37
View File
@@ -0,0 +1,37 @@
import * as ReactJSXRuntimeDev from 'react/jsx-dev-runtime'
import Emotion, { createEmotionProps } from './emotion-element'
import { hasOwn } from './utils'
import { Interpolation } from '@emotion/serialize'
import { Theme } from './theming'
export type { EmotionJSX as JSX } from './jsx-namespace'
export const Fragment = ReactJSXRuntimeDev.Fragment
export const jsxDEV: typeof ReactJSXRuntimeDev.jsxDEV = (
type,
props,
key,
isStaticChildren,
source,
self
) => {
if (!hasOwn.call(props, 'css')) {
return ReactJSXRuntimeDev.jsxDEV(
type,
props,
key,
isStaticChildren,
source,
self
)
}
return ReactJSXRuntimeDev.jsxDEV(
Emotion,
createEmotionProps(type, props as { css: Interpolation<Theme> }),
key,
isStaticChildren,
source,
self
)
}
+107
View File
@@ -0,0 +1,107 @@
import 'react'
import { Interpolation } from '@emotion/serialize'
import { Theme } from './theming'
type IsPreReact19 = 2 extends Parameters<React.FunctionComponent<any>>['length']
? true
: false
type WithConditionalCSSProp<P> = 'className' extends keyof P
? string extends P['className' & keyof P]
? { css?: Interpolation<Theme> }
: {}
: {}
// unpack all here to avoid infinite self-referencing when defining our own JSX namespace for the pre-React 19 case
// the IsPreReact19 and @ts-ignore comments are to allow @emotion/react to support three different cases of types
// - pre-React 18.something which didn't have `React.JSX`
// - React 18.something with `React.JSX`
// - React 19 with `React.JSX` and no global `JSX`
// we support both pre-React 19 cases by using the global `JSX` and with the React 19 types, we use `React.JSX`
// to make this work, we need @ts-ignore comments to ignore references that are invalid
// though note that the error types resulting from ignoring the errors will never be used
// since the pre vs post React 19 conditional will pick the one that won't error
// prettier-ignore
/** @ts-ignore */
type ReactJSXElement = true extends IsPreReact19 ? JSX.Element : React.JSX.Element
// prettier-ignore
/** @ts-ignore */
type ReactJSXElementClass = true extends IsPreReact19 ? JSX.ElementClass : React.JSX.ElementClass
// prettier-ignore
/** @ts-ignore */
type ReactJSXElementAttributesProperty = true extends IsPreReact19 ? JSX.ElementAttributesProperty : React.JSX.ElementAttributesProperty
// prettier-ignore
/** @ts-ignore */
type ReactJSXElementChildrenAttribute = true extends IsPreReact19 ? JSX.ElementChildrenAttribute : React.JSX.ElementChildrenAttribute
// prettier-ignore
/** @ts-ignore */
type ReactJSXLibraryManagedAttributes<C, P> = true extends IsPreReact19 ? JSX.LibraryManagedAttributes<C, P> : React.JSX.LibraryManagedAttributes<C, P>
// prettier-ignore
/** @ts-ignore */
type ReactJSXIntrinsicAttributes = true extends IsPreReact19 ? JSX.IntrinsicAttributes : React.JSX.IntrinsicAttributes
// prettier-ignore
/** @ts-ignore */
type ReactJSXIntrinsicClassAttributes<T> = true extends IsPreReact19 ? JSX.IntrinsicClassAttributes<T> : React.JSX.IntrinsicClassAttributes<T>
// prettier-ignore
/** @ts-ignore */
type ReactJSXIntrinsicElements = true extends IsPreReact19 ? JSX.IntrinsicElements : React.JSX.IntrinsicElements
// based on the code from @types/react@18.2.8
// https://github.com/DefinitelyTyped/DefinitelyTyped/blob/3197efc097d522c4bf02b94e1a0766d007d6cdeb/types/react/index.d.ts#LL3204C13-L3204C13
// prettier-ignore
/** @ts-ignore */
type ReactJSXElementType = true extends IsPreReact19 ? string | React.JSXElementConstructor<any> : React.JSX.ElementType
export namespace ReactJSX {
export type ElementType = ReactJSXElementType
export interface Element extends ReactJSXElement {}
export interface ElementClass extends ReactJSXElementClass {}
export interface ElementAttributesProperty
extends ReactJSXElementAttributesProperty {}
export interface ElementChildrenAttribute
extends ReactJSXElementChildrenAttribute {}
export type LibraryManagedAttributes<C, P> = ReactJSXLibraryManagedAttributes<
C,
P
>
export interface IntrinsicAttributes extends ReactJSXIntrinsicAttributes {}
export interface IntrinsicClassAttributes<T>
extends ReactJSXIntrinsicClassAttributes<T> {}
export type IntrinsicElements = ReactJSXIntrinsicElements
}
export namespace EmotionJSX {
export type ElementType = ReactJSXElementType
export interface Element extends ReactJSXElement {}
export interface ElementClass extends ReactJSXElementClass {}
export interface ElementAttributesProperty
extends ReactJSXElementAttributesProperty {}
export interface ElementChildrenAttribute
extends ReactJSXElementChildrenAttribute {}
export type LibraryManagedAttributes<C, P> = P extends unknown
? WithConditionalCSSProp<P> & ReactJSXLibraryManagedAttributes<C, P>
: never
export interface IntrinsicAttributes extends ReactJSXIntrinsicAttributes {}
export interface IntrinsicClassAttributes<T>
extends ReactJSXIntrinsicClassAttributes<T> {}
export type IntrinsicElements = {
[K in keyof ReactJSXIntrinsicElements]: ReactJSXIntrinsicElements[K] & {
css?: Interpolation<Theme>
}
}
}
+32
View File
@@ -0,0 +1,32 @@
import * as ReactJSXRuntime from 'react/jsx-runtime'
import Emotion, { createEmotionProps } from './emotion-element'
import { hasOwn } from './utils'
import { Interpolation } from '@emotion/serialize'
import { Theme } from './theming'
export type { EmotionJSX as JSX } from './jsx-namespace'
export const Fragment = ReactJSXRuntime.Fragment
export const jsx: typeof ReactJSXRuntime.jsx = (type, props, key) => {
if (!hasOwn.call(props, 'css')) {
return ReactJSXRuntime.jsx(type, props, key)
}
return ReactJSXRuntime.jsx(
Emotion,
createEmotionProps(type, props as { css: Interpolation<Theme> }),
key
)
}
export const jsxs: typeof ReactJSXRuntime.jsxs = (type, props, key) => {
if (!hasOwn.call(props, 'css')) {
return ReactJSXRuntime.jsxs(type, props, key)
}
return ReactJSXRuntime.jsxs(
Emotion,
createEmotionProps(type, props as { css: Interpolation<Theme> }),
key
)
}
+45
View File
@@ -0,0 +1,45 @@
import * as React from 'react'
import Emotion, { createEmotionProps } from './emotion-element'
import { EmotionJSX } from './jsx-namespace'
import { hasOwn } from './utils'
export const jsx: typeof React.createElement = function (
type: any,
props: any
): any {
// eslint-disable-next-line prefer-rest-params
let args: any = arguments
if (props == null || !hasOwn.call(props, 'css')) {
return React.createElement.apply(undefined, args)
}
let argsLength = args.length
let createElementArgArray: any = new Array(argsLength)
createElementArgArray[0] = Emotion
createElementArgArray[1] = createEmotionProps(type, props)
for (let i = 2; i < argsLength; i++) {
createElementArgArray[i] = args[i]
}
return React.createElement.apply(null, createElementArgArray)
}
export namespace jsx {
export namespace JSX {
export type ElementType = EmotionJSX.ElementType
export interface Element extends EmotionJSX.Element {}
export interface ElementClass extends EmotionJSX.ElementClass {}
export interface ElementAttributesProperty
extends EmotionJSX.ElementAttributesProperty {}
export interface ElementChildrenAttribute
extends EmotionJSX.ElementChildrenAttribute {}
export type LibraryManagedAttributes<C, P> =
EmotionJSX.LibraryManagedAttributes<C, P>
export interface IntrinsicAttributes
extends EmotionJSX.IntrinsicAttributes {}
export interface IntrinsicClassAttributes<T>
extends EmotionJSX.IntrinsicClassAttributes<T> {}
export type IntrinsicElements = EmotionJSX.IntrinsicElements
}
}
+27
View File
@@ -0,0 +1,27 @@
import { CSSInterpolation } from '@emotion/serialize'
import css from './css'
type Keyframes = {
name: string
styles: string
anim: 1
toString: () => string
} & string
export function keyframes(
template: TemplateStringsArray,
...args: CSSInterpolation[]
): Keyframes
export function keyframes(...args: CSSInterpolation[]): Keyframes
export function keyframes(...args: CSSInterpolation[]) {
let insertable = css(...args)
const name = `animation-${insertable.name}`
return {
name,
styles: `@keyframes ${name}{${insertable.styles}}`,
anim: 1,
toString() {
return `_EMO_${this.name}_${this.styles}_EMO_`
}
}
}
+105
View File
@@ -0,0 +1,105 @@
import * as React from 'react'
import weakMemoize from '@emotion/weak-memoize'
import isDevelopment from '#is-development'
import hoistNonReactStatics from './_isolated-hnrs'
import { DistributiveOmit, PropsOf } from './types'
// tslint:disable-next-line: no-empty-interface
export interface Theme {}
export interface ThemeProviderProps {
theme: Partial<Theme> | ((outerTheme: Theme) => Theme)
children: React.ReactNode
}
export interface ThemeProvider {
(props: ThemeProviderProps): React.ReactElement
}
export type WithTheme<P, T> = P extends { theme: infer Theme }
? P & { theme: Exclude<Theme, undefined> }
: P & { theme: T }
export const ThemeContext = /* #__PURE__ */ React.createContext({} as Theme)
if (isDevelopment) {
ThemeContext.displayName = 'EmotionThemeContext'
}
export const useTheme = () => React.useContext(ThemeContext)
const getTheme = (
outerTheme: Theme,
theme: Partial<Theme> | ((theme: Theme) => Theme)
): Theme => {
if (typeof theme === 'function') {
const mergedTheme = theme(outerTheme)
if (
isDevelopment &&
(mergedTheme == null ||
typeof mergedTheme !== 'object' ||
Array.isArray(mergedTheme))
) {
throw new Error(
'[ThemeProvider] Please return an object from your theme function, i.e. theme={() => ({})}!'
)
}
return mergedTheme
}
if (
isDevelopment &&
(theme == null || typeof theme !== 'object' || Array.isArray(theme))
) {
throw new Error(
'[ThemeProvider] Please make your theme prop a plain object'
)
}
return { ...outerTheme, ...theme }
}
let createCacheWithTheme = /* #__PURE__ */ weakMemoize((outerTheme: Theme) => {
return weakMemoize((theme: Partial<Theme> | ((theme: Theme) => Theme)) => {
return getTheme(outerTheme, theme)
})
})
export interface ThemeProviderProps {
theme: Partial<Theme> | ((outerTheme: Theme) => Theme)
children: React.ReactNode
}
export const ThemeProvider = (props: ThemeProviderProps) => {
let theme = React.useContext(ThemeContext)
if (props.theme !== theme) {
theme = createCacheWithTheme(theme)(props.theme)
}
return (
<ThemeContext.Provider value={theme}>
{props.children}
</ThemeContext.Provider>
)
}
export function withTheme<
C extends React.ComponentType<React.ComponentProps<C>>
>(
Component: C
): React.ForwardRefExoticComponent<
DistributiveOmit<PropsOf<C>, 'theme'> & { theme?: Theme }
>
export function withTheme(
Component: React.ComponentType<any>
): React.ForwardRefExoticComponent<any> {
const componentName = Component.displayName || Component.name || 'Component'
let WithTheme = React.forwardRef(function render(props, ref) {
let theme = React.useContext(ThemeContext)
return <Component theme={theme} ref={ref} {...props} />
})
WithTheme.displayName = `WithTheme(${componentName})`
return hoistNonReactStatics(WithTheme, Component)
}
+14
View File
@@ -0,0 +1,14 @@
import { ReactJSX } from './jsx-namespace'
/**
* @desc Utility type for getting props type of React component.
* It takes `defaultProps` into an account - making props with defaults optional.
*/
export type PropsOf<
C extends keyof ReactJSX.IntrinsicElements | React.JSXElementConstructor<any>
> = ReactJSX.LibraryManagedAttributes<C, React.ComponentProps<C>>
// We need to use this version of Omit as it's distributive (Will preserve unions)
export type DistributiveOmit<T, U> = T extends any
? Pick<T, Exclude<keyof T, U>>
: never
+1
View File
@@ -0,0 +1 @@
export const hasOwn = {}.hasOwnProperty
+9
View File
@@ -0,0 +1,9 @@
import {} from 'react'
import { Interpolation } from '@emotion/serialize'
import { Theme } from '@emotion/react'
declare module 'react' {
interface Attributes {
css?: Interpolation<Theme>
}
}