Skip to content

Commit 7a80d80

Browse files
committed
Added 09-tailwindcss
1 parent ca66163 commit 7a80d80

13 files changed

Lines changed: 271 additions & 0 deletions

File tree

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
VITE_API_BASE=http://localhost:8080
2+
VITE_ENABLE_FEATURE_A=true
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
# TailwindcCSS
2+
3+
In this example, we are going add TailwindCSS integration.
4+
5+
📌 We start from sample `08-env-vars`.
6+
7+
# Steps to build it
8+
9+
## Prerequisites
10+
11+
Install [Node.js and npm](https://nodejs.org/en/) (20.19.0 || >=22.12.0) if they are not already installed on your computer.
12+
13+
> ⚠ Verify that you are running at least latest Node LTS version and npm. You can check your current version by running `node -v` and `npm -v` in a terminal/console window. Older versions may produce errors.
14+
15+
## Steps
16+
17+
- We start from `08-env-vars`. Just copy the project and install:
18+
19+
```bash
20+
npm install
21+
```
22+
23+
- Let's add a TailwindCSS and TailwindCSS's Vite plugin:
24+
25+
_.env_
26+
27+
```bash
28+
npm install tailwindcss @tailwindcss/vite --save-dev
29+
```
30+
31+
- Let's modify `vite.config.ts` to include the plugin:
32+
33+
_vite.config.ts_
34+
35+
```diff
36+
import { defineConfig } from "vite";
37+
import checker from "vite-plugin-checker";
38+
import react from "@vitejs/plugin-react";
39+
+ import tailwindcss from "@tailwindcss/vite";
40+
41+
export default defineConfig({
42+
- plugins: [checker({ typescript: true }), react()],
43+
+ plugins: [checker({ typescript: true }), tailwindcss(), react()],
44+
});
45+
```
46+
47+
- Create `src/styless.css` that will contain TailwindCSS entrypoint:
48+
49+
_src/styless.css_
50+
51+
```css
52+
@import "tailwindcss";
53+
```
54+
55+
- And import it in our `index.tsx`;
56+
57+
_index.html_
58+
59+
```diff
60+
import { createRoot } from "react-dom/client";
61+
import { HelloComponent } from "./hello";
62+
+ import "./styles.css";
63+
64+
const root = createRoot(document.getElementById("root"));
65+
```
66+
67+
- Now let's update `HelloComponent` to include new code with TailwindCSS classes:
68+
69+
_src/hello.tsx_
70+
71+
```diff
72+
<p>Feature A is {config.IS_FEATURE_A_ENABLED ? "enabled" : "disabled"}</p>
73+
<p>Counter state: {counter}</p>
74+
+ <a
75+
+ href="#"
76+
+ className="m-2 block max-w-sm p-6 bg-white border border-gray-200 rounded-lg shadow-sm hover:bg-gray-100"
77+
+ >
78+
+ <h5 className="mb-2 text-2xl font-bold tracking-tight text-gray-900">
79+
+ Card title
80+
+ </h5>
81+
+ <p className="font-normal text-gray-700">
82+
+ Some quick example text to build on the card title and make up the
83+
+ bulk of the card's content.
84+
+ </p>
85+
+ </a>
86+
```
87+
88+
- Let's run the project:
89+
90+
```bash
91+
npm start
92+
```
93+
94+
🔎 Navigate to [http://localhost:5173](http://localhost:5173) and you'll see the card with style.
95+
96+
- Let's do one more update. We'll add a dark mode. Modify `src/styles.css` to add new variant:
97+
98+
_src/styles.css_
99+
100+
```diff
101+
@import "tailwindcss";
102+
+ @custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *));
103+
```
104+
105+
- Update our `HelloComponent` to include styles for our new dark theme:
106+
107+
\__src/hello.tsx_
108+
109+
```diff
110+
- <a
111+
- href="#"
112+
- className="m-2 block max-w-sm p-6 bg-white border border-gray-200 rounded-lg shadow-sm hover:bg-gray-100"
113+
- >
114+
- <h5 className="mb-2 text-2xl font-bold tracking-tight text-gray-900">
115+
- Card title
116+
- </h5>
117+
- <p className="font-normal text-gray-700 dark:text-gray-600">
118+
- Some quick example text to build on the card title and make up the
119+
- bulk of the card's content.
120+
- </p>
121+
- </a>
122+
+ <a
123+
+ href="#"
124+
+ className="m-2 block max-w-sm p-6 bg-white border border-gray-200 rounded-lg shadow-sm hover:bg-gray-100 dark:bg-gray-800 dark:border-gray-700 dark:hover:bg-gray-700"
125+
+ >
126+
+ <h5 className="mb-2 text-2xl font-bold tracking-tight text-gray-900 dark:text-white">
127+
+ Card title
128+
+ </h5>
129+
+ <p className="font-normal text-gray-700 dark:text-gray-400">
130+
+ Some quick example text to build on the card title and make up the
131+
+ bulk of the card's content.
132+
+ </p>
133+
+ </a>
134+
```
135+
136+
- Finally to see our style in action update `index.html`:
137+
138+
_index.html_
139+
140+
```diff
141+
<!DOCTYPE html>
142+
- <html lang="en">
143+
+ <html lang="en" data-theme="dark">
144+
<head>
145+
```
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!DOCTYPE html>
2+
<html lang="en" data-theme="dark">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>Vite App</title>
7+
</head>
8+
<body>
9+
<div id="root"></div>
10+
<script type="module" src="/src/index.tsx"></script>
11+
</body>
12+
</html>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"name": "hello-vite",
3+
"private": true,
4+
"type": "module",
5+
"version": "0.0.0",
6+
"description": "Let's start with a very basic sample, just add an html plus a simple console log (E5). This is what you can find in the getting started tutorial.",
7+
"scripts": {
8+
"start": "vite --host",
9+
"build": "vite build",
10+
"preview": "vite preview"
11+
},
12+
"devDependencies": {
13+
"@tailwindcss/vite": "^4.1.11",
14+
"@types/react": "^19.1.8",
15+
"@types/react-dom": "^19.1.6",
16+
"@vitejs/plugin-react": "^4.6.0",
17+
"sass-embedded": "^1.89.2",
18+
"tailwindcss": "^4.1.11",
19+
"typescript": "^5.8.3",
20+
"vite": "^7.0.4",
21+
"vite-plugin-checker": "^0.10.0"
22+
},
23+
"dependencies": {
24+
"bootstrap": "^5.3.7",
25+
"react": "^19.1.0",
26+
"react-dom": "^19.1.0"
27+
}
28+
}
21.9 KB
Loading
14.2 KB
Loading
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
const config = {
2+
API_BASE: import.meta.env.VITE_API_BASE,
3+
IS_FEATURE_A_ENABLED: import.meta.env.VITE_ENABLE_FEATURE_A === "true",
4+
} as const;
5+
6+
export default config;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { FC, useEffect, useState } from "react";
2+
import config from "./env-config";
3+
4+
export const HelloComponent: FC = () => {
5+
const [counter, setCounter] = useState(0);
6+
7+
useEffect(() => {
8+
const timer = setInterval(() => {
9+
setCounter((prev) => prev + 1);
10+
}, 1_000);
11+
12+
return () => clearInterval(timer);
13+
}, []);
14+
15+
return (
16+
<>
17+
<h2>Hello from React</h2>
18+
<p>Api server is {config.API_BASE}</p>
19+
<p>Feature A is {config.IS_FEATURE_A_ENABLED ? "enabled" : "disabled"}</p>
20+
<p>Counter state: {counter}</p>
21+
<a
22+
href="#"
23+
className="m-2 block max-w-sm p-6 bg-white border border-gray-200 rounded-lg shadow-sm hover:bg-gray-100 dark:bg-gray-800 dark:border-gray-700 dark:hover:bg-gray-700"
24+
>
25+
<h5 className="mb-2 text-2xl font-bold tracking-tight text-gray-900 dark:text-white">
26+
Card title
27+
</h5>
28+
<p className="font-normal text-gray-700 dark:text-gray-400">
29+
Some quick example text to build on the card title and make up the
30+
bulk of the card's content.
31+
</p>
32+
</a>
33+
</>
34+
);
35+
};
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { createRoot } from "react-dom/client";
2+
import { HelloComponent } from "./hello";
3+
import "./styles.css";
4+
5+
const root = createRoot(document.getElementById("root"));
6+
7+
root.render(<HelloComponent />);
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
@import "tailwindcss";
2+
@custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *));

0 commit comments

Comments
 (0)