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

Drop compat plugin #3294

Open
wants to merge 53 commits into
base: next
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
12de7a9
Use React 19
Andarist Dec 10, 2024
c4c06d4
Specify TS 5.0 as min TS version in most dtslint tests
Andarist Dec 10, 2024
ed8213d
try patching dtslint
Andarist Dec 10, 2024
dd2e711
update lockfile
Andarist Dec 10, 2024
ed1823f
fixed TS error
Andarist Dec 10, 2024
4e49e28
dedupe `@types/react`
Andarist Dec 10, 2024
a46a081
update react testing library
Andarist Dec 10, 2024
a6cc13f
add `@testing-library/dom`
Andarist Dec 11, 2024
5f3a38e
migrate tests
Andarist Dec 12, 2024
ed9538e
migrate more
Andarist Dec 12, 2024
ea9a228
moar
Andarist Dec 12, 2024
d3957b6
moar
Andarist Dec 12, 2024
11002c5
fix
Andarist Dec 12, 2024
2853c3a
more
Andarist Dec 12, 2024
a9142b3
more
Andarist Dec 12, 2024
2fbf0e3
more
Andarist Dec 12, 2024
b42fcfe
more
Andarist Dec 12, 2024
570f8d7
more
Andarist Dec 12, 2024
45f4a22
more
Andarist Dec 12, 2024
245185a
more
Andarist Dec 12, 2024
883ba0c
more
Andarist Dec 12, 2024
c3d4d20
fix
Andarist Dec 12, 2024
4ebcc12
migrate more tests
Andarist Dec 12, 2024
f7d5d69
moar
Andarist Dec 12, 2024
d0ea8cd
moar
Andarist Dec 12, 2024
a055fc8
moar
Andarist Dec 12, 2024
e52d3e6
moar
Andarist Dec 12, 2024
138227a
moar
Andarist Dec 12, 2024
229812d
more
Andarist Dec 12, 2024
1ad40d2
more
Andarist Dec 12, 2024
aa49a2e
more
Andarist Dec 12, 2024
2d6717f
tweak
Andarist Dec 12, 2024
8deec1f
more converted tests
Andarist Dec 12, 2024
8082f02
fix thing
Andarist Dec 12, 2024
fb2f0c4
fix
Andarist Dec 12, 2024
35b151c
tweak
Andarist Dec 12, 2024
6511abc
fixed test
Andarist Dec 12, 2024
9e3912b
tweaks
Andarist Dec 12, 2024
bd315a1
unskip 2 tests
Andarist Dec 12, 2024
de74f25
unskip again
Andarist Dec 12, 2024
5f411c7
stuff
Andarist Dec 13, 2024
a9cf700
fix streams
Andarist Dec 13, 2024
65735bc
skip some tests
Andarist Dec 13, 2024
88873ec
tweak
Andarist Dec 13, 2024
04f6467
fix things
Andarist Dec 13, 2024
1c8ad31
fix snap
Andarist Dec 13, 2024
76e4586
fixed snapshot indent
Andarist Dec 14, 2024
b4a7248
fixed extra snapshot issue
Andarist Dec 14, 2024
9b62fd2
strip-ansi
Andarist Dec 14, 2024
ab928db
Require TS 5.1
Andarist Dec 14, 2024
9717107
`useInsertionEffect` directly in `Global`
Andarist Dec 14, 2024
8e9a366
Drop compat plugin
Andarist Dec 14, 2024
b98f72b
add changeset
Andarist Dec 14, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .changeset/odd-adults-hang.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
'@emotion/styled': major
'@emotion/cache': major
'@emotion/react': major
'@emotion/css': major
---

Removed special-casing of pseudo classes and pseudo elements. Previously they were always implicitly nested in the "current context" but that's not how many other popular CSS preprocessor work and conflicts with some newer CSS features like `:where` and `:is`.

You should migrate your code like this:

