Compare commits

..

17 Commits

Author SHA1 Message Date
github-actions[bot]
d3cc7a3a6f chore(release): version packages (#179)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-04-17 16:55:42 +04:00
shadcn
96f300ea74 ci: skip type check temporarily (#178) 2023-04-17 15:52:17 +04:00
shadcn
a243262748 feat(shadcn-ui): init command 2023-04-17 15:41:03 +04:00
shadcn
b5d43688b9 feat(shadcn-ui): add support for aliases 2023-04-17 12:59:57 +04:00
shadcn
3819f07d9d chore: update template 2023-04-06 12:19:55 +04:00
Raj Savaliya
81ee0de71c chore: replace third party @next/font with next/font (#145) 2023-04-03 09:15:23 +04:00
Storm
4444c28b9f docs(collapsible): add missing imports for collapsible (#150) 2023-04-03 08:30:50 +04:00
Hugo Sainte-Marie
3899b1cc10 docs(dialog): update dialog (#137) 2023-04-03 08:19:47 +04:00
Hugo Sainte-Marie
49dbba624f docs(scroll-area): update description for scroll-area (#136) 2023-04-03 08:14:59 +04:00
Storm
309267b73c docs: change sheet wrong import (#141) 2023-04-01 08:06:06 +04:00
Luke McDonald
d6933321dc fix: remove extra curly brace in style element (#146) 2023-04-01 07:52:48 +04:00
shadcn
272c7c0980 feat(button): remove active:scale-95 2023-04-01 07:11:34 +04:00
shadcn
29a333721a feat: update front page 2023-04-01 06:55:03 +04:00
shadcn
a86af454cc chore: update pnpm lock 2023-04-01 06:47:39 +04:00
shadcn
33e72a6796 fix: remove dropdown from main nav 2023-04-01 06:46:14 +04:00
shadcn
3961f15dc6 fix: remove unist dependency 2023-04-01 06:46:01 +04:00
shadcn
faf05aa086 docs(www): update prod message 2023-03-08 19:27:03 +04:00
43 changed files with 3369 additions and 2801 deletions

View File

@@ -28,7 +28,7 @@ jobs:
for (const artifact of allArtifacts.data.artifacts) {
// Extract the PR number and package version from the artifact name
const match = /^npm-package-@shadcn-ui@(.*?)-pr-(\d+)/.exec(artifact.name);
const match = /^npm-package-shadcn-ui@(.*?)-pr-(\d+)/.exec(artifact.name);
if (match) {
require("fs").appendFileSync(
@@ -49,7 +49,7 @@ jobs:
A new prerelease is available for testing:
```sh
pnpm @shadcn/ui@${{ env.BETA_PACKAGE_VERSION }}
npx shadcn-ui@${{ env.BETA_PACKAGE_VERSION }}
```
- name: "Remove the autorelease label once published"

View File

@@ -54,5 +54,5 @@ jobs:
- name: Upload packaged artifact
uses: actions/upload-artifact@v2
with:
name: npm-package-@shadcn-ui@${{ steps.package-version.outputs.current-version }}-pr-${{ github.event.number }} # encode the PR number into the artifact name
name: npm-package-shadcn-ui@${{ steps.package-version.outputs.current-version }}-pr-${{ github.event.number }} # encode the PR number into the artifact name
path: packages/cli/dist/index.js

View File

@@ -30,8 +30,8 @@ jobs:
- name: Install NPM Dependencies
run: pnpm install
- name: Check for errors
run: pnpm check
# - name: Check for errors
# run: pnpm check
- name: Build the package
run: pnpm build:cli

View File

@@ -1,4 +1,4 @@
import { Inter as FontSans } from "@next/font/google"
import { Inter as FontSans } from "next/font/google"
import "@/styles/globals.css"
import { cn } from "@/lib/utils"

View File

@@ -4,6 +4,7 @@ import { siteConfig } from "@/config/site"
import { cn } from "@/lib/utils"
import { AppleMusicDemo } from "@/components/apple-music-demo"
import { CopyButton } from "@/components/copy-button"
import { Icons } from "@/components/icons"
import { PromoVideo } from "@/components/promo-video"
import { buttonVariants } from "@/components/ui/button"
@@ -30,7 +31,7 @@ export default function IndexPage() {
</div>
<div className="flex flex-col space-y-4 sm:flex-row sm:space-y-0 sm:space-x-4 md:flex-row">
<Link href="/docs" className={buttonVariants({ size: "lg" })}>
Documentation
Get Started
</Link>
<Link
target="_blank"
@@ -38,20 +39,12 @@ export default function IndexPage() {
href={siteConfig.links.github}
className={cn(
buttonVariants({ variant: "outline", size: "lg" }),
"md:hidden"
"pl-6"
)}
>
<Icons.gitHub className="mr-2 h-4 w-4" />
GitHub
</Link>
<pre className="hidden h-11 items-center justify-between space-x-2 overflow-x-auto rounded-lg border border-slate-100 bg-slate-100 pr-2 pl-6 dark:border-slate-700 dark:bg-black md:flex">
<code className="font-mono text-sm font-semibold text-slate-900 dark:text-slate-50">
npx create-next-app -e https://github.com/shadcn/next-template
</code>
<CopyButton
value="npx create-next-app -e https://github.com/shadcn/next-template"
className="border-none text-slate-900 hover:bg-transparent dark:text-slate-50"
/>
</pre>
</div>
<div>
<p className="text-sm text-slate-500 dark:text-slate-400">

View File

@@ -3,7 +3,7 @@
import {
JetBrains_Mono as FontMono,
Inter as FontSans,
} from "@next/font/google"
} from "next/font/google"
const fontSans = FontSans({
subsets: ["latin"],

View File

@@ -1,23 +1,8 @@
"use client"
import * as React from "react"
import Link from "next/link"
import { allDocs } from "contentlayer/generated"
import { siteConfig } from "@/config/site"
import { cn } from "@/lib/utils"
import { Icons } from "@/components/icons"
import { buttonVariants } from "@/components/ui/button"
import {
NavigationMenu,
NavigationMenuContent,
NavigationMenuItem,
NavigationMenuLink,
NavigationMenuList,
NavigationMenuTrigger,
navigationMenuTriggerStyle,
} from "@/components/ui/navigation-menu"
import { Separator } from "@/components/ui/separator"
export function MainNav() {
return (
@@ -28,114 +13,12 @@ export function MainNav() {
{siteConfig.name}
</span>
</Link>
<NavigationMenu>
<NavigationMenuList>
<NavigationMenuItem>
<NavigationMenuTrigger className="h-9">
Getting started
</NavigationMenuTrigger>
<NavigationMenuContent>
<ul className="grid gap-3 p-6 md:w-[400px] lg:w-[500px] lg:grid-cols-[.75fr_1fr]">
<li className="row-span-3">
<Link href="/" passHref legacyBehavior>
<NavigationMenuLink
className="flex h-full w-full select-none
flex-col justify-end space-y-2 rounded-md bg-gradient-to-b from-rose-500 to-indigo-700 p-6 no-underline outline-none focus:shadow-md"
>
<div className="text-lg font-medium text-white">
{siteConfig.name}
</div>
<p className="text-sm leading-snug text-white/90">
{siteConfig.description}
</p>
</NavigationMenuLink>
</Link>
</li>
<ListItem href="/docs" title="Introduction">
Re-usable components built using Radix UI and Tailwind CSS.
</ListItem>
<ListItem href="/docs/installation" title="Installation">
How to install dependencies and structure your app.
</ListItem>
<ListItem href="/docs/primitives/typography" title="Typography">
Styles for headings, paragraphs, lists...etc
</ListItem>
</ul>
</NavigationMenuContent>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuTrigger className="h-9">
Components
</NavigationMenuTrigger>
<NavigationMenuContent>
<ul className="grid w-[600px] grid-cols-2 gap-3 p-4">
{allDocs
.filter((doc) => doc.featured)
.map((doc) => (
<ListItem key={doc._id} title={doc.title} href={doc.slug}>
{doc.description}
</ListItem>
))}
</ul>
<div className="p-4 pt-0">
<Separator className="mb-4" />
<Link href="/docs/primitives/accordion" passHref legacyBehavior>
<NavigationMenuLink
className={cn(
buttonVariants({ variant: "outline" }),
"w-full dark:hover:bg-slate-700"
)}
>
Browse components
</NavigationMenuLink>
</Link>
</div>
</NavigationMenuContent>
</NavigationMenuItem>
<NavigationMenuItem className="hidden lg:flex">
<Link href="/figma" legacyBehavior passHref>
<NavigationMenuLink
className={cn(navigationMenuTriggerStyle(), "h-9")}
>
Figma
</NavigationMenuLink>
</Link>
</NavigationMenuItem>
<NavigationMenuItem className="hidden lg:flex">
<Link href={siteConfig.links.github} legacyBehavior passHref>
<NavigationMenuLink
className={cn(navigationMenuTriggerStyle(), "h-9")}
>
GitHub
</NavigationMenuLink>
</Link>
</NavigationMenuItem>
</NavigationMenuList>
</NavigationMenu>
<nav className="flex items-center space-x-6 text-sm font-medium">
<Link href="/docs">Documentation</Link>
<Link href="/docs/primitives/accordion">Components</Link>
<Link href="/figma">Figma</Link>
<Link href={siteConfig.links.github}>GitHub</Link>
</nav>
</div>
)
}
const ListItem = React.forwardRef<
React.ElementRef<typeof Link>,
React.ComponentPropsWithoutRef<typeof Link>
>(({ className, title, children, href, ...props }, ref) => {
return (
<li>
<Link href={href} passHref legacyBehavior {...props}>
<NavigationMenuLink
className={cn(
"block select-none space-y-1 rounded-md p-3 leading-none no-underline outline-none transition-colors hover:bg-slate-100 focus:bg-slate-100 dark:hover:bg-slate-700 dark:focus:bg-slate-700",
className
)}
>
<div className="text-sm font-medium leading-none">{title}</div>
<p className="line-clamp-2 text-sm leading-snug text-slate-500 dark:text-slate-400">
{children}
</p>
</NavigationMenuLink>
</Link>
</li>
)
})
ListItem.displayName = "ListItem"

View File

@@ -4,7 +4,7 @@ import { VariantProps, cva } from "class-variance-authority"
import { cn } from "@/lib/utils"
const buttonVariants = cva(
"active:scale-95 inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-slate-400 focus:ring-offset-2 dark:hover:bg-slate-800 dark:hover:text-slate-100 disabled:opacity-50 dark:focus:ring-slate-400 disabled:pointer-events-none dark:focus:ring-offset-slate-900 data-[state=open]:bg-slate-100 dark:data-[state=open]:bg-slate-800",
"inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-slate-400 focus:ring-offset-2 dark:hover:bg-slate-800 dark:hover:text-slate-100 disabled:opacity-50 dark:focus:ring-slate-400 disabled:pointer-events-none dark:focus:ring-offset-slate-900 data-[state=open]:bg-slate-100 dark:data-[state=open]:bg-slate-800",
{
variants: {
variant: {

View File

@@ -0,0 +1,189 @@
// Inspired by react-hot-toast library
import * as React from "react"
import { ToastActionElement, type ToastProps } from "@/components/ui/toast"
const TOAST_LIMIT = 1
const TOAST_REMOVE_DELAY = 1000
type ToasterToast = ToastProps & {
id: string
title?: React.ReactNode
description?: React.ReactNode
action?: ToastActionElement
}
const actionTypes = {
ADD_TOAST: "ADD_TOAST",
UPDATE_TOAST: "UPDATE_TOAST",
DISMISS_TOAST: "DISMISS_TOAST",
REMOVE_TOAST: "REMOVE_TOAST",
} as const
let count = 0
function genId() {
count = (count + 1) % Number.MAX_VALUE
return count.toString()
}
type ActionType = typeof actionTypes
type Action =
| {
type: ActionType["ADD_TOAST"]
toast: ToasterToast
}
| {
type: ActionType["UPDATE_TOAST"]
toast: Partial<ToasterToast>
}
| {
type: ActionType["DISMISS_TOAST"]
toastId?: ToasterToast["id"]
}
| {
type: ActionType["REMOVE_TOAST"]
toastId?: ToasterToast["id"]
}
interface State {
toasts: ToasterToast[]
}
const toastTimeouts = new Map<string, ReturnType<typeof setTimeout>>()
const addToRemoveQueue = (toastId: string) => {
if (toastTimeouts.has(toastId)) {
return
}
const timeout = setTimeout(() => {
toastTimeouts.delete(toastId)
dispatch({
type: "REMOVE_TOAST",
toastId: toastId,
})
}, TOAST_REMOVE_DELAY)
toastTimeouts.set(toastId, timeout)
}
export const reducer = (state: State, action: Action): State => {
switch (action.type) {
case "ADD_TOAST":
return {
...state,
toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT),
}
case "UPDATE_TOAST":
return {
...state,
toasts: state.toasts.map((t) =>
t.id === action.toast.id ? { ...t, ...action.toast } : t
),
}
case "DISMISS_TOAST": {
const { toastId } = action
// ! Side effects ! - This could be extracted into a dismissToast() action,
// but I'll keep it here for simplicity
if (toastId) {
addToRemoveQueue(toastId)
} else {
state.toasts.forEach((toast) => {
addToRemoveQueue(toast.id)
})
}
return {
...state,
toasts: state.toasts.map((t) =>
t.id === toastId || toastId === undefined
? {
...t,
open: false,
}
: t
),
}
}
case "REMOVE_TOAST":
if (action.toastId === undefined) {
return {
...state,
toasts: [],
}
}
return {
...state,
toasts: state.toasts.filter((t) => t.id !== action.toastId),
}
}
}
const listeners: Array<(state: State) => void> = []
let memoryState: State = { toasts: [] }
function dispatch(action: Action) {
memoryState = reducer(memoryState, action)
listeners.forEach((listener) => {
listener(memoryState)
})
}
interface Toast extends Omit<ToasterToast, "id"> {}
function toast({ ...props }: Toast) {
const id = genId()
const update = (props: ToasterToast) =>
dispatch({
type: "UPDATE_TOAST",
toast: { ...props, id },
})
const dismiss = () => dispatch({ type: "DISMISS_TOAST", toastId: id })
dispatch({
type: "ADD_TOAST",
toast: {
...props,
id,
open: true,
onOpenChange: (open) => {
if (!open) dismiss()
},
},
})
return {
id: id,
dismiss,
update,
}
}
function useToast() {
const [state, setState] = React.useState<State>(memoryState)
React.useEffect(() => {
listeners.push(setState)
return () => {
const index = listeners.indexOf(setState)
if (index > -1) {
listeners.splice(index, 1)
}
}
}, [state])
return {
...state,
toast,
dismiss: (toastId?: string) => dispatch({ type: "DISMISS_TOAST", toastId }),
}
}
export { useToast, toast }

View File

@@ -1,295 +1,179 @@
export const components = [
{
component: "accordion",
name: "Accordion",
dependencies: ["@radix-ui/react-accordion"],
files: [
{
name: "accordion.tsx",
dir: "components/ui",
},
],
files: ["components/ui/accordion.tsx"],
},
{
component: "alert-dialog",
name: "Alert Dialog",
dependencies: ["@radix-ui/react-alert-dialog"],
files: [
{
name: "alert-dialog.tsx",
dir: "components/ui",
},
],
files: ["components/ui/alert-dialog.tsx"],
},
{
component: "aspect-ratio",
name: "Aspect Ratio",
dependencies: ["@radix-ui/react-aspect-ratio"],
files: [
{
name: "aspect-ratio.tsx",
dir: "components/ui",
},
],
files: ["components/ui/aspect-ratio.tsx"],
},
{
component: "avatar",
name: "Avatar",
dependencies: ["@radix-ui/react-avatar"],
files: [
{
name: "avatar.tsx",
dir: "components/ui",
},
],
files: ["components/ui/avatar.tsx"],
},
{
component: "button",
name: "Button",
files: [
{
name: "button.tsx",
dir: "components/ui",
},
],
files: ["components/ui/button.tsx"],
},
{
component: "checkbox",
name: "Checkbox",
dependencies: ["@radix-ui/react-checkbox"],
files: [
{
name: "checkbox.tsx",
dir: "components/ui",
},
],
files: ["components/ui/checkbox.tsx"],
},
{
component: "collapsible",
name: "Collapsible",
dependencies: ["@radix-ui/react-collapsible"],
files: [
{
name: "collapsible.tsx",
dir: "components/ui",
},
],
files: ["components/ui/collapsible.tsx"],
},
{
component: "command",
name: "Command",
dependencies: ["cmdk"],
files: [
{
name: "command.tsx",
dir: "components/ui",
},
],
files: ["components/ui/command.tsx"],
},
{
component: "context-menu",
name: "Context Menu",
dependencies: ["@radix-ui/react-context-menu"],
files: [
{
name: "context-menu.tsx",
dir: "components/ui",
},
],
files: ["components/ui/context-menu.tsx"],
},
{
component: "dialog",
name: "Dialog",
dependencies: ["@radix-ui/react-dialog"],
files: [
{
name: "dialog.tsx",
dir: "components/ui",
},
],
files: ["components/ui/dialog.tsx"],
},
{
component: "dropdown-menu",
name: "Dropdown Menu",
dependencies: ["@radix-ui/react-dropdown-menu"],
files: [
{
name: "dropdown-menu.tsx",
dir: "components/ui",
},
],
files: ["components/ui/dropdown-menu.tsx"],
},
{
component: "hover-card",
name: "Hover Card",
dependencies: ["@radix-ui/react-hover-card"],
files: [
{
name: "hover-card.tsx",
dir: "components/ui",
},
],
files: ["components/ui/hover-card.tsx"],
},
{ name: "Input", files: [{ name: "input.tsx", dir: "components/ui" }] },
{
component: "input",
name: "Input",
files: ["components/ui/input.tsx"],
},
{
component: "label",
name: "Label",
dependencies: ["@radix-ui/react-label"],
files: [
{
name: "label.tsx",
dir: "components/ui",
},
],
files: ["components/ui/label.tsx"],
},
{
component: "menubar",
name: "Menubar",
dependencies: ["@radix-ui/react-menubar"],
files: [
{
name: "menubar.tsx",
dir: "components/ui",
},
],
files: ["components/ui/menubar.tsx"],
},
{
component: "navigation-menu",
name: "Navigation Menu",
dependencies: ["@radix-ui/react-navigation-menu"],
files: [
{
name: "navigation-menu.tsx",
dir: "components/ui",
},
],
files: ["components/ui/navigation-menu.tsx"],
},
{
component: "popover",
name: "Popover",
dependencies: ["@radix-ui/react-popover"],
files: [
{
name: "popover.tsx",
dir: "components/ui",
},
],
files: ["components/ui/popover.tsx"],
},
{
component: "progress",
name: "Progress",
dependencies: ["@radix-ui/react-progress"],
files: [
{
name: "progress.tsx",
dir: "components/ui",
},
],
files: ["components/ui/progress.tsx"],
},
{
component: "radio-group",
name: "Radio Group",
dependencies: ["@radix-ui/react-radio-group"],
files: [
{
name: "radio-group.tsx",
dir: "components/ui",
},
],
files: ["components/ui/radio-group.tsx"],
},
{
component: "scroll-area",
name: "Scroll-area",
dependencies: ["@radix-ui/react-scroll-area"],
files: [
{
name: "scroll-area.tsx",
dir: "components/ui",
},
],
files: ["components/ui/scroll-area.tsx"],
},
{
component: "select",
name: "Select",
dependencies: ["@radix-ui/react-select"],
files: [
{
name: "select.tsx",
dir: "components/ui",
},
],
files: ["components/ui/select.tsx"],
},
{
component: "separator",
name: "Separator",
dependencies: ["@radix-ui/react-separator"],
files: [
{
name: "separator.tsx",
dir: "components/ui",
},
],
files: ["components/ui/separator.tsx"],
},
{
component: "sheet",
name: "Sheet",
dependencies: ["@radix-ui/react-dialog"],
files: [
{
name: "sheet.tsx",
dir: "components/ui",
},
],
files: ["components/ui/sheet.tsx"],
},
{
component: "slider",
name: "Slider",
dependencies: ["@radix-ui/react-slider"],
files: [
{
name: "slider.tsx",
dir: "components/ui",
},
],
files: ["components/ui/slider.tsx"],
},
{
component: "switch",
name: "Switch",
dependencies: ["@radix-ui/react-switch"],
files: [
{
name: "switch.tsx",
dir: "components/ui",
},
],
files: ["components/ui/switch.tsx"],
},
{
component: "tabs",
name: "Tabs",
dependencies: ["@radix-ui/react-tabs"],
files: [
{
name: "tabs.tsx",
dir: "components/ui",
},
],
files: ["components/ui/tabs.tsx"],
},
{
component: "textarea",
name: "Textarea",
files: [
{
name: "textarea.tsx",
dir: "components/ui",
},
],
files: ["components/ui/textarea.tsx"],
},
{
component: "toast",
name: "Toast",
dependencies: ["@radix-ui/react-toast"],
files: [
{
name: "toast.tsx",
dir: "components/ui",
},
{
name: "use-toast.ts",
dir: "hooks",
},
],
files: ["components/ui/toast.tsx", "components/ui/use-toast.ts"],
},
{
component: "toggle",
name: "Toggle",
dependencies: ["@radix-ui/react-toggle"],
files: [
{
name: "toggle.tsx",
dir: "components/ui",
},
],
files: ["components/ui/toggle.tsx"],
},
{
component: "tooltip",
name: "Tooltip",
dependencies: ["@radix-ui/react-tooltip"],
files: [
{
name: "tooltip.tsx",
dir: "components/ui",
},
],
files: ["components/ui/tooltip.tsx"],
},
]

View File

@@ -57,7 +57,7 @@ I did. But I'm not really a designer. Most of what you see here, I learned by lo
### Is it ready for production?
Almost. I'm using it in production, but I'm still adding components and fixing bugs. See the roadmap on [GitHub](https://github.com/shadcn/ui).
Yes. You can use it in your production apps.
### How do I customize the colors?

View File

@@ -33,7 +33,11 @@ This is the `<Collapsible />` primitive. You can place it in a file at `componen
## Usage
```tsx
import { Collapsible } from "@/components/ui/collapsible"
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
} from "@/components/ui/collapsible"
```
```tsx

View File

@@ -1,6 +1,6 @@
---
title: Dialog
description: A modal dialog that interrupts the user with important content and expects a response.
description: A window overlaid on either the primary window or another dialog window, rendering the content underneath inert.
featured: true
component: true
radix:

View File

@@ -1,6 +1,6 @@
---
title: Scroll-area
description: Visually or semantically separates content.
description: Augments native scroll functionality for custom, cross-browser styling.
component: true
radix:
link: https://www.radix-ui.com/docs/primitives/components/scroll-area

View File

@@ -39,7 +39,7 @@ import {
SheetHeader,
SheetTitle,
SheetTrigger,
} from "@/components/ui/dialog"
} from "@/components/ui/sheet"
```
```tsx

View File

@@ -1,5 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
/// <reference types="next/navigation-types/compat/navigation" />
// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.

View File

@@ -14,7 +14,6 @@
"format:check": "prettier --check \"**/*.{ts,tsx,mdx}\" --cache"
},
"dependencies": {
"@next/font": "^13.1.6",
"@radix-ui/react-accessible-icon": "^1.0.1",
"@radix-ui/react-accordion": "^1.1.0",
"@radix-ui/react-alert-dialog": "^1.0.2",
@@ -50,7 +49,7 @@
"cmdk": "^0.1.21",
"contentlayer": "^0.3.0",
"lucide-react": "0.105.0-alpha.4",
"next": "^13.1.6",
"next": "13.2.4",
"next-contentlayer": "^0.3.0",
"next-themes": "^0.2.1",
"react": "^18.2.0",
@@ -77,7 +76,6 @@
"shiki": "^0.12.1",
"tailwindcss": "^3.1.7",
"typescript": "^4.5.3",
"unist": "^8.0.11",
"unist-builder": "^3.0.0",
"unist-util-visit": "^4.1.1"
},

File diff suppressed because one or more lines are too long

View File

@@ -6,13 +6,11 @@ import { components } from "../config/components"
const payload = components
.map((component) => {
const files = component.files?.map((file) => {
const content = fs.readFileSync(
path.join(process.cwd(), file.dir, file.name),
"utf8"
)
const content = fs.readFileSync(path.join(process.cwd(), file), "utf8")
return {
...file,
name: basename(file),
dir: dirname(file),
content,
}
})

View File

@@ -16,10 +16,11 @@
],
"scripts": {
"build": "turbo run build",
"build:cli": "turbo --filter=@shadcn/ui build",
"build:cli": "turbo --filter=shadcn-ui build",
"build:components": "pnpm --filter=www build:components",
"dev": "turbo run dev --parallel",
"dev:cli": "turbo --filter=@shadcn/ui dev",
"start:cli": "pnpm --filter=@shadcn/ui start:dev",
"dev:cli": "turbo --filter=shadcn-ui dev",
"start:cli": "pnpm --filter=shadcn-ui start:dev",
"lint": "turbo run lint",
"preview": "turbo run preview",
"typecheck": "turbo run typecheck",

View File

@@ -1,5 +1,15 @@
# @shadcn/ui
## 0.1.0
### Minor Changes
- [#178](https://github.com/shadcn/ui/pull/178) [`96f300e`](https://github.com/shadcn/ui/commit/96f300ea7471de9de9d433114d010d8fef2c8bae) Thanks [@shadcn](https://github.com/shadcn)! - add init command
### Patch Changes
- [#175](https://github.com/shadcn/ui/pull/175) [`b5d4368`](https://github.com/shadcn/ui/commit/b5d43688b975eb66b95b71af0396d07f94dde247) Thanks [@shadcn](https://github.com/shadcn)! - rename package to shadcn-ui
## 0.0.4
### Patch Changes

View File

@@ -1,7 +1,7 @@
# @shadcn/ui
# shadcn-ui
## Usage
```
npx @shadcn/ui
npx shadcn-ui add
```

View File

@@ -1,7 +1,7 @@
{
"name": "@shadcn/ui",
"version": "0.0.4",
"description": "Add @shadcn/ui components to your app.",
"name": "shadcn-ui",
"version": "0.1.0",
"description": "Add components to your apps.",
"publishConfig": {
"access": "public"
},
@@ -15,6 +15,9 @@
"url": "https://github.com/shadcn/ui.git",
"directory": "packages/cli"
},
"files": [
"dist"
],
"keywords": [
"components",
"ui",
@@ -24,15 +27,13 @@
],
"type": "module",
"exports": "./dist/index.js",
"bin": {
"@shadcn/ui": "./dist/index.js"
},
"bin": "./dist/index.js",
"scripts": {
"dev": "tsup --watch",
"build": "tsup",
"typecheck": "tsc --noEmit",
"clean": "rimraf dist && rimraf components",
"start:dev": "cross-env COMPONENTS_BASE_URL=http://localhost:3000 node dist/index.js",
"start:dev": "cross-env COMPONENTS_BASE_URL=http://localhost:3001 node dist/index.js",
"start": "node dist/index.js",
"format:write": "prettier --write \"**/*.{ts,tsx,mdx}\" --cache",
"format:check": "prettier --check \"**/*.{ts,tsx,mdx}\" --cache",
@@ -57,6 +58,6 @@
"rimraf": "^4.1.3",
"tsup": "^6.6.3",
"type-fest": "^3.6.1",
"typescript": "^4.9.5"
"typescript": "^4.5.5"
}
}

View File

@@ -9,27 +9,123 @@ import prompts from "prompts"
import { Component, getAvailableComponents } from "./utils/get-components"
import { getPackageInfo } from "./utils/get-package-info"
import { getPackageManager } from "./utils/get-package-manager"
import { getProjectInfo } from "./utils/get-project-info"
import { logger } from "./utils/logger"
import { STYLES, TAILWIND_CONFIG, UTILS } from "./utils/templates"
process.on("SIGINT", () => process.exit(0))
process.on("SIGTERM", () => process.exit(0))
const PROJECT_DEPENDENCIES = [
"tailwindcss-animate",
"class-variance-authority",
"clsx",
"tailwind-merge",
"lucide-react",
]
async function main() {
const packageInfo = await getPackageInfo()
const projectInfo = await getProjectInfo()
const packageManager = getPackageManager()
const program = new Command()
.name("@shadcn/ui")
.description("Add @shadcn/ui components to your project")
.name("shadcn-ui")
.description("Add shadcn-ui components to your project")
.version(
packageInfo.version || "1.0.0",
"-v, --version",
"display the version number"
)
program
.command("init")
.description("Configure your Next.js project.")
.option("-y, --yes", "Skip confirmation prompt.")
.action(async (options) => {
logger.warn(
"Running the following command will overwrite existing files."
)
logger.warn(
"Make sure you have committed your changes before proceeding."
)
logger.warn("")
logger.warn(
"This command assumes a Next.js project with TypeScript and Tailwind CSS."
)
logger.warn(
"If you don't have these, follow the manual steps at https://ui.shadcn.com/docs/installation."
)
logger.warn("")
if (!options.yes) {
const { proceed } = await prompts({
type: "confirm",
name: "proceed",
message:
"Running this command will install dependencies and overwrite files. Proceed?",
initial: true,
})
if (!proceed) {
process.exit(0)
}
}
// Install dependencies.
const dependenciesSpinner = ora(`Installing dependencies...`).start()
await execa(packageManager, [
packageManager === "npm" ? "install" : "add",
...PROJECT_DEPENDENCIES,
])
dependenciesSpinner.succeed()
// Ensure styles directory exists.
if (!projectInfo?.appDir) {
const stylesDir = projectInfo?.srcDir ? "./src/styles" : "./styles"
if (!existsSync(path.resolve(stylesDir))) {
await fs.mkdir(path.resolve(stylesDir), { recursive: true })
}
}
// Update styles.css
let stylesDestination = projectInfo?.srcDir
? "./src/styles/globals.css"
: "./styles/globals.css"
if (projectInfo?.appDir) {
stylesDestination = projectInfo?.srcDir
? "./src/app/globals.css"
: "./app/globals.css"
}
const stylesSpinner = ora(`Adding styles with CSS variables...`).start()
await fs.writeFile(stylesDestination, STYLES, "utf8")
stylesSpinner.succeed()
// Ensure lib directory exists.
const libDir = projectInfo?.srcDir ? "./src/lib" : "./lib"
if (!existsSync(path.resolve(libDir))) {
await fs.mkdir(path.resolve(libDir), { recursive: true })
}
// Create lib/utils.ts
const utilsDestination = projectInfo?.srcDir
? "./src/lib/utils.ts"
: "./lib/utils.ts"
const utilsSpinner = ora(`Adding utils...`).start()
await fs.writeFile(utilsDestination, UTILS, "utf8")
utilsSpinner.succeed()
const tailwindDestination = "./tailwind.config.js"
const tailwindSpinner = ora(`Updating tailwind.config.js...`).start()
await fs.writeFile(tailwindDestination, TAILWIND_CONFIG, "utf8")
tailwindSpinner.succeed()
})
program
.command("add")
.description("add components to your project")
.action(async () => {
.argument("[components...]", "name of components")
.action(async (components: string[]) => {
logger.warn(
"Running the following command will overwrite existing files."
)
@@ -38,8 +134,26 @@ async function main() {
)
logger.warn("")
const { components, dir } = await promptForAddOptions()
if (!components?.length) {
const availableComponents = await getAvailableComponents()
if (!availableComponents?.length) {
logger.error(
"An error occurred while fetching components. Please try again."
)
process.exit(0)
}
let selectedComponents = availableComponents.filter((component) =>
components.includes(component.component)
)
if (!selectedComponents?.length) {
selectedComponents = await promptForComponents(availableComponents)
}
const dir = await promptForDestinationDir()
if (!selectedComponents?.length) {
logger.warn("No components selected. Nothing to install.")
process.exit(0)
}
@@ -52,14 +166,19 @@ async function main() {
spinner.succeed()
}
const packageManager = getPackageManager()
logger.success(`Installing components...`)
for (const component of components) {
logger.success(
`Installing ${selectedComponents.length} component(s) and dependencies...`
)
for (const component of selectedComponents) {
const componentSpinner = ora(`${component.name}...`).start()
// Write the files.
for (const file of component.files) {
// Replace alias with the project's alias.
if (projectInfo?.alias) {
file.content = file.content.replace(/@\//g, projectInfo.alias)
}
const filePath = path.resolve(dir, file.name)
await fs.writeFile(filePath, file.content)
}
@@ -79,34 +198,24 @@ async function main() {
program.parse()
}
type AddOptions = {
components: Component[]
dir: string
async function promptForComponents(components: Component[]) {
const { components: selectedComponents } = await prompts({
type: "autocompleteMultiselect",
name: "components",
message: "Which component(s) would you like to add?",
hint: "Space to select. A to select all. I to invert selection.",
instructions: false,
choices: components.map((component) => ({
title: component.name,
value: component,
})),
})
return selectedComponents
}
async function promptForAddOptions() {
const availableComponents = await getAvailableComponents()
if (!availableComponents?.length) {
logger.error(
"An error occurred while fetching components. Please try again."
)
process.exit(0)
}
const options = await prompts([
{
type: "multiselect",
name: "components",
message: "Which component(s) would you like to add?",
hint: "Space to select. A to select all. I to invert selection.",
instructions: false,
choices: availableComponents.map((component) => ({
title: component.name,
value: component,
})),
},
async function promptForDestinationDir() {
const { dir } = await prompts([
{
type: "text",
name: "dir",
@@ -115,7 +224,7 @@ async function promptForAddOptions() {
},
])
return options as AddOptions
return dir
}
main()

View File

@@ -4,6 +4,7 @@ import * as z from "zod"
const baseUrl = process.env.COMPONENTS_BASE_URL ?? "https://ui.shadcn.com"
const componentSchema = z.object({
component: z.string(),
name: z.string(),
dependencies: z.array(z.string()).optional(),
files: z.array(

View File

@@ -0,0 +1,44 @@
import { existsSync } from "fs"
import path from "path"
import fs from "fs-extra"
export async function getProjectInfo() {
const info = {
tsconfig: null,
alias: null,
srcDir: false,
appDir: false,
}
try {
const tsconfig = await getTsConfig()
const paths = tsconfig?.compilerOptions?.paths
const alias = paths ? Object.keys(paths)[0].replace("*", "") : null
return {
tsconfig,
alias,
srcDir: existsSync(path.resolve("./src")),
appDir:
existsSync(path.resolve("./app")) ||
existsSync(path.resolve("./src/app")),
}
} catch (error) {
return info
}
}
export async function getTsConfig() {
try {
const tsconfigPath = path.join("tsconfig.json")
const tsconfig = await fs.readJSON(tsconfigPath)
if (!tsconfig) {
throw new Error("tsconfig.json is missing")
}
return tsconfig
} catch (error) {
return null
}
}

View File

@@ -0,0 +1,165 @@
export const STYLES = `@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%;
--card: 0 0% 100%;
--card-foreground: 222.2 47.4% 11.2%;
--border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%;
--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%;
--popover: 224 71% 4%;
--popover-foreground: 215 20.2% 65.1%;
--card: 0 0% 100%;
--card-foreground: 222.2 47.4% 11.2%;
--border: 216 34% 17%;
--input: 216 34% 17%;
--primary: 210 40% 98%;
--primary-foreground: 222.2 47.4% 1.2%;
--secondary: 222.2 47.4% 11.2%;
--secondary-foreground: 210 40% 98%;
--accent: 216 34% 17%;
--accent-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;
}
}`
export const UTILS = `import { ClassValue, clsx } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
`
export const TAILWIND_CONFIG = `/** @type {import('tailwindcss').Config} */
module.exports = {
darkMode: ["class"],
content: [
'./pages/**/*.{ts,tsx}',
'./components/**/*.{ts,tsx}',
'./app/**/*.{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)",
},
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")],
}`

4903
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -50,7 +50,7 @@ const AccordionContent = React.forwardRef<
<AccordionPrimitive.Content
ref={ref}
className={cn(
"overflow-hidden text-sm transition-all data-[state=open]:animate-accordion-down data-[state=closed]:animate-accordion-up",
"data-[state=open]:animate-accordion-down data-[state=closed]:animate-accordion-up overflow-hidden text-sm transition-all",
className
)}
{...props}

View File

@@ -28,7 +28,7 @@ const AlertDialogOverlay = React.forwardRef<
>(({ className, children, ...props }, ref) => (
<AlertDialogPrimitive.Overlay
className={cn(
"fixed inset-0 z-50 bg-black/50 backdrop-blur-sm transition-opacity animate-in fade-in",
"animate-in fade-in fixed inset-0 z-50 bg-black/50 backdrop-blur-sm transition-opacity",
className
)}
{...props}
@@ -46,7 +46,7 @@ const AlertDialogContent = React.forwardRef<
<AlertDialogPrimitive.Content
ref={ref}
className={cn(
"fixed z-50 grid w-full max-w-lg scale-100 gap-4 bg-white p-6 opacity-100 animate-in fade-in-90 slide-in-from-bottom-10 sm:rounded-lg sm:zoom-in-90 sm:slide-in-from-bottom-0 md:w-full",
"animate-in fade-in-90 slide-in-from-bottom-10 sm:zoom-in-90 sm:slide-in-from-bottom-0 fixed z-50 grid w-full max-w-lg scale-100 gap-4 bg-white p-6 opacity-100 sm:rounded-lg md:w-full",
"dark:bg-slate-900",
className
)}

View File

@@ -4,7 +4,7 @@ import { VariantProps, cva } from "class-variance-authority"
import { cn } from "@/lib/utils"
const buttonVariants = cva(
"active:scale-95 inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-slate-400 focus:ring-offset-2 dark:hover:bg-slate-800 dark:hover:text-slate-100 disabled:opacity-50 dark:focus:ring-slate-400 disabled:pointer-events-none dark:focus:ring-offset-slate-900 data-[state=open]:bg-slate-100 dark:data-[state=open]:bg-slate-800",
"inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-slate-400 focus:ring-offset-2 dark:hover:bg-slate-800 dark:hover:text-slate-100 disabled:opacity-50 dark:focus:ring-slate-400 disabled:pointer-events-none dark:focus:ring-offset-slate-900 data-[state=open]:bg-slate-100 dark:data-[state=open]:bg-slate-800",
{
variants: {
variant: {

View File

@@ -2,8 +2,8 @@
import * as React from "react"
import { DialogProps } from "@radix-ui/react-dialog"
import { Command as CommandPrimitive, useCommandState } from "cmdk"
import { ChevronsUpDown, Search } from "lucide-react"
import { Command as CommandPrimitive } from "cmdk"
import { Search } from "lucide-react"
import { cn } from "@/lib/utils"
import { Dialog, DialogContent } from "@/components/ui/dialog"

View File

@@ -46,7 +46,7 @@ const ContextMenuSubContent = React.forwardRef<
<ContextMenuPrimitive.SubContent
ref={ref}
className={cn(
"z-50 min-w-[8rem] overflow-hidden rounded-md border border-slate-100 bg-white p-1 shadow-md animate-in slide-in-from-left-1 dark:border-slate-700 dark:bg-slate-800",
"animate-in slide-in-from-left-1 z-50 min-w-[8rem] overflow-hidden rounded-md border border-slate-100 bg-white p-1 shadow-md dark:border-slate-700 dark:bg-slate-800",
className
)}
{...props}
@@ -62,7 +62,7 @@ const ContextMenuContent = React.forwardRef<
<ContextMenuPrimitive.Content
ref={ref}
className={cn(
"z-50 min-w-[8rem] overflow-hidden rounded-md border border-slate-100 bg-white p-1 text-slate-700 shadow-md animate-in fade-in-80 dark:border-slate-800 dark:bg-slate-800 dark:text-slate-400",
"animate-in fade-in-80 z-50 min-w-[8rem] overflow-hidden rounded-md border border-slate-100 bg-white p-1 text-slate-700 shadow-md dark:border-slate-800 dark:bg-slate-800 dark:text-slate-400",
className
)}
{...props}

View File

@@ -29,7 +29,7 @@ const DialogOverlay = React.forwardRef<
>(({ className, children, ...props }, ref) => (
<DialogPrimitive.Overlay
className={cn(
"fixed inset-0 z-50 bg-black/50 backdrop-blur-sm transition-all duration-100 data-[state=closed]:animate-out data-[state=open]:fade-in data-[state=closed]:fade-out",
"data-[state=closed]:animate-out data-[state=open]:fade-in data-[state=closed]:fade-out fixed inset-0 z-50 bg-black/50 backdrop-blur-sm transition-all duration-100",
className
)}
{...props}
@@ -47,7 +47,7 @@ const DialogContent = React.forwardRef<
<DialogPrimitive.Content
ref={ref}
className={cn(
"fixed z-50 grid w-full gap-4 rounded-b-lg bg-white p-6 animate-in data-[state=open]:fade-in-90 data-[state=open]:slide-in-from-bottom-10 sm:max-w-lg sm:rounded-lg sm:zoom-in-90 data-[state=open]:sm:slide-in-from-bottom-0",
"animate-in data-[state=open]:fade-in-90 data-[state=open]:slide-in-from-bottom-10 sm:zoom-in-90 data-[state=open]:sm:slide-in-from-bottom-0 fixed z-50 grid w-full gap-4 rounded-b-lg bg-white p-6 sm:max-w-lg sm:rounded-lg",
"dark:bg-slate-900",
className
)}

View File

@@ -47,7 +47,7 @@ const DropdownMenuSubContent = React.forwardRef<
<DropdownMenuPrimitive.SubContent
ref={ref}
className={cn(
"z-50 min-w-[8rem] overflow-hidden rounded-md border border-slate-100 bg-white p-1 text-slate-700 shadow-md animate-in slide-in-from-left-1 dark:border-slate-800 dark:bg-slate-800 dark:text-slate-400",
"animate-in slide-in-from-left-1 z-50 min-w-[8rem] overflow-hidden rounded-md border border-slate-100 bg-white p-1 text-slate-700 shadow-md dark:border-slate-800 dark:bg-slate-800 dark:text-slate-400",
className
)}
{...props}
@@ -65,7 +65,7 @@ const DropdownMenuContent = React.forwardRef<
ref={ref}
sideOffset={sideOffset}
className={cn(
"z-50 min-w-[8rem] overflow-hidden rounded-md border border-slate-100 bg-white p-1 text-slate-700 shadow-md animate-in data-[side=right]:slide-in-from-left-2 data-[side=left]:slide-in-from-right-2 data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2 dark:border-slate-800 dark:bg-slate-800 dark:text-slate-400",
"animate-in data-[side=right]:slide-in-from-left-2 data-[side=left]:slide-in-from-right-2 data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] overflow-hidden rounded-md border border-slate-100 bg-white p-1 text-slate-700 shadow-md dark:border-slate-800 dark:bg-slate-800 dark:text-slate-400",
className
)}
{...props}

View File

@@ -18,7 +18,7 @@ const HoverCardContent = React.forwardRef<
align={align}
sideOffset={sideOffset}
className={cn(
"z-50 w-64 rounded-md border border-slate-100 bg-white p-4 shadow-md outline-none animate-in zoom-in-90 dark:border-slate-800 dark:bg-slate-800",
"animate-in zoom-in-90 z-50 w-64 rounded-md border border-slate-100 bg-white p-4 shadow-md outline-none dark:border-slate-800 dark:bg-slate-800",
className
)}
{...props}

View File

@@ -74,7 +74,7 @@ const MenubarSubContent = React.forwardRef<
<MenubarPrimitive.SubContent
ref={ref}
className={cn(
"z-50 min-w-[8rem] overflow-hidden rounded-md border border-slate-100 bg-white p-1 shadow-md animate-in slide-in-from-left-1 dark:border-slate-700 dark:bg-slate-800",
"animate-in slide-in-from-left-1 z-50 min-w-[8rem] overflow-hidden rounded-md border border-slate-100 bg-white p-1 shadow-md dark:border-slate-700 dark:bg-slate-800",
className
)}
{...props}
@@ -97,7 +97,7 @@ const MenubarContent = React.forwardRef<
alignOffset={alignOffset}
sideOffset={sideOffset}
className={cn(
"z-50 min-w-[12rem] overflow-hidden rounded-md border border-slate-100 bg-white p-1 text-slate-700 shadow-md animate-in slide-in-from-top-1 dark:border-slate-800 dark:bg-slate-800 dark:text-slate-400",
"animate-in slide-in-from-top-1 z-50 min-w-[12rem] overflow-hidden rounded-md border border-slate-100 bg-white p-1 text-slate-700 shadow-md dark:border-slate-800 dark:bg-slate-800 dark:text-slate-400",
className
)}
{...props}

View File

@@ -69,7 +69,7 @@ const NavigationMenuContent = React.forwardRef<
<NavigationMenuPrimitive.Content
ref={ref}
className={cn(
"top-0 left-0 w-full data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=to-start]:slide-out-to-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=from-end]:slide-in-from-right-52 md:absolute md:w-auto ",
"data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=to-start]:slide-out-to-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=from-end]:slide-in-from-right-52 top-0 left-0 w-full md:absolute md:w-auto ",
className
)}
{...props}
@@ -86,7 +86,7 @@ const NavigationMenuViewport = React.forwardRef<
<div className={cn("absolute left-0 top-full flex justify-center")}>
<NavigationMenuPrimitive.Viewport
className={cn(
"origin-top-center relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border border-slate-200 bg-white shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=open]:zoom-in-90 data-[state=closed]:zoom-out-95 dark:border-slate-700 dark:bg-slate-800 md:w-[var(--radix-navigation-menu-viewport-width)]",
"origin-top-center data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=open]:zoom-in-90 data-[state=closed]:zoom-out-95 relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border border-slate-200 bg-white shadow-lg dark:border-slate-700 dark:bg-slate-800 md:w-[var(--radix-navigation-menu-viewport-width)]",
className
)}
ref={ref}
@@ -104,7 +104,7 @@ const NavigationMenuIndicator = React.forwardRef<
<NavigationMenuPrimitive.Indicator
ref={ref}
className={cn(
"top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=visible]:fade-in data-[state=hidden]:fade-out",
"data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=visible]:fade-in data-[state=hidden]:fade-out top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden",
className
)}
{...props}

View File

@@ -19,7 +19,7 @@ const PopoverContent = React.forwardRef<
align={align}
sideOffset={sideOffset}
className={cn(
"z-50 w-72 rounded-md border border-slate-100 bg-white p-4 shadow-md outline-none animate-in data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2 data-[side=right]:slide-in-from-left-2 data-[side=left]:slide-in-from-right-2 dark:border-slate-800 dark:bg-slate-800",
"animate-in data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2 data-[side=right]:slide-in-from-left-2 data-[side=left]:slide-in-from-right-2 z-50 w-72 rounded-md border border-slate-100 bg-white p-4 shadow-md outline-none dark:border-slate-800 dark:bg-slate-800",
className
)}
{...props}

View File

@@ -38,7 +38,7 @@ const SelectContent = React.forwardRef<
<SelectPrimitive.Content
ref={ref}
className={cn(
"relative z-50 min-w-[8rem] overflow-hidden rounded-md border border-slate-100 bg-white text-slate-700 shadow-md animate-in fade-in-80 dark:border-slate-800 dark:bg-slate-800 dark:text-slate-400",
"animate-in fade-in-80 relative z-50 min-w-[8rem] overflow-hidden rounded-md border border-slate-100 bg-white text-slate-700 shadow-md dark:border-slate-800 dark:bg-slate-800 dark:text-slate-400",
className
)}
{...props}

View File

@@ -45,7 +45,7 @@ const SheetOverlay = React.forwardRef<
>(({ className, children, ...props }, ref) => (
<SheetPrimitive.Overlay
className={cn(
"fixed inset-0 z-50 bg-black/50 backdrop-blur-sm transition-all duration-100 data-[state=closed]:animate-out data-[state=open]:fade-in data-[state=closed]:fade-out",
"data-[state=closed]:animate-out data-[state=open]:fade-in data-[state=closed]:fade-out fixed inset-0 z-50 bg-black/50 backdrop-blur-sm transition-all duration-100",
className
)}
{...props}

View File

@@ -20,7 +20,7 @@ const TooltipContent = React.forwardRef<
ref={ref}
sideOffset={sideOffset}
className={cn(
"z-50 overflow-hidden rounded-md border border-slate-100 bg-white px-3 py-1.5 text-sm text-slate-700 shadow-md animate-in fade-in-50 data-[side=bottom]:slide-in-from-top-1 data-[side=top]:slide-in-from-bottom-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 dark:border-slate-800 dark:bg-slate-800 dark:text-slate-400",
"animate-in fade-in-50 data-[side=bottom]:slide-in-from-top-1 data-[side=top]:slide-in-from-bottom-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 z-50 overflow-hidden rounded-md border border-slate-100 bg-white px-3 py-1.5 text-sm text-slate-700 shadow-md dark:border-slate-800 dark:bg-slate-800 dark:text-slate-400",
className
)}
{...props}

View File

@@ -14,10 +14,10 @@ export default function App({ Component, pageProps }: AppProps) {
return (
<>
<style jsx global>{`
:root {
--font-sans: ${fontSans.style.fontFamily};
}
}`}</style>
:root {
--font-sans: ${fontSans.style.fontFamily};
}
`}</style>
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
<Component {...pageProps} />
</ThemeProvider>