Skip to content

Commit 317cf08

Browse files
Upgrade: Migrate prefixed group and peer classes (#15208)
Resolves #15193 This PR fixes an issue where `group` and `peer` would not have their prefixes migrated as part of the upgrade script. We do this by registering `group` and `peer` as utilities during the codemods. This way, `parseCandidate` will find these classes to be valid Tailwind candidates and the prefix can be migrated just like any other utility. ## Test Plan Tried it with the v3 upgrade playground in the repo and it worked fine: <img width="1257" alt="Screenshot 2024-11-27 at 12 17 25" src="https://github.com/user-attachments/assets/1ee101e1-1d6a-4ce0-b0d4-8d51e5f6b0d2"> I've also added tests to our prefix upgrade integration test and the prefix migration unit tests.
1 parent bfcc144 commit 317cf08

File tree

5 files changed

+27
-3
lines changed

5 files changed

+27
-3
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- _Upgrade (experimental)_: Migrate prefixes for `.group` and `.peer` classes ([#15208](https://github.com/tailwindlabs/tailwindcss/pull/15208))
13+
1014
### Fixed
1115

1216
- Ensure any necessary vendor prefixes are generated for iOS Safari, Firefox, and Chrome ([#15166](https://github.com/tailwindlabs/tailwindcss/pull/15166))

integrations/upgrade/index.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,9 @@ test(
187187
<div
188188
class="!tw__flex sm:!tw__block tw__bg-gradient-to-t flex [color:red] group-[]:tw__flex"
189189
></div>
190+
<div
191+
class="tw__group tw__group/foo tw__peer tw__peer/foo group-hover:tw__flex group-hover/foo:tw__flex peer-hover:tw__flex peer-hover/foo:tw__flex"
192+
></div>
190193
`,
191194
'src/input.css': css`
192195
@tailwind base;
@@ -208,6 +211,9 @@ test(
208211
<div
209212
class="tw:flex! tw:sm:block! tw:bg-linear-to-t flex tw:[color:red] tw:in-[.tw\\:group]:flex"
210213
></div>
214+
<div
215+
class="tw:group tw:group/foo tw:peer tw:peer/foo tw:group-hover:flex tw:group-hover/foo:flex tw:peer-hover:flex tw:peer-hover/foo:flex"
216+
></div>
211217
212218
--- ./src/input.css ---
213219
@import 'tailwindcss' prefix(tw);

packages/@tailwindcss-upgrade/src/template/codemods/prefix.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ describe('for projects with configured prefix', () => {
2020

2121
// Adds prefix to arbitrary candidates
2222
['[color:red]', 'tw:[color:red]'],
23+
24+
// `.group` and `.peer` classes
25+
['tw-group', 'tw:group'],
26+
['tw-group/foo', 'tw:group/foo'],
27+
['tw-peer', 'tw:peer'],
28+
['tw-peer/foo', 'tw:peer/foo'],
2329
])('%s => %s', async (candidate, result) => {
2430
let designSystem = await __unstable__loadDesignSystem('@import "tailwindcss" prefix(tw);', {
2531
base: __dirname,

packages/@tailwindcss-upgrade/src/template/codemods/prefix.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,21 @@ import type { DesignSystem } from '../../../../tailwindcss/src/design-system'
44
import { segment } from '../../../../tailwindcss/src/utils/segment'
55
import { printCandidate } from '../candidates'
66

7+
let seenDesignSystems = new WeakSet<DesignSystem>()
8+
79
export function prefix(
810
designSystem: DesignSystem,
911
userConfig: Config,
1012
rawCandidate: string,
1113
): string {
1214
if (!designSystem.theme.prefix) return rawCandidate
1315

16+
if (!seenDesignSystems.has(designSystem)) {
17+
designSystem.utilities.functional('group', () => null)
18+
designSystem.utilities.functional('peer', () => null)
19+
seenDesignSystems.add(designSystem)
20+
}
21+
1422
let v3Base = extractV3Base(designSystem, userConfig, rawCandidate)
1523

1624
if (!v3Base) return rawCandidate

packages/@tailwindcss-upgrade/src/template/codemods/simple-legacy-classes.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,19 @@ const LEGACY_CLASS_MAP = {
1919
'outline-none': 'outline-hidden',
2020
}
2121

22-
const SEEDED = new WeakSet<DesignSystem>()
22+
let seenDesignSystems = new WeakSet<DesignSystem>()
2323

2424
export function simpleLegacyClasses(
2525
designSystem: DesignSystem,
2626
_userConfig: Config,
2727
rawCandidate: string,
2828
): string {
2929
// Prepare design system with the unknown legacy classes
30-
if (!SEEDED.has(designSystem)) {
30+
if (!seenDesignSystems.has(designSystem)) {
3131
for (let old in LEGACY_CLASS_MAP) {
3232
designSystem.utilities.static(old, () => [])
3333
}
34-
SEEDED.add(designSystem)
34+
seenDesignSystems.add(designSystem)
3535
}
3636

3737
for (let candidate of designSystem.parseCandidate(rawCandidate)) {

0 commit comments

Comments
 (0)