mirror of
https://github.com/shadcn-ui/ui.git
synced 2026-07-08 14:35:09 +00:00
523 lines
14 KiB
Plaintext
523 lines
14 KiB
Plaintext
---
|
||
title: Changelog
|
||
description: Latest updates and announcements.
|
||
toc: false
|
||
---
|
||
|
||
## July 2023 - JavaScript
|
||
|
||
This project and the components are written in TypeScript. **We recommend using TypeScript for your project as well**.
|
||
|
||
However we provide a JavaScript version of the components, available via the [cli](/docs/cli).
|
||
|
||
```txt
|
||
Would you like to use TypeScript (recommended)? no
|
||
```
|
||
|
||
To opt-out of TypeScript, you can use the `tsx` flag in your `components.json` file.
|
||
|
||
```json {10} title="components.json"
|
||
{
|
||
"style": "default",
|
||
"tailwind": {
|
||
"config": "tailwind.config.js",
|
||
"css": "src/app/globals.css",
|
||
"baseColor": "zinc",
|
||
"cssVariables": true
|
||
},
|
||
"rsc": false,
|
||
"tsx": false,
|
||
"aliases": {
|
||
"utils": "~/lib/utils",
|
||
"components": "~/components"
|
||
}
|
||
}
|
||
```
|
||
|
||
To configure import aliases, you can use the following `jsconfig.json`:
|
||
|
||
```json {4} title="jsconfig.json"
|
||
{
|
||
"compilerOptions": {
|
||
"paths": {
|
||
"@/*": ["./*"]
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
## June 2023 - New CLI, Styles and more
|
||
|
||
I have a lot of updates to share with you today:
|
||
|
||
- [**New CLI**](#new-cli) - Rewrote the CLI from scratch. You can now add components, dependencies and configure import paths.
|
||
- [**Theming**](#theming-with-css-variables-or-tailwind-colors) - Choose between using CSS variables or Tailwind CSS utility classes for theming.
|
||
- [**Base color**](#base-color) - Configure the base color for your project. This will be used to generate the default color palette for your components.
|
||
- [**React Server Components**](#react-server-components) - Opt out of using React Server Components. The CLI will automatically append or remove the `use client` directive.
|
||
- [**Styles**](#styles) - Introducing a new concept called _Style_. A style comes with its own set of components, animations, icons and more.
|
||
- [**Exit animations**](#exit-animations) - Added exit animations to all components.
|
||
- [**Other updates**](#other-updates) - New `icon` button size, updated `sheet` component and more.
|
||
- [**Updating your project**](#updating-your-project) - How to update your project to get the latest changes.
|
||
|
||
---
|
||
|
||
### New CLI
|
||
|
||
I've been working on a new CLI for the past few weeks. It's a complete rewrite. It comes with a lot of new features and improvements.
|
||
|
||
### `init`
|
||
|
||
```bash
|
||
npx shadcn-ui@latest init
|
||
```
|
||
|
||
When you run the `init` command, you will be asked a few questions to configure `components.json`:
|
||
|
||
```txt showLineNumbers
|
||
Which style would you like to use? › Default
|
||
Which color would you like to use as base color? › Slate
|
||
Where is your global CSS file? › › app/globals.css
|
||
Do you want to use CSS variables for colors? › no / yes
|
||
Where is your tailwind.config.js located? › tailwind.config.js
|
||
Configure the import alias for components: › @/components
|
||
Configure the import alias for utils: › @/lib/utils
|
||
Are you using React Server Components? › no / yes
|
||
```
|
||
|
||
This file contains all the information about your components: where to install them, the import paths, how they are styled...etc.
|
||
|
||
You can use this file to change the import path of a component, set a baseColor or change the styling method.
|
||
|
||
```json title="components.json"
|
||
{
|
||
"style": "default",
|
||
"tailwind": {
|
||
"config": "tailwind.config.ts",
|
||
"css": "src/app/globals.css",
|
||
"baseColor": "zinc",
|
||
"cssVariables": true
|
||
},
|
||
"rsc": false,
|
||
"aliases": {
|
||
"utils": "~/lib/utils",
|
||
"components": "~/components"
|
||
}
|
||
}
|
||
```
|
||
|
||
This means you can now use the CLI with any directory structure including `src` and `app` directories.
|
||
|
||
### `add`
|
||
|
||
```bash
|
||
npx shadcn-ui@latest add
|
||
```
|
||
|
||
The `add` command is now much more capable. You can now add UI components but also import more complex components (coming soon).
|
||
|
||
The CLI will automatically resolve all components and dependencies, format them based on your custom config and add them to your project.
|
||
|
||
### `diff` (experimental)
|
||
|
||
```bash
|
||
npx shadcn-ui diff
|
||
```
|
||
|
||
We're also introducing a new `diff` command to help you keep track of upstream updates.
|
||
|
||
You can use this command to see what has changed in the upstream repository and update your project accordingly.
|
||
|
||
Run the `diff` command to get a list of components that have updates available:
|
||
|
||
```bash
|
||
npx shadcn-ui diff
|
||
```
|
||
|
||
```txt
|
||
The following components have updates available:
|
||
- button
|
||
- /path/to/my-app/components/ui/button.tsx
|
||
- toast
|
||
- /path/to/my-app/components/ui/use-toast.ts
|
||
- /path/to/my-app/components/ui/toaster.tsx
|
||
```
|
||
|
||
Then run `diff [component]` to see the changes:
|
||
|
||
```bash
|
||
npx shadcn-ui diff alert
|
||
```
|
||
|
||
```diff /pl-12/
|
||
const alertVariants = cva(
|
||
- "relative w-full rounded-lg border",
|
||
+ "relative w-full pl-12 rounded-lg border"
|
||
)
|
||
```
|
||
|
||
---
|
||
|
||
### Theming with CSS Variables or Tailwind Colors
|
||
|
||
You can choose between using CSS variables or Tailwind CSS utility classes for theming.
|
||
|
||
When you add new components, the CLI will automatically use the correct theming methods based on your `components.json` configuration.
|
||
|
||
#### Utility classes
|
||
|
||
```tsx /bg-zinc-950/ /text-zinc-50/ /dark:bg-white/ /dark:text-zinc-950/
|
||
<div className="bg-zinc-950 dark:bg-white" />
|
||
```
|
||
|
||
To use utility classes for theming set `tailwind.cssVariables` to `false` in your `components.json` file.
|
||
|
||
```json {6} title="components.json"
|
||
{
|
||
"tailwind": {
|
||
"config": "tailwind.config.js",
|
||
"css": "app/globals.css",
|
||
"baseColor": "slate",
|
||
"cssVariables": false
|
||
}
|
||
}
|
||
```
|
||
|
||
#### CSS Variables
|
||
|
||
```tsx /bg-background/ /text-foreground/
|
||
<div className="bg-background text-foreground" />
|
||
```
|
||
|
||
To use CSS variables classes for theming set `tailwind.cssVariables` to `true` in your `components.json` file.
|
||
|
||
```json {6} title="components.json"
|
||
{
|
||
"tailwind": {
|
||
"config": "tailwind.config.js",
|
||
"css": "app/globals.css",
|
||
"baseColor": "slate",
|
||
"cssVariables": true
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### Base color
|
||
|
||
You can now configure the base color for your project. This will be used to generate the default color palette for your components.
|
||
|
||
```json {5} title="components.json"
|
||
{
|
||
"tailwind": {
|
||
"config": "tailwind.config.js",
|
||
"css": "app/globals.css",
|
||
"baseColor": "zinc",
|
||
"cssVariables": false
|
||
}
|
||
}
|
||
```
|
||
|
||
Choose between `gray`, `neutral`, `slate`, `stone` or `zinc`.
|
||
|
||
If you have `cssVariables` set to `true`, we will set the base colors as CSS variables in your `globals.css` file. If you have `cssVariables` set to `false`, we will inline the Tailwind CSS utility classes in your components.
|
||
|
||
---
|
||
|
||
### React Server Components
|
||
|
||
If you're using a framework that does not support React Server Components, you can now opt out by setting `rsc` to `false`. We will automatically append or remove the `use client` directive when adding components.
|
||
|
||
```json title="components.json"
|
||
{
|
||
"rsc": false
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### Styles
|
||
|
||
We are introducing a new concept called _Style_.
|
||
|
||
_You can think of style as the visual foundation: shapes, icons, animations & typography._ A style comes with its own set of components, animations, icons and more.
|
||
|
||
We are shipping two styles: `default` and `new-york` (with more coming soon).
|
||
|
||
<Image
|
||
src="/images/style.jpg"
|
||
width="716"
|
||
height="402"
|
||
alt="Default vs New York style"
|
||
className="border rounded-lg overflow-hidden mt-6"
|
||
/>
|
||
|
||
The `default` style is the one you are used to. It's the one we've been using since the beginning of this project. It uses `lucide-react` for icons and `tailwindcss-animate` for animations.
|
||
|
||
The `new-york` style is a new style. It ships with smaller buttons, cards with shadows and a new set of icons from [Radix Icons](https://icons.radix-ui.com).
|
||
|
||
When you run the `init` command, you will be asked which style you would like to use. This is saved in your `components.json` file.
|
||
|
||
```json title="components.json"
|
||
{
|
||
"style": "new-york"
|
||
}
|
||
```
|
||
|
||
### Theming
|
||
|
||
Start with a style as the base then theme using CSS variables or Tailwind CSS utility classes to completely change the look of your components.
|
||
|
||
<Image
|
||
src="/images/style-with-theming.jpg"
|
||
width="716"
|
||
height="402"
|
||
alt="Style with theming"
|
||
className="border rounded-lg overflow-hidden mt-6"
|
||
/>
|
||
|
||
---
|
||
|
||
### Exit animations
|
||
|
||
I added exit animations to all components. Click on the combobox below to see the subtle exit animation.
|
||
|
||
<ComponentPreview name="combobox-demo" className="[&_.preview]:items-start" />
|
||
|
||
The animations can be customized using utility classes.
|
||
|
||
---
|
||
|
||
### Other updates
|
||
|
||
### Button
|
||
|
||
- Added a new button size `icon`:
|
||
|
||
<ComponentPreview name="button-icon" />
|
||
|
||
### Sheet
|
||
|
||
- Renamed `position` to `side` to match the other elements.
|
||
|
||
<ComponentPreview name="sheet-side" />
|
||
|
||
- Removed the `size` props. Use `className="w-[200px] md:w-[450px]"` for responsive sizing.
|
||
|
||
---
|
||
|
||
### Updating your project
|
||
|
||
Since we follow a copy and paste approach, you will need to manually update your project to get the latest changes.
|
||
|
||
<Callout className="mt-4">
|
||
Note: we are working on a [`diff`](#diff-experimental) command to help you
|
||
keep track of upstream updates.
|
||
</Callout>
|
||
|
||
<Steps>
|
||
|
||
### Add `components.json`
|
||
|
||
Creating a `components.json` file at the root:
|
||
|
||
```json title="components.json"
|
||
{
|
||
"style": "default",
|
||
"rsc": true,
|
||
"tailwind": {
|
||
"config": "tailwind.config.js",
|
||
"css": "app/globals.css",
|
||
"baseColor": "slate",
|
||
"cssVariables": true
|
||
},
|
||
"aliases": {
|
||
"components": "@/components",
|
||
"utils": "@/lib/utils"
|
||
}
|
||
}
|
||
```
|
||
|
||
Update the values for `tailwind.css` and `aliases` to match your project structure.
|
||
|
||
### Button
|
||
|
||
Add the `icon` size to the `buttonVariants`:
|
||
|
||
```tsx {7} title="components/ui/button.tsx"
|
||
const buttonVariants = cva({
|
||
variants: {
|
||
size: {
|
||
default: "h-10 px-4 py-2",
|
||
sm: "h-9 rounded-md px-3",
|
||
lg: "h-11 rounded-md px-8",
|
||
icon: "h-10 w-10",
|
||
},
|
||
},
|
||
})
|
||
```
|
||
|
||
### Sheet
|
||
|
||
1. Replace the content of `sheet.tsx` with the following:
|
||
|
||
```tsx title="components/ui/sheet.tsx"
|
||
"use client"
|
||
|
||
import * as React from "react"
|
||
import * as SheetPrimitive from "@radix-ui/react-dialog"
|
||
import { cva, type VariantProps } from "class-variance-authority"
|
||
import { X } from "lucide-react"
|
||
|
||
import { cn } from "@/lib/utils"
|
||
|
||
const Sheet = SheetPrimitive.Root
|
||
|
||
const SheetTrigger = SheetPrimitive.Trigger
|
||
|
||
const SheetClose = SheetPrimitive.Close
|
||
|
||
const SheetPortal = ({
|
||
className,
|
||
...props
|
||
}: SheetPrimitive.DialogPortalProps) => (
|
||
<SheetPrimitive.Portal className={cn(className)} {...props} />
|
||
)
|
||
SheetPortal.displayName = SheetPrimitive.Portal.displayName
|
||
|
||
const SheetOverlay = React.forwardRef<
|
||
React.ElementRef<typeof SheetPrimitive.Overlay>,
|
||
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>
|
||
>(({ className, ...props }, ref) => (
|
||
<SheetPrimitive.Overlay
|
||
className={cn(
|
||
"fixed inset-0 z-50 bg-background/80 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
||
className
|
||
)}
|
||
{...props}
|
||
ref={ref}
|
||
/>
|
||
))
|
||
SheetOverlay.displayName = SheetPrimitive.Overlay.displayName
|
||
|
||
const sheetVariants = cva(
|
||
"fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
|
||
{
|
||
variants: {
|
||
side: {
|
||
top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
|
||
bottom:
|
||
"inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
|
||
left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
|
||
right:
|
||
"inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
|
||
},
|
||
},
|
||
defaultVariants: {
|
||
side: "right",
|
||
},
|
||
}
|
||
)
|
||
|
||
interface SheetContentProps
|
||
extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,
|
||
VariantProps<typeof sheetVariants> {}
|
||
|
||
const SheetContent = React.forwardRef<
|
||
React.ElementRef<typeof SheetPrimitive.Content>,
|
||
SheetContentProps
|
||
>(({ side = "right", className, children, ...props }, ref) => (
|
||
<SheetPortal>
|
||
<SheetOverlay />
|
||
<SheetPrimitive.Content
|
||
ref={ref}
|
||
className={cn(sheetVariants({ side }), className)}
|
||
{...props}
|
||
>
|
||
{children}
|
||
<SheetPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary">
|
||
<X className="h-4 w-4" />
|
||
<span className="sr-only">Close</span>
|
||
</SheetPrimitive.Close>
|
||
</SheetPrimitive.Content>
|
||
</SheetPortal>
|
||
))
|
||
SheetContent.displayName = SheetPrimitive.Content.displayName
|
||
|
||
const SheetHeader = ({
|
||
className,
|
||
...props
|
||
}: React.HTMLAttributes<HTMLDivElement>) => (
|
||
<div
|
||
className={cn(
|
||
"flex flex-col space-y-2 text-center sm:text-left",
|
||
className
|
||
)}
|
||
{...props}
|
||
/>
|
||
)
|
||
SheetHeader.displayName = "SheetHeader"
|
||
|
||
const SheetFooter = ({
|
||
className,
|
||
...props
|
||
}: React.HTMLAttributes<HTMLDivElement>) => (
|
||
<div
|
||
className={cn(
|
||
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
|
||
className
|
||
)}
|
||
{...props}
|
||
/>
|
||
)
|
||
SheetFooter.displayName = "SheetFooter"
|
||
|
||
const SheetTitle = React.forwardRef<
|
||
React.ElementRef<typeof SheetPrimitive.Title>,
|
||
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>
|
||
>(({ className, ...props }, ref) => (
|
||
<SheetPrimitive.Title
|
||
ref={ref}
|
||
className={cn("text-lg font-semibold text-foreground", className)}
|
||
{...props}
|
||
/>
|
||
))
|
||
SheetTitle.displayName = SheetPrimitive.Title.displayName
|
||
|
||
const SheetDescription = React.forwardRef<
|
||
React.ElementRef<typeof SheetPrimitive.Description>,
|
||
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>
|
||
>(({ className, ...props }, ref) => (
|
||
<SheetPrimitive.Description
|
||
ref={ref}
|
||
className={cn("text-sm text-muted-foreground", className)}
|
||
{...props}
|
||
/>
|
||
))
|
||
SheetDescription.displayName = SheetPrimitive.Description.displayName
|
||
|
||
export {
|
||
Sheet,
|
||
SheetTrigger,
|
||
SheetClose,
|
||
SheetContent,
|
||
SheetHeader,
|
||
SheetFooter,
|
||
SheetTitle,
|
||
SheetDescription,
|
||
}
|
||
```
|
||
|
||
2. Rename `position` to `side`
|
||
|
||
```diff /position/ /side/
|
||
- <Sheet position="right" />
|
||
+ <Sheet side="right" />
|
||
```
|
||
|
||
</Steps>
|
||
|
||
### Thank you
|
||
|
||
I'd like to thank everyone who has been using this project, providing feedback and contributing to it. I really appreciate it. Thank you 🙏
|