-
Notifications
You must be signed in to change notification settings - Fork 672
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
Add theme-aware Global component #2385
Changes from 3 commits
115e22d
e044fad
9bc8b3b
4c104fc
a9dba92
6e8f8d2
8837825
8bc670a
af0ed1c
ac36c53
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
--- | ||
title: '@theme-ui/global' | ||
--- | ||
|
||
import Readme from '@theme-ui/global/README.md' | ||
|
||
<Readme /> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# @theme-ui/global | ||
|
||
Wrapper around the Emotion `Global` component, made Theme UI theme-aware. | ||
|
||
**Note:** _This package is included in the main `theme-ui` package and a | ||
separate installation is not required unless you’re using `@theme-ui/core`._ | ||
|
||
```sh | ||
npm i @theme-ui/global @theme-ui/core @emotion/react | ||
``` | ||
|
||
```jsx | ||
import Global from '@theme-ui/global' | ||
|
||
export default (props) => ( | ||
<Global | ||
sx={{ | ||
button: { | ||
m: 0, | ||
bg: 'primary', | ||
color: 'background', | ||
border: 0, | ||
}, | ||
}} | ||
/> | ||
) | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
{ | ||
"name": "@theme-ui/global", | ||
"version": "0.15.4", | ||
"repository": "system-ui/theme-ui", | ||
"main": "dist/theme-ui-global.cjs.js", | ||
"module": "dist/theme-ui-global.esm.js", | ||
"source": "src/index.tsx", | ||
"author": "Lachlan Campbell", | ||
"license": "MIT", | ||
"sideEffects": false, | ||
"publishConfig": { | ||
"access": "public" | ||
}, | ||
"dependencies": { | ||
"@theme-ui/core": "workspace:^", | ||
"@theme-ui/css": "workspace:^" | ||
}, | ||
"peerDependencies": { | ||
"@emotion/react": "^11", | ||
"react": ">=18" | ||
}, | ||
"devDependencies": { | ||
"@babel/core": "^7.0.0", | ||
"@types/react": "^18", | ||
"@theme-ui/test-utils": "workspace:^" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import React from 'react' | ||
import { jsx, type ThemeUIStyleObject } from '@theme-ui/core' | ||
import { css, type Theme } from '@theme-ui/css' | ||
import { Global as EmotionGlobal } from '@emotion/react' | ||
|
||
const Global = ({ sx }: { sx: ThemeUIStyleObject }) => | ||
jsx(EmotionGlobal, { | ||
styles: (emotionTheme: unknown) => { | ||
const theme = emotionTheme as Theme | ||
return css(sx)(theme) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm kinda wondering if useMemo(() => css(sx)(theme), [sx, theme]) here would be an overkill. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh good call. I wish evaluating perf with hooks like that with were easier…conceptually makes sense to use it at least |
||
}, | ||
}) | ||
|
||
export default Global |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`renders global and component styles 1`] = ` | ||
.emotion-0 { | ||
color: pink; | ||
} | ||
|
||
<html> | ||
<head> | ||
<style | ||
data-emotion="css" | ||
data-s="" | ||
> | ||
|
||
.css-2cx43c{} | ||
</style> | ||
<style | ||
data-emotion="css" | ||
data-s="" | ||
> | ||
|
||
.css-2cx43c html{background-color:hotpink;} | ||
</style> | ||
<style | ||
data-emotion="css" | ||
data-s="" | ||
> | ||
|
||
.emotion-0{color:pink;} | ||
</style> | ||
</head> | ||
<body> | ||
<div> | ||
<header> | ||
<div | ||
class="emotion-0" | ||
/> | ||
</header> | ||
</div> | ||
</body> | ||
</html> | ||
`; | ||
|
||
exports[`renders global styles 1`] = ` | ||
<html> | ||
<head> | ||
<style | ||
data-emotion="css" | ||
data-s="" | ||
> | ||
|
||
.css-ck0s41{} | ||
</style> | ||
<style | ||
data-emotion="css" | ||
data-s="" | ||
> | ||
|
||
@font-face{font-family:some-name;} | ||
</style> | ||
<style | ||
data-emotion="css" | ||
data-s="" | ||
> | ||
|
||
.css-ck0s41 body{font-family:Georgia,serif;margin:0;} | ||
</style> | ||
<style | ||
data-emotion="css" | ||
data-s="" | ||
> | ||
|
||
.css-ck0s41 h1{color:salmon;} | ||
</style> | ||
</head> | ||
<body> | ||
<div> | ||
<h1> | ||
Hello | ||
</h1> | ||
</div> | ||
</body> | ||
</html> | ||
`; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
/** | ||
* @jest-environment jsdom | ||
* @jsx jsx | ||
*/ | ||
|
||
import { jsx } from '@theme-ui/core' | ||
import { cleanup } from '@testing-library/react' | ||
import { render } from '@theme-ui/test-utils' | ||
import { matchers } from '@emotion/jest' | ||
|
||
import { ThemeProvider } from '@theme-ui/core' | ||
import Global from '../src' | ||
|
||
expect.extend(matchers) | ||
|
||
beforeEach(() => { | ||
document.head.innerHTML = '' | ||
jest.resetAllMocks() | ||
}) | ||
|
||
afterEach(cleanup) | ||
|
||
test('renders global styles', async () => { | ||
const root = ( | ||
<ThemeProvider | ||
theme={{ | ||
config: { | ||
useRootStyles: false, | ||
}, | ||
fonts: { | ||
body: 'Georgia,serif', | ||
}, | ||
colors: { | ||
primary: 'salmon', | ||
}, | ||
}} | ||
> | ||
<Global | ||
sx={{ | ||
'@font-face': { | ||
fontFamily: 'some-name', | ||
}, | ||
body: { | ||
fontFamily: 'body', | ||
margin: 0, | ||
}, | ||
h1: { | ||
color: 'primary', | ||
}, | ||
}} | ||
/> | ||
<h1>Hello</h1> | ||
</ThemeProvider> | ||
) | ||
|
||
const document = render(root) | ||
expect(document.baseElement.parentElement).toMatchSnapshot() | ||
|
||
// const style = window.getComputedStyle(document.baseElement.parentElement!) | ||
// expect(style.fontFamily).toBe('Georgia,serif') | ||
// expect(style.margin).toBe('0px') | ||
|
||
// const h1 = document.baseElement.querySelector('h1')! | ||
// const h1Style = global.getComputedStyle(h1) | ||
// expect(h1Style.fontFamily).toBe('Georgia,serif') | ||
// expect(h1Style.color).toBe('salmon') | ||
}) | ||
|
||
test('renders global and component styles', () => { | ||
const root = ( | ||
<header> | ||
<Global | ||
sx={{ | ||
html: { | ||
backgroundColor: 'hotpink', | ||
}, | ||
}} | ||
/> | ||
<div sx={{ color: 'pink' }} /> | ||
</header> | ||
) | ||
const { baseElement } = render(root) | ||
expect(baseElement.parentElement).toMatchSnapshot() | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After running
pnpm build
Next.js dev server doesn't catch that the libraries are built instantly, so I removed.next
dir in the example, restartedpnpm dev
and the error on this import went away.The error was basically saying we can't import TypeScript files directly, and that's totally fine, because we want to develop examples against prebuilt libraries, but even after rebuilding you gotta clean the cache if you started dev server previously.