```diff
css`
- :hover {
+ &:hover {
color: hotpink;
}
`
```
10 changes: 0 additions & 10 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,6 @@ jobs:
- name: Check Types
run: yarn tsc:all

test_react18:
name: Test React 18
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/ci-setup

- name: Run Tests with React 18
run: yarn test:react18:ci

test_prod:
name: Test Prod
runs-on: ubuntu-latest
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
diff --git a/dist/index.js b/dist/index.js
index 0a9abde5fbe918397794db0c0962129cf6bec3fa..26fe2b048b7fa898282d2d9d0dbd1719384b1f60 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -8,9 +8,9 @@ const assert_1 = __importDefault(require("assert"));
var TypeScriptVersion;
(function (TypeScriptVersion) {
/** Add to this list when a version actually ships. */
- TypeScriptVersion.shipped = ["3.9", "4.0", "4.1", "4.2", "4.3", "4.4", "4.5", "4.6"];
+ TypeScriptVersion.shipped = ["3.9", "4.0", "4.1", "4.2", "4.3", "4.4", "4.5", "4.6", "4.7", "4.8", "4.9", "5.0", "5.1", "5.2", "5.3", "5.4", "5.5", "5.6", "5.7"];
/** Add to this list when a version is available as typescript@next */
- TypeScriptVersion.supported = [...TypeScriptVersion.shipped, "4.7"];
+ TypeScriptVersion.supported = [...TypeScriptVersion.shipped, "5.8"];
/** Add to this list when it will no longer be supported on Definitely Typed */
TypeScriptVersion.unsupported = [
"2.0",
8 changes: 4 additions & 4 deletions docs/testing.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ expect.addSnapshotSerializer(createSerializer())

### Writing a test

Writing a test with `@emotion/jest` involves creating a snapshot from the `react-test-renderer`'s resulting JSON.
Writing a test with `@emotion/jest` involves creating a snapshot from the `@testing-library/react`'s result.

```jsx
import React from 'react'
import renderer from 'react-test-renderer'
import { render } from '@testing-library/react'

const Button = props => (
<button
Expand All @@ -51,7 +51,7 @@ const Button = props => (

test('Button renders correctly', () => {
expect(
renderer.create(<Button>This is hotpink.</Button>).toJSON()
render(<Button>This is hotpink.</Button>).container
).toMatchSnapshot()
})
```
Expand All @@ -67,7 +67,7 @@ exports[`Button renders correctly 1`] = `
}

<div
className="emotion-0"
class="emotion-0"
>
This is hotpink.
</div>
Expand Down
9 changes: 0 additions & 9 deletions jest-react18.config.js

This file was deleted.

19 changes: 8 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,8 @@
"test:size": "npm-run-all build size",
"test:debug": "node --inspect-brk ./node_modules/jest/bin/jest.js --runInBand --watch",
"test": "jest",
"test:react18": "jest -c jest-react18.config.js",
"test:typescript": "yarn workspaces foreach --verbose --exclude emotion-monorepo run test:typescript",
"test:ci": "jest --coverage --no-cache --ci --runInBand",
"test:react18:ci": "yarn test:react18 --coverage --no-cache --ci --runInBand",
"test:dist": "yarn build && jest -c jest.dist.js --no-cache --ci --runInBand",
"test:prod": "jest -c jest.prod.js --no-cache --ci --runInBand",
"lint:check": "eslint .",
Expand Down Expand Up @@ -185,10 +183,11 @@
"@changesets/cli": "^2.27.7",
"@manypkg/cli": "^0.19.1",
"@preconstruct/cli": "^2.8.8",
"@testing-library/react": "13.0.0-alpha.5",
"@testing-library/dom": "^10.4.0",
"@testing-library/react": "^16.1.0",
"@types/jest": "^29.5.12",
"@types/node": "^12.20.37",
"@types/react": "18.3.12",
"@types/react": "19.0.1",
"@typescript-eslint/eslint-plugin": "^7.13.0",
"@typescript-eslint/parser": "^7.13.0",
"babel-check-duplicated-nodes": "^1.0.0",
Expand Down Expand Up @@ -226,14 +225,11 @@
"polished": "^1.2.1",
"prettier": "^3.3.2",
"raf": "^3.4.0",
"react": "16.14.0",
"react-dom": "16.14.0",
"react": "19.0.0",
"react-dom": "19.0.0",
"react-native": "^0.63.2",
"react-primitives": "^0.8.1",
"react-test-renderer": "16.8.6",
"react18": "npm:[email protected]",
"react18-dom": "npm:[email protected]",
"react18-test-renderer": "npm:[email protected]",
"react-test-renderer": "19.0.0",
"svg-tag-names": "^1.1.1",
"through": "^2.3.8",
"typescript": "^5.4.5",
Expand All @@ -242,6 +238,7 @@
},
"packageManager": "[email protected]",
"resolutions": {
"@definitelytyped/[email protected]": "patch:@definitelytyped/dtslint@npm%3A0.0.112#./.yarn/patches/@definitelytyped-dtslint-npm-0.0.112-1e6b842976.patch"
"@definitelytyped/[email protected]": "patch:@definitelytyped/dtslint@npm%3A0.0.112#./.yarn/patches/@definitelytyped-dtslint-npm-0.0.112-1e6b842976.patch",
"@definitelytyped/typescript-versions@^0.0.112": "patch:@definitelytyped/typescript-versions@npm%3A0.0.112#./.yarn/patches/@definitelytyped-typescript-versions-npm-0.0.112-f668f50e03.patch"
}
}
3 changes: 1 addition & 2 deletions packages/cache/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import memoize from '@emotion/memoize'
import isDevelopment from '#is-development'
import isBrowser from '#is-browser'
import {
compat,
removeLabel,
createUnsafeSelectorsAlarm,
incorrectImportAlarm
Expand Down Expand Up @@ -121,7 +120,7 @@ let createCache = (options: Options): EmotionCache => {
sheet: StyleSheet,
shouldCache: boolean
) => string | void
const omnipresentPlugins = [compat, removeLabel]
const omnipresentPlugins = [removeLabel]

if (isDevelopment) {
omnipresentPlugins.push(
Expand Down
141 changes: 1 addition & 140 deletions packages/cache/src/stylis-plugins.ts
Original file line number Diff line number Diff line change
@@ -1,144 +1,5 @@
import { EmotionCache } from '@emotion/utils'
import {
alloc,
dealloc,
delimit,
Element,
from,
Middleware,
next,
peek,
position,
slice,
token
} from 'stylis'

// based on https://github.com/thysultan/stylis.js/blob/e6843c373ebcbbfade25ebcc23f540ed8508da0a/src/Tokenizer.js#L239-L244
const identifierWithPointTracking = (
begin: number,
points: number[],
index: number
) => {
let previous = 0
let character = 0

while (true) {
previous = character
character = peek()

// &\f
if (previous === 38 && character === 12) {
points[index] = 1
}

if (token(character)) {
break
}

next()
}

return slice(begin, position)
}

const toRules = (parsed: string[], points: number[]) => {
// pretend we've started with a comma
let index = -1
let character = 44

do {
switch (token(character)) {
case 0:
// &\f
if (character === 38 && peek() === 12) {
// this is not 100% correct, we don't account for literal sequences here - like for example quoted strings
// stylis inserts \f after & to know when & where it should replace this sequence with the context selector
// and when it should just concatenate the outer and inner selectors
// it's very unlikely for this sequence to actually appear in a different context, so we just leverage this fact here
points[index] = 1
}
parsed[index] += identifierWithPointTracking(
position - 1,
points,
index
)
break
case 2:
parsed[index] += delimit(character)
break
case 4:
// comma
if (character === 44) {
// colon
parsed[++index] = peek() === 58 ? '&\f' : ''
points[index] = parsed[index].length
break
}
// fallthrough
default:
parsed[index] += from(character)
}
} while ((character = next()))

return parsed
}

const getRules = (value: string, points: number[]) =>
dealloc(toRules(alloc(value) as string[], points))

// WeakSet would be more appropriate, but only WeakMap is supported in IE11
const fixedElements = /* #__PURE__ */ new WeakMap()

export let compat: Middleware = element => {
if (
element.type !== 'rule' ||
!element.parent ||
// positive .length indicates that this rule contains pseudo
// negative .length indicates that this rule has been already prefixed
element.length < 1
) {
return
}

let value = element.value
let parent: Element | null = element.parent
let isImplicitRule =
element.column === parent.column && element.line === parent.line

while (parent.type !== 'rule') {
parent = parent.parent
if (!parent) return
}

// short-circuit for the simplest case
if (
element.props.length === 1 &&
value.charCodeAt(0) !== 58 /* colon */ &&
!fixedElements.get(parent)
) {
return
}

// if this is an implicitly inserted rule (the one eagerly inserted at the each new nested level)
// then the props has already been manipulated beforehand as they that array is shared between it and its "rule parent"
if (isImplicitRule) {
return
}

fixedElements.set(element, true)

const points: number[] = []
const rules = getRules(value, points)
const parentRules = parent.props

for (let i = 0, k = 0; i < rules.length; i++) {
for (let j = 0; j < parentRules.length; j++, k++) {
;(element.props as string[])[k] = points[i]
? rules[i].replace(/&\f/g, parentRules[j])
: `${parentRules[j]} ${rules[i]}`
}
}
}
import { Element, Middleware } from 'stylis'

export let removeLabel: Middleware = element => {
if (element.type === 'decl') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ exports[`component selector should be converted to use the emotion target classN
}

<div
className="emotion-0"
class="emotion-0"
>
<div
className="emotion-1 emotion-2"
class="emotion-1 emotion-2"
/>
</div>
`;
Loading
Loading