Files
shadcn-ui/apps/www/content/docs/tailwind-v4.mdx
2025-02-10 21:12:25 +04:00

297 lines
7.7 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: An update on Tailwind v4
description: How to use shadcn/ui with Tailwind v4.
---
Its here! Tailwind v4 and React 19. Ready for you to try out. It's available in the `canary` release of the CLI. You can start using it today.
## TLDR
If you're starting a new project with Tailwind v4 and React 19, use the `canary` version of the command-line:
```bash
npx shadcn@canary init
```
## What's New
- The CLI (`canary`) can now initialize projects with Tailwind v4.
- Full support for the new `@theme` directive and `@theme inline` option.
- All components are updated for Tailwind v4 and React 19.
- Weve removed the forwardRefs and adjusted the types.
- Every primitive now has a `data-slot` attribute for styling.
- We've fixed and cleaned up the style of the components.
- We're deprecating the `toast` component in favor of `sonner`.
- Buttons now use the default cursor.
- We're deprecating the `default` style. New projects will use `new-york`.
**Note: this is non-breaking. Your existing apps with Tailwind v3 and React 18 will still work. When you add new components, they'll still be in v3 and React 18 until you upgrade. Only new projects start with Tailwind v4 and React 19.**
## What's Coming Next
The following is still being worked on. I'll post updates soon.
- Migrating colors to OKLCH.
- Fix and improve animations.
## See it Live
I put together a demo with all the updated components here: https://v4.shadcn.com
Take a look and test the components. If you find any bugs, leave a comment on the [GitHub issue](https://github.com/shadcn-ui/ui/issues/6585).
- The code for the app is here: https://github.com/shadcn-ui/ui/tree/main/apps/v4
- The v4 components can be found here: https://github.com/shadcn-ui/ui/tree/main/apps/v4/registry/new-york-v4/ui
## Try It Out
You can test Tailwind v4 + React 19 today using the `canary` release of the CLI.
```bash
pnpm dlx shadcn@canary init
```
I'm still working on the docs, but here's a quick guide to testing new projects:
### Next.js
1. Start a new project with Tailwind v4 and React 19:
```bash
pnpm create next-app@canary --tailwind --eslint --typescript --app --no-src-dir
```
2. Init shadcn/ui. This will create your `components.json` and set up your CSS variables:
```bash
pnpm dlx shadcn@canary init
```
3. You should now be able to add components:
```bash
pnpm dlx shadcn@canary add button
```
### Vite
1. Create a new project with React 19:
```bash
pnpm create vite --template=react-ts
```
2. Follow the official guide to add Tailwind CSS: https://tailwindcss.com/docs/installation/using-vite
3. Add path aliases to `tsconfig.json`:
```json title="tsconfig.json" showLineNumbers
{
"files": [],
"references": [
{ "path": "./tsconfig.app.json" },
{ "path": "./tsconfig.node.json" }
],
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
}
```
4. Add path aliases to `tsconfig.app.json`:
```json title="tsconfig.app.json" showLineNumbers
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
}
```
5. Install `@types/node`:
```bash
pnpm add -D @types/node
```
6. Add resolve alias config to `vite.config.ts`:
```ts title="vite.config.ts" showLineNumbers
import path from "path"
import tailwindcss from "@tailwindcss/vite"
import react from "@vitejs/plugin-react"
import { defineConfig } from "vite"
export default defineConfig({
plugins: [react(), tailwindcss()],
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
},
},
})
```
7. Init `shadcn/ui`. This will create your `components.json` and set up your CSS variables:
```bash
pnpm dlx shadcn@canary init
```
8. You should now be able to add components:
```bash
pnpm dlx shadcn@canary add button
```
(Note: If you need help with other frameworks, drop a comment below. I'll update the guide)
## Upgrade Your Project
One of the major advantages of using `shadcn/ui` is that the code you end up with is exactly what you'd write yourself. There are no hidden abstractions.
This means when a dependency has a new release, you can just follow the official upgrade paths.
Here's how to upgrade your existing projects (full docs are on the way):
### 1. Follow the Tailwind v4 Upgrade Guide
- Upgrade to Tailwind v4 by following the official upgrade guide: https://tailwindcss.com/docs/upgrade-guide
- Use the `@tailwindcss/upgrade@next` codemod to remove deprecated utility classes and update tailwind config.
### 2. Update your CSS variables
The codemod will migrate your CSS variables as references under the `@theme` directive.
```css showLineNumbers
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 0 0% 3.9%;
}
}
@theme {
--color-background: hsl(var(--background));
--color-foreground: hsl(var(--foreground));
}
```
This works. But to make it easier to work with colors and other variables, we'll need to move the `hsl` wrappers and use `@theme inline`.
Here's how you do it:
1. Move `:root` and `.dark` out of the `@layer` base.
2. Wrap the color values in `hsl()`
3. Add the `inline` option to `@theme` i.e `@theme inline {`
4. Remove the `hsl()` wrappers from `@theme`
```css showLineNumbers
:root {
--background: hsl(0 0% 100%); // <-- Wrap in hsl
--foreground: hsl(0 0% 3.9%);
}
dark {
--background: hsl(0 0% 3.9%); // <-- Wrap in hsl
--foreground: hsl(0 0% 98%);
}
@theme inline {
--color-background: var(--background); // <-- Remove hsl
--color-foreground: var(--foreground);
}
```
This change makes it much simpler to access your theme variables in both utility classes and outside of CSS for eg. using color values in JavaScript.
### 3. Update colors for charts
Now that the theme colors come with `hsl()`, you can remove the wrapper in your `chartConfig`:
```diff
const chartConfig = {
desktop: {
label: "Desktop",
- color: "hsl(var(--chart-1))",
+ color: "var(--chart-1)",
},
mobile: {
label: "Mobile",
- color: "hsl(var(--chart-2))",
+ color: "var(--chart-2)",
},
} satisfies ChartConfig
```
### 4. Use new `size-*` utility
The new `size-*` utility (added in Tailwind v3.4), is now fully supported by `tailwind-merge`. You can replace `w-* h-*` with the new `size-*` utility:
```diff
- w-4 h-4
+ size-4
```
### 5. Update your dependencies
```bash
pnpm up "@radix-ui/*" cmdk lucide-react recharts tailwind-merge clsx --latest
```
### 6. Remove forwardRef
You can use the `preset-19` codemod to migrate your `forwardRef` to props or manually update the primitives.
For the codemod, see https://react.dev/blog/2024/04/25/react-19-upgrade-guide#typescript-changes.
If you want to do it manually, here's how to do it step by step:
1. Replace `React.forwardRef<...>` with `React.ComponentProps<...>`
2. Remove `ref={ref}` from the component.
3. Add a `data-slot` attribute. This will come in handy for styling with Tailwind.
4. You can optionally convert to a named function and remove the `displayName`.
#### Before
```tsx showLineNumbers
const AccordionItem = React.forwardRef<
React.ElementRef<typeof AccordionPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>
>(({ className, ...props }, ref) => (
<AccordionPrimitive.Item
ref={ref}
className={cn("border-b last:border-b-0", className)}
{...props}
/>
))
AccordionItem.displayName = "AccordionItem"
```
#### After
```tsx showLineNumbers
function AccordionItem({
className,
...props
}: React.ComponentProps<typeof AccordionPrimitive.Item>) {
return (
<AccordionPrimitive.Item
data-slot="accordion-item"
className={cn("border-b last:border-b-0", className)}
{...props}
/>
)
}
```
## Share Your Feedback
Wed love for you to test these updates and share your feedback! If you run into anything weird or have suggestions, add a comment below.