mirror of
https://github.com/shadcn-ui/ui.git
synced 2026-02-09 02:49:29 +08:00
Fixes #659 Fixes #633 Create Next App is using `tailwind.config.ts` in the TypeScript template. Since this is a very common use case it would be nice to preserve the type safety of the file. I added new templates for TypeScript files. I see there is an issue #1073 which asks for ESM support as well. This is not included in this PR. I also fixed the type error in the keyframes that is also handled in #636
244 lines
5.6 KiB
Plaintext
244 lines
5.6 KiB
Plaintext
---
|
|
title: Manual Installation
|
|
description: Add dependencies to your project manually.
|
|
---
|
|
|
|
<Steps>
|
|
|
|
### Add Tailwind CSS
|
|
|
|
Components are styled using Tailwind CSS. You need to install Tailwind CSS in your project.
|
|
|
|
[Follow the Tailwind CSS installation instructions to get started.](https://tailwindcss.com/docs/installation)
|
|
|
|
### Add dependencies
|
|
|
|
Add the following dependencies to your project:
|
|
|
|
```bash
|
|
npm install tailwindcss-animate class-variance-authority clsx tailwind-merge
|
|
```
|
|
|
|
### Add icon library
|
|
|
|
If you're using the `default` style, install `lucide-react`:
|
|
|
|
```bash
|
|
npm install lucide-react
|
|
```
|
|
|
|
If you're using the `new-york` style, install `@radix-ui/react-icons`:
|
|
|
|
```bash
|
|
npm install @radix-ui/react-icons
|
|
```
|
|
|
|
### Configure path aliases
|
|
|
|
I use the `@` alias. This is how I configure it in tsconfig.json:
|
|
|
|
```json {3-6} title="tsconfig.json"
|
|
{
|
|
"compilerOptions": {
|
|
"baseUrl": ".",
|
|
"paths": {
|
|
"@/*": ["./*"]
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
The `@` alias is a preference. You can use other aliases if you want.
|
|
|
|
**If you use a different alias such as ~, you'll need to update import statements when adding components.**
|
|
|
|
### Configure tailwind.config.js
|
|
|
|
Here's what my `tailwind.config.js` file looks like:
|
|
|
|
```js title="tailwind.config.js"
|
|
const { fontFamily } = require("tailwindcss/defaultTheme")
|
|
|
|
/** @type {import('tailwindcss').Config} */
|
|
module.exports = {
|
|
darkMode: ["class"],
|
|
content: ["app/**/*.{ts,tsx}", "components/**/*.{ts,tsx}"],
|
|
theme: {
|
|
container: {
|
|
center: true,
|
|
padding: "2rem",
|
|
screens: {
|
|
"2xl": "1400px",
|
|
},
|
|
},
|
|
extend: {
|
|
colors: {
|
|
border: "hsl(var(--border))",
|
|
input: "hsl(var(--input))",
|
|
ring: "hsl(var(--ring))",
|
|
background: "hsl(var(--background))",
|
|
foreground: "hsl(var(--foreground))",
|
|
primary: {
|
|
DEFAULT: "hsl(var(--primary))",
|
|
foreground: "hsl(var(--primary-foreground))",
|
|
},
|
|
secondary: {
|
|
DEFAULT: "hsl(var(--secondary))",
|
|
foreground: "hsl(var(--secondary-foreground))",
|
|
},
|
|
destructive: {
|
|
DEFAULT: "hsl(var(--destructive))",
|
|
foreground: "hsl(var(--destructive-foreground))",
|
|
},
|
|
muted: {
|
|
DEFAULT: "hsl(var(--muted))",
|
|
foreground: "hsl(var(--muted-foreground))",
|
|
},
|
|
accent: {
|
|
DEFAULT: "hsl(var(--accent))",
|
|
foreground: "hsl(var(--accent-foreground))",
|
|
},
|
|
popover: {
|
|
DEFAULT: "hsl(var(--popover))",
|
|
foreground: "hsl(var(--popover-foreground))",
|
|
},
|
|
card: {
|
|
DEFAULT: "hsl(var(--card))",
|
|
foreground: "hsl(var(--card-foreground))",
|
|
},
|
|
},
|
|
borderRadius: {
|
|
lg: `var(--radius)`,
|
|
md: `calc(var(--radius) - 2px)`,
|
|
sm: "calc(var(--radius) - 4px)",
|
|
},
|
|
fontFamily: {
|
|
sans: ["var(--font-sans)", ...fontFamily.sans],
|
|
},
|
|
keyframes: {
|
|
"accordion-down": {
|
|
from: { height: "0" },
|
|
to: { height: "var(--radix-accordion-content-height)" },
|
|
},
|
|
"accordion-up": {
|
|
from: { height: "var(--radix-accordion-content-height)" },
|
|
to: { height: "0" },
|
|
},
|
|
},
|
|
animation: {
|
|
"accordion-down": "accordion-down 0.2s ease-out",
|
|
"accordion-up": "accordion-up 0.2s ease-out",
|
|
},
|
|
},
|
|
},
|
|
plugins: [require("tailwindcss-animate")],
|
|
}
|
|
```
|
|
|
|
### Configure styles
|
|
|
|
Add the following to your styles/globals.css file. You can learn more about using CSS variables for theming in the [theming section](/docs/theming).
|
|
|
|
```css title="globals.css"
|
|
@tailwind base;
|
|
@tailwind components;
|
|
@tailwind utilities;
|
|
|
|
@layer base {
|
|
:root {
|
|
--background: 0 0% 100%;
|
|
--foreground: 222.2 47.4% 11.2%;
|
|
|
|
--muted: 210 40% 96.1%;
|
|
--muted-foreground: 215.4 16.3% 46.9%;
|
|
|
|
--popover: 0 0% 100%;
|
|
--popover-foreground: 222.2 47.4% 11.2%;
|
|
|
|
--border: 214.3 31.8% 91.4%;
|
|
--input: 214.3 31.8% 91.4%;
|
|
|
|
--card: 0 0% 100%;
|
|
--card-foreground: 222.2 47.4% 11.2%;
|
|
|
|
--primary: 222.2 47.4% 11.2%;
|
|
--primary-foreground: 210 40% 98%;
|
|
|
|
--secondary: 210 40% 96.1%;
|
|
--secondary-foreground: 222.2 47.4% 11.2%;
|
|
|
|
--accent: 210 40% 96.1%;
|
|
--accent-foreground: 222.2 47.4% 11.2%;
|
|
|
|
--destructive: 0 100% 50%;
|
|
--destructive-foreground: 210 40% 98%;
|
|
|
|
--ring: 215 20.2% 65.1%;
|
|
|
|
--radius: 0.5rem;
|
|
}
|
|
|
|
.dark {
|
|
--background: 224 71% 4%;
|
|
--foreground: 213 31% 91%;
|
|
|
|
--muted: 223 47% 11%;
|
|
--muted-foreground: 215.4 16.3% 56.9%;
|
|
|
|
--accent: 216 34% 17%;
|
|
--accent-foreground: 210 40% 98%;
|
|
|
|
--popover: 224 71% 4%;
|
|
--popover-foreground: 215 20.2% 65.1%;
|
|
|
|
--border: 216 34% 17%;
|
|
--input: 216 34% 17%;
|
|
|
|
--card: 224 71% 4%;
|
|
--card-foreground: 213 31% 91%;
|
|
|
|
--primary: 210 40% 98%;
|
|
--primary-foreground: 222.2 47.4% 1.2%;
|
|
|
|
--secondary: 222.2 47.4% 11.2%;
|
|
--secondary-foreground: 210 40% 98%;
|
|
|
|
--destructive: 0 63% 31%;
|
|
--destructive-foreground: 210 40% 98%;
|
|
|
|
--ring: 216 34% 17%;
|
|
|
|
--radius: 0.5rem;
|
|
}
|
|
}
|
|
|
|
@layer base {
|
|
* {
|
|
@apply border-border;
|
|
}
|
|
body {
|
|
@apply bg-background text-foreground;
|
|
font-feature-settings: "rlig" 1, "calt" 1;
|
|
}
|
|
}
|
|
```
|
|
|
|
### Add a cn helper
|
|
|
|
I use a `cn` helper to make it easier to conditionally add Tailwind CSS classes. Here's how I define it in `lib/utils.ts`:
|
|
|
|
```ts title="lib/utils.ts"
|
|
import { clsx, type ClassValue } from "clsx"
|
|
import { twMerge } from "tailwind-merge"
|
|
|
|
export function cn(...inputs: ClassValue[]) {
|
|
return twMerge(clsx(inputs))
|
|
}
|
|
```
|
|
|
|
### That's it
|
|
|
|
You can now start adding components to your project.
|
|
|
|
</Steps>
|