Skip to content

Commit 77c6c7e

Browse files
bjohansebasAugustinMauroyovflowd
authored
feat(tailwind): migrate to v4 (#7507)
* chore(tailwind): update to v4 * fix: dark theme * simplify postcss * fix: using good source * fix: lock-file * chore: cleaned package.json * fix some bugs and add missing comment * fix(ui-components): remove unnecessary aspect ratio utility from Preview styles * fix(ui-components): update shadow variables to use --alpha for transparency * fix(ui-components): adjust shadow variables to ensure proper fallback for color transparency * fix fonts? * fix(route): add TODO to use CSS variables instead of absolute values * fix(effects): update background image from turtle.png to smoke.gif * fix: storybook postcss implementation --------- Co-authored-by: Augustin Mauroy <[email protected]> Co-authored-by: Claudio Wunder <[email protected]>
1 parent b7364b9 commit 77c6c7e

File tree

73 files changed

+2053
-2538
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+2053
-2538
lines changed

Diff for: COLLABORATOR_GUIDE.md

+1-10
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,6 @@ The Node.js Website is built upon [React][] and [Next.js][] respectively, the UI
7575
The Website also uses several other Open Source libraries (not limited to) listed below:
7676

7777
- Styling is done with [PostCSS][] and CSS Modules
78-
- We use a combination of PostCSS plugins to create a [Sass](https://sass-lang.com/) alike environment
79-
- We recommend reading the documentation of our plugins in case of doubt
80-
- [PostCSS Mixins](https://github.com/postcss/postcss-mixins)
81-
- [PostCSS Import](https://github.com/postcss/postcss-import)
82-
- [PostCSS Simple Vars](https://github.com/postcss/postcss-simple-vars)
8378
- [Tailwind][] is used as our CSS Framework and the Foundation of our Design System
8479
- [Hero Icons](https://heroicons.com/) is an SVG Icon Library used within our Codebase
8580
- [Radix UI][] is a collection of customizable UI components
@@ -577,15 +572,11 @@ We currently use a set of PostCSS plugins that create a SCSS-a-like environment.
577572

578573
#### What PostCSS Plugins we use?
579574

580-
- `postcss-mixins`: Allows us to use Sass-like Mixins
581-
- `postcss-import`: Allows us to use Sass-like Imports
582-
- `postcss-simple-vars`: Allows us to use Sass-like Variables
583-
- `postcss-nested`: Allows us to use Sass-like Nesting
584575
- `postcss-calc`: Strips `calc` expressions and replaces them with the result
576+
- `@tailwindcss/postcss`: Allows us to use Tailwind within PostCSS
585577

586578
It is important to mention that even though we use SCSS-like syntax, we do not use SCSS, and some of these plugins
587579
are not 100% compatible with the SCSS syntax.
588-
For example, `postcss-mixins` does not support `@include` and `@extend` directives (and it uses `@define-mixin` for defining Mixins and `@mixin` for including Mixins).
589580

590581
#### Do we use a CSS Framework?
591582

Diff for: apps/site/.postcssrc.json

+1-6
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
{
22
"plugins": {
3-
"postcss-mixins": {},
4-
"postcss-simple-vars": {},
53
"postcss-calc": {},
6-
"postcss-import": {},
7-
"tailwindcss/nesting": {},
8-
"tailwindcss": {},
9-
"autoprefixer": {}
4+
"@tailwindcss/postcss": {}
105
}
116
}

Diff for: apps/site/.stylelintrc.mjs

+6-4
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@ const CUSTOM_AT_RULES = [
44
'apply',
55
'layer',
66
'responsive',
7+
'reference',
8+
'utility',
9+
'theme',
10+
'custom-variant',
711
'screen',
12+
'source',
813
'tailwind',
914
'variants',
10-
// PostCSS-specific at-rules
11-
'define-mixin',
12-
'mixin',
1315
];
1416

1517
// Enforces certain selectors to be only in camelCase notation
@@ -42,6 +44,6 @@ export default {
4244
// Adopts the import notation from `postcss-import`
4345
'import-notation': 'string',
4446
// Allow the `@apply` at rule as its part of Tailwind
45-
'at-rule-no-deprecated': [true, { ignoreAtRules: ['apply'] }],
47+
'at-rule-no-deprecated': [true, { ignoreAtRules: CUSTOM_AT_RULES }],
4648
},
4749
};

Diff for: apps/site/app/[locale]/next-data/og/[category]/[title]/route.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ import { ImageResponse } from 'next/og';
44

55
import { DEFAULT_CATEGORY_OG_TYPE } from '@/next.constants.mjs';
66
import { defaultLocale } from '@/next.locales.mjs';
7-
import tailwindConfig from '@/tailwind.config';
87
import { hexToRGBA } from '@/util/hexToRGBA';
98

9+
// TODO: use CSS variables instead of absolute values
1010
const CATEGORY_TO_THEME_COLOUR_MAP = {
11-
announcement: tailwindConfig.theme.colors.green['700'],
12-
release: tailwindConfig.theme.colors.info['600'],
13-
vulnerability: tailwindConfig.theme.colors.warning['600'],
11+
announcement: '#1a3f1d',
12+
release: '#0c7bb3',
13+
vulnerability: '#ae5f00',
1414
};
1515

1616
type Category = keyof typeof CATEGORY_TO_THEME_COLOUR_MAP;

Diff for: apps/site/components/Blog/BlogHeader/index.module.css

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
@reference "../../../styles/index.css";
2+
13
.blogHeader {
24
h1 {
35
@apply inline-flex

Diff for: apps/site/components/Blog/BlogPostCard/index.module.css

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
@reference "../../../styles/index.css";
2+
13
.container {
24
@apply max-w-full
35
flex-1;

Diff for: apps/site/components/Common/Search/utils.ts

+32-35
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,43 @@
1-
import tailwindConfig from '@/tailwind.config';
2-
3-
const colors = tailwindConfig.theme.colors;
41
export const themeConfig = {
52
typography: {
63
'--font-primary': 'var(--font-open-sans)',
74
},
85
colors: {
96
light: {
10-
'--text-color-primary': colors.neutral[900],
11-
'--text-color-accent': colors.green[600],
12-
'--background-color-secondary': colors.neutral[100],
13-
'--background-color-tertiary': colors.neutral[300],
14-
'--border-color-accent': colors.green[600],
15-
'--border-color-primary': colors.neutral[200],
16-
'--border-color-tertiary': colors.green[700],
17-
'--button-background-color-primary': colors.green[600],
18-
'--button-background-color-secondary': colors.white,
19-
'--button-background-color-secondary-hover': colors.neutral[100],
20-
'--button-border-color-secondary': colors.neutral[300],
21-
'--button-text-color-secondary': colors.neutral[900],
22-
'--chat-button-border-color-gradientThree': colors.green[400],
23-
'--chat-button-border-color-gradientFour': colors.green[700],
24-
'--chat-button-background-color-gradientOne': colors.green[600],
25-
'--chat-button-background-color-gradientTwo': colors.green[300],
7+
'--text-color-primary': 'var(--color-neutral-900)',
8+
'--text-color-accent': 'var(--color-green-600)',
9+
'--background-color-secondary': 'var(--color-neutral-100)',
10+
'--background-color-tertiary': 'var(--color-neutral-300)',
11+
'--border-color-accent': 'var(--color-green-600)',
12+
'--border-color-primary': 'var(--color-neutral-200)',
13+
'--border-color-tertiary': 'var(--color-green-700)',
14+
'--button-background-color-primary': 'var(--color-green-600)',
15+
'--button-background-color-secondary': 'var(--color-white)',
16+
'--button-background-color-secondary-hover': 'var(--color-neutral-100)',
17+
'--button-border-color-secondary': 'var(--color-neutral-300)',
18+
'--button-text-color-secondary': 'var(--color-neutral-900)',
19+
'--chat-button-border-color-gradientThree': 'var(--color-green-400)',
20+
'--chat-button-border-color-gradientFour': 'var(--color-green-700)',
21+
'--chat-button-background-color-gradientOne': 'var(--color-green-600)',
22+
'--chat-button-background-color-gradientTwo': 'var(--color-green-300)',
2623
},
2724
dark: {
28-
'--text-color-primary': colors.neutral[100],
29-
'--text-color-accent': colors.green[400],
30-
'--background-color-secondary': colors.neutral[950],
31-
'--background-color-tertiary': colors.neutral[900],
32-
'--border-color-accent': colors.green[400],
33-
'--border-color-primary': colors.neutral[900],
34-
'--border-color-tertiary': colors.green[300],
35-
'--button-background-color-primary': colors.green[400],
36-
'--button-background-color-secondary': colors.neutral[950],
37-
'--button-background-color-secondary-hover': colors.neutral[900],
38-
'--button-border-color-secondary': colors.neutral[900],
39-
'--button-text-color-secondary': colors.neutral[200],
40-
'--chat-button-border-color-gradientThree': colors.green[400],
41-
'--chat-button-border-color-gradientFour': colors.green[700],
42-
'--chat-button-background-color-gradientOne': colors.green[400],
43-
'--chat-button-background-color-gradientTwo': colors.green[800],
25+
'--text-color-primary': 'var(--color-neutral-100)',
26+
'--text-color-accent': 'var(--color-green-400)',
27+
'--background-color-secondary': 'var(--color-neutral-950)',
28+
'--background-color-tertiary': 'var(--color-neutral-900)',
29+
'--border-color-accent': 'var(--color-green-400)',
30+
'--border-color-primary': 'var(--color-neutral-900)',
31+
'--border-color-tertiary': 'var(--color-green-300)',
32+
'--button-background-color-primary': 'var(--color-green-400)',
33+
'--button-background-color-secondary': 'var(--color-neutral-950)',
34+
'--button-background-color-secondary-hover': 'var(--color-neutral-900)',
35+
'--button-border-color-secondary': 'var(--color-neutral-900)',
36+
'--button-text-color-secondary': 'var(--color-neutral-200)',
37+
'--chat-button-border-color-gradientThree': 'var(--color-green-400)',
38+
'--chat-button-border-color-gradientFour': 'var(--color-green-700)',
39+
'--chat-button-background-color-gradientOne': 'var(--color-green-400)',
40+
'--chat-button-background-color-gradientTwo': 'var(--color-green-800)',
4441
},
4542
},
4643
};

Diff for: apps/site/components/Downloads/DownloadButton/index.module.css

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
@reference "../../../styles/index.css";
2+
13
.downloadButton {
24
@apply justify-center;
35

Diff for: apps/site/components/MDX/Calendar/Event/index.module.css

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
@reference "../../../../styles/index.css";
2+
13
.event {
24
@apply flex
35
w-fit

Diff for: apps/site/components/MDX/Calendar/calendar.module.css

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
@reference "../../../styles/index.css";
2+
13
.events {
24
@apply flex
35
flex-col

Diff for: apps/site/components/withBlogCategories.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ const WithBlogCategories: FC<WithBlogCategoriesProps> = ({
3030
tabs={categories}
3131
activeTab={blogData.category}
3232
>
33-
<div className="max-xs:grid-cols-[1fr] grid grid-cols-[repeat(auto-fill,minmax(theme(spacing.80),1fr))] [grid-gap:theme(spacing.12)_theme(spacing.8)]">
33+
<div className="max-xs:grid-cols-[1fr] grid grid-cols-[repeat(auto-fill,minmax(--spacing(80),1fr))] [grid-gap:--spacing(12)_--spacing(8)]">
3434
{blogData.posts.map(post => (
3535
<BlogPostCard
3636
key={post.slug}

Diff for: apps/site/layouts/layouts.module.css

+11-9
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
@reference "../styles/index.css";
2+
13
.baseLayout {
24
@apply grid
35
h-max
@@ -9,21 +11,21 @@
911

1012
.articleLayout {
1113
@apply max-w-8xl
12-
sm:grid-areas-[sidebar_main,sidebar_footer]
13-
lg:grid-areas-[sidebar_main_metabar,sidebar_footer_metabar]
1414
mx-auto
1515
block
1616
w-full
1717
sm:grid
1818
sm:grid-cols-[theme(spacing.52)_1fr]
1919
sm:grid-rows-[1fr]
2020
sm:overflow-visible
21+
sm:[grid-template-areas:'sidebar_main''sidebar_footer']
2122
md:grid-cols-[theme(spacing.64)_1fr]
2223
lg:grid-cols-[theme(spacing.52)_1fr_theme(spacing.52)]
24+
lg:[grid-template-areas:'sidebar_main_metabar''sidebar_footer_metabar']
2325
xl:grid-cols-[theme(spacing.80)_1fr_theme(spacing.80)];
2426

2527
> *:nth-child(1) {
26-
@apply grid-in-[sidebar]
28+
@apply [grid-area:sidebar]
2729
lg:sticky
2830
lg:top-0
2931
lg:h-[100vh]
@@ -35,20 +37,20 @@
3537
sm:max-lg:block;
3638

3739
> *:first-child {
38-
@apply grid-in-[main]
39-
sm:bg-gradient-subtle
40+
@apply sm:bg-gradient-subtle
4041
sm:dark:bg-gradient-subtle-dark
4142
xl:px-18
4243
p-4
44+
[grid-area:main]
4345
motion-safe:scroll-smooth
4446
sm:bg-fixed
4547
sm:p-12;
4648
}
4749

4850
> *:last-child {
49-
@apply grid-in-[metabar]
50-
mt-8
51+
@apply mt-8
5152
border-t
53+
[grid-area:metabar]
5254
sm:mt-0
5355
lg:sticky
5456
lg:top-0
@@ -59,8 +61,7 @@
5961
}
6062

6163
> *:nth-child(3) {
62-
@apply grid-in-[footer]
63-
sticky
64+
@apply sticky
6465
bottom-0
6566
flex
6667
w-full
@@ -71,6 +72,7 @@
7172
border-t-neutral-200
7273
bg-white
7374
py-4
75+
[grid-area:footer]
7476
dark:border-t-neutral-900
7577
dark:bg-neutral-950;
7678
}

Diff for: apps/site/package.json

+18-20
Original file line numberDiff line numberDiff line change
@@ -31,51 +31,49 @@
3131
"@radix-ui/react-slot": "^1.1.2",
3232
"@radix-ui/react-tabs": "^1.1.3",
3333
"@radix-ui/react-toast": "^1.2.6",
34+
"@radix-ui/react-tooltip": "^1.1.8",
35+
"@tailwindcss/postcss": "~4.0.17",
3436
"@vcarl/remark-headings": "~0.1.0",
3537
"@vercel/analytics": "~1.5.0",
36-
"@vercel/otel": "~1.10.1",
38+
"@vercel/otel": "~1.10.4",
3739
"@vercel/speed-insights": "~1.2.0",
38-
"autoprefixer": "~10.4.20",
3940
"classnames": "~2.5.1",
4041
"cross-env": "7.0.3",
4142
"feed": "~4.2.2",
4243
"github-slugger": "~2.0.0",
4344
"glob": "~11.0.1",
4445
"gray-matter": "~4.0.3",
45-
"next": "15.2.3",
46+
"next": "15.2.4",
4647
"next-intl": "~4.0.2",
47-
"next-themes": "~0.4.4",
48+
"next-themes": "~0.4.6",
4849
"postcss": "~8.5.3",
4950
"postcss-calc": "~10.1.1",
50-
"postcss-import": "~16.1.0",
5151
"postcss-loader": "~8.1.1",
52-
"postcss-mixins": "~11.0.3",
53-
"postcss-simple-vars": "~7.0.1",
54-
"react": "19.0.0",
55-
"react-dom": "19.0.0",
52+
"react": "19.1.0",
53+
"react-dom": "19.1.0",
5654
"rehype-autolink-headings": "~7.1.0",
5755
"rehype-slug": "~6.0.0",
5856
"remark-gfm": "~4.0.1",
5957
"remark-reading-time": "~2.0.1",
6058
"semver": "~7.7.1",
61-
"shiki": "~3.1.0",
62-
"sval": "^0.6.1",
63-
"tailwindcss": "~3.4.17",
59+
"shiki": "~3.2.1",
60+
"sval": "^0.6.3",
61+
"tailwindcss": "~4.0.17",
6462
"unist-util-visit": "~5.0.0",
6563
"vfile": "~6.0.3",
66-
"vfile-matter": "~5.0.0"
64+
"vfile-matter": "~5.0.1"
6765
},
6866
"devDependencies": {
6967
"@eslint/compat": "~1.2.7",
70-
"@next/eslint-plugin-next": "15.2.0",
68+
"@next/eslint-plugin-next": "15.2.4",
7169
"@testing-library/jest-dom": "~6.6.3",
7270
"@testing-library/react": "~16.2.0",
7371
"@testing-library/user-event": "~14.6.1",
7472
"@types/jest": "29.5.14",
75-
"@types/semver": "~7.5.8",
76-
"eslint-config-next": "15.2.0",
77-
"eslint-import-resolver-typescript": "~3.8.3",
78-
"eslint-plugin-mdx": "~3.1.5",
73+
"@types/semver": "~7.7.0",
74+
"eslint-config-next": "15.2.4",
75+
"eslint-import-resolver-typescript": "~4.3.1",
76+
"eslint-plugin-mdx": "~3.3.1",
7977
"eslint-plugin-react": "~7.37.4",
8078
"eslint-plugin-react-hooks": "5.2.0",
8179
"handlebars": "4.7.8",
@@ -84,12 +82,12 @@
8482
"jest-junit": "16.0.0",
8583
"remark-frontmatter": "5.0.0",
8684
"remark-preset-lint-node": "5.1.2",
87-
"stylelint": "16.15.0",
85+
"stylelint": "16.17.0",
8886
"stylelint-config-standard": "37.0.0",
8987
"stylelint-order": "6.0.4",
9088
"stylelint-selector-bem-pattern": "4.0.1",
9189
"typescript": "~5.7.2",
92-
"typescript-eslint": "~8.25.0",
90+
"typescript-eslint": "~8.28.0",
9391
"user-agent-data-types": "0.4.2"
9492
}
9593
}

Diff for: apps/site/pages/en/about/branding.mdx

+3-3
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ Credit to [Angela Angelini](https://www.linkedin.com/in/angeliningl/) for design
6666
<img
6767
alt="Node.js Light Stacked Logo"
6868
src="/static/logos/nodejsStackedLight.svg"
69-
className="h-[164px] w-[267px] rounded bg-neutral-950 p-2 dark:bg-transparent"
69+
className="rounded-xs h-[164px] w-[267px] bg-neutral-950 p-2 dark:bg-transparent"
7070
width="267"
7171
height="164"
7272
/>
@@ -83,7 +83,7 @@ Credit to [Angela Angelini](https://www.linkedin.com/in/angeliningl/) for design
8383
<img
8484
alt="Node.js White Stacked Logo"
8585
src="/static/logos/nodejsStackedWhite.svg"
86-
className="rounded bg-neutral-950 p-2 dark:bg-transparent"
86+
className="rounded-xs bg-neutral-950 p-2 dark:bg-transparent"
8787
/>
8888
</td>
8989
</tr>
@@ -108,7 +108,7 @@ Credit to [Angela Angelini](https://www.linkedin.com/in/angeliningl/) for design
108108
<img
109109
alt="White JS Icons"
110110
src="/static/logos/jsIconWhite.svg"
111-
className="height-[80px] mx-auto w-[71px] rounded bg-neutral-950 p-2 dark:bg-transparent"
111+
className="height-[80px] rounded-xs mx-auto w-[71px] bg-neutral-950 p-2 dark:bg-transparent"
112112
width="71"
113113
height="80"
114114
/>

0 commit comments

Comments
 (0)