mirror of
https://github.com/shadcn-ui/ui.git
synced 2026-06-14 11:21:36 +00:00
Compare commits
55 Commits
shadcn-ui@
...
shadcn-ui@
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
897376329b | ||
|
|
d3d52fc687 | ||
|
|
4d0864a5c2 | ||
|
|
e8f58932bd | ||
|
|
2f0dbca221 | ||
|
|
58d012e342 | ||
|
|
963114e118 | ||
|
|
0a4286500e | ||
|
|
ae845788f6 | ||
|
|
ccb2d695a7 | ||
|
|
b838ffe8cc | ||
|
|
7ce6c495bd | ||
|
|
c9ca64d2b9 | ||
|
|
4bb9e9de53 | ||
|
|
c21ecfb665 | ||
|
|
613ec3583f | ||
|
|
170d3c087c | ||
|
|
4b0fbe27fa | ||
|
|
c34193cd34 | ||
|
|
88fdc989e9 | ||
|
|
4506822389 | ||
|
|
33a5fc7966 | ||
|
|
33b77e2f31 | ||
|
|
e3769277d8 | ||
|
|
3992a7b19c | ||
|
|
52c23746bc | ||
|
|
f68976b667 | ||
|
|
7a1f80af2c | ||
|
|
646f715388 | ||
|
|
9441130f05 | ||
|
|
48e3a4a326 | ||
|
|
98078fbe01 | ||
|
|
8be9e5d966 | ||
|
|
a8b1ea7e55 | ||
|
|
3c9f7ca0e2 | ||
|
|
c598f19845 | ||
|
|
7962cee384 | ||
|
|
de3c34845b | ||
|
|
6a1354e52d | ||
|
|
1532a15894 | ||
|
|
8e5d080900 | ||
|
|
cf95943446 | ||
|
|
3210bed755 | ||
|
|
eaa91d43df | ||
|
|
8cf0c7f3ba | ||
|
|
da7729644c | ||
|
|
aca3ef97e3 | ||
|
|
c9fecd4cdf | ||
|
|
6cf598d47f | ||
|
|
91727ec460 | ||
|
|
5e172fc34f | ||
|
|
f461ab0910 | ||
|
|
26c8d0f662 | ||
|
|
ac5c727fc9 | ||
|
|
54b1f5b661 |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "https://unpkg.com/@changesets/config@2.3.0/schema.json",
|
||||
"changelog": ["@changesets/changelog-github", { "repo": "shadcn/ui" }],
|
||||
"changelog": ["@changesets/changelog-github", { "repo": "shadcn-ui/ui" }],
|
||||
"commit": false,
|
||||
"fixed": [],
|
||||
"linked": [],
|
||||
|
||||
2
.github/workflows/prerelease-comment.yml
vendored
2
.github/workflows/prerelease-comment.yml
vendored
@@ -10,7 +10,7 @@ on:
|
||||
jobs:
|
||||
comment:
|
||||
if: |
|
||||
github.repository_owner == 'shadcn' &&
|
||||
github.repository_owner == 'shadcn-ui' &&
|
||||
${{ github.event.workflow_run.conclusion == 'success' }}
|
||||
runs-on: ubuntu-latest
|
||||
name: Write comment to the PR
|
||||
|
||||
2
.github/workflows/prerelease.yml
vendored
2
.github/workflows/prerelease.yml
vendored
@@ -10,7 +10,7 @@ on:
|
||||
jobs:
|
||||
prerelease:
|
||||
if: |
|
||||
github.repository_owner == 'shadcn' &&
|
||||
github.repository_owner == 'shadcn-ui' &&
|
||||
contains(github.event.pull_request.labels.*.name, '🚀 autorelease')
|
||||
name: Build & Publish a beta release to NPM
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -9,7 +9,7 @@ on:
|
||||
|
||||
jobs:
|
||||
release:
|
||||
if: ${{ github.repository_owner == 'shadcn' }}
|
||||
if: ${{ github.repository_owner == 'shadcn-ui' }}
|
||||
name: Create a PR for release workflow
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
162
CONTRIBUTING.md
Normal file
162
CONTRIBUTING.md
Normal file
@@ -0,0 +1,162 @@
|
||||
# Contributing
|
||||
|
||||
Thanks for your interest in contributing to ui.shadcn.com. We're happy to have you here.
|
||||
|
||||
Please take a moment to review this document before submitting your first pull request. We also strongly recommend that you check for open issues and pull requests to see if someone else is working on something similar.
|
||||
|
||||
If you need any help, feel free to reach out to [@shadcn](https://twitter.com/shadcn).
|
||||
|
||||
## About this repository
|
||||
|
||||
This repository is a monorepo.
|
||||
|
||||
- We use [pnpm](https://pnpm.io) and [`workspaces`](https://pnpm.io/workspaces) for development.
|
||||
- We use [Turborepo](https://turbo.build/repo) as our build system.
|
||||
- We use [changesets](https://github.com/changesets/changesets) for managing releases.
|
||||
|
||||
## Structure
|
||||
|
||||
This repository is structured as follows:
|
||||
|
||||
```
|
||||
apps
|
||||
└── www
|
||||
├── app
|
||||
├── components
|
||||
├── content
|
||||
└── registry
|
||||
├── default
|
||||
│ ├── example
|
||||
│ └── ui
|
||||
└── new-york
|
||||
├── example
|
||||
└── ui
|
||||
packages
|
||||
└── cli
|
||||
```
|
||||
|
||||
| Path | Description |
|
||||
| --------------------- | ---------------------------------------- |
|
||||
| `apps/www/app` | The Next.js application for the website. |
|
||||
| `apps/www/components` | The React components for the website. |
|
||||
| `apps/www/content` | The content for the website. |
|
||||
| `apps/www/registry` | The registry for the components. |
|
||||
| `packages/cli` | The `shadcn-ui` package. |
|
||||
|
||||
## Development
|
||||
|
||||
### Start by cloning the repository:
|
||||
|
||||
```
|
||||
git clone git@github.com:shadcn-ui/ui.git
|
||||
```
|
||||
|
||||
### Install dependencies
|
||||
|
||||
```
|
||||
pnpm install
|
||||
```
|
||||
|
||||
### Run a workspace
|
||||
|
||||
You can use the `pnpm --filter=[WORKSPACE]` command to start the development process for a workspace.
|
||||
|
||||
#### Examples
|
||||
|
||||
1. To run the `ui.shadcn.com` website:
|
||||
|
||||
```
|
||||
pnpm --filter=www dev
|
||||
```
|
||||
|
||||
2. To run the `shadcn-ui` package:
|
||||
|
||||
```
|
||||
pnpm --filter=shadcn-ui dev
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
The documentation for this project is located in the `www` workspace. You can run the documentation locally by running the following command:
|
||||
|
||||
```bash
|
||||
pnpm --filter=www dev
|
||||
```
|
||||
|
||||
Documentation is written using [MDX](https://mdxjs.com). You can find the documentation files in the `apps/www/content/docs` directory.
|
||||
|
||||
## Components
|
||||
|
||||
We use a registry system for developing components. You can find the source code for the components under `apps/www/registry`. The components are organized by styles.
|
||||
|
||||
```bash
|
||||
apps
|
||||
└── www
|
||||
└── registry
|
||||
├── default
|
||||
│ ├── example
|
||||
│ └── ui
|
||||
└── new-york
|
||||
├── example
|
||||
└── ui
|
||||
```
|
||||
|
||||
When adding or modifying components, please ensure that:
|
||||
|
||||
1. You make the changes for every style.
|
||||
2. You update the documentation.
|
||||
3. You run `pnpm build:registry` to update the registry.
|
||||
|
||||
## Commit Convention
|
||||
|
||||
Before you create a Pull Request, please check whether your commits comply with
|
||||
the commit conventions used in this repository.
|
||||
|
||||
When you create a commit we kindly ask you to follow the convention
|
||||
`category(scope or module): message` in your commit message while using one of
|
||||
the following categories:
|
||||
|
||||
- `feat / feature`: all changes that introduce completely new code or new
|
||||
features
|
||||
- `fix`: changes that fix a bug (ideally you will additionally reference an
|
||||
issue if present)
|
||||
- `refactor`: any code related change that is not a fix nor a feature
|
||||
- `docs`: changing existing or creating new documentation (i.e. README, docs for
|
||||
usage of a lib or cli usage)
|
||||
- `build`: all changes regarding the build of the software, changes to
|
||||
dependencies or the addition of new dependencies
|
||||
- `test`: all changes regarding tests (adding new tests or changing existing
|
||||
ones)
|
||||
- `ci`: all changes regarding the configuration of continuous integration (i.e.
|
||||
github actions, ci system)
|
||||
- `chore`: all changes to the repository that do not fit into any of the above
|
||||
categories
|
||||
|
||||
e.g. `feat(components): add new prop to the avatar component`
|
||||
|
||||
|
||||
If you are interested in the detailed specification you can visit
|
||||
https://www.conventionalcommits.org/ or check out the
|
||||
[Angular Commit Message Guidelines](https://github.com/angular/angular/blob/22b96b9/CONTRIBUTING.md#-commit-message-guidelines).
|
||||
|
||||
|
||||
|
||||
## Requests for new components
|
||||
|
||||
If you have a request for a new component, please open a discussion on GitHub. We'll be happy to help you out.
|
||||
|
||||
## CLI
|
||||
|
||||
The `shadcn-ui` package is a CLI for adding components to your project. You can find the documentation for the CLI [here](https://ui.shadcn.com/docs/cli).
|
||||
|
||||
Any changes to the CLI should be made in the `packages/cli` directory. If you can, it would be great if you could add tests for your changes.
|
||||
|
||||
## Testing
|
||||
|
||||
Tests are written using [Vitest](https://vitest.dev). You can run all the tests from the root of the repository.
|
||||
|
||||
```bash
|
||||
pnpm test
|
||||
```
|
||||
|
||||
Please ensure that the tests are passing when submitting a pull request. If you're adding new features, please include tests.
|
||||
@@ -8,6 +8,10 @@ Accessible and customizable components that you can copy and paste into your app
|
||||
|
||||
Visit http://ui.shadcn.com/docs to view the documentation.
|
||||
|
||||
## Contributing
|
||||
|
||||
Please read the [contributing guide](/CONTRIBUTING.md).
|
||||
|
||||
## License
|
||||
|
||||
Licensed under the [MIT license](https://github.com/shadcn/ui/blob/main/LICENSE.md).
|
||||
|
||||
@@ -1006,6 +1006,13 @@ export const Index: Record<string, any> = {
|
||||
component: React.lazy(() => import("@/registry/default/example/mode-toggle")),
|
||||
files: ["registry/default/example/mode-toggle.tsx"],
|
||||
},
|
||||
"cards": {
|
||||
name: "cards",
|
||||
type: "components:example",
|
||||
registryDependencies: undefined,
|
||||
component: React.lazy(() => import("@/registry/default/example/cards")),
|
||||
files: ["registry/default/example/cards/cards.tsx"],
|
||||
},
|
||||
}, "new-york": {
|
||||
"accordion": {
|
||||
name: "accordion",
|
||||
@@ -2008,5 +2015,12 @@ export const Index: Record<string, any> = {
|
||||
component: React.lazy(() => import("@/registry/new-york/example/mode-toggle")),
|
||||
files: ["registry/new-york/example/mode-toggle.tsx"],
|
||||
},
|
||||
"cards": {
|
||||
name: "cards",
|
||||
type: "components:example",
|
||||
registryDependencies: undefined,
|
||||
component: React.lazy(() => import("@/registry/new-york/example/cards")),
|
||||
files: ["registry/new-york/example/cards/cards.tsx"],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -139,9 +139,11 @@ export default async function DocPage({ params }: DocPageProps) {
|
||||
</div>
|
||||
{doc.toc && (
|
||||
<div className="hidden text-sm xl:block">
|
||||
<div className="sticky top-16 -mt-10 h-[calc(100vh-3.5rem)] overflow-hidden pt-6">
|
||||
<div className="sticky top-16 -mt-10 pt-4">
|
||||
<ScrollArea className="pb-10">
|
||||
<DashboardTableOfContents toc={toc} />
|
||||
<div className="sticky top-16 -mt-10 h-[calc(100vh-3.5rem)] py-12">
|
||||
<DashboardTableOfContents toc={toc} />
|
||||
</div>
|
||||
</ScrollArea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -30,42 +30,52 @@ export function DemoPaymentMethod() {
|
||||
</CardHeader>
|
||||
<CardContent className="grid gap-6">
|
||||
<RadioGroup defaultValue="card" className="grid grid-cols-3 gap-4">
|
||||
<Label
|
||||
htmlFor="card"
|
||||
className="flex flex-col items-center justify-between rounded-md border-2 border-muted bg-popover p-4 hover:bg-accent hover:text-accent-foreground [&:has([data-state=checked])]:border-primary"
|
||||
>
|
||||
<RadioGroupItem value="card" id="card" className="sr-only" />
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
className="mb-3 h-6 w-6"
|
||||
<div>
|
||||
<RadioGroupItem value="card" id="card" className="peer sr-only" />
|
||||
<Label
|
||||
htmlFor="card"
|
||||
className="flex flex-col items-center justify-between rounded-md border-2 border-muted bg-popover p-4 hover:bg-accent hover:text-accent-foreground peer-data-[state=checked]:border-primary [&:has([data-state=checked])]:border-primary"
|
||||
>
|
||||
<rect width="20" height="14" x="2" y="5" rx="2" />
|
||||
<path d="M2 10h20" />
|
||||
</svg>
|
||||
Card
|
||||
</Label>
|
||||
<Label
|
||||
htmlFor="paypal"
|
||||
className="flex flex-col items-center justify-between rounded-md border-2 border-muted bg-popover p-4 hover:bg-accent hover:text-accent-foreground [&:has([data-state=checked])]:border-primary"
|
||||
>
|
||||
<RadioGroupItem value="paypal" id="paypal" className="sr-only" />
|
||||
<Icons.paypal className="mb-3 h-6 w-6" />
|
||||
Paypal
|
||||
</Label>
|
||||
<Label
|
||||
htmlFor="apple"
|
||||
className="flex flex-col items-center justify-between rounded-md border-2 border-muted bg-popover p-4 hover:bg-accent hover:text-accent-foreground [&:has([data-state=checked])]:border-primary"
|
||||
>
|
||||
<RadioGroupItem value="apple" id="apple" className="sr-only" />
|
||||
<Icons.apple className="mb-3 h-6 w-6" />
|
||||
Apple
|
||||
</Label>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
className="mb-3 h-6 w-6"
|
||||
>
|
||||
<rect width="20" height="14" x="2" y="5" rx="2" />
|
||||
<path d="M2 10h20" />
|
||||
</svg>
|
||||
Card
|
||||
</Label>
|
||||
</div>
|
||||
<div>
|
||||
<RadioGroupItem
|
||||
value="paypal"
|
||||
id="paypal"
|
||||
className="peer sr-only"
|
||||
/>
|
||||
<Label
|
||||
htmlFor="paypal"
|
||||
className="flex flex-col items-center justify-between rounded-md border-2 border-muted bg-popover p-4 hover:bg-accent hover:text-accent-foreground peer-data-[state=checked]:border-primary [&:has([data-state=checked])]:border-primary"
|
||||
>
|
||||
<Icons.paypal className="mb-3 h-6 w-6" />
|
||||
Paypal
|
||||
</Label>
|
||||
</div>
|
||||
<div>
|
||||
<RadioGroupItem value="apple" id="apple" className="peer sr-only" />
|
||||
<Label
|
||||
htmlFor="apple"
|
||||
className="flex flex-col items-center justify-between rounded-md border-2 border-muted bg-popover p-4 hover:bg-accent hover:text-accent-foreground peer-data-[state=checked]:border-primary [&:has([data-state=checked])]:border-primary"
|
||||
>
|
||||
<Icons.apple className="mb-3 h-6 w-6" />
|
||||
Apple
|
||||
</Label>
|
||||
</div>
|
||||
</RadioGroup>
|
||||
<div className="grid gap-2">
|
||||
<Label htmlFor="name">Name</Label>
|
||||
|
||||
@@ -75,7 +75,7 @@ export default function CardsPage() {
|
||||
<DemoNotifications />
|
||||
</DemoContainer>
|
||||
</div>
|
||||
<div className="col-span-2 grid items-start gap-6 lg:col-span-1 lg:grid-cols-2 xl:grid-cols-1">
|
||||
<div className="col-span-2 grid items-start gap-6 lg:col-span-2 lg:grid-cols-2 xl:col-span-1 xl:grid-cols-1">
|
||||
<DemoContainer>
|
||||
<DemoReportAnIssue />
|
||||
</DemoContainer>
|
||||
|
||||
@@ -25,7 +25,7 @@ import { UserNav } from "@/app/examples/dashboard/components/user-nav"
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Dashboard",
|
||||
description: "Example dashboard app using the components.",
|
||||
description: "Example dashboard app built using the components.",
|
||||
}
|
||||
|
||||
export default function DashboardPage() {
|
||||
|
||||
@@ -184,10 +184,10 @@ export function AccountForm() {
|
||||
<CommandGroup>
|
||||
{languages.map((language) => (
|
||||
<CommandItem
|
||||
value={language.value}
|
||||
value={language.label}
|
||||
key={language.value}
|
||||
onSelect={(value) => {
|
||||
form.setValue("language", value)
|
||||
onSelect={() => {
|
||||
form.setValue("language", language.value)
|
||||
}}
|
||||
>
|
||||
<CheckIcon
|
||||
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
} from "@/registry/new-york/ui/popover"
|
||||
import { Separator } from "@/registry/new-york/ui/separator"
|
||||
|
||||
interface DataTableFacetedFilter<TData, TValue> {
|
||||
interface DataTableFacetedFilterProps<TData, TValue> {
|
||||
column?: Column<TData, TValue>
|
||||
title?: string
|
||||
options: {
|
||||
@@ -35,7 +35,7 @@ export function DataTableFacetedFilter<TData, TValue>({
|
||||
column,
|
||||
title,
|
||||
options,
|
||||
}: DataTableFacetedFilter<TData, TValue>) {
|
||||
}: DataTableFacetedFilterProps<TData, TValue>) {
|
||||
const facets = column?.getFacetedUniqueValues()
|
||||
const selectedValues = new Set(column?.getFilterValue() as string[])
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import { ThemeProvider } from "@/components/providers"
|
||||
import { SiteFooter } from "@/components/site-footer"
|
||||
import { SiteHeader } from "@/components/site-header"
|
||||
import { TailwindIndicator } from "@/components/tailwind-indicator"
|
||||
import { ThemeSwitcher } from "@/components/theme-switcher"
|
||||
import { Toaster as DefaultToaster } from "@/registry/default/ui/toaster"
|
||||
import { Toaster as NewYorkToaster } from "@/registry/new-york/ui/toaster"
|
||||
|
||||
@@ -82,7 +83,12 @@ export default function RootLayout({ children }: RootLayoutProps) {
|
||||
fontSans.variable
|
||||
)}
|
||||
>
|
||||
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
|
||||
<ThemeProvider
|
||||
attribute="class"
|
||||
defaultTheme="system"
|
||||
enableSystem
|
||||
disableTransitionOnChange
|
||||
>
|
||||
<div className="relative flex min-h-screen flex-col">
|
||||
<SiteHeader />
|
||||
<div className="flex-1">{children}</div>
|
||||
@@ -90,6 +96,7 @@ export default function RootLayout({ children }: RootLayoutProps) {
|
||||
</div>
|
||||
<TailwindIndicator />
|
||||
</ThemeProvider>
|
||||
<ThemeSwitcher />
|
||||
<Analytics />
|
||||
<NewYorkToaster />
|
||||
<DefaultToaster />
|
||||
|
||||
38
apps/www/app/themes/page.tsx
Normal file
38
apps/www/app/themes/page.tsx
Normal file
@@ -0,0 +1,38 @@
|
||||
import { Metadata } from "next"
|
||||
|
||||
import "public/registry/themes.css"
|
||||
import {
|
||||
PageHeader,
|
||||
PageHeaderDescription,
|
||||
PageHeaderHeading,
|
||||
} from "@/components/page-header"
|
||||
import { ThemeCustomizer } from "@/components/theme-customizer"
|
||||
import { ThemeWrapper } from "@/components/theme-wrapper"
|
||||
import { ThemesTabs } from "@/app/themes/tabs"
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Themes",
|
||||
description: "Hand-picked themes that you can copy and paste into your apps.",
|
||||
}
|
||||
|
||||
export default function ThemesPage() {
|
||||
return (
|
||||
<div className="container">
|
||||
<ThemeWrapper
|
||||
defaultTheme="zinc"
|
||||
className="relative flex flex-col items-start md:flex-row md:items-center"
|
||||
>
|
||||
<PageHeader className="relative pb-4 md:pb-8 lg:pb-12">
|
||||
<PageHeaderHeading>Make it yours.</PageHeaderHeading>
|
||||
<PageHeaderDescription>
|
||||
Hand-picked themes that you can copy and paste into your apps.
|
||||
</PageHeaderDescription>
|
||||
</PageHeader>
|
||||
<div className="px-4 pb-8 md:ml-auto md:pb-0">
|
||||
<ThemeCustomizer />
|
||||
</div>
|
||||
</ThemeWrapper>
|
||||
<ThemesTabs />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
73
apps/www/app/themes/tabs.tsx
Normal file
73
apps/www/app/themes/tabs.tsx
Normal file
@@ -0,0 +1,73 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
|
||||
import { useConfig } from "@/hooks/use-config"
|
||||
import { ThemeWrapper } from "@/components/theme-wrapper"
|
||||
import CardsDefault from "@/registry/default/example/cards"
|
||||
import { Skeleton } from "@/registry/default/ui/skeleton"
|
||||
import CardsNewYork from "@/registry/new-york/example/cards"
|
||||
|
||||
export function ThemesTabs() {
|
||||
const [mounted, setMounted] = React.useState(false)
|
||||
const [config] = useConfig()
|
||||
|
||||
React.useEffect(() => {
|
||||
setMounted(true)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="space-y-8">
|
||||
{!mounted ? (
|
||||
<div className="md:grids-col-2 grid md:gap-4 lg:grid-cols-10 xl:gap-6">
|
||||
<div className="space-y-4 lg:col-span-4 xl:col-span-6 xl:space-y-6">
|
||||
<Skeleton className="h-[218px] w-full" />
|
||||
<div className="grid gap-1 sm:grid-cols-[260px_1fr] md:hidden">
|
||||
<Skeleton className="h-[218px] w-full" />
|
||||
<div className="pt-3 sm:pl-2 sm:pt-0 xl:pl-4">
|
||||
<Skeleton className="h-[218px] w-full" />
|
||||
</div>
|
||||
<div className="pt-3 sm:col-span-2 xl:pt-4">
|
||||
<Skeleton className="h-[218px] w-full" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid gap-6 md:grid-cols-2 lg:grid-cols-1 xl:grid-cols-2">
|
||||
<div className="space-y-4 xl:space-y-6">
|
||||
<Skeleton className="h-[218px] w-full" />
|
||||
<Skeleton className="h-[218px] w-full" />
|
||||
<Skeleton className="h-[218px] w-full" />
|
||||
</div>
|
||||
<div className="space-y-4 xl:space-y-6">
|
||||
<Skeleton className="h-[218px] w-full" />
|
||||
<Skeleton className="h-[218px] w-full" />
|
||||
<div className="hidden xl:block">
|
||||
<Skeleton className="h-[218px] w-full" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-4 lg:col-span-6 xl:col-span-4 xl:space-y-6">
|
||||
<div className="hidden gap-1 sm:grid-cols-[260px_1fr] md:grid">
|
||||
<Skeleton className="h-[218px] w-full" />
|
||||
<div className="pt-3 sm:pl-2 sm:pt-0 xl:pl-4">
|
||||
<Skeleton className="h-[218px] w-full" />
|
||||
</div>
|
||||
<div className="pt-3 sm:col-span-2 xl:pt-4">
|
||||
<Skeleton className="h-[218px] w-full" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="hidden md:block">
|
||||
<Skeleton className="h-[218px] w-full" />
|
||||
</div>
|
||||
<Skeleton className="h-[218px] w-full" />
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<ThemeWrapper>
|
||||
{config.style === "new-york" && <CardsNewYork />}
|
||||
{config.style === "default" && <CardsDefault />}
|
||||
</ThemeWrapper>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -102,7 +102,7 @@ export function ComponentPreview({
|
||||
codeString && <CopyButton value={codeString} />
|
||||
)}
|
||||
</div>
|
||||
<ThemeWrapper>
|
||||
<ThemeWrapper defaultTheme="zinc">
|
||||
<div
|
||||
className={cn(
|
||||
"preview flex min-h-[350px] w-full justify-center p-10",
|
||||
|
||||
@@ -21,7 +21,7 @@ interface CopyButtonProps extends React.HTMLAttributes<HTMLButtonElement> {
|
||||
event?: Event["name"]
|
||||
}
|
||||
|
||||
async function copyToClipboardWithMeta(value: string, event?: Event) {
|
||||
export async function copyToClipboardWithMeta(value: string, event?: Event) {
|
||||
navigator.clipboard.writeText(value)
|
||||
if (event) {
|
||||
trackEvent(event)
|
||||
|
||||
31
apps/www/components/drawer.tsx
Normal file
31
apps/www/components/drawer.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
"use client"
|
||||
|
||||
import { forwardRef } from "react"
|
||||
import { Drawer as DrawerPrimitive } from "vaul"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
const DrawerTrigger = DrawerPrimitive.Trigger
|
||||
|
||||
const DrawerContent = forwardRef<
|
||||
React.ElementRef<typeof DrawerPrimitive.Content>,
|
||||
React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Content>
|
||||
>(({ className, children, ...props }, ref) => (
|
||||
<DrawerPrimitive.Portal>
|
||||
<DrawerPrimitive.Overlay className="fixed inset-0 z-50 bg-zinc-950/60" />
|
||||
<DrawerPrimitive.Content
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"fixed inset-x-0 bottom-0 z-50 mt-24 h-[96%] rounded-t-[10px] bg-background",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<div className="absolute left-1/2 top-3 h-2 w-[100px] translate-x-[-50%] rounded-full bg-muted" />
|
||||
{children}
|
||||
</DrawerPrimitive.Content>
|
||||
</DrawerPrimitive.Portal>
|
||||
))
|
||||
DrawerContent.displayName = "DrawerContent"
|
||||
|
||||
export { DrawerTrigger, DrawerContent }
|
||||
@@ -7,6 +7,7 @@ import { usePathname } from "next/navigation"
|
||||
import { siteConfig } from "@/config/site"
|
||||
import { cn } from "@/lib/utils"
|
||||
import { Icons } from "@/components/icons"
|
||||
import { Badge } from "@/registry/new-york/ui/badge"
|
||||
|
||||
export function MainNav() {
|
||||
const pathname = usePathname()
|
||||
@@ -40,6 +41,17 @@ export function MainNav() {
|
||||
>
|
||||
Components
|
||||
</Link>
|
||||
<Link
|
||||
href="/themes"
|
||||
className={cn(
|
||||
"transition-colors hover:text-foreground/80",
|
||||
pathname?.startsWith("/themes")
|
||||
? "text-foreground"
|
||||
: "text-foreground/60"
|
||||
)}
|
||||
>
|
||||
Themes
|
||||
</Link>
|
||||
<Link
|
||||
href="/examples"
|
||||
className={cn(
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import * as React from "react"
|
||||
import Image from "next/image"
|
||||
import Link, { LinkProps } from "next/link"
|
||||
import Link from "next/link"
|
||||
import { useMDXComponent } from "next-contentlayer/hooks"
|
||||
import { NpmCommands } from "types/unist"
|
||||
|
||||
@@ -292,6 +292,12 @@ const components = {
|
||||
}: React.ComponentProps<typeof FrameworkDocs>) => (
|
||||
<FrameworkDocs className={cn(className)} {...props} />
|
||||
),
|
||||
Link: ({ className, ...props }: React.ComponentProps<typeof Link>) => (
|
||||
<Link
|
||||
className={cn("font-medium underline underline-offset-4", className)}
|
||||
{...props}
|
||||
/>
|
||||
),
|
||||
LinkedCard: ({ className, ...props }: React.ComponentProps<typeof Link>) => (
|
||||
<Link
|
||||
className={cn(
|
||||
|
||||
@@ -11,7 +11,7 @@ import { buttonVariants } from "@/registry/new-york/ui/button"
|
||||
|
||||
export function SiteHeader() {
|
||||
return (
|
||||
<header className="supports-backdrop-blur:bg-background/60 sticky top-0 z-40 w-full border-b bg-background/95 backdrop-blur">
|
||||
<header className="supports-backdrop-blur:bg-background/60 sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur">
|
||||
<div className="container flex h-14 items-center">
|
||||
<MainNav />
|
||||
<MobileNav />
|
||||
|
||||
52
apps/www/components/theme-component.tsx
Normal file
52
apps/www/components/theme-component.tsx
Normal file
@@ -0,0 +1,52 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import { Index } from "@/__registry__"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
import { useConfig } from "@/hooks/use-config"
|
||||
import { Icons } from "@/components/icons"
|
||||
|
||||
interface ThemeComponentProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
name: string
|
||||
extractClassname?: boolean
|
||||
extractedClassNames?: string
|
||||
align?: "center" | "start" | "end"
|
||||
}
|
||||
|
||||
export function ThemeComponent({ name, ...props }: ThemeComponentProps) {
|
||||
const [config] = useConfig()
|
||||
|
||||
const Preview = React.useMemo(() => {
|
||||
const Component = Index[config.style][name]?.component
|
||||
|
||||
if (!Component) {
|
||||
return (
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Component{" "}
|
||||
<code className="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm">
|
||||
{name}
|
||||
</code>{" "}
|
||||
not found in registry.
|
||||
</p>
|
||||
)
|
||||
}
|
||||
|
||||
return <Component />
|
||||
}, [name, config.style])
|
||||
|
||||
return (
|
||||
<div className={cn("relative")} {...props}>
|
||||
<React.Suspense
|
||||
fallback={
|
||||
<div className="flex items-center text-sm text-muted-foreground">
|
||||
<Icons.spinner className="mr-2 h-4 w-4 animate-spin" />
|
||||
Loading...
|
||||
</div>
|
||||
}
|
||||
>
|
||||
{Preview}
|
||||
</React.Suspense>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
629
apps/www/components/theme-customizer.tsx
Normal file
629
apps/www/components/theme-customizer.tsx
Normal file
@@ -0,0 +1,629 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import {
|
||||
CheckIcon,
|
||||
CopyIcon,
|
||||
InfoCircledIcon,
|
||||
MoonIcon,
|
||||
ResetIcon,
|
||||
SunIcon,
|
||||
} from "@radix-ui/react-icons"
|
||||
import template from "lodash.template"
|
||||
import { Paintbrush } from "lucide-react"
|
||||
import { useTheme } from "next-themes"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
import { useConfig } from "@/hooks/use-config"
|
||||
import { copyToClipboardWithMeta } from "@/components/copy-button"
|
||||
import { DrawerContent, DrawerTrigger } from "@/components/drawer"
|
||||
import { ThemeWrapper } from "@/components/theme-wrapper"
|
||||
import { Button } from "@/registry/new-york/ui/button"
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from "@/registry/new-york/ui/dialog"
|
||||
import { Label } from "@/registry/new-york/ui/label"
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from "@/registry/new-york/ui/popover"
|
||||
import { Skeleton } from "@/registry/new-york/ui/skeleton"
|
||||
import { Theme, themes } from "@/registry/themes"
|
||||
|
||||
import "@/styles/mdx.css"
|
||||
import { Drawer } from "vaul"
|
||||
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipTrigger,
|
||||
} from "@/registry/new-york/ui/tooltip"
|
||||
|
||||
export function ThemeCustomizer() {
|
||||
const [config, setConfig] = useConfig()
|
||||
const { resolvedTheme: mode } = useTheme()
|
||||
const [mounted, setMounted] = React.useState(false)
|
||||
|
||||
React.useEffect(() => {
|
||||
setMounted(true)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="flex items-center space-x-2">
|
||||
<Drawer.Root>
|
||||
<DrawerTrigger asChild>
|
||||
<Button variant="outline" className="md:hidden">
|
||||
<Paintbrush className="mr-2 h-4 w-4" />
|
||||
Customize
|
||||
</Button>
|
||||
</DrawerTrigger>
|
||||
<DrawerContent className="h-[85%] p-6 pt-10">
|
||||
<Customizer />
|
||||
</DrawerContent>
|
||||
</Drawer.Root>
|
||||
<div className="hidden md:flex">
|
||||
<div className="mr-2 hidden items-center space-x-0.5 lg:flex">
|
||||
{mounted ? (
|
||||
<>
|
||||
{["zinc", "rose", "blue", "green", "orange"].map((color) => {
|
||||
const theme = themes.find((theme) => theme.name === color)
|
||||
const isActive = config.theme === color
|
||||
|
||||
if (!theme) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<Tooltip key={theme.name}>
|
||||
<TooltipTrigger asChild>
|
||||
<button
|
||||
onClick={() =>
|
||||
setConfig({
|
||||
...config,
|
||||
theme: theme.name,
|
||||
})
|
||||
}
|
||||
className={cn(
|
||||
"flex h-9 w-9 items-center justify-center rounded-full border-2 text-xs",
|
||||
isActive
|
||||
? "border-[--theme-primary]"
|
||||
: "border-transparent"
|
||||
)}
|
||||
style={
|
||||
{
|
||||
"--theme-primary": `hsl(${
|
||||
theme?.activeColor[
|
||||
mode === "dark" ? "dark" : "light"
|
||||
]
|
||||
})`,
|
||||
} as React.CSSProperties
|
||||
}
|
||||
>
|
||||
<span
|
||||
className={cn(
|
||||
"flex h-6 w-6 items-center justify-center rounded-full bg-[--theme-primary]"
|
||||
)}
|
||||
>
|
||||
{isActive && (
|
||||
<CheckIcon className="h-4 w-4 text-white" />
|
||||
)}
|
||||
</span>
|
||||
<span className="sr-only">{theme.label}</span>
|
||||
</button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent
|
||||
align="center"
|
||||
className="rounded-[0.5rem] bg-zinc-900 text-zinc-50"
|
||||
>
|
||||
{theme.label}
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
)
|
||||
})}
|
||||
</>
|
||||
) : (
|
||||
<div className="mr-1 flex items-center space-x-3">
|
||||
<Skeleton className="h-6 w-6 rounded-full" />
|
||||
<Skeleton className="h-6 w-6 rounded-full" />
|
||||
<Skeleton className="h-6 w-6 rounded-full" />
|
||||
<Skeleton className="h-6 w-6 rounded-full" />
|
||||
<Skeleton className="h-6 w-6 rounded-full" />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<Button variant="outline">
|
||||
<Paintbrush className="mr-2 h-4 w-4" />
|
||||
Customize
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent
|
||||
align="end"
|
||||
className="z-40 w-[340px] rounded-[0.5rem] bg-white p-6 dark:bg-zinc-950"
|
||||
>
|
||||
<Customizer />
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</div>
|
||||
<CopyCodeButton />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function Customizer() {
|
||||
const [mounted, setMounted] = React.useState(false)
|
||||
const { setTheme: setMode, resolvedTheme: mode } = useTheme()
|
||||
const [config, setConfig] = useConfig()
|
||||
|
||||
React.useEffect(() => {
|
||||
setMounted(true)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<ThemeWrapper
|
||||
defaultTheme="zinc"
|
||||
className="flex flex-col space-y-4 md:space-y-6"
|
||||
>
|
||||
<div className="flex items-start">
|
||||
<div className="space-y-1 pr-2">
|
||||
<div className="font-semibold leading-none tracking-tight">
|
||||
Customize
|
||||
</div>
|
||||
<div className="text-xs text-muted-foreground">
|
||||
Pick a style and color for your components.
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="ml-auto rounded-[0.5rem]"
|
||||
onClick={() => {
|
||||
setConfig({
|
||||
...config,
|
||||
theme: "zinc",
|
||||
radius: 0.5,
|
||||
})
|
||||
}}
|
||||
>
|
||||
<ResetIcon />
|
||||
<span className="sr-only">Reset</span>
|
||||
</Button>
|
||||
</div>
|
||||
<div className="flex flex-1 flex-col space-y-4 md:space-y-6">
|
||||
<div className="space-y-1.5">
|
||||
<div className="flex w-full items-center">
|
||||
<Label className="text-xs">Style</Label>
|
||||
<Popover>
|
||||
<PopoverTrigger>
|
||||
<InfoCircledIcon className="ml-1 h-3 w-3" />
|
||||
<span className="sr-only">About styles</span>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent
|
||||
className="space-y-3 rounded-[0.5rem] text-sm"
|
||||
side="right"
|
||||
align="start"
|
||||
alignOffset={-20}
|
||||
>
|
||||
<p className="font-medium">
|
||||
What is the difference between the New York and Default style?
|
||||
</p>
|
||||
<p>
|
||||
A style comes with its own set of components, animations,
|
||||
icons and more.
|
||||
</p>
|
||||
<p>
|
||||
The <span className="font-medium">Default</span> style has
|
||||
larger inputs, uses lucide-react for icons and
|
||||
tailwindcss-animate for animations.
|
||||
</p>
|
||||
<p>
|
||||
The <span className="font-medium">New York</span> style ships
|
||||
with smaller buttons and cards with shadows. It uses icons
|
||||
from Radix Icons.
|
||||
</p>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</div>
|
||||
<div className="grid grid-cols-3 gap-2">
|
||||
<Button
|
||||
variant={"outline"}
|
||||
size="sm"
|
||||
onClick={() => setConfig({ ...config, style: "default" })}
|
||||
className={cn(
|
||||
config.style === "default" && "border-2 border-primary"
|
||||
)}
|
||||
>
|
||||
Default
|
||||
</Button>
|
||||
<Button
|
||||
variant={"outline"}
|
||||
size="sm"
|
||||
onClick={() => setConfig({ ...config, style: "new-york" })}
|
||||
className={cn(
|
||||
config.style === "new-york" && "border-2 border-primary"
|
||||
)}
|
||||
>
|
||||
New York
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-1.5">
|
||||
<Label className="text-xs">Color</Label>
|
||||
<div className="grid grid-cols-3 gap-2">
|
||||
{themes.map((theme) => {
|
||||
const isActive = config.theme === theme.name
|
||||
|
||||
return mounted ? (
|
||||
<Button
|
||||
variant={"outline"}
|
||||
size="sm"
|
||||
key={theme.name}
|
||||
onClick={() => {
|
||||
setConfig({
|
||||
...config,
|
||||
theme: theme.name,
|
||||
})
|
||||
}}
|
||||
className={cn(
|
||||
"justify-start",
|
||||
isActive && "border-2 border-primary"
|
||||
)}
|
||||
style={
|
||||
{
|
||||
"--theme-primary": `hsl(${
|
||||
theme?.activeColor[mode === "dark" ? "dark" : "light"]
|
||||
})`,
|
||||
} as React.CSSProperties
|
||||
}
|
||||
>
|
||||
<span
|
||||
className={cn(
|
||||
"mr-1 flex h-5 w-5 shrink-0 -translate-x-1 items-center justify-center rounded-full bg-[--theme-primary]"
|
||||
)}
|
||||
>
|
||||
{isActive && <CheckIcon className="h-4 w-4 text-white" />}
|
||||
</span>
|
||||
{theme.label}
|
||||
</Button>
|
||||
) : (
|
||||
<Skeleton className="h-8 w-full" key={theme.name} />
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-1.5">
|
||||
<Label className="text-xs">Radius</Label>
|
||||
<div className="grid grid-cols-5 gap-2">
|
||||
{["0", "0.3", "0.5", "0.75", "1.0"].map((value) => {
|
||||
return (
|
||||
<Button
|
||||
variant={"outline"}
|
||||
size="sm"
|
||||
key={value}
|
||||
onClick={() => {
|
||||
setConfig({
|
||||
...config,
|
||||
radius: parseFloat(value),
|
||||
})
|
||||
}}
|
||||
className={cn(
|
||||
config.radius === parseFloat(value) &&
|
||||
"border-2 border-primary"
|
||||
)}
|
||||
>
|
||||
{value}
|
||||
</Button>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-1.5">
|
||||
<Label className="text-xs">Mode</Label>
|
||||
<div className="grid grid-cols-3 gap-2">
|
||||
{mounted ? (
|
||||
<>
|
||||
<Button
|
||||
variant={"outline"}
|
||||
size="sm"
|
||||
onClick={() => setMode("light")}
|
||||
className={cn(mode === "light" && "border-2 border-primary")}
|
||||
>
|
||||
<SunIcon className="mr-1 -translate-x-1" />
|
||||
Light
|
||||
</Button>
|
||||
<Button
|
||||
variant={"outline"}
|
||||
size="sm"
|
||||
onClick={() => setMode("dark")}
|
||||
className={cn(mode === "dark" && "border-2 border-primary")}
|
||||
>
|
||||
<MoonIcon className="mr-1 -translate-x-1" />
|
||||
Dark
|
||||
</Button>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Skeleton className="h-8 w-full" />
|
||||
<Skeleton className="h-8 w-full" />
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ThemeWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
function CopyCodeButton() {
|
||||
const [config] = useConfig()
|
||||
const activeTheme = themes.find((theme) => theme.name === config.theme)
|
||||
const [hasCopied, setHasCopied] = React.useState(false)
|
||||
|
||||
React.useEffect(() => {
|
||||
setTimeout(() => {
|
||||
setHasCopied(false)
|
||||
}, 2000)
|
||||
}, [hasCopied])
|
||||
|
||||
return (
|
||||
<>
|
||||
{activeTheme && (
|
||||
<Button
|
||||
onClick={() => {
|
||||
copyToClipboardWithMeta(getThemeCode(activeTheme, config.radius), {
|
||||
name: "copy_theme_code",
|
||||
properties: {
|
||||
theme: activeTheme.name,
|
||||
radius: config.radius,
|
||||
},
|
||||
})
|
||||
setHasCopied(true)
|
||||
}}
|
||||
className="md:hidden"
|
||||
>
|
||||
{hasCopied ? (
|
||||
<CheckIcon className="mr-2 h-4 w-4" />
|
||||
) : (
|
||||
<CopyIcon className="mr-2 h-4 w-4" />
|
||||
)}
|
||||
Copy
|
||||
</Button>
|
||||
)}
|
||||
<Dialog>
|
||||
<DialogTrigger asChild>
|
||||
<Button className="hidden md:flex">Copy code</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent className="max-w-2xl outline-none">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Theme</DialogTitle>
|
||||
<DialogDescription>
|
||||
Copy and paste the following code into your CSS file.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<ThemeWrapper defaultTheme="zinc" className="relative">
|
||||
<CustomizerCode />
|
||||
{activeTheme && (
|
||||
<Button
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
copyToClipboardWithMeta(
|
||||
getThemeCode(activeTheme, config.radius),
|
||||
{
|
||||
name: "copy_theme_code",
|
||||
properties: {
|
||||
theme: activeTheme.name,
|
||||
radius: config.radius,
|
||||
},
|
||||
}
|
||||
)
|
||||
setHasCopied(true)
|
||||
}}
|
||||
className="absolute right-4 top-4 bg-muted text-muted-foreground hover:bg-muted hover:text-muted-foreground"
|
||||
>
|
||||
{hasCopied ? (
|
||||
<CheckIcon className="mr-2 h-4 w-4" />
|
||||
) : (
|
||||
<CopyIcon className="mr-2 h-4 w-4" />
|
||||
)}
|
||||
Copy
|
||||
</Button>
|
||||
)}
|
||||
</ThemeWrapper>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
function CustomizerCode() {
|
||||
const [config] = useConfig()
|
||||
const activeTheme = themes.find((theme) => theme.name === config.theme)
|
||||
|
||||
return (
|
||||
<ThemeWrapper defaultTheme="zinc" className="relative space-y-4">
|
||||
<div data-rehype-pretty-code-fragment="">
|
||||
<pre className="max-h-[450px] overflow-x-auto rounded-lg border bg-zinc-950 py-4 dark:bg-zinc-900">
|
||||
<code className="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm">
|
||||
<span className="line text-white">@layer base {</span>
|
||||
<span className="line text-white"> :root {</span>
|
||||
<span className="line text-white">
|
||||
--background:{" "}
|
||||
{activeTheme?.cssVars.light["background"]};
|
||||
</span>
|
||||
<span className="line text-white">
|
||||
--foreground:{" "}
|
||||
{activeTheme?.cssVars.light["foreground"]};
|
||||
</span>
|
||||
{[
|
||||
"card",
|
||||
"popover",
|
||||
"primary",
|
||||
"secondary",
|
||||
"muted",
|
||||
"accent",
|
||||
"destructive",
|
||||
].map((prefix) => (
|
||||
<>
|
||||
<span className="line text-white">
|
||||
--{prefix}:{" "}
|
||||
{
|
||||
activeTheme?.cssVars.light[
|
||||
prefix as keyof typeof activeTheme.cssVars.light
|
||||
]
|
||||
}
|
||||
;
|
||||
</span>
|
||||
<span className="line text-white">
|
||||
--{prefix}-foreground:{" "}
|
||||
{
|
||||
activeTheme?.cssVars.light[
|
||||
`${prefix}-foreground` as keyof typeof activeTheme.cssVars.light
|
||||
]
|
||||
}
|
||||
;
|
||||
</span>
|
||||
</>
|
||||
))}
|
||||
<span className="line text-white">
|
||||
--border:{" "}
|
||||
{activeTheme?.cssVars.light["border"]};
|
||||
</span>
|
||||
<span className="line text-white">
|
||||
--input:{" "}
|
||||
{activeTheme?.cssVars.light["input"]};
|
||||
</span>
|
||||
<span className="line text-white">
|
||||
--ring:{" "}
|
||||
{activeTheme?.cssVars.light["ring"]};
|
||||
</span>
|
||||
<span className="line text-white">
|
||||
--radius: {config.radius}rem;
|
||||
</span>
|
||||
<span className="line text-white"> }</span>
|
||||
<span className="line text-white"> </span>
|
||||
<span className="line text-white"> .dark {</span>
|
||||
<span className="line text-white">
|
||||
--background:{" "}
|
||||
{activeTheme?.cssVars.dark["background"]};
|
||||
</span>
|
||||
<span className="line text-white">
|
||||
--foreground:{" "}
|
||||
{activeTheme?.cssVars.dark["foreground"]};
|
||||
</span>
|
||||
{[
|
||||
"card",
|
||||
"popover",
|
||||
"primary",
|
||||
"secondary",
|
||||
"muted",
|
||||
"accent",
|
||||
"destructive",
|
||||
].map((prefix) => (
|
||||
<>
|
||||
<span className="line text-white">
|
||||
--{prefix}:{" "}
|
||||
{
|
||||
activeTheme?.cssVars.dark[
|
||||
prefix as keyof typeof activeTheme.cssVars.dark
|
||||
]
|
||||
}
|
||||
;
|
||||
</span>
|
||||
<span className="line text-white">
|
||||
--{prefix}-foreground:{" "}
|
||||
{
|
||||
activeTheme?.cssVars.dark[
|
||||
`${prefix}-foreground` as keyof typeof activeTheme.cssVars.dark
|
||||
]
|
||||
}
|
||||
;
|
||||
</span>
|
||||
</>
|
||||
))}
|
||||
<span className="line text-white">
|
||||
--border:{" "}
|
||||
{activeTheme?.cssVars.dark["border"]};
|
||||
</span>
|
||||
<span className="line text-white">
|
||||
--input:{" "}
|
||||
{activeTheme?.cssVars.dark["input"]};
|
||||
</span>
|
||||
<span className="line text-white">
|
||||
--ring:{" "}
|
||||
{activeTheme?.cssVars.dark["ring"]};
|
||||
</span>
|
||||
<span className="line text-white"> }</span>
|
||||
<span className="line text-white">}</span>
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
</ThemeWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
function getThemeCode(theme: Theme, radius: number) {
|
||||
if (!theme) {
|
||||
return ""
|
||||
}
|
||||
|
||||
return template(BASE_STYLES_WITH_VARIABLES)({
|
||||
colors: theme.cssVars,
|
||||
radius,
|
||||
})
|
||||
}
|
||||
|
||||
const BASE_STYLES_WITH_VARIABLES = `
|
||||
@layer base {
|
||||
:root {
|
||||
--background: <%- colors.light["background"] %>;
|
||||
--foreground: <%- colors.light["foreground"] %>;
|
||||
--card: <%- colors.light["card"] %>;
|
||||
--card-foreground: <%- colors.light["card-foreground"] %>;
|
||||
--popover: <%- colors.light["popover"] %>;
|
||||
--popover-foreground: <%- colors.light["popover-foreground"] %>;
|
||||
--primary: <%- colors.light["primary"] %>;
|
||||
--primary-foreground: <%- colors.light["primary-foreground"] %>;
|
||||
--secondary: <%- colors.light["secondary"] %>;
|
||||
--secondary-foreground: <%- colors.light["secondary-foreground"] %>;
|
||||
--muted: <%- colors.light["muted"] %>;
|
||||
--muted-foreground: <%- colors.light["muted-foreground"] %>;
|
||||
--accent: <%- colors.light["accent"] %>;
|
||||
--accent-foreground: <%- colors.light["accent-foreground"] %>;
|
||||
--destructive: <%- colors.light["destructive"] %>;
|
||||
--destructive-foreground: <%- colors.light["destructive-foreground"] %>;
|
||||
--border: <%- colors.light["border"] %>;
|
||||
--input: <%- colors.light["input"] %>;
|
||||
--ring: <%- colors.light["ring"] %>;
|
||||
--radius: <%- radius %>rem;
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: <%- colors.dark["background"] %>;
|
||||
--foreground: <%- colors.dark["foreground"] %>;
|
||||
--card: <%- colors.dark["card"] %>;
|
||||
--card-foreground: <%- colors.dark["card-foreground"] %>;
|
||||
--popover: <%- colors.dark["popover"] %>;
|
||||
--popover-foreground: <%- colors.dark["popover-foreground"] %>;
|
||||
--primary: <%- colors.dark["primary"] %>;
|
||||
--primary-foreground: <%- colors.dark["primary-foreground"] %>;
|
||||
--secondary: <%- colors.dark["secondary"] %>;
|
||||
--secondary-foreground: <%- colors.dark["secondary-foreground"] %>;
|
||||
--muted: <%- colors.dark["muted"] %>;
|
||||
--muted-foreground: <%- colors.dark["muted-foreground"] %>;
|
||||
--accent: <%- colors.dark["accent"] %>;
|
||||
--accent-foreground: <%- colors.dark["accent-foreground"] %>;
|
||||
--destructive: <%- colors.dark["destructive"] %>;
|
||||
--destructive-foreground: <%- colors.dark["destructive-foreground"] %>;
|
||||
--border: <%- colors.dark["border"] %>;
|
||||
--input: <%- colors.dark["input"] %>;
|
||||
--ring: <%- colors.dark["ring"] %>;
|
||||
}
|
||||
}
|
||||
`
|
||||
26
apps/www/components/theme-switcher.tsx
Normal file
26
apps/www/components/theme-switcher.tsx
Normal file
@@ -0,0 +1,26 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import { useSelectedLayoutSegment } from "next/navigation"
|
||||
|
||||
import { useConfig } from "@/hooks/use-config"
|
||||
|
||||
export function ThemeSwitcher() {
|
||||
const [config] = useConfig()
|
||||
const segment = useSelectedLayoutSegment()
|
||||
|
||||
React.useEffect(() => {
|
||||
document.body.classList.forEach((className) => {
|
||||
if (className.match(/^theme.*/)) {
|
||||
document.body.classList.remove(className)
|
||||
}
|
||||
})
|
||||
|
||||
const theme = segment === "themes" ? config.theme : null
|
||||
if (theme) {
|
||||
return document.body.classList.add(`theme-${theme}`)
|
||||
}
|
||||
}, [segment, config])
|
||||
|
||||
return null
|
||||
}
|
||||
@@ -3,8 +3,31 @@
|
||||
import { cn } from "@/lib/utils"
|
||||
import { useConfig } from "@/hooks/use-config"
|
||||
|
||||
export function ThemeWrapper({ children }: React.ComponentProps<"div">) {
|
||||
interface ThemeWrapperProps extends React.ComponentProps<"div"> {
|
||||
defaultTheme?: string
|
||||
}
|
||||
|
||||
export function ThemeWrapper({
|
||||
defaultTheme,
|
||||
children,
|
||||
className,
|
||||
}: ThemeWrapperProps) {
|
||||
const [config] = useConfig()
|
||||
|
||||
return <div className={cn(`theme-${config.theme}`, "w-full")}>{children}</div>
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
`theme-${defaultTheme || config.theme}`,
|
||||
"w-full",
|
||||
className
|
||||
)}
|
||||
style={
|
||||
{
|
||||
"--radius": `${defaultTheme ? 0.5 : config.radius}rem`,
|
||||
} as React.CSSProperties
|
||||
}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -15,6 +15,10 @@ export const docsConfig: DocsConfig = {
|
||||
title: "Components",
|
||||
href: "/docs/components/accordion",
|
||||
},
|
||||
{
|
||||
title: "Themes",
|
||||
href: "/themes",
|
||||
},
|
||||
{
|
||||
title: "Examples",
|
||||
href: "/examples",
|
||||
@@ -48,6 +52,11 @@ export const docsConfig: DocsConfig = {
|
||||
href: "/docs/installation",
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
title: "components.json",
|
||||
href: "/docs/components-json",
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
title: "Theming",
|
||||
href: "/docs/theming",
|
||||
@@ -113,6 +122,11 @@ export const docsConfig: DocsConfig = {
|
||||
href: "/docs/installation/astro",
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
title: "Laravel",
|
||||
href: "/docs/installation/laravel",
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
title: "Manual",
|
||||
href: "/docs/installation/manual",
|
||||
@@ -120,6 +134,21 @@ export const docsConfig: DocsConfig = {
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Dark Mode",
|
||||
items: [
|
||||
{
|
||||
title: "Next.js",
|
||||
href: "/docs/dark-mode/next",
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
title: "Vite",
|
||||
href: "/docs/dark-mode/vite",
|
||||
items: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Components",
|
||||
items: [
|
||||
|
||||
@@ -6,7 +6,7 @@ export const siteConfig = {
|
||||
"Beautifully designed components built with Radix UI and Tailwind CSS.",
|
||||
links: {
|
||||
twitter: "https://twitter.com/shadcn",
|
||||
github: "https://github.com/shadcn/ui",
|
||||
github: "https://github.com/shadcn-ui/ui",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -6,9 +6,9 @@ toc: false
|
||||
|
||||
## July 2023 - JavaScript
|
||||
|
||||
This project and the components are written in TypeScript. We recommend using TypeScript for your project as well.
|
||||
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 as well. The JavaScript version is available via the [cli](/docs/cli).
|
||||
However we provide a JavaScript version of the components, available via the [cli](/docs/cli).
|
||||
|
||||
```txt
|
||||
Would you like to use TypeScript (recommended)? no
|
||||
|
||||
@@ -16,6 +16,7 @@ npx shadcn-ui@latest init
|
||||
You will be asked a few questions to configure `components.json`:
|
||||
|
||||
```txt showLineNumbers
|
||||
Would you like to use TypeScript (recommended)? no/yes
|
||||
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
|
||||
@@ -50,7 +51,8 @@ npx shadcn-ui@latest add [component]
|
||||
You will be presented with a list of components to choose from:
|
||||
|
||||
```txt
|
||||
Which components would you like to add? › Space to select. Return to submit.
|
||||
Which components would you like to add? › Space to select. A to toggle all.
|
||||
Enter to submit.
|
||||
|
||||
◯ accordion
|
||||
◯ alert
|
||||
|
||||
163
apps/www/content/docs/components-json.mdx
Normal file
163
apps/www/content/docs/components-json.mdx
Normal file
@@ -0,0 +1,163 @@
|
||||
---
|
||||
title: components.json
|
||||
description: Configuration for your project.
|
||||
---
|
||||
|
||||
The `components.json` file holds configuration for your project.
|
||||
|
||||
We use it to understand how your project is set up and how to generate components customized for your project.
|
||||
|
||||
<Callout className="mt-6">
|
||||
Note: The `components.json` file is optional and **only required if you're
|
||||
using the CLI** to add components to your project. If you're using the copy
|
||||
and paste method, you don't need this file.
|
||||
</Callout>
|
||||
|
||||
You can create a `components.json` file in your project by running the following command:
|
||||
|
||||
```bash
|
||||
npx shadcn-ui@latest init
|
||||
```
|
||||
|
||||
See the <Link href="/docs/cli">CLI section</Link> for more information.
|
||||
|
||||
## $schema
|
||||
|
||||
You can see the JSON Schema for `components.json` [here](https://ui.shadcn.com/schema.json).
|
||||
|
||||
```json title="components.json"
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema.json"
|
||||
}
|
||||
```
|
||||
|
||||
## style
|
||||
|
||||
The style for your components. **This cannot be changed after initialization.**
|
||||
|
||||
```json title="components.json"
|
||||
{
|
||||
"style": "default" | "new-york"
|
||||
}
|
||||
```
|
||||
|
||||
<ComponentPreview name="card-with-form" />
|
||||
|
||||
## tailwind
|
||||
|
||||
Configuration to help the CLI understand how Tailwind CSS is set up in your project.
|
||||
|
||||
See the <Link href="/docs/installation">installation section</Link> for how to set up Tailwind CSS.
|
||||
|
||||
### tailwind.config
|
||||
|
||||
Path to where your `tailwind.config.js` file is located.
|
||||
|
||||
```json title="components.json"
|
||||
{
|
||||
"tailwind": {
|
||||
"config": "tailwind.config.js" | "tailwind.config.ts"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### tailwind.css
|
||||
|
||||
Path to the CSS file that imports Tailwind CSS into your project.
|
||||
|
||||
```json title="components.json"
|
||||
{
|
||||
"tailwind": {
|
||||
"css": "styles/global.css"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### tailwind.baseColor
|
||||
|
||||
This is used to generate the default color palette for your components. **This cannot be changed after initialization.**
|
||||
|
||||
```json title="components.json"
|
||||
{
|
||||
"tailwind": {
|
||||
"baseColor": "gray" | "neutral" | "slate" | "stone" | "zinc"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### tailwind.cssVariables
|
||||
|
||||
You can choose between using CSS variables or Tailwind CSS utility classes for theming.
|
||||
|
||||
To use utility classes for theming set `tailwind.cssVariables` to `false`. For CSS variables, set `tailwind.cssVariables` to `true`.
|
||||
|
||||
```json title="components.json"
|
||||
{
|
||||
"tailwind": {
|
||||
"cssVariables": `true` | `false`
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
For more information, see the <Link href="/docs/theming">theming docs</Link>.
|
||||
|
||||
**This cannot be changed after initialization.** To switch between CSS variables and utility classes, you'll have to delete and re-install your components.
|
||||
|
||||
## rsc
|
||||
|
||||
Whether or not to enable support for React Server Components.
|
||||
|
||||
The CLI automatically adds a `use client` directive to client components when set to `true`.
|
||||
|
||||
```json title="components.json"
|
||||
{
|
||||
"rsc": `true` | `false`
|
||||
}
|
||||
```
|
||||
|
||||
## tsx
|
||||
|
||||
Choose between TypeScript or JavaScript components.
|
||||
|
||||
Setting this option to `false` allows components to be added as JavaScript with the `.jsx` file extension.
|
||||
|
||||
```json title="components.json"
|
||||
{
|
||||
"tsx": `true` | `false`
|
||||
}
|
||||
```
|
||||
|
||||
## aliases
|
||||
|
||||
The CLI uses these values and the `paths` config from your `tsconfig.json` or `jsconfig.json` file to place generated components in the correct location.
|
||||
|
||||
Path aliases have to be set up in your `tsconfig.json` or `jsconfig.json` file.
|
||||
|
||||
<Callout className="mt-6">
|
||||
**Important:** If you're using the `src` directory, make sure it is included
|
||||
under `paths` in your `tsconfig.json` or `jsconfig.json` file.
|
||||
</Callout>
|
||||
|
||||
### aliases.utils
|
||||
|
||||
Import alias for your utility functions.
|
||||
|
||||
```json title="components.json"
|
||||
{
|
||||
"aliases": {
|
||||
"utils": "@/lib/utils"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### aliases.components
|
||||
|
||||
Import alias for your components.
|
||||
|
||||
```json title="components.json"
|
||||
{
|
||||
"aliases": {
|
||||
"components": "@/components"
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -58,11 +58,7 @@ import { AspectRatio } from "@/components/ui/aspect-ratio"
|
||||
```tsx
|
||||
<div className="w-[450px]">
|
||||
<AspectRatio ratio={16 / 9}>
|
||||
<Image
|
||||
src="..."
|
||||
alt=Image""
|
||||
className="rounded-md object-cover"
|
||||
/>
|
||||
<Image src="..." alt="Image" className="rounded-md object-cover" />
|
||||
</AspectRatio>
|
||||
</div>
|
||||
```
|
||||
|
||||
@@ -56,6 +56,7 @@ npm install cmdk
|
||||
|
||||
```tsx
|
||||
import {
|
||||
Command,
|
||||
CommandDialog,
|
||||
CommandEmpty,
|
||||
CommandGroup,
|
||||
@@ -101,7 +102,8 @@ export function CommandMenu() {
|
||||
|
||||
React.useEffect(() => {
|
||||
const down = (e: KeyboardEvent) => {
|
||||
if (e.key === "k" && e.metaKey) {
|
||||
if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
|
||||
e.preventDefault()
|
||||
setOpen((open) => !open)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +73,14 @@ const form = useForm()
|
||||
|
||||
## Installation
|
||||
|
||||
<Tabs defaultValue="cli">
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">CLI</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
<Steps>
|
||||
|
||||
### Command
|
||||
@@ -83,6 +91,30 @@ npx shadcn-ui@latest add form
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-label @radix-ui/react-slot react-hook-form @hookform/resolvers zod
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource name="form" />
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</Tabs>
|
||||
|
||||
## Usage
|
||||
|
||||
<Steps>
|
||||
@@ -94,7 +126,6 @@ Define the shape of your form using a Zod schema. You can read more about using
|
||||
```tsx showLineNumbers {4,6-8}
|
||||
"use client"
|
||||
|
||||
import Link from "next/link"
|
||||
import * as z from "zod"
|
||||
|
||||
const formSchema = z.object({
|
||||
@@ -109,7 +140,6 @@ Use the `useForm` hook from `react-hook-form` to create a form.
|
||||
```tsx showLineNumbers {4,14-20,22-27}
|
||||
"use client"
|
||||
|
||||
import Link from "next/link"
|
||||
import { zodResolver } from "@hookform/resolvers/zod"
|
||||
import * as z from "zod"
|
||||
|
||||
@@ -146,7 +176,6 @@ We can now use the `<Form />` components to build our form.
|
||||
```tsx showLineNumbers {7-17,28-50}
|
||||
"use client"
|
||||
|
||||
import Link from "next/link"
|
||||
import { zodResolver } from "@hookform/resolvers/zod"
|
||||
import * as z from "zod"
|
||||
|
||||
|
||||
@@ -61,8 +61,18 @@ npm install @radix-ui/react-toast
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
`toast.tsx`
|
||||
|
||||
<ComponentSource name="toast" />
|
||||
|
||||
`toaster.tsx`
|
||||
|
||||
<ComponentSource name="toast" fileName="toaster" />
|
||||
|
||||
`use-toast.tsx`
|
||||
|
||||
<ComponentSource name="toast" fileName="use-toast" />
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
<Step>Add the Toaster component</Step>
|
||||
|
||||
37
apps/www/content/docs/dark-mode/index.mdx
Normal file
37
apps/www/content/docs/dark-mode/index.mdx
Normal file
@@ -0,0 +1,37 @@
|
||||
---
|
||||
title: Dark Mode
|
||||
description: Adding dark mode to your site.
|
||||
---
|
||||
|
||||
<div className="grid sm:grid-cols-2 gap-4 sm:gap-6">
|
||||
<LinkedCard href="/docs/dark-mode/next">
|
||||
<svg
|
||||
role="img"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="w-10 h-10"
|
||||
fill="currentColor"
|
||||
>
|
||||
<title>Next.js</title>
|
||||
<path d="M11.5725 0c-.1763 0-.3098.0013-.3584.0067-.0516.0053-.2159.021-.3636.0328-3.4088.3073-6.6017 2.1463-8.624 4.9728C1.1004 6.584.3802 8.3666.1082 10.255c-.0962.659-.108.8537-.108 1.7474s.012 1.0884.108 1.7476c.652 4.506 3.8591 8.2919 8.2087 9.6945.7789.2511 1.6.4223 2.5337.5255.3636.04 1.9354.04 2.299 0 1.6117-.1783 2.9772-.577 4.3237-1.2643.2065-.1056.2464-.1337.2183-.1573-.0188-.0139-.8987-1.1938-1.9543-2.62l-1.919-2.592-2.4047-3.5583c-1.3231-1.9564-2.4117-3.556-2.4211-3.556-.0094-.0026-.0187 1.5787-.0235 3.509-.0067 3.3802-.0093 3.5162-.0516 3.596-.061.115-.108.1618-.2064.2134-.075.0374-.1408.0445-.495.0445h-.406l-.1078-.068a.4383.4383 0 01-.1572-.1712l-.0493-.1056.0053-4.703.0067-4.7054.0726-.0915c.0376-.0493.1174-.1125.1736-.143.0962-.047.1338-.0517.5396-.0517.4787 0 .5584.0187.6827.1547.0353.0377 1.3373 1.9987 2.895 4.3608a10760.433 10760.433 0 004.7344 7.1706l1.9002 2.8782.096-.0633c.8518-.5536 1.7525-1.3418 2.4657-2.1627 1.5179-1.7429 2.4963-3.868 2.8247-6.134.0961-.6591.1078-.854.1078-1.7475 0-.8937-.012-1.0884-.1078-1.7476-.6522-4.506-3.8592-8.2919-8.2087-9.6945-.7672-.2487-1.5836-.42-2.4985-.5232-.169-.0176-1.0835-.0366-1.6123-.037zm4.0685 7.217c.3473 0 .4082.0053.4857.047.1127.0562.204.1642.237.2767.0186.061.0234 1.3653.0186 4.3044l-.0067 4.2175-.7436-1.14-.7461-1.14v-3.066c0-1.982.0093-3.0963.0234-3.1502.0375-.1313.1196-.2346.2323-.2955.0961-.0494.1313-.054.4997-.054z" />
|
||||
</svg>
|
||||
<p className="font-medium mt-2">Next.js</p>
|
||||
</LinkedCard>
|
||||
<LinkedCard href="/docs/dark-mode/vite">
|
||||
<svg
|
||||
role="img"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="w-10 h-10"
|
||||
fill="currentColor"
|
||||
>
|
||||
<title>Vite</title>
|
||||
<path d="m8.286 10.578.512-8.657a.306.306 0 0 1 .247-.282L17.377.006a.306.306 0 0 1 .353.385l-1.558 5.403a.306.306 0 0 0 .352.385l2.388-.46a.306.306 0 0 1 .332.438l-6.79 13.55-.123.19a.294.294 0 0 1-.252.14c-.177 0-.35-.152-.305-.369l1.095-5.301a.306.306 0 0 0-.388-.355l-1.433.435a.306.306 0 0 1-.389-.354l.69-3.375a.306.306 0 0 0-.37-.36l-2.32.536a.306.306 0 0 1-.374-.316zm14.976-7.926L17.284 3.74l-.544 1.887 2.077-.4a.8.8 0 0 1 .84.369.8.8 0 0 1 .034.783L12.9 19.93l-.013.025-.015.023-.122.19a.801.801 0 0 1-.672.37.826.826 0 0 1-.634-.302.8.8 0 0 1-.16-.67l1.029-4.981-1.12.34a.81.81 0 0 1-.86-.262.802.802 0 0 1-.165-.67l.63-3.08-2.027.468a.808.808 0 0 1-.768-.233.81.81 0 0 1-.217-.6l.389-6.57-7.44-1.33a.612.612 0 0 0-.64.906L11.58 23.691a.612.612 0 0 0 1.066-.004l11.26-20.135a.612.612 0 0 0-.644-.9z" />
|
||||
</svg>
|
||||
<p className="font-medium mt-2">Vite</p>
|
||||
</LinkedCard>
|
||||
</div>
|
||||
|
||||
## Other frameworks
|
||||
|
||||
I'm looking for help writing guides for other frameworks. Help me write guides for Remix, Astro and Vite by [opening an PR](https://github.com/shadcn/ui).
|
||||
@@ -1,12 +1,20 @@
|
||||
---
|
||||
title: Dark Mode
|
||||
description: Adding dark mode to your site.
|
||||
title: Next.js
|
||||
description: Adding dark mode to your next app.
|
||||
---
|
||||
|
||||
## Next.js
|
||||
## Dark mode
|
||||
|
||||
<Steps>
|
||||
|
||||
### Install next-themes
|
||||
|
||||
Start by installing `next-themes`:
|
||||
|
||||
```bash
|
||||
npm install next-themes
|
||||
```
|
||||
|
||||
### Create a theme provider
|
||||
|
||||
```tsx title="components/theme-provider.tsx"
|
||||
@@ -34,7 +42,12 @@ export default function RootLayout({ children }: RootLayoutProps) {
|
||||
<html lang="en" suppressHydrationWarning>
|
||||
<head />
|
||||
<body>
|
||||
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
|
||||
<ThemeProvider
|
||||
attribute="class"
|
||||
defaultTheme="system"
|
||||
enableSystem
|
||||
disableTransitionOnChange
|
||||
>
|
||||
{children}
|
||||
</ThemeProvider>
|
||||
</body>
|
||||
@@ -51,7 +64,3 @@ Place a mode toggle on your site to toggle between light and dark mode.
|
||||
<ComponentPreview name="mode-toggle" className="[&_.preview]:items-start" />
|
||||
|
||||
</Steps>
|
||||
|
||||
## Other frameworks
|
||||
|
||||
I'm looking for help writing guides for other frameworks. Help me write guides for Remix, Astro and Vite by [opening an PR](https://github.com/shadcn/ui).
|
||||
150
apps/www/content/docs/dark-mode/vite.mdx
Normal file
150
apps/www/content/docs/dark-mode/vite.mdx
Normal file
@@ -0,0 +1,150 @@
|
||||
---
|
||||
title: Vite
|
||||
description: Adding dark mode to your vite app.
|
||||
---
|
||||
|
||||
## Dark mode
|
||||
|
||||
<Steps>
|
||||
|
||||
### Create a theme provider
|
||||
|
||||
```tsx title="components/theme-provider.tsx"
|
||||
import { createContext, useContext, useEffect, useState } from "react"
|
||||
|
||||
type Theme = "dark" | "light" | "system"
|
||||
|
||||
type ThemeProviderProps = {
|
||||
children: React.ReactNode
|
||||
defaultTheme?: Theme
|
||||
storageKey?: string
|
||||
}
|
||||
|
||||
type ThemeProviderState = {
|
||||
theme: Theme
|
||||
setTheme: (theme: Theme) => void
|
||||
}
|
||||
|
||||
const initialState: ThemeProviderState = {
|
||||
theme: "system",
|
||||
setTheme: () => null,
|
||||
}
|
||||
|
||||
const ThemeProviderContext = createContext<ThemeProviderState>(initialState)
|
||||
|
||||
export function ThemeProvider({
|
||||
children,
|
||||
defaultTheme = "system",
|
||||
storageKey = "vite-ui-theme",
|
||||
...props
|
||||
}: ThemeProviderProps) {
|
||||
const [theme, setTheme] = useState<Theme>(
|
||||
() => (localStorage.getItem(storageKey) as Theme) || defaultTheme
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
const root = window.document.documentElement
|
||||
|
||||
root.classList.remove("light", "dark")
|
||||
|
||||
if (theme === "system") {
|
||||
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)")
|
||||
.matches
|
||||
? "dark"
|
||||
: "light"
|
||||
|
||||
root.classList.add(systemTheme)
|
||||
return
|
||||
}
|
||||
|
||||
root.classList.add(theme)
|
||||
}, [theme])
|
||||
|
||||
const value = {
|
||||
theme,
|
||||
setTheme: (theme: Theme) => {
|
||||
localStorage.setItem(storageKey, theme)
|
||||
setTheme(theme)
|
||||
},
|
||||
}
|
||||
|
||||
return (
|
||||
<ThemeProviderContext.Provider {...props} value={value}>
|
||||
{children}
|
||||
</ThemeProviderContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export const useTheme = () => {
|
||||
const context = useContext(ThemeProviderContext)
|
||||
|
||||
if (context === undefined)
|
||||
throw new Error("useTheme must be used within a ThemeProvider")
|
||||
|
||||
return context
|
||||
}
|
||||
```
|
||||
|
||||
### Wrap your root layout
|
||||
|
||||
Add the `ThemeProvider` to your root layout.
|
||||
|
||||
```tsx {1,5-7} title="App.tsx"
|
||||
import { ThemeProvider } from "@/components/theme-provider"
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<ThemeProvider defaultTheme="dark" storageKey="vite-ui-theme">
|
||||
{children}
|
||||
</ThemeProvider>
|
||||
)
|
||||
}
|
||||
|
||||
export default App
|
||||
```
|
||||
|
||||
### Add a mode toggle
|
||||
|
||||
Place a mode toggle on your site to toggle between light and dark mode.
|
||||
|
||||
```tsx title="components/mode-toggle.tsx"
|
||||
import { Moon, Sun } from "lucide-react"
|
||||
|
||||
import { Button } from "@/components/ui/button"
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu"
|
||||
import { useTheme } from "@/components/theme-provider"
|
||||
|
||||
export function ModeToggle() {
|
||||
const { setTheme } = useTheme()
|
||||
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="outline" size="icon">
|
||||
<Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
|
||||
<Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
|
||||
<span className="sr-only">Toggle theme</span>
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
<DropdownMenuItem onClick={() => setTheme("light")}>
|
||||
Light
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem onClick={() => setTheme("dark")}>
|
||||
Dark
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem onClick={() => setTheme("system")}>
|
||||
System
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
</Steps>
|
||||
@@ -46,7 +46,7 @@ Which frameworks are supported?
|
||||
</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
|
||||
You can use any framework that supports React. Next.js, Astro, Remix, Gatsby etc.
|
||||
You can use any framework that supports React. [Next.js](https://ui.shadcn.com/docs/installation/next), [Astro](https://ui.shadcn.com/docs/installation/astro), [Remix](https://ui.shadcn.com/docs/installation/remix), [Gatsby](https://ui.shadcn.com/docs/installation/gatsby) etc.
|
||||
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
|
||||
@@ -109,6 +109,20 @@ import '@/styles/globals.css'
|
||||
---
|
||||
```
|
||||
|
||||
### Update astro tailwind config
|
||||
|
||||
To prevent serving the Tailwind base styles twice, we need to tell Astro not to apply the base styles, since we already include them in our own `globals.css` file. To do this, set the `applyBaseStyles` config option for the tailwind plugin in `astro.config.mjs` to `false`.
|
||||
|
||||
```ts {3-5} showLineNumbers
|
||||
export default defineConfig({
|
||||
integrations: [
|
||||
tailwind({
|
||||
applyBaseStyles: false,
|
||||
}),
|
||||
],
|
||||
})
|
||||
```
|
||||
|
||||
### That's it
|
||||
|
||||
You can now start adding components to your project.
|
||||
|
||||
@@ -106,7 +106,7 @@ npx shadcn-ui@latest add button
|
||||
The command above will add the `Button` component to your project. You can then import it like this:
|
||||
|
||||
```tsx {1,6} showLineNumbers
|
||||
import { Button } from "@/components/ui"
|
||||
import { Button } from "@/components/ui/button"
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
|
||||
@@ -74,6 +74,18 @@ description: How to install dependencies and structure your app.
|
||||
</svg>
|
||||
<p className="font-medium mt-2">Astro</p>
|
||||
</LinkedCard>
|
||||
<LinkedCard href="/docs/installation/laravel">
|
||||
<svg
|
||||
role="img"
|
||||
viewBox="0 0 62 65"
|
||||
fill="currentColor"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="w-10 h-10"
|
||||
>
|
||||
<path d="M61.8548 14.6253C61.8778 14.7102 61.8895 14.7978 61.8897 14.8858V28.5615C61.8898 28.737 61.8434 28.9095 61.7554 29.0614C61.6675 29.2132 61.5409 29.3392 61.3887 29.4265L49.9104 36.0351V49.1337C49.9104 49.4902 49.7209 49.8192 49.4118 49.9987L25.4519 63.7916C25.3971 63.8227 25.3372 63.8427 25.2774 63.8639C25.255 63.8714 25.2338 63.8851 25.2101 63.8913C25.0426 63.9354 24.8666 63.9354 24.6991 63.8913C24.6716 63.8838 24.6467 63.8689 24.6205 63.8589C24.5657 63.8389 24.5084 63.8215 24.456 63.7916L0.501061 49.9987C0.348882 49.9113 0.222437 49.7853 0.134469 49.6334C0.0465019 49.4816 0.000120578 49.3092 0 49.1337L0 8.10652C0 8.01678 0.0124642 7.92953 0.0348998 7.84477C0.0423783 7.8161 0.0598282 7.78993 0.0697995 7.76126C0.0884958 7.70891 0.105946 7.65531 0.133367 7.6067C0.152063 7.5743 0.179485 7.54812 0.20192 7.51821C0.230588 7.47832 0.256763 7.43719 0.290416 7.40229C0.319084 7.37362 0.356476 7.35243 0.388883 7.32751C0.425029 7.29759 0.457436 7.26518 0.498568 7.2415L12.4779 0.345059C12.6296 0.257786 12.8015 0.211853 12.9765 0.211853C13.1515 0.211853 13.3234 0.257786 13.475 0.345059L25.4531 7.2415H25.4556C25.4955 7.26643 25.5292 7.29759 25.5653 7.32626C25.5977 7.35119 25.6339 7.37362 25.6625 7.40104C25.6974 7.43719 25.7224 7.47832 25.7523 7.51821C25.7735 7.54812 25.8021 7.5743 25.8196 7.6067C25.8483 7.65656 25.8645 7.70891 25.8844 7.76126C25.8944 7.78993 25.9118 7.8161 25.9193 7.84602C25.9423 7.93096 25.954 8.01853 25.9542 8.10652V33.7317L35.9355 27.9844V14.8846C35.9355 14.7973 35.948 14.7088 35.9704 14.6253C35.9792 14.5954 35.9954 14.5692 36.0053 14.5405C36.0253 14.4882 36.0427 14.4346 36.0702 14.386C36.0888 14.3536 36.1163 14.3274 36.1375 14.2975C36.1674 14.2576 36.1923 14.2165 36.2272 14.1816C36.2559 14.1529 36.292 14.1317 36.3244 14.1068C36.3618 14.0769 36.3942 14.0445 36.4341 14.0208L48.4147 7.12434C48.5663 7.03694 48.7383 6.99094 48.9133 6.99094C49.0883 6.99094 49.2602 7.03694 49.4118 7.12434L61.3899 14.0208C61.4323 14.0457 61.4647 14.0769 61.5021 14.1055C61.5333 14.1305 61.5694 14.1529 61.5981 14.1803C61.633 14.2165 61.6579 14.2576 61.6878 14.2975C61.7103 14.3274 61.7377 14.3536 61.7551 14.386C61.7838 14.4346 61.8 14.4882 61.8199 14.5405C61.8312 14.5692 61.8474 14.5954 61.8548 14.6253ZM59.893 27.9844V16.6121L55.7013 19.0252L49.9104 22.3593V33.7317L59.8942 27.9844H59.893ZM47.9149 48.5566V37.1768L42.2187 40.4299L25.953 49.7133V61.2003L47.9149 48.5566ZM1.99677 9.83281V48.5566L23.9562 61.199V49.7145L12.4841 43.2219L12.4804 43.2194L12.4754 43.2169C12.4368 43.1945 12.4044 43.1621 12.3682 43.1347C12.3371 43.1097 12.3009 43.0898 12.2735 43.0624L12.271 43.0586C12.2386 43.0275 12.2162 42.9888 12.1887 42.9539C12.1638 42.9203 12.1339 42.8916 12.114 42.8567L12.1127 42.853C12.0903 42.8156 12.0766 42.7707 12.0604 42.7283C12.0442 42.6909 12.023 42.656 12.013 42.6161C12.0005 42.5688 11.998 42.5177 11.9931 42.4691C11.9881 42.4317 11.9781 42.3943 11.9781 42.3569V15.5801L6.18848 12.2446L1.99677 9.83281ZM12.9777 2.36177L2.99764 8.10652L12.9752 13.8513L22.9541 8.10527L12.9752 2.36177H12.9777ZM18.1678 38.2138L23.9574 34.8809V9.83281L19.7657 12.2459L13.9749 15.5801V40.6281L18.1678 38.2138ZM48.9133 9.14105L38.9344 14.8858L48.9133 20.6305L58.8909 14.8846L48.9133 9.14105ZM47.9149 22.3593L42.124 19.0252L37.9323 16.6121V27.9844L43.7219 31.3174L47.9149 33.7317V22.3593ZM24.9533 47.987L39.59 39.631L46.9065 35.4555L36.9352 29.7145L25.4544 36.3242L14.9907 42.3482L24.9533 47.987Z" />
|
||||
</svg>
|
||||
<p className="font-medium mt-2">Laravel</p>
|
||||
</LinkedCard>
|
||||
<LinkedCard href="/docs/installation/manual">
|
||||
<svg
|
||||
role="img"
|
||||
|
||||
153
apps/www/content/docs/installation/laravel.mdx
Normal file
153
apps/www/content/docs/installation/laravel.mdx
Normal file
@@ -0,0 +1,153 @@
|
||||
---
|
||||
title: Laravel
|
||||
description: Install and configure Laravel with Inertia
|
||||
---
|
||||
|
||||
<Steps>
|
||||
|
||||
### Create project
|
||||
|
||||
Start by creating a new Laravel project with Inertia and React using the laravel installer `laravel new my-app`:
|
||||
|
||||
```bash
|
||||
laravel new my-app --typescript --breeze --stack=react --git --no-interaction
|
||||
```
|
||||
|
||||
### Run the CLI
|
||||
|
||||
Run the `shadcn-ui` init command to setup your project:
|
||||
|
||||
```bash
|
||||
npx shadcn-ui@latest init
|
||||
```
|
||||
|
||||
### Configure components.json
|
||||
|
||||
You will be asked a few questions to configure `components.json`:
|
||||
|
||||
```txt showLineNumbers
|
||||
Would you like to use TypeScript (recommended)? no / yes
|
||||
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? › resources/css/app.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
|
||||
```
|
||||
|
||||
### Update tailwind.config.js
|
||||
|
||||
The `shadcn-ui` CLI will automatically overwrite your `tailwind.config.js`. Update it to look like this:
|
||||
|
||||
```js
|
||||
import forms from "@tailwindcss/forms"
|
||||
import defaultTheme from "tailwindcss/defaultTheme"
|
||||
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
export default {
|
||||
darkMode: "class",
|
||||
content: [
|
||||
"./vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php",
|
||||
"./storage/framework/views/*.php",
|
||||
"./resources/views/**/*.blade.php",
|
||||
"./resources/js/**/*.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: ["Figtree", ...defaultTheme.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: [forms, require("tailwindcss-animate")],
|
||||
}
|
||||
```
|
||||
|
||||
### That's it
|
||||
|
||||
You can now start adding components to your project.
|
||||
|
||||
```bash
|
||||
npx shadcn-ui@latest add button
|
||||
```
|
||||
|
||||
The command above will add the `Button` component to your project. You can then import it like this:
|
||||
|
||||
```tsx {1,6} showLineNumbers
|
||||
import { Button } from "@/Components/ui/button"
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<div>
|
||||
<Button>Click me</Button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
</Steps>
|
||||
@@ -139,7 +139,7 @@ module.exports = {
|
||||
|
||||
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="styles.css"
|
||||
```css title="globals.css"
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@@ -82,7 +82,7 @@ npx shadcn-ui@latest add button
|
||||
The command above will add the `Button` component to your project. You can then import it like this:
|
||||
|
||||
```tsx {1,6} showLineNumbers
|
||||
import { Button } from "@/components/ui"
|
||||
import { Button } from "@/components/ui/button"
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
|
||||
@@ -103,7 +103,7 @@ npx shadcn-ui@latest add button
|
||||
The command above will add the `Button` component to your project. You can then import it like this:
|
||||
|
||||
```tsx {1,6} showLineNumbers
|
||||
import { Button } from "@/components/ui"
|
||||
import { Button } from "~/components/ui/button"
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
|
||||
@@ -93,7 +93,7 @@ npx shadcn-ui@latest add button
|
||||
The command above will add the `Button` component to your project. You can then import it like this:
|
||||
|
||||
```tsx {1,6} showLineNumbers
|
||||
import { Button } from "@/components/ui"
|
||||
import { Button } from "@/components/ui/button"
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
|
||||
@@ -7,11 +7,13 @@ import { Theme } from "@/registry/themes"
|
||||
type Config = {
|
||||
style: Style["name"]
|
||||
theme: Theme["name"]
|
||||
radius: number
|
||||
}
|
||||
|
||||
const configAtom = atomWithStorage<Config>("config", {
|
||||
style: "default",
|
||||
theme: "zinc",
|
||||
radius: 0.5,
|
||||
})
|
||||
|
||||
export function useConfig() {
|
||||
|
||||
@@ -7,6 +7,7 @@ const eventSchema = z.object({
|
||||
"copy_usage_import_code",
|
||||
"copy_usage_code",
|
||||
"copy_primitive_code",
|
||||
"copy_theme_code",
|
||||
]),
|
||||
// declare type AllowedPropertyValues = string | number | boolean | null
|
||||
properties: z
|
||||
|
||||
@@ -10,19 +10,41 @@ import { styles } from "../registry/styles"
|
||||
export function rehypeComponent() {
|
||||
return async (tree: UnistTree) => {
|
||||
visit(tree, (node: UnistNode) => {
|
||||
const { value: src } = getNodeAttributeByName(node, "src") || {}
|
||||
// src prop overrides both name and fileName.
|
||||
const { value: srcPath } =
|
||||
(getNodeAttributeByName(node, "src") as {
|
||||
name: string
|
||||
value?: string
|
||||
type?: string
|
||||
}) || {}
|
||||
|
||||
if (node.name === "ComponentSource") {
|
||||
const name = getNodeAttributeByName(node, "name")?.value as string
|
||||
const fileName = getNodeAttributeByName(node, "fileName")?.value as
|
||||
| string
|
||||
| undefined
|
||||
|
||||
if (!name) {
|
||||
if (!name && !srcPath) {
|
||||
return null
|
||||
}
|
||||
|
||||
try {
|
||||
for (const style of styles) {
|
||||
const component = Index[style.name][name]
|
||||
const src = component.files[0]
|
||||
let src: string
|
||||
|
||||
if (srcPath) {
|
||||
src = srcPath
|
||||
} else {
|
||||
const component = Index[style.name][name]
|
||||
src = fileName
|
||||
? component.files.find((file: string) => {
|
||||
return (
|
||||
file.endsWith(`${fileName}.tsx`) ||
|
||||
file.endsWith(`${fileName}.ts`)
|
||||
)
|
||||
}) || component.files[0]
|
||||
: component.files[0]
|
||||
}
|
||||
|
||||
// Read the source file.
|
||||
const filePath = path.join(process.cwd(), src)
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
"recharts": "^2.6.2",
|
||||
"sharp": "^0.31.3",
|
||||
"tailwind-merge": "^1.12.0",
|
||||
"vaul": "^0.2.0",
|
||||
"zod": "^3.21.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
{
|
||||
"name": "alert.tsx",
|
||||
"dir": "components/ui",
|
||||
"content": "import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst alertVariants = cva(\n \"relative w-full rounded-lg border p-4 [&>svg]:absolute [&>svg]:text-foreground [&>svg]:left-4 [&>svg]:top-4 [&>svg+div]:translate-y-[-3px] [&:has(svg)]:pl-11\",\n {\n variants: {\n variant: {\n default: \"bg-background text-foreground\",\n destructive:\n \"text-destructive border-destructive/50 dark:border-destructive [&>svg]:text-destructive text-destructive\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nconst Alert = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants>\n>(({ className, variant, ...props }, ref) => (\n <div\n ref={ref}\n role=\"alert\"\n className={cn(alertVariants({ variant }), className)}\n {...props}\n />\n))\nAlert.displayName = \"Alert\"\n\nconst AlertTitle = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLHeadingElement>\n>(({ className, ...props }, ref) => (\n <h5\n ref={ref}\n className={cn(\"mb-1 font-medium leading-none tracking-tight\", className)}\n {...props}\n />\n))\nAlertTitle.displayName = \"AlertTitle\"\n\nconst AlertDescription = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\"text-sm [&_p]:leading-relaxed\", className)}\n {...props}\n />\n))\nAlertDescription.displayName = \"AlertDescription\"\n\nexport { Alert, AlertTitle, AlertDescription }\n"
|
||||
"content": "import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst alertVariants = cva(\n \"relative w-full rounded-lg border p-4 [&>svg]:absolute [&>svg]:text-foreground [&>svg]:left-4 [&>svg]:top-4 [&>svg+div]:translate-y-[-3px] [&>svg~*]:pl-7\",\n {\n variants: {\n variant: {\n default: \"bg-background text-foreground\",\n destructive:\n \"text-destructive border-destructive/50 dark:border-destructive [&>svg]:text-destructive text-destructive\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nconst Alert = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants>\n>(({ className, variant, ...props }, ref) => (\n <div\n ref={ref}\n role=\"alert\"\n className={cn(alertVariants({ variant }), className)}\n {...props}\n />\n))\nAlert.displayName = \"Alert\"\n\nconst AlertTitle = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLHeadingElement>\n>(({ className, ...props }, ref) => (\n <h5\n ref={ref}\n className={cn(\"mb-1 font-medium leading-none tracking-tight\", className)}\n {...props}\n />\n))\nAlertTitle.displayName = \"AlertTitle\"\n\nconst AlertDescription = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\"text-sm [&_p]:leading-relaxed\", className)}\n {...props}\n />\n))\nAlertDescription.displayName = \"AlertDescription\"\n\nexport { Alert, AlertTitle, AlertDescription }\n"
|
||||
}
|
||||
],
|
||||
"type": "ui"
|
||||
|
||||
@@ -3,90 +3,90 @@
|
||||
"light": {
|
||||
"background": "white",
|
||||
"foreground": "gray-950",
|
||||
"muted": "gray-100",
|
||||
"muted-foreground": "gray-500",
|
||||
"popover": "white",
|
||||
"popover-foreground": "gray-950",
|
||||
"border": "gray-200",
|
||||
"input": "gray-200",
|
||||
"card": "white",
|
||||
"card-foreground": "gray-950",
|
||||
"popover": "white",
|
||||
"popover-foreground": "gray-950",
|
||||
"primary": "gray-900",
|
||||
"primary-foreground": "gray-50",
|
||||
"secondary": "gray-100",
|
||||
"secondary-foreground": "gray-900",
|
||||
"muted": "gray-100",
|
||||
"muted-foreground": "gray-500",
|
||||
"accent": "gray-100",
|
||||
"accent-foreground": "gray-900",
|
||||
"destructive": "red-500",
|
||||
"destructive-foreground": "gray-50",
|
||||
"ring": "gray-400"
|
||||
"border": "gray-200",
|
||||
"input": "gray-200",
|
||||
"ring": "gray-950"
|
||||
},
|
||||
"dark": {
|
||||
"background": "gray-950",
|
||||
"foreground": "gray-50",
|
||||
"muted": "gray-800",
|
||||
"muted-foreground": "gray-400",
|
||||
"popover": "gray-950",
|
||||
"popover-foreground": "gray-50",
|
||||
"border": "gray-800",
|
||||
"input": "gray-800",
|
||||
"card": "gray-950",
|
||||
"card-foreground": "gray-50",
|
||||
"popover": "gray-950",
|
||||
"popover-foreground": "gray-50",
|
||||
"primary": "gray-50",
|
||||
"primary-foreground": "gray-900",
|
||||
"secondary": "gray-800",
|
||||
"secondary-foreground": "gray-50",
|
||||
"muted": "gray-800",
|
||||
"muted-foreground": "gray-400",
|
||||
"accent": "gray-800",
|
||||
"accent-foreground": "gray-50",
|
||||
"destructive": "red-900",
|
||||
"destructive-foreground": "red-50",
|
||||
"ring": "gray-800"
|
||||
"destructive-foreground": "gray-50",
|
||||
"border": "gray-800",
|
||||
"input": "gray-800",
|
||||
"ring": "gray-300"
|
||||
}
|
||||
},
|
||||
"cssVars": {
|
||||
"light": {
|
||||
"background": "0 0% 100%",
|
||||
"foreground": "224 71.4% 4.1%",
|
||||
"muted": "220 14.3% 95.9%",
|
||||
"muted-foreground": "220 8.9% 46.1%",
|
||||
"popover": "0 0% 100%",
|
||||
"popover-foreground": "224 71.4% 4.1%",
|
||||
"border": "220 13% 91%",
|
||||
"input": "220 13% 91%",
|
||||
"card": "0 0% 100%",
|
||||
"card-foreground": "224 71.4% 4.1%",
|
||||
"popover": "0 0% 100%",
|
||||
"popover-foreground": "224 71.4% 4.1%",
|
||||
"primary": "220.9 39.3% 11%",
|
||||
"primary-foreground": "210 20% 98%",
|
||||
"secondary": "220 14.3% 95.9%",
|
||||
"secondary-foreground": "220.9 39.3% 11%",
|
||||
"muted": "220 14.3% 95.9%",
|
||||
"muted-foreground": "220 8.9% 46.1%",
|
||||
"accent": "220 14.3% 95.9%",
|
||||
"accent-foreground": "220.9 39.3% 11%",
|
||||
"destructive": "0 84.2% 60.2%",
|
||||
"destructive-foreground": "210 20% 98%",
|
||||
"ring": "217.9 10.6% 64.9%"
|
||||
"border": "220 13% 91%",
|
||||
"input": "220 13% 91%",
|
||||
"ring": "224 71.4% 4.1%"
|
||||
},
|
||||
"dark": {
|
||||
"background": "224 71.4% 4.1%",
|
||||
"foreground": "210 20% 98%",
|
||||
"muted": "215 27.9% 16.9%",
|
||||
"muted-foreground": "217.9 10.6% 64.9%",
|
||||
"popover": "224 71.4% 4.1%",
|
||||
"popover-foreground": "210 20% 98%",
|
||||
"border": "215 27.9% 16.9%",
|
||||
"input": "215 27.9% 16.9%",
|
||||
"card": "224 71.4% 4.1%",
|
||||
"card-foreground": "210 20% 98%",
|
||||
"popover": "224 71.4% 4.1%",
|
||||
"popover-foreground": "210 20% 98%",
|
||||
"primary": "210 20% 98%",
|
||||
"primary-foreground": "220.9 39.3% 11%",
|
||||
"secondary": "215 27.9% 16.9%",
|
||||
"secondary-foreground": "210 20% 98%",
|
||||
"muted": "215 27.9% 16.9%",
|
||||
"muted-foreground": "217.9 10.6% 64.9%",
|
||||
"accent": "215 27.9% 16.9%",
|
||||
"accent-foreground": "210 20% 98%",
|
||||
"destructive": "0 62.8% 30.6%",
|
||||
"destructive-foreground": "0 85.7% 97.3%",
|
||||
"ring": "215 27.9% 16.9%"
|
||||
"destructive-foreground": "210 20% 98%",
|
||||
"border": "215 27.9% 16.9%",
|
||||
"input": "215 27.9% 16.9%",
|
||||
"ring": "216 12.2% 83.9%"
|
||||
}
|
||||
},
|
||||
"inlineColorsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n",
|
||||
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n \n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 224 71.4% 4.1%;\n \n --muted: 220 14.3% 95.9%;\n --muted-foreground: 220 8.9% 46.1%;\n \n --popover: 0 0% 100%;\n --popover-foreground: 224 71.4% 4.1%;\n \n --card: 0 0% 100%;\n --card-foreground: 224 71.4% 4.1%;\n \n --border: 220 13% 91%;\n --input: 220 13% 91%;\n \n --primary: 220.9 39.3% 11%;\n --primary-foreground: 210 20% 98%;\n \n --secondary: 220 14.3% 95.9%;\n --secondary-foreground: 220.9 39.3% 11%;\n \n --accent: 220 14.3% 95.9%;\n --accent-foreground: 220.9 39.3% 11%;\n \n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 210 20% 98%;\n \n --ring: 217.9 10.6% 64.9%;\n \n --radius: 0.5rem;\n }\n \n .dark {\n --background: 224 71.4% 4.1%;\n --foreground: 210 20% 98%;\n \n --muted: 215 27.9% 16.9%;\n --muted-foreground: 217.9 10.6% 64.9%;\n \n --popover: 224 71.4% 4.1%;\n --popover-foreground: 210 20% 98%;\n \n --card: 224 71.4% 4.1%;\n --card-foreground: 210 20% 98%;\n \n --border: 215 27.9% 16.9%;\n --input: 215 27.9% 16.9%;\n \n --primary: 210 20% 98%;\n --primary-foreground: 220.9 39.3% 11%;\n \n --secondary: 215 27.9% 16.9%;\n --secondary-foreground: 210 20% 98%;\n \n --accent: 215 27.9% 16.9%;\n --accent-foreground: 210 20% 98%;\n \n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 0 85.7% 97.3%;\n \n --ring: 215 27.9% 16.9%;\n }\n}\n \n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
|
||||
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n \n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 224 71.4% 4.1%;\n\n --card: 0 0% 100%;\n --card-foreground: 224 71.4% 4.1%;\n \n --popover: 0 0% 100%;\n --popover-foreground: 224 71.4% 4.1%;\n \n --primary: 220.9 39.3% 11%;\n --primary-foreground: 210 20% 98%;\n \n --secondary: 220 14.3% 95.9%;\n --secondary-foreground: 220.9 39.3% 11%;\n \n --muted: 220 14.3% 95.9%;\n --muted-foreground: 220 8.9% 46.1%;\n \n --accent: 220 14.3% 95.9%;\n --accent-foreground: 220.9 39.3% 11%;\n \n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 210 20% 98%;\n\n --border: 220 13% 91%;\n --input: 220 13% 91%;\n --ring: 224 71.4% 4.1%;\n \n --radius: 0.5rem;\n }\n \n .dark {\n --background: 224 71.4% 4.1%;\n --foreground: 210 20% 98%;\n \n --card: 224 71.4% 4.1%;\n --card-foreground: 210 20% 98%;\n \n --popover: 224 71.4% 4.1%;\n --popover-foreground: 210 20% 98%;\n \n --primary: 210 20% 98%;\n --primary-foreground: 220.9 39.3% 11%;\n \n --secondary: 215 27.9% 16.9%;\n --secondary-foreground: 210 20% 98%;\n \n --muted: 215 27.9% 16.9%;\n --muted-foreground: 217.9 10.6% 64.9%;\n \n --accent: 215 27.9% 16.9%;\n --accent-foreground: 210 20% 98%;\n \n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 210 20% 98%;\n \n --border: 215 27.9% 16.9%;\n --input: 215 27.9% 16.9%;\n --ring: 216 12.2% 83.9%;\n }\n}\n \n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
|
||||
}
|
||||
@@ -45,9 +45,9 @@
|
||||
"scale": 300,
|
||||
"hex": "#cbd5e1",
|
||||
"rgb": "rgb(203,213,225)",
|
||||
"hsl": "hsl(212.7,26.8%,83.9)",
|
||||
"hsl": "hsl(212.7,26.8%,83.9%)",
|
||||
"rgbChannel": "203 213 225",
|
||||
"hslChannel": "hsl(212.7,26.8%,83.9)"
|
||||
"hslChannel": "212.7 26.8% 83.9%"
|
||||
},
|
||||
{
|
||||
"scale": 400,
|
||||
@@ -1996,4 +1996,4 @@
|
||||
"hslChannel": "343.1 87.7% 15.9%"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
{
|
||||
"inlineColors": {
|
||||
"light": {
|
||||
"background": "white",
|
||||
"foreground": "lime-950",
|
||||
"muted": "lime-100",
|
||||
"muted-foreground": "lime-500",
|
||||
"popover": "white",
|
||||
"popover-foreground": "lime-950",
|
||||
"border": "lime-200",
|
||||
"input": "lime-200",
|
||||
"card": "white",
|
||||
"card-foreground": "lime-950",
|
||||
"primary": "lime-900",
|
||||
"primary-foreground": "lime-50",
|
||||
"secondary": "lime-100",
|
||||
"secondary-foreground": "lime-900",
|
||||
"accent": "lime-100",
|
||||
"accent-foreground": "lime-900",
|
||||
"destructive": "red-500",
|
||||
"destructive-foreground": "lime-50",
|
||||
"ring": "lime-400"
|
||||
},
|
||||
"dark": {
|
||||
"background": "lime-950",
|
||||
"foreground": "lime-50",
|
||||
"muted": "lime-800",
|
||||
"muted-foreground": "lime-400",
|
||||
"popover": "lime-950",
|
||||
"popover-foreground": "lime-50",
|
||||
"border": "lime-800",
|
||||
"input": "lime-800",
|
||||
"card": "lime-950",
|
||||
"card-foreground": "lime-50",
|
||||
"primary": "lime-50",
|
||||
"primary-foreground": "lime-900",
|
||||
"secondary": "lime-800",
|
||||
"secondary-foreground": "lime-50",
|
||||
"accent": "lime-800",
|
||||
"accent-foreground": "lime-50",
|
||||
"destructive": "red-900",
|
||||
"destructive-foreground": "red-50",
|
||||
"ring": "lime-800"
|
||||
}
|
||||
},
|
||||
"cssVars": {
|
||||
"light": {
|
||||
"background": "0 0% 100%",
|
||||
"foreground": "89.3 80.4% 10%",
|
||||
"muted": "79.6 89.1% 89.2%",
|
||||
"muted-foreground": "83.7 80.5% 44.3%",
|
||||
"popover": "0 0% 100%",
|
||||
"popover-foreground": "89.3 80.4% 10%",
|
||||
"border": "80.9 88.5% 79.6%",
|
||||
"input": "80.9 88.5% 79.6%",
|
||||
"card": "0 0% 100%",
|
||||
"card-foreground": "89.3 80.4% 10%",
|
||||
"primary": "87.6 61.2% 20.2%",
|
||||
"primary-foreground": "78.3 92% 95.1%",
|
||||
"secondary": "79.6 89.1% 89.2%",
|
||||
"secondary-foreground": "87.6 61.2% 20.2%",
|
||||
"accent": "79.6 89.1% 89.2%",
|
||||
"accent-foreground": "87.6 61.2% 20.2%",
|
||||
"destructive": "0 84.2% 60.2%",
|
||||
"destructive-foreground": "78.3 92% 95.1%",
|
||||
"ring": "82.7 78% 55.5%"
|
||||
},
|
||||
"dark": {
|
||||
"background": "89.3 80.4% 10%",
|
||||
"foreground": "78.3 92% 95.1%",
|
||||
"muted": "86.3 69% 22.7%",
|
||||
"muted-foreground": "82.7 78% 55.5%",
|
||||
"popover": "89.3 80.4% 10%",
|
||||
"popover-foreground": "78.3 92% 95.1%",
|
||||
"border": "86.3 69% 22.7%",
|
||||
"input": "86.3 69% 22.7%",
|
||||
"card": "89.3 80.4% 10%",
|
||||
"card-foreground": "78.3 92% 95.1%",
|
||||
"primary": "78.3 92% 95.1%",
|
||||
"primary-foreground": "87.6 61.2% 20.2%",
|
||||
"secondary": "86.3 69% 22.7%",
|
||||
"secondary-foreground": "78.3 92% 95.1%",
|
||||
"accent": "86.3 69% 22.7%",
|
||||
"accent-foreground": "78.3 92% 95.1%",
|
||||
"destructive": "0 62.8% 30.6%",
|
||||
"destructive-foreground": "0 85.7% 97.3%",
|
||||
"ring": "86.3 69% 22.7%"
|
||||
}
|
||||
},
|
||||
"inlineColorsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n",
|
||||
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n \n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 89.3 80.4% 10%;\n \n --muted: 79.6 89.1% 89.2%;\n --muted-foreground: 83.7 80.5% 44.3%;\n \n --popover: 0 0% 100%;\n --popover-foreground: 89.3 80.4% 10%;\n \n --card: 0 0% 100%;\n --card-foreground: 89.3 80.4% 10%;\n \n --border: 80.9 88.5% 79.6%;\n --input: 80.9 88.5% 79.6%;\n \n --primary: 87.6 61.2% 20.2%;\n --primary-foreground: 78.3 92% 95.1%;\n \n --secondary: 79.6 89.1% 89.2%;\n --secondary-foreground: 87.6 61.2% 20.2%;\n \n --accent: 79.6 89.1% 89.2%;\n --accent-foreground: 87.6 61.2% 20.2%;\n \n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 78.3 92% 95.1%;\n \n --ring: 82.7 78% 55.5%;\n \n --radius: 0.5rem;\n }\n \n .dark {\n --background: 89.3 80.4% 10%;\n --foreground: 78.3 92% 95.1%;\n \n --muted: 86.3 69% 22.7%;\n --muted-foreground: 82.7 78% 55.5%;\n \n --popover: 89.3 80.4% 10%;\n --popover-foreground: 78.3 92% 95.1%;\n \n --card: 89.3 80.4% 10%;\n --card-foreground: 78.3 92% 95.1%;\n \n --border: 86.3 69% 22.7%;\n --input: 86.3 69% 22.7%;\n \n --primary: 78.3 92% 95.1%;\n --primary-foreground: 87.6 61.2% 20.2%;\n \n --secondary: 86.3 69% 22.7%;\n --secondary-foreground: 78.3 92% 95.1%;\n \n --accent: 86.3 69% 22.7%;\n --accent-foreground: 78.3 92% 95.1%;\n \n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 0 85.7% 97.3%;\n \n --ring: 86.3 69% 22.7%;\n }\n}\n \n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
|
||||
}
|
||||
@@ -3,90 +3,90 @@
|
||||
"light": {
|
||||
"background": "white",
|
||||
"foreground": "neutral-950",
|
||||
"muted": "neutral-100",
|
||||
"muted-foreground": "neutral-500",
|
||||
"popover": "white",
|
||||
"popover-foreground": "neutral-950",
|
||||
"border": "neutral-200",
|
||||
"input": "neutral-200",
|
||||
"card": "white",
|
||||
"card-foreground": "neutral-950",
|
||||
"popover": "white",
|
||||
"popover-foreground": "neutral-950",
|
||||
"primary": "neutral-900",
|
||||
"primary-foreground": "neutral-50",
|
||||
"secondary": "neutral-100",
|
||||
"secondary-foreground": "neutral-900",
|
||||
"muted": "neutral-100",
|
||||
"muted-foreground": "neutral-500",
|
||||
"accent": "neutral-100",
|
||||
"accent-foreground": "neutral-900",
|
||||
"destructive": "red-500",
|
||||
"destructive-foreground": "neutral-50",
|
||||
"ring": "neutral-400"
|
||||
"border": "neutral-200",
|
||||
"input": "neutral-200",
|
||||
"ring": "neutral-950"
|
||||
},
|
||||
"dark": {
|
||||
"background": "neutral-950",
|
||||
"foreground": "neutral-50",
|
||||
"muted": "neutral-800",
|
||||
"muted-foreground": "neutral-400",
|
||||
"popover": "neutral-950",
|
||||
"popover-foreground": "neutral-50",
|
||||
"border": "neutral-800",
|
||||
"input": "neutral-800",
|
||||
"card": "neutral-950",
|
||||
"card-foreground": "neutral-50",
|
||||
"popover": "neutral-950",
|
||||
"popover-foreground": "neutral-50",
|
||||
"primary": "neutral-50",
|
||||
"primary-foreground": "neutral-900",
|
||||
"secondary": "neutral-800",
|
||||
"secondary-foreground": "neutral-50",
|
||||
"muted": "neutral-800",
|
||||
"muted-foreground": "neutral-400",
|
||||
"accent": "neutral-800",
|
||||
"accent-foreground": "neutral-50",
|
||||
"destructive": "red-900",
|
||||
"destructive-foreground": "red-50",
|
||||
"ring": "neutral-800"
|
||||
"destructive-foreground": "neutral-50",
|
||||
"border": "neutral-800",
|
||||
"input": "neutral-800",
|
||||
"ring": "neutral-300"
|
||||
}
|
||||
},
|
||||
"cssVars": {
|
||||
"light": {
|
||||
"background": "0 0% 100%",
|
||||
"foreground": "0 0% 3.9%",
|
||||
"muted": "0 0% 96.1%",
|
||||
"muted-foreground": "0 0% 45.1%",
|
||||
"popover": "0 0% 100%",
|
||||
"popover-foreground": "0 0% 3.9%",
|
||||
"border": "0 0% 89.8%",
|
||||
"input": "0 0% 89.8%",
|
||||
"card": "0 0% 100%",
|
||||
"card-foreground": "0 0% 3.9%",
|
||||
"popover": "0 0% 100%",
|
||||
"popover-foreground": "0 0% 3.9%",
|
||||
"primary": "0 0% 9%",
|
||||
"primary-foreground": "0 0% 98%",
|
||||
"secondary": "0 0% 96.1%",
|
||||
"secondary-foreground": "0 0% 9%",
|
||||
"muted": "0 0% 96.1%",
|
||||
"muted-foreground": "0 0% 45.1%",
|
||||
"accent": "0 0% 96.1%",
|
||||
"accent-foreground": "0 0% 9%",
|
||||
"destructive": "0 84.2% 60.2%",
|
||||
"destructive-foreground": "0 0% 98%",
|
||||
"ring": "0 0% 63.9%"
|
||||
"border": "0 0% 89.8%",
|
||||
"input": "0 0% 89.8%",
|
||||
"ring": "0 0% 3.9%"
|
||||
},
|
||||
"dark": {
|
||||
"background": "0 0% 3.9%",
|
||||
"foreground": "0 0% 98%",
|
||||
"muted": "0 0% 14.9%",
|
||||
"muted-foreground": "0 0% 63.9%",
|
||||
"popover": "0 0% 3.9%",
|
||||
"popover-foreground": "0 0% 98%",
|
||||
"border": "0 0% 14.9%",
|
||||
"input": "0 0% 14.9%",
|
||||
"card": "0 0% 3.9%",
|
||||
"card-foreground": "0 0% 98%",
|
||||
"popover": "0 0% 3.9%",
|
||||
"popover-foreground": "0 0% 98%",
|
||||
"primary": "0 0% 98%",
|
||||
"primary-foreground": "0 0% 9%",
|
||||
"secondary": "0 0% 14.9%",
|
||||
"secondary-foreground": "0 0% 98%",
|
||||
"muted": "0 0% 14.9%",
|
||||
"muted-foreground": "0 0% 63.9%",
|
||||
"accent": "0 0% 14.9%",
|
||||
"accent-foreground": "0 0% 98%",
|
||||
"destructive": "0 62.8% 30.6%",
|
||||
"destructive-foreground": "0 85.7% 97.3%",
|
||||
"ring": "0 0% 14.9%"
|
||||
"destructive-foreground": "0 0% 98%",
|
||||
"border": "0 0% 14.9%",
|
||||
"input": "0 0% 14.9%",
|
||||
"ring": "0 0% 83.1%"
|
||||
}
|
||||
},
|
||||
"inlineColorsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n",
|
||||
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n \n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 0 0% 3.9%;\n \n --muted: 0 0% 96.1%;\n --muted-foreground: 0 0% 45.1%;\n \n --popover: 0 0% 100%;\n --popover-foreground: 0 0% 3.9%;\n \n --card: 0 0% 100%;\n --card-foreground: 0 0% 3.9%;\n \n --border: 0 0% 89.8%;\n --input: 0 0% 89.8%;\n \n --primary: 0 0% 9%;\n --primary-foreground: 0 0% 98%;\n \n --secondary: 0 0% 96.1%;\n --secondary-foreground: 0 0% 9%;\n \n --accent: 0 0% 96.1%;\n --accent-foreground: 0 0% 9%;\n \n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 0 0% 98%;\n \n --ring: 0 0% 63.9%;\n \n --radius: 0.5rem;\n }\n \n .dark {\n --background: 0 0% 3.9%;\n --foreground: 0 0% 98%;\n \n --muted: 0 0% 14.9%;\n --muted-foreground: 0 0% 63.9%;\n \n --popover: 0 0% 3.9%;\n --popover-foreground: 0 0% 98%;\n \n --card: 0 0% 3.9%;\n --card-foreground: 0 0% 98%;\n \n --border: 0 0% 14.9%;\n --input: 0 0% 14.9%;\n \n --primary: 0 0% 98%;\n --primary-foreground: 0 0% 9%;\n \n --secondary: 0 0% 14.9%;\n --secondary-foreground: 0 0% 98%;\n \n --accent: 0 0% 14.9%;\n --accent-foreground: 0 0% 98%;\n \n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 0 85.7% 97.3%;\n \n --ring: 0 0% 14.9%;\n }\n}\n \n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
|
||||
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n \n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 0 0% 3.9%;\n\n --card: 0 0% 100%;\n --card-foreground: 0 0% 3.9%;\n \n --popover: 0 0% 100%;\n --popover-foreground: 0 0% 3.9%;\n \n --primary: 0 0% 9%;\n --primary-foreground: 0 0% 98%;\n \n --secondary: 0 0% 96.1%;\n --secondary-foreground: 0 0% 9%;\n \n --muted: 0 0% 96.1%;\n --muted-foreground: 0 0% 45.1%;\n \n --accent: 0 0% 96.1%;\n --accent-foreground: 0 0% 9%;\n \n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 0 0% 98%;\n\n --border: 0 0% 89.8%;\n --input: 0 0% 89.8%;\n --ring: 0 0% 3.9%;\n \n --radius: 0.5rem;\n }\n \n .dark {\n --background: 0 0% 3.9%;\n --foreground: 0 0% 98%;\n \n --card: 0 0% 3.9%;\n --card-foreground: 0 0% 98%;\n \n --popover: 0 0% 3.9%;\n --popover-foreground: 0 0% 98%;\n \n --primary: 0 0% 98%;\n --primary-foreground: 0 0% 9%;\n \n --secondary: 0 0% 14.9%;\n --secondary-foreground: 0 0% 98%;\n \n --muted: 0 0% 14.9%;\n --muted-foreground: 0 0% 63.9%;\n \n --accent: 0 0% 14.9%;\n --accent-foreground: 0 0% 98%;\n \n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 0 0% 98%;\n \n --border: 0 0% 14.9%;\n --input: 0 0% 14.9%;\n --ring: 0 0% 83.1%;\n }\n}\n \n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
|
||||
}
|
||||
@@ -3,90 +3,90 @@
|
||||
"light": {
|
||||
"background": "white",
|
||||
"foreground": "slate-950",
|
||||
"muted": "slate-100",
|
||||
"muted-foreground": "slate-500",
|
||||
"popover": "white",
|
||||
"popover-foreground": "slate-950",
|
||||
"border": "slate-200",
|
||||
"input": "slate-200",
|
||||
"card": "white",
|
||||
"card-foreground": "slate-950",
|
||||
"popover": "white",
|
||||
"popover-foreground": "slate-950",
|
||||
"primary": "slate-900",
|
||||
"primary-foreground": "slate-50",
|
||||
"secondary": "slate-100",
|
||||
"secondary-foreground": "slate-900",
|
||||
"muted": "slate-100",
|
||||
"muted-foreground": "slate-500",
|
||||
"accent": "slate-100",
|
||||
"accent-foreground": "slate-900",
|
||||
"destructive": "red-500",
|
||||
"destructive-foreground": "slate-50",
|
||||
"ring": "slate-400"
|
||||
"border": "slate-200",
|
||||
"input": "slate-200",
|
||||
"ring": "slate-950"
|
||||
},
|
||||
"dark": {
|
||||
"background": "slate-950",
|
||||
"foreground": "slate-50",
|
||||
"muted": "slate-800",
|
||||
"muted-foreground": "slate-400",
|
||||
"popover": "slate-950",
|
||||
"popover-foreground": "slate-50",
|
||||
"border": "slate-800",
|
||||
"input": "slate-800",
|
||||
"card": "slate-950",
|
||||
"card-foreground": "slate-50",
|
||||
"popover": "slate-950",
|
||||
"popover-foreground": "slate-50",
|
||||
"primary": "slate-50",
|
||||
"primary-foreground": "slate-900",
|
||||
"secondary": "slate-800",
|
||||
"secondary-foreground": "slate-50",
|
||||
"muted": "slate-800",
|
||||
"muted-foreground": "slate-400",
|
||||
"accent": "slate-800",
|
||||
"accent-foreground": "slate-50",
|
||||
"destructive": "red-900",
|
||||
"destructive-foreground": "red-50",
|
||||
"ring": "slate-800"
|
||||
"destructive-foreground": "slate-50",
|
||||
"border": "slate-800",
|
||||
"input": "slate-800",
|
||||
"ring": "slate-300"
|
||||
}
|
||||
},
|
||||
"cssVars": {
|
||||
"light": {
|
||||
"background": "0 0% 100%",
|
||||
"foreground": "222.2 84% 4.9%",
|
||||
"muted": "210 40% 96.1%",
|
||||
"muted-foreground": "215.4 16.3% 46.9%",
|
||||
"popover": "0 0% 100%",
|
||||
"popover-foreground": "222.2 84% 4.9%",
|
||||
"border": "214.3 31.8% 91.4%",
|
||||
"input": "214.3 31.8% 91.4%",
|
||||
"card": "0 0% 100%",
|
||||
"card-foreground": "222.2 84% 4.9%",
|
||||
"popover": "0 0% 100%",
|
||||
"popover-foreground": "222.2 84% 4.9%",
|
||||
"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%",
|
||||
"muted": "210 40% 96.1%",
|
||||
"muted-foreground": "215.4 16.3% 46.9%",
|
||||
"accent": "210 40% 96.1%",
|
||||
"accent-foreground": "222.2 47.4% 11.2%",
|
||||
"destructive": "0 84.2% 60.2%",
|
||||
"destructive-foreground": "210 40% 98%",
|
||||
"ring": "215 20.2% 65.1%"
|
||||
"border": "214.3 31.8% 91.4%",
|
||||
"input": "214.3 31.8% 91.4%",
|
||||
"ring": "222.2 84% 4.9%"
|
||||
},
|
||||
"dark": {
|
||||
"background": "222.2 84% 4.9%",
|
||||
"foreground": "210 40% 98%",
|
||||
"muted": "217.2 32.6% 17.5%",
|
||||
"muted-foreground": "215 20.2% 65.1%",
|
||||
"popover": "222.2 84% 4.9%",
|
||||
"popover-foreground": "210 40% 98%",
|
||||
"border": "217.2 32.6% 17.5%",
|
||||
"input": "217.2 32.6% 17.5%",
|
||||
"card": "222.2 84% 4.9%",
|
||||
"card-foreground": "210 40% 98%",
|
||||
"popover": "222.2 84% 4.9%",
|
||||
"popover-foreground": "210 40% 98%",
|
||||
"primary": "210 40% 98%",
|
||||
"primary-foreground": "222.2 47.4% 11.2%",
|
||||
"secondary": "217.2 32.6% 17.5%",
|
||||
"secondary-foreground": "210 40% 98%",
|
||||
"muted": "217.2 32.6% 17.5%",
|
||||
"muted-foreground": "215 20.2% 65.1%",
|
||||
"accent": "217.2 32.6% 17.5%",
|
||||
"accent-foreground": "210 40% 98%",
|
||||
"destructive": "0 62.8% 30.6%",
|
||||
"destructive-foreground": "0 85.7% 97.3%",
|
||||
"ring": "217.2 32.6% 17.5%"
|
||||
"destructive-foreground": "210 40% 98%",
|
||||
"border": "217.2 32.6% 17.5%",
|
||||
"input": "217.2 32.6% 17.5%",
|
||||
"ring": "212.7 26.8% 83.9%"
|
||||
}
|
||||
},
|
||||
"inlineColorsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n",
|
||||
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n \n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 222.2 84% 4.9%;\n \n --muted: 210 40% 96.1%;\n --muted-foreground: 215.4 16.3% 46.9%;\n \n --popover: 0 0% 100%;\n --popover-foreground: 222.2 84% 4.9%;\n \n --card: 0 0% 100%;\n --card-foreground: 222.2 84% 4.9%;\n \n --border: 214.3 31.8% 91.4%;\n --input: 214.3 31.8% 91.4%;\n \n --primary: 222.2 47.4% 11.2%;\n --primary-foreground: 210 40% 98%;\n \n --secondary: 210 40% 96.1%;\n --secondary-foreground: 222.2 47.4% 11.2%;\n \n --accent: 210 40% 96.1%;\n --accent-foreground: 222.2 47.4% 11.2%;\n \n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 210 40% 98%;\n \n --ring: 215 20.2% 65.1%;\n \n --radius: 0.5rem;\n }\n \n .dark {\n --background: 222.2 84% 4.9%;\n --foreground: 210 40% 98%;\n \n --muted: 217.2 32.6% 17.5%;\n --muted-foreground: 215 20.2% 65.1%;\n \n --popover: 222.2 84% 4.9%;\n --popover-foreground: 210 40% 98%;\n \n --card: 222.2 84% 4.9%;\n --card-foreground: 210 40% 98%;\n \n --border: 217.2 32.6% 17.5%;\n --input: 217.2 32.6% 17.5%;\n \n --primary: 210 40% 98%;\n --primary-foreground: 222.2 47.4% 11.2%;\n \n --secondary: 217.2 32.6% 17.5%;\n --secondary-foreground: 210 40% 98%;\n \n --accent: 217.2 32.6% 17.5%;\n --accent-foreground: 210 40% 98%;\n \n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 0 85.7% 97.3%;\n \n --ring: 217.2 32.6% 17.5%;\n }\n}\n \n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
|
||||
}
|
||||
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n \n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 222.2 84% 4.9%;\n\n --card: 0 0% 100%;\n --card-foreground: 222.2 84% 4.9%;\n \n --popover: 0 0% 100%;\n --popover-foreground: 222.2 84% 4.9%;\n \n --primary: 222.2 47.4% 11.2%;\n --primary-foreground: 210 40% 98%;\n \n --secondary: 210 40% 96.1%;\n --secondary-foreground: 222.2 47.4% 11.2%;\n \n --muted: 210 40% 96.1%;\n --muted-foreground: 215.4 16.3% 46.9%;\n \n --accent: 210 40% 96.1%;\n --accent-foreground: 222.2 47.4% 11.2%;\n \n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 210 40% 98%;\n\n --border: 214.3 31.8% 91.4%;\n --input: 214.3 31.8% 91.4%;\n --ring: 222.2 84% 4.9%;\n \n --radius: 0.5rem;\n }\n \n .dark {\n --background: 222.2 84% 4.9%;\n --foreground: 210 40% 98%;\n \n --card: 222.2 84% 4.9%;\n --card-foreground: 210 40% 98%;\n \n --popover: 222.2 84% 4.9%;\n --popover-foreground: 210 40% 98%;\n \n --primary: 210 40% 98%;\n --primary-foreground: 222.2 47.4% 11.2%;\n \n --secondary: 217.2 32.6% 17.5%;\n --secondary-foreground: 210 40% 98%;\n \n --muted: 217.2 32.6% 17.5%;\n --muted-foreground: 215 20.2% 65.1%;\n \n --accent: 217.2 32.6% 17.5%;\n --accent-foreground: 210 40% 98%;\n \n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 210 40% 98%;\n \n --border: 217.2 32.6% 17.5%;\n --input: 217.2 32.6% 17.5%;\n --ring: 212.7 26.8% 83.9%;\n }\n}\n \n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
|
||||
}
|
||||
|
||||
@@ -3,90 +3,90 @@
|
||||
"light": {
|
||||
"background": "white",
|
||||
"foreground": "stone-950",
|
||||
"muted": "stone-100",
|
||||
"muted-foreground": "stone-500",
|
||||
"popover": "white",
|
||||
"popover-foreground": "stone-950",
|
||||
"border": "stone-200",
|
||||
"input": "stone-200",
|
||||
"card": "white",
|
||||
"card-foreground": "stone-950",
|
||||
"popover": "white",
|
||||
"popover-foreground": "stone-950",
|
||||
"primary": "stone-900",
|
||||
"primary-foreground": "stone-50",
|
||||
"secondary": "stone-100",
|
||||
"secondary-foreground": "stone-900",
|
||||
"muted": "stone-100",
|
||||
"muted-foreground": "stone-500",
|
||||
"accent": "stone-100",
|
||||
"accent-foreground": "stone-900",
|
||||
"destructive": "red-500",
|
||||
"destructive-foreground": "stone-50",
|
||||
"ring": "stone-400"
|
||||
"border": "stone-200",
|
||||
"input": "stone-200",
|
||||
"ring": "stone-950"
|
||||
},
|
||||
"dark": {
|
||||
"background": "stone-950",
|
||||
"foreground": "stone-50",
|
||||
"muted": "stone-800",
|
||||
"muted-foreground": "stone-400",
|
||||
"popover": "stone-950",
|
||||
"popover-foreground": "stone-50",
|
||||
"border": "stone-800",
|
||||
"input": "stone-800",
|
||||
"card": "stone-950",
|
||||
"card-foreground": "stone-50",
|
||||
"popover": "stone-950",
|
||||
"popover-foreground": "stone-50",
|
||||
"primary": "stone-50",
|
||||
"primary-foreground": "stone-900",
|
||||
"secondary": "stone-800",
|
||||
"secondary-foreground": "stone-50",
|
||||
"muted": "stone-800",
|
||||
"muted-foreground": "stone-400",
|
||||
"accent": "stone-800",
|
||||
"accent-foreground": "stone-50",
|
||||
"destructive": "red-900",
|
||||
"destructive-foreground": "red-50",
|
||||
"ring": "stone-800"
|
||||
"destructive-foreground": "stone-50",
|
||||
"border": "stone-800",
|
||||
"input": "stone-800",
|
||||
"ring": "stone-300"
|
||||
}
|
||||
},
|
||||
"cssVars": {
|
||||
"light": {
|
||||
"background": "0 0% 100%",
|
||||
"foreground": "20 14.3% 4.1%",
|
||||
"muted": "60 4.8% 95.9%",
|
||||
"muted-foreground": "25 5.3% 44.7%",
|
||||
"popover": "0 0% 100%",
|
||||
"popover-foreground": "20 14.3% 4.1%",
|
||||
"border": "20 5.9% 90%",
|
||||
"input": "20 5.9% 90%",
|
||||
"card": "0 0% 100%",
|
||||
"card-foreground": "20 14.3% 4.1%",
|
||||
"popover": "0 0% 100%",
|
||||
"popover-foreground": "20 14.3% 4.1%",
|
||||
"primary": "24 9.8% 10%",
|
||||
"primary-foreground": "60 9.1% 97.8%",
|
||||
"secondary": "60 4.8% 95.9%",
|
||||
"secondary-foreground": "24 9.8% 10%",
|
||||
"muted": "60 4.8% 95.9%",
|
||||
"muted-foreground": "25 5.3% 44.7%",
|
||||
"accent": "60 4.8% 95.9%",
|
||||
"accent-foreground": "24 9.8% 10%",
|
||||
"destructive": "0 84.2% 60.2%",
|
||||
"destructive-foreground": "60 9.1% 97.8%",
|
||||
"ring": "24 5.4% 63.9%"
|
||||
"border": "20 5.9% 90%",
|
||||
"input": "20 5.9% 90%",
|
||||
"ring": "20 14.3% 4.1%"
|
||||
},
|
||||
"dark": {
|
||||
"background": "20 14.3% 4.1%",
|
||||
"foreground": "60 9.1% 97.8%",
|
||||
"muted": "12 6.5% 15.1%",
|
||||
"muted-foreground": "24 5.4% 63.9%",
|
||||
"popover": "20 14.3% 4.1%",
|
||||
"popover-foreground": "60 9.1% 97.8%",
|
||||
"border": "12 6.5% 15.1%",
|
||||
"input": "12 6.5% 15.1%",
|
||||
"card": "20 14.3% 4.1%",
|
||||
"card-foreground": "60 9.1% 97.8%",
|
||||
"popover": "20 14.3% 4.1%",
|
||||
"popover-foreground": "60 9.1% 97.8%",
|
||||
"primary": "60 9.1% 97.8%",
|
||||
"primary-foreground": "24 9.8% 10%",
|
||||
"secondary": "12 6.5% 15.1%",
|
||||
"secondary-foreground": "60 9.1% 97.8%",
|
||||
"muted": "12 6.5% 15.1%",
|
||||
"muted-foreground": "24 5.4% 63.9%",
|
||||
"accent": "12 6.5% 15.1%",
|
||||
"accent-foreground": "60 9.1% 97.8%",
|
||||
"destructive": "0 62.8% 30.6%",
|
||||
"destructive-foreground": "0 85.7% 97.3%",
|
||||
"ring": "12 6.5% 15.1%"
|
||||
"destructive-foreground": "60 9.1% 97.8%",
|
||||
"border": "12 6.5% 15.1%",
|
||||
"input": "12 6.5% 15.1%",
|
||||
"ring": "24 5.7% 82.9%"
|
||||
}
|
||||
},
|
||||
"inlineColorsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n",
|
||||
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n \n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 20 14.3% 4.1%;\n \n --muted: 60 4.8% 95.9%;\n --muted-foreground: 25 5.3% 44.7%;\n \n --popover: 0 0% 100%;\n --popover-foreground: 20 14.3% 4.1%;\n \n --card: 0 0% 100%;\n --card-foreground: 20 14.3% 4.1%;\n \n --border: 20 5.9% 90%;\n --input: 20 5.9% 90%;\n \n --primary: 24 9.8% 10%;\n --primary-foreground: 60 9.1% 97.8%;\n \n --secondary: 60 4.8% 95.9%;\n --secondary-foreground: 24 9.8% 10%;\n \n --accent: 60 4.8% 95.9%;\n --accent-foreground: 24 9.8% 10%;\n \n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 60 9.1% 97.8%;\n \n --ring: 24 5.4% 63.9%;\n \n --radius: 0.5rem;\n }\n \n .dark {\n --background: 20 14.3% 4.1%;\n --foreground: 60 9.1% 97.8%;\n \n --muted: 12 6.5% 15.1%;\n --muted-foreground: 24 5.4% 63.9%;\n \n --popover: 20 14.3% 4.1%;\n --popover-foreground: 60 9.1% 97.8%;\n \n --card: 20 14.3% 4.1%;\n --card-foreground: 60 9.1% 97.8%;\n \n --border: 12 6.5% 15.1%;\n --input: 12 6.5% 15.1%;\n \n --primary: 60 9.1% 97.8%;\n --primary-foreground: 24 9.8% 10%;\n \n --secondary: 12 6.5% 15.1%;\n --secondary-foreground: 60 9.1% 97.8%;\n \n --accent: 12 6.5% 15.1%;\n --accent-foreground: 60 9.1% 97.8%;\n \n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 0 85.7% 97.3%;\n \n --ring: 12 6.5% 15.1%;\n }\n}\n \n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
|
||||
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n \n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 20 14.3% 4.1%;\n\n --card: 0 0% 100%;\n --card-foreground: 20 14.3% 4.1%;\n \n --popover: 0 0% 100%;\n --popover-foreground: 20 14.3% 4.1%;\n \n --primary: 24 9.8% 10%;\n --primary-foreground: 60 9.1% 97.8%;\n \n --secondary: 60 4.8% 95.9%;\n --secondary-foreground: 24 9.8% 10%;\n \n --muted: 60 4.8% 95.9%;\n --muted-foreground: 25 5.3% 44.7%;\n \n --accent: 60 4.8% 95.9%;\n --accent-foreground: 24 9.8% 10%;\n \n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 60 9.1% 97.8%;\n\n --border: 20 5.9% 90%;\n --input: 20 5.9% 90%;\n --ring: 20 14.3% 4.1%;\n \n --radius: 0.5rem;\n }\n \n .dark {\n --background: 20 14.3% 4.1%;\n --foreground: 60 9.1% 97.8%;\n \n --card: 20 14.3% 4.1%;\n --card-foreground: 60 9.1% 97.8%;\n \n --popover: 20 14.3% 4.1%;\n --popover-foreground: 60 9.1% 97.8%;\n \n --primary: 60 9.1% 97.8%;\n --primary-foreground: 24 9.8% 10%;\n \n --secondary: 12 6.5% 15.1%;\n --secondary-foreground: 60 9.1% 97.8%;\n \n --muted: 12 6.5% 15.1%;\n --muted-foreground: 24 5.4% 63.9%;\n \n --accent: 12 6.5% 15.1%;\n --accent-foreground: 60 9.1% 97.8%;\n \n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 60 9.1% 97.8%;\n \n --border: 12 6.5% 15.1%;\n --input: 12 6.5% 15.1%;\n --ring: 24 5.7% 82.9%;\n }\n}\n \n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
|
||||
}
|
||||
@@ -3,90 +3,90 @@
|
||||
"light": {
|
||||
"background": "white",
|
||||
"foreground": "zinc-950",
|
||||
"muted": "zinc-100",
|
||||
"muted-foreground": "zinc-500",
|
||||
"popover": "white",
|
||||
"popover-foreground": "zinc-950",
|
||||
"border": "zinc-200",
|
||||
"input": "zinc-200",
|
||||
"card": "white",
|
||||
"card-foreground": "zinc-950",
|
||||
"popover": "white",
|
||||
"popover-foreground": "zinc-950",
|
||||
"primary": "zinc-900",
|
||||
"primary-foreground": "zinc-50",
|
||||
"secondary": "zinc-100",
|
||||
"secondary-foreground": "zinc-900",
|
||||
"muted": "zinc-100",
|
||||
"muted-foreground": "zinc-500",
|
||||
"accent": "zinc-100",
|
||||
"accent-foreground": "zinc-900",
|
||||
"destructive": "red-500",
|
||||
"destructive-foreground": "zinc-50",
|
||||
"ring": "zinc-400"
|
||||
"border": "zinc-200",
|
||||
"input": "zinc-200",
|
||||
"ring": "zinc-950"
|
||||
},
|
||||
"dark": {
|
||||
"background": "zinc-950",
|
||||
"foreground": "zinc-50",
|
||||
"muted": "zinc-800",
|
||||
"muted-foreground": "zinc-400",
|
||||
"popover": "zinc-950",
|
||||
"popover-foreground": "zinc-50",
|
||||
"border": "zinc-800",
|
||||
"input": "zinc-800",
|
||||
"card": "zinc-950",
|
||||
"card-foreground": "zinc-50",
|
||||
"popover": "zinc-950",
|
||||
"popover-foreground": "zinc-50",
|
||||
"primary": "zinc-50",
|
||||
"primary-foreground": "zinc-900",
|
||||
"secondary": "zinc-800",
|
||||
"secondary-foreground": "zinc-50",
|
||||
"muted": "zinc-800",
|
||||
"muted-foreground": "zinc-400",
|
||||
"accent": "zinc-800",
|
||||
"accent-foreground": "zinc-50",
|
||||
"destructive": "red-900",
|
||||
"destructive-foreground": "red-50",
|
||||
"ring": "zinc-800"
|
||||
"destructive-foreground": "zinc-50",
|
||||
"border": "zinc-800",
|
||||
"input": "zinc-800",
|
||||
"ring": "zinc-300"
|
||||
}
|
||||
},
|
||||
"cssVars": {
|
||||
"light": {
|
||||
"background": "0 0% 100%",
|
||||
"foreground": "240 10% 3.9%",
|
||||
"muted": "240 4.8% 95.9%",
|
||||
"muted-foreground": "240 3.8% 46.1%",
|
||||
"popover": "0 0% 100%",
|
||||
"popover-foreground": "240 10% 3.9%",
|
||||
"border": "240 5.9% 90%",
|
||||
"input": "240 5.9% 90%",
|
||||
"card": "0 0% 100%",
|
||||
"card-foreground": "240 10% 3.9%",
|
||||
"popover": "0 0% 100%",
|
||||
"popover-foreground": "240 10% 3.9%",
|
||||
"primary": "240 5.9% 10%",
|
||||
"primary-foreground": "0 0% 98%",
|
||||
"secondary": "240 4.8% 95.9%",
|
||||
"secondary-foreground": "240 5.9% 10%",
|
||||
"muted": "240 4.8% 95.9%",
|
||||
"muted-foreground": "240 3.8% 46.1%",
|
||||
"accent": "240 4.8% 95.9%",
|
||||
"accent-foreground": "240 5.9% 10%",
|
||||
"destructive": "0 84.2% 60.2%",
|
||||
"destructive-foreground": "0 0% 98%",
|
||||
"ring": "240 5% 64.9%"
|
||||
"border": "240 5.9% 90%",
|
||||
"input": "240 5.9% 90%",
|
||||
"ring": "240 10% 3.9%"
|
||||
},
|
||||
"dark": {
|
||||
"background": "240 10% 3.9%",
|
||||
"foreground": "0 0% 98%",
|
||||
"muted": "240 3.7% 15.9%",
|
||||
"muted-foreground": "240 5% 64.9%",
|
||||
"popover": "240 10% 3.9%",
|
||||
"popover-foreground": "0 0% 98%",
|
||||
"border": "240 3.7% 15.9%",
|
||||
"input": "240 3.7% 15.9%",
|
||||
"card": "240 10% 3.9%",
|
||||
"card-foreground": "0 0% 98%",
|
||||
"popover": "240 10% 3.9%",
|
||||
"popover-foreground": "0 0% 98%",
|
||||
"primary": "0 0% 98%",
|
||||
"primary-foreground": "240 5.9% 10%",
|
||||
"secondary": "240 3.7% 15.9%",
|
||||
"secondary-foreground": "0 0% 98%",
|
||||
"muted": "240 3.7% 15.9%",
|
||||
"muted-foreground": "240 5% 64.9%",
|
||||
"accent": "240 3.7% 15.9%",
|
||||
"accent-foreground": "0 0% 98%",
|
||||
"destructive": "0 62.8% 30.6%",
|
||||
"destructive-foreground": "0 85.7% 97.3%",
|
||||
"ring": "240 3.7% 15.9%"
|
||||
"destructive-foreground": "0 0% 98%",
|
||||
"border": "240 3.7% 15.9%",
|
||||
"input": "240 3.7% 15.9%",
|
||||
"ring": "240 4.9% 83.9%"
|
||||
}
|
||||
},
|
||||
"inlineColorsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n",
|
||||
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n \n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 240 10% 3.9%;\n \n --muted: 240 4.8% 95.9%;\n --muted-foreground: 240 3.8% 46.1%;\n \n --popover: 0 0% 100%;\n --popover-foreground: 240 10% 3.9%;\n \n --card: 0 0% 100%;\n --card-foreground: 240 10% 3.9%;\n \n --border: 240 5.9% 90%;\n --input: 240 5.9% 90%;\n \n --primary: 240 5.9% 10%;\n --primary-foreground: 0 0% 98%;\n \n --secondary: 240 4.8% 95.9%;\n --secondary-foreground: 240 5.9% 10%;\n \n --accent: 240 4.8% 95.9%;\n --accent-foreground: 240 5.9% 10%;\n \n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 0 0% 98%;\n \n --ring: 240 5% 64.9%;\n \n --radius: 0.5rem;\n }\n \n .dark {\n --background: 240 10% 3.9%;\n --foreground: 0 0% 98%;\n \n --muted: 240 3.7% 15.9%;\n --muted-foreground: 240 5% 64.9%;\n \n --popover: 240 10% 3.9%;\n --popover-foreground: 0 0% 98%;\n \n --card: 240 10% 3.9%;\n --card-foreground: 0 0% 98%;\n \n --border: 240 3.7% 15.9%;\n --input: 240 3.7% 15.9%;\n \n --primary: 0 0% 98%;\n --primary-foreground: 240 5.9% 10%;\n \n --secondary: 240 3.7% 15.9%;\n --secondary-foreground: 0 0% 98%;\n \n --accent: 240 3.7% 15.9%;\n --accent-foreground: 0 0% 98%;\n \n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 0 85.7% 97.3%;\n \n --ring: 240 3.7% 15.9%;\n }\n}\n \n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
|
||||
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n \n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 240 10% 3.9%;\n\n --card: 0 0% 100%;\n --card-foreground: 240 10% 3.9%;\n \n --popover: 0 0% 100%;\n --popover-foreground: 240 10% 3.9%;\n \n --primary: 240 5.9% 10%;\n --primary-foreground: 0 0% 98%;\n \n --secondary: 240 4.8% 95.9%;\n --secondary-foreground: 240 5.9% 10%;\n \n --muted: 240 4.8% 95.9%;\n --muted-foreground: 240 3.8% 46.1%;\n \n --accent: 240 4.8% 95.9%;\n --accent-foreground: 240 5.9% 10%;\n \n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 0 0% 98%;\n\n --border: 240 5.9% 90%;\n --input: 240 5.9% 90%;\n --ring: 240 10% 3.9%;\n \n --radius: 0.5rem;\n }\n \n .dark {\n --background: 240 10% 3.9%;\n --foreground: 0 0% 98%;\n \n --card: 240 10% 3.9%;\n --card-foreground: 0 0% 98%;\n \n --popover: 240 10% 3.9%;\n --popover-foreground: 0 0% 98%;\n \n --primary: 0 0% 98%;\n --primary-foreground: 240 5.9% 10%;\n \n --secondary: 240 3.7% 15.9%;\n --secondary-foreground: 0 0% 98%;\n \n --muted: 240 3.7% 15.9%;\n --muted-foreground: 240 5% 64.9%;\n \n --accent: 240 3.7% 15.9%;\n --accent-foreground: 0 0% 98%;\n \n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 0 0% 98%;\n \n --border: 240 3.7% 15.9%;\n --input: 240 3.7% 15.9%;\n --ring: 240 4.9% 83.9%;\n }\n}\n \n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
"files": [
|
||||
{
|
||||
"name": "alert.tsx",
|
||||
"content": "import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst alertVariants = cva(\n \"relative w-full rounded-lg border p-4 [&:has(svg)]:pl-11 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground\",\n {\n variants: {\n variant: {\n default: \"bg-background text-foreground\",\n destructive:\n \"border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nconst Alert = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants>\n>(({ className, variant, ...props }, ref) => (\n <div\n ref={ref}\n role=\"alert\"\n className={cn(alertVariants({ variant }), className)}\n {...props}\n />\n))\nAlert.displayName = \"Alert\"\n\nconst AlertTitle = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLHeadingElement>\n>(({ className, ...props }, ref) => (\n <h5\n ref={ref}\n className={cn(\"mb-1 font-medium leading-none tracking-tight\", className)}\n {...props}\n />\n))\nAlertTitle.displayName = \"AlertTitle\"\n\nconst AlertDescription = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\"text-sm [&_p]:leading-relaxed\", className)}\n {...props}\n />\n))\nAlertDescription.displayName = \"AlertDescription\"\n\nexport { Alert, AlertTitle, AlertDescription }\n"
|
||||
"content": "import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst alertVariants = cva(\n \"relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground\",\n {\n variants: {\n variant: {\n default: \"bg-background text-foreground\",\n destructive:\n \"border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nconst Alert = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants>\n>(({ className, variant, ...props }, ref) => (\n <div\n ref={ref}\n role=\"alert\"\n className={cn(alertVariants({ variant }), className)}\n {...props}\n />\n))\nAlert.displayName = \"Alert\"\n\nconst AlertTitle = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLHeadingElement>\n>(({ className, ...props }, ref) => (\n <h5\n ref={ref}\n className={cn(\"mb-1 font-medium leading-none tracking-tight\", className)}\n {...props}\n />\n))\nAlertTitle.displayName = \"AlertTitle\"\n\nconst AlertDescription = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\"text-sm [&_p]:leading-relaxed\", className)}\n {...props}\n />\n))\nAlertDescription.displayName = \"AlertDescription\"\n\nexport { Alert, AlertTitle, AlertDescription }\n"
|
||||
}
|
||||
],
|
||||
"type": "components:ui"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"files": [
|
||||
{
|
||||
"name": "card.tsx",
|
||||
"content": "import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst Card = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n \"rounded-lg border bg-card text-card-foreground shadow-sm\",\n className\n )}\n {...props}\n />\n))\nCard.displayName = \"Card\"\n\nconst CardHeader = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\"flex flex-col space-y-1.5 p-6\", className)}\n {...props}\n />\n))\nCardHeader.displayName = \"CardHeader\"\n\nconst CardTitle = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLHeadingElement>\n>(({ className, ...props }, ref) => (\n <h3\n ref={ref}\n className={cn(\n \"text-2xl font-semibold leading-none tracking-tight\",\n className\n )}\n {...props}\n />\n))\nCardTitle.displayName = \"CardTitle\"\n\nconst CardDescription = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => (\n <p\n ref={ref}\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n))\nCardDescription.displayName = \"CardDescription\"\n\nconst CardContent = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div ref={ref} className={cn(\"p-6 pt-0\", className)} {...props} />\n))\nCardContent.displayName = \"CardContent\"\n\nconst CardFooter = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\" flex items-center p-6 pt-0\", className)}\n {...props}\n />\n))\nCardFooter.displayName = \"CardFooter\"\n\nexport { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }\n"
|
||||
"content": "import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst Card = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n \"rounded-lg border bg-card text-card-foreground shadow-sm\",\n className\n )}\n {...props}\n />\n))\nCard.displayName = \"Card\"\n\nconst CardHeader = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\"flex flex-col space-y-1.5 p-6\", className)}\n {...props}\n />\n))\nCardHeader.displayName = \"CardHeader\"\n\nconst CardTitle = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLHeadingElement>\n>(({ className, ...props }, ref) => (\n <h3\n ref={ref}\n className={cn(\n \"text-2xl font-semibold leading-none tracking-tight\",\n className\n )}\n {...props}\n />\n))\nCardTitle.displayName = \"CardTitle\"\n\nconst CardDescription = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => (\n <p\n ref={ref}\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n))\nCardDescription.displayName = \"CardDescription\"\n\nconst CardContent = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div ref={ref} className={cn(\"p-6 pt-0\", className)} {...props} />\n))\nCardContent.displayName = \"CardContent\"\n\nconst CardFooter = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\"flex items-center p-6 pt-0\", className)}\n {...props}\n />\n))\nCardFooter.displayName = \"CardFooter\"\n\nexport { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }\n"
|
||||
}
|
||||
],
|
||||
"type": "components:ui"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"files": [
|
||||
{
|
||||
"name": "select.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport * as SelectPrimitive from \"@radix-ui/react-select\"\nimport { Check, ChevronDown } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst Select = SelectPrimitive.Root\n\nconst SelectGroup = SelectPrimitive.Group\n\nconst SelectValue = SelectPrimitive.Value\n\nconst SelectTrigger = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Trigger>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>\n>(({ className, children, ...props }, ref) => (\n <SelectPrimitive.Trigger\n ref={ref}\n className={cn(\n \"flex h-10 w-full items-center justify-between rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50\",\n className\n )}\n {...props}\n >\n {children}\n <SelectPrimitive.Icon asChild>\n <ChevronDown className=\"h-4 w-4 opacity-50\" />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n))\nSelectTrigger.displayName = SelectPrimitive.Trigger.displayName\n\nconst SelectContent = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>\n>(({ className, children, position = \"popper\", ...props }, ref) => (\n <SelectPrimitive.Portal>\n <SelectPrimitive.Content\n ref={ref}\n className={cn(\n \"relative z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n position === \"popper\" &&\n \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\",\n className\n )}\n position={position}\n {...props}\n >\n <SelectPrimitive.Viewport\n className={cn(\n \"p-1\",\n position === \"popper\" &&\n \"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]\"\n )}\n >\n {children}\n </SelectPrimitive.Viewport>\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n))\nSelectContent.displayName = SelectPrimitive.Content.displayName\n\nconst SelectLabel = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Label>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.Label\n ref={ref}\n className={cn(\"py-1.5 pl-8 pr-2 text-sm font-semibold\", className)}\n {...props}\n />\n))\nSelectLabel.displayName = SelectPrimitive.Label.displayName\n\nconst SelectItem = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>\n>(({ className, children, ...props }, ref) => (\n <SelectPrimitive.Item\n ref={ref}\n className={cn(\n \"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n className\n )}\n {...props}\n >\n <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <SelectPrimitive.ItemIndicator>\n <Check className=\"h-4 w-4\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n))\nSelectItem.displayName = SelectPrimitive.Item.displayName\n\nconst SelectSeparator = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.Separator\n ref={ref}\n className={cn(\"-mx-1 my-1 h-px bg-muted\", className)}\n {...props}\n />\n))\nSelectSeparator.displayName = SelectPrimitive.Separator.displayName\n\nexport {\n Select,\n SelectGroup,\n SelectValue,\n SelectTrigger,\n SelectContent,\n SelectLabel,\n SelectItem,\n SelectSeparator,\n}\n"
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport * as SelectPrimitive from \"@radix-ui/react-select\"\nimport { Check, ChevronDown } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst Select = SelectPrimitive.Root\n\nconst SelectGroup = SelectPrimitive.Group\n\nconst SelectValue = SelectPrimitive.Value\n\nconst SelectTrigger = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Trigger>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>\n>(({ className, children, ...props }, ref) => (\n <SelectPrimitive.Trigger\n ref={ref}\n className={cn(\n \"flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50\",\n className\n )}\n {...props}\n >\n {children}\n <SelectPrimitive.Icon asChild>\n <ChevronDown className=\"h-4 w-4 opacity-50\" />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n))\nSelectTrigger.displayName = SelectPrimitive.Trigger.displayName\n\nconst SelectContent = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>\n>(({ className, children, position = \"popper\", ...props }, ref) => (\n <SelectPrimitive.Portal>\n <SelectPrimitive.Content\n ref={ref}\n className={cn(\n \"relative z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n position === \"popper\" &&\n \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\",\n className\n )}\n position={position}\n {...props}\n >\n <SelectPrimitive.Viewport\n className={cn(\n \"p-1\",\n position === \"popper\" &&\n \"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]\"\n )}\n >\n {children}\n </SelectPrimitive.Viewport>\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n))\nSelectContent.displayName = SelectPrimitive.Content.displayName\n\nconst SelectLabel = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Label>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.Label\n ref={ref}\n className={cn(\"py-1.5 pl-8 pr-2 text-sm font-semibold\", className)}\n {...props}\n />\n))\nSelectLabel.displayName = SelectPrimitive.Label.displayName\n\nconst SelectItem = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>\n>(({ className, children, ...props }, ref) => (\n <SelectPrimitive.Item\n ref={ref}\n className={cn(\n \"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n className\n )}\n {...props}\n >\n <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <SelectPrimitive.ItemIndicator>\n <Check className=\"h-4 w-4\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n))\nSelectItem.displayName = SelectPrimitive.Item.displayName\n\nconst SelectSeparator = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.Separator\n ref={ref}\n className={cn(\"-mx-1 my-1 h-px bg-muted\", className)}\n {...props}\n />\n))\nSelectSeparator.displayName = SelectPrimitive.Separator.displayName\n\nexport {\n Select,\n SelectGroup,\n SelectValue,\n SelectTrigger,\n SelectContent,\n SelectLabel,\n SelectItem,\n SelectSeparator,\n}\n"
|
||||
}
|
||||
],
|
||||
"type": "components:ui"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"files": [
|
||||
{
|
||||
"name": "textarea.tsx",
|
||||
"content": "import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nexport interface TextareaProps\n extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}\n\nconst Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(\n ({ className, ...props }, ref) => {\n return (\n <textarea\n className={cn(\n \"flex min-h-[80px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50\",\n className\n )}\n ref={ref}\n {...props}\n />\n )\n }\n)\nTextarea.displayName = \"Textarea\"\n\nexport { Textarea }\n"
|
||||
"content": "import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nexport interface TextareaProps\n extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}\n\nconst Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(\n ({ className, ...props }, ref) => {\n return (\n <textarea\n className={cn(\n \"flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50\",\n className\n )}\n ref={ref}\n {...props}\n />\n )\n }\n)\nTextarea.displayName = \"Textarea\"\n\nexport { Textarea }\n"
|
||||
}
|
||||
],
|
||||
"type": "components:ui"
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -3,7 +3,7 @@
|
||||
"files": [
|
||||
{
|
||||
"name": "alert.tsx",
|
||||
"content": "import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst alertVariants = cva(\n \"relative w-full rounded-lg border px-4 py-3 text-sm [&:has(svg)]:pl-11 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground\",\n {\n variants: {\n variant: {\n default: \"bg-background text-foreground\",\n destructive:\n \"border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nconst Alert = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants>\n>(({ className, variant, ...props }, ref) => (\n <div\n ref={ref}\n role=\"alert\"\n className={cn(alertVariants({ variant }), className)}\n {...props}\n />\n))\nAlert.displayName = \"Alert\"\n\nconst AlertTitle = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLHeadingElement>\n>(({ className, ...props }, ref) => (\n <h5\n ref={ref}\n className={cn(\"mb-1 font-medium leading-none tracking-tight\", className)}\n {...props}\n />\n))\nAlertTitle.displayName = \"AlertTitle\"\n\nconst AlertDescription = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\"text-sm [&_p]:leading-relaxed\", className)}\n {...props}\n />\n))\nAlertDescription.displayName = \"AlertDescription\"\n\nexport { Alert, AlertTitle, AlertDescription }\n"
|
||||
"content": "import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst alertVariants = cva(\n \"relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7\",\n {\n variants: {\n variant: {\n default: \"bg-background text-foreground\",\n destructive:\n \"border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nconst Alert = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants>\n>(({ className, variant, ...props }, ref) => (\n <div\n ref={ref}\n role=\"alert\"\n className={cn(alertVariants({ variant }), className)}\n {...props}\n />\n))\nAlert.displayName = \"Alert\"\n\nconst AlertTitle = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLHeadingElement>\n>(({ className, ...props }, ref) => (\n <h5\n ref={ref}\n className={cn(\"mb-1 font-medium leading-none tracking-tight\", className)}\n {...props}\n />\n))\nAlertTitle.displayName = \"AlertTitle\"\n\nconst AlertDescription = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\"text-sm [&_p]:leading-relaxed\", className)}\n {...props}\n />\n))\nAlertDescription.displayName = \"AlertDescription\"\n\nexport { Alert, AlertTitle, AlertDescription }\n"
|
||||
}
|
||||
],
|
||||
"type": "components:ui"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"files": [
|
||||
{
|
||||
"name": "button.tsx",
|
||||
"content": "import * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50\",\n {\n variants: {\n variant: {\n default:\n \"bg-primary text-primary-foreground shadow hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90\",\n outline:\n \"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground\",\n secondary:\n \"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80\",\n ghost: \"hover:bg-accent hover:text-accent-foreground\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-9 px-4 py-2\",\n sm: \"h-8 rounded-md px-3 text-xs\",\n lg: \"h-10 rounded-md px-8\",\n icon: \"h-9 w-9\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nexport interface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {\n asChild?: boolean\n}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, asChild = false, ...props }, ref) => {\n const Comp = asChild ? Slot : \"button\"\n return (\n <Comp\n className={cn(buttonVariants({ variant, size, className }))}\n ref={ref}\n {...props}\n />\n )\n }\n)\nButton.displayName = \"Button\"\n\nexport { Button, buttonVariants }\n"
|
||||
"content": "import * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50\",\n {\n variants: {\n variant: {\n default:\n \"bg-primary text-primary-foreground shadow hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90\",\n outline:\n \"border border-input bg-transparent shadow-sm hover:bg-accent hover:text-accent-foreground\",\n secondary:\n \"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80\",\n ghost: \"hover:bg-accent hover:text-accent-foreground\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-9 px-4 py-2\",\n sm: \"h-8 rounded-md px-3 text-xs\",\n lg: \"h-10 rounded-md px-8\",\n icon: \"h-9 w-9\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nexport interface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {\n asChild?: boolean\n}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, asChild = false, ...props }, ref) => {\n const Comp = asChild ? Slot : \"button\"\n return (\n <Comp\n className={cn(buttonVariants({ variant, size, className }))}\n ref={ref}\n {...props}\n />\n )\n }\n)\nButton.displayName = \"Button\"\n\nexport { Button, buttonVariants }\n"
|
||||
}
|
||||
],
|
||||
"type": "components:ui"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"files": [
|
||||
{
|
||||
"name": "calendar.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { ChevronLeftIcon, ChevronRightIcon } from \"@radix-ui/react-icons\"\nimport { DayPicker } from \"react-day-picker\"\n\nimport { cn } from \"@/lib/utils\"\nimport { buttonVariants } from \"@/registry/default/ui/button\"\n\nexport type CalendarProps = React.ComponentProps<typeof DayPicker>\n\nfunction Calendar({\n className,\n classNames,\n showOutsideDays = true,\n ...props\n}: CalendarProps) {\n return (\n <DayPicker\n showOutsideDays={showOutsideDays}\n className={cn(\"p-3\", className)}\n classNames={{\n months: \"flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0\",\n month: \"space-y-4\",\n caption: \"flex justify-center pt-1 relative items-center\",\n caption_label: \"text-sm font-medium\",\n nav: \"space-x-1 flex items-center\",\n nav_button: cn(\n buttonVariants({ variant: \"outline\" }),\n \"h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100\"\n ),\n nav_button_previous: \"absolute left-1\",\n nav_button_next: \"absolute right-1\",\n table: \"w-full border-collapse space-y-1\",\n head_row: \"flex\",\n head_cell:\n \"text-muted-foreground rounded-md w-8 font-normal text-[0.8rem]\",\n row: \"flex w-full mt-2\",\n cell: \"text-center text-sm p-0 relative [&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md focus-within:relative focus-within:z-20\",\n day: cn(\n buttonVariants({ variant: \"ghost\" }),\n \"h-8 w-8 p-0 font-normal aria-selected:opacity-100\"\n ),\n day_selected:\n \"bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground\",\n day_today: \"bg-accent text-accent-foreground\",\n day_outside: \"text-muted-foreground opacity-50\",\n day_disabled: \"text-muted-foreground opacity-50\",\n day_range_middle:\n \"aria-selected:bg-accent aria-selected:text-accent-foreground\",\n day_hidden: \"invisible\",\n ...classNames,\n }}\n components={{\n IconLeft: ({ ...props }) => <ChevronLeftIcon className=\"h-4 w-4\" />,\n IconRight: ({ ...props }) => <ChevronRightIcon className=\"h-4 w-4\" />,\n }}\n {...props}\n />\n )\n}\nCalendar.displayName = \"Calendar\"\n\nexport { Calendar }\n"
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { ChevronLeftIcon, ChevronRightIcon } from \"@radix-ui/react-icons\"\nimport { DayPicker } from \"react-day-picker\"\n\nimport { cn } from \"@/lib/utils\"\nimport { buttonVariants } from \"@/registry/default/ui/button\"\n\nexport type CalendarProps = React.ComponentProps<typeof DayPicker>\n\nfunction Calendar({\n className,\n classNames,\n showOutsideDays = true,\n ...props\n}: CalendarProps) {\n return (\n <DayPicker\n showOutsideDays={showOutsideDays}\n className={cn(\"p-3\", className)}\n classNames={{\n months: \"flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0\",\n month: \"space-y-4\",\n caption: \"flex justify-center pt-1 relative items-center\",\n caption_label: \"text-sm font-medium\",\n nav: \"space-x-1 flex items-center\",\n nav_button: cn(\n buttonVariants({ variant: \"outline\" }),\n \"h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100\"\n ),\n nav_button_previous: \"absolute left-1\",\n nav_button_next: \"absolute right-1\",\n table: \"w-full border-collapse space-y-1\",\n head_row: \"flex\",\n head_cell:\n \"text-muted-foreground rounded-md w-8 font-normal text-[0.8rem]\",\n row: \"flex w-full mt-2\",\n cell: cn(\n \"relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([aria-selected])]:bg-accent\",\n props.mode === \"range\"\n ? \"[&:has(>.day-range-end)]:rounded-r-md [&:has(>.day-range-start)]:rounded-l-md first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md\"\n : \"[&:has([aria-selected])]:rounded-md\"\n ),\n day: cn(\n buttonVariants({ variant: \"ghost\" }),\n \"h-8 w-8 p-0 font-normal aria-selected:opacity-100\"\n ),\n day_range_start: \"day-range-start\",\n day_range_end: \"day-range-end\",\n day_selected:\n \"bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground\",\n day_today: \"bg-accent text-accent-foreground\",\n day_outside: \"text-muted-foreground opacity-50\",\n day_disabled: \"text-muted-foreground opacity-50\",\n day_range_middle:\n \"aria-selected:bg-accent aria-selected:text-accent-foreground\",\n day_hidden: \"invisible\",\n ...classNames,\n }}\n components={{\n IconLeft: ({ ...props }) => <ChevronLeftIcon className=\"h-4 w-4\" />,\n IconRight: ({ ...props }) => <ChevronRightIcon className=\"h-4 w-4\" />,\n }}\n {...props}\n />\n )\n}\nCalendar.displayName = \"Calendar\"\n\nexport { Calendar }\n"
|
||||
}
|
||||
],
|
||||
"type": "components:ui"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"files": [
|
||||
{
|
||||
"name": "card.tsx",
|
||||
"content": "import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst Card = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n \"rounded-xl border bg-card text-card-foreground shadow\",\n className\n )}\n {...props}\n />\n))\nCard.displayName = \"Card\"\n\nconst CardHeader = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\"flex flex-col space-y-1.5 p-6\", className)}\n {...props}\n />\n))\nCardHeader.displayName = \"CardHeader\"\n\nconst CardTitle = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLHeadingElement>\n>(({ className, ...props }, ref) => (\n <h3\n ref={ref}\n className={cn(\"font-semibold leading-none tracking-tight\", className)}\n {...props}\n />\n))\nCardTitle.displayName = \"CardTitle\"\n\nconst CardDescription = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => (\n <p\n ref={ref}\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n))\nCardDescription.displayName = \"CardDescription\"\n\nconst CardContent = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div ref={ref} className={cn(\"p-6 pt-0\", className)} {...props} />\n))\nCardContent.displayName = \"CardContent\"\n\nconst CardFooter = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\" flex items-center p-6 pt-0\", className)}\n {...props}\n />\n))\nCardFooter.displayName = \"CardFooter\"\n\nexport { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }\n"
|
||||
"content": "import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst Card = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n \"rounded-xl border bg-card text-card-foreground shadow\",\n className\n )}\n {...props}\n />\n))\nCard.displayName = \"Card\"\n\nconst CardHeader = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\"flex flex-col space-y-1.5 p-6\", className)}\n {...props}\n />\n))\nCardHeader.displayName = \"CardHeader\"\n\nconst CardTitle = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLHeadingElement>\n>(({ className, ...props }, ref) => (\n <h3\n ref={ref}\n className={cn(\"font-semibold leading-none tracking-tight\", className)}\n {...props}\n />\n))\nCardTitle.displayName = \"CardTitle\"\n\nconst CardDescription = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => (\n <p\n ref={ref}\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n))\nCardDescription.displayName = \"CardDescription\"\n\nconst CardContent = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div ref={ref} className={cn(\"p-6 pt-0\", className)} {...props} />\n))\nCardContent.displayName = \"CardContent\"\n\nconst CardFooter = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\"flex items-center p-6 pt-0\", className)}\n {...props}\n />\n))\nCardFooter.displayName = \"CardFooter\"\n\nexport { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }\n"
|
||||
}
|
||||
],
|
||||
"type": "components:ui"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"files": [
|
||||
{
|
||||
"name": "input.tsx",
|
||||
"content": "import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nexport interface InputProps\n extends React.InputHTMLAttributes<HTMLInputElement> {}\n\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(\n ({ className, type, ...props }, ref) => {\n return (\n <input\n type={type}\n className={cn(\n \"flex h-9 w-full rounded-md border border-input bg-background px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\",\n className\n )}\n ref={ref}\n {...props}\n />\n )\n }\n)\nInput.displayName = \"Input\"\n\nexport { Input }\n"
|
||||
"content": "import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nexport interface InputProps\n extends React.InputHTMLAttributes<HTMLInputElement> {}\n\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(\n ({ className, type, ...props }, ref) => {\n return (\n <input\n type={type}\n className={cn(\n \"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\",\n className\n )}\n ref={ref}\n {...props}\n />\n )\n }\n)\nInput.displayName = \"Input\"\n\nexport { Input }\n"
|
||||
}
|
||||
],
|
||||
"type": "components:ui"
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,68 +1,4 @@
|
||||
|
||||
.theme-default {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 222.2 84% 4.9%;
|
||||
|
||||
--muted: 210 40% 96.1%;
|
||||
--muted-foreground: 215.4 16.3% 46.9%;
|
||||
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 222.2 84% 4.9%;
|
||||
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 222.2 84% 4.9%;
|
||||
|
||||
--border: 214.3 31.8% 91.4%;
|
||||
--input: 214.3 31.8% 91.4%;
|
||||
|
||||
--primary: 160 90% 46%;
|
||||
--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 84.2% 60.2%;
|
||||
--destructive-foreground: 210 40% 98%;
|
||||
|
||||
--ring: 215 20.2% 65.1%;
|
||||
|
||||
--radius: 0.5rem;
|
||||
}
|
||||
|
||||
.dark .theme-default {
|
||||
--background: 222.2 84% 4.9%;
|
||||
--foreground: 210 40% 98%;
|
||||
|
||||
--muted: 217.2 32.6% 17.5%;
|
||||
--muted-foreground: 215 20.2% 65.1%;
|
||||
|
||||
--popover: 222.2 84% 4.9%;
|
||||
--popover-foreground: 210 40% 98%;
|
||||
|
||||
--card: 222.2 84% 4.9%;
|
||||
--card-foreground: 210 40% 98%;
|
||||
|
||||
--border: 217.2 32.6% 17.5%;
|
||||
--input: 217.2 32.6% 17.5%;
|
||||
|
||||
--primary: 210 40% 98%;
|
||||
--primary-foreground: 222.2 47.4% 11.2%;
|
||||
|
||||
--secondary: 217.2 32.6% 17.5%;
|
||||
--secondary-foreground: 210 40% 98%;
|
||||
|
||||
--accent: 217.2 32.6% 17.5%;
|
||||
--accent-foreground: 210 40% 98%;
|
||||
|
||||
--destructive: 0 62.8% 30.6%;
|
||||
--destructive-foreground: 0 85.7% 97.3%;
|
||||
|
||||
--ring: 217.2 32.6% 17.5%;
|
||||
}
|
||||
|
||||
.theme-zinc {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 240 10% 3.9%;
|
||||
@@ -91,7 +27,7 @@
|
||||
--destructive: 0 84.2% 60.2%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
|
||||
--ring: 240 5% 64.9%;
|
||||
--ring: 240 5.9% 10%;
|
||||
|
||||
--radius: 0.5rem;
|
||||
}
|
||||
@@ -122,12 +58,332 @@
|
||||
--accent-foreground: 0 0% 98%;
|
||||
|
||||
--destructive: 0 62.8% 30.6%;
|
||||
--destructive-foreground: 0 85.7% 97.3%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
|
||||
--ring: 240 3.7% 15.9%;
|
||||
--ring: 240 4.9% 83.9%;
|
||||
}
|
||||
|
||||
.theme-lime {
|
||||
.theme-slate {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 222.2 84% 4.9%;
|
||||
|
||||
--muted: 210 40% 96.1%;
|
||||
--muted-foreground: 215.4 16.3% 46.9%;
|
||||
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 222.2 84% 4.9%;
|
||||
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 222.2 84% 4.9%;
|
||||
|
||||
--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 84.2% 60.2%;
|
||||
--destructive-foreground: 210 40% 98%;
|
||||
|
||||
--ring: 222.2 84% 4.9%;
|
||||
|
||||
--radius: 0.5rem;
|
||||
}
|
||||
|
||||
.dark .theme-slate {
|
||||
--background: 222.2 84% 4.9%;
|
||||
--foreground: 210 40% 98%;
|
||||
|
||||
--muted: 217.2 32.6% 17.5%;
|
||||
--muted-foreground: 215 20.2% 65.1%;
|
||||
|
||||
--popover: 222.2 84% 4.9%;
|
||||
--popover-foreground: 210 40% 98%;
|
||||
|
||||
--card: 222.2 84% 4.9%;
|
||||
--card-foreground: 210 40% 98%;
|
||||
|
||||
--border: 217.2 32.6% 17.5%;
|
||||
--input: 217.2 32.6% 17.5%;
|
||||
|
||||
--primary: 210 40% 98%;
|
||||
--primary-foreground: 222.2 47.4% 11.2%;
|
||||
|
||||
--secondary: 217.2 32.6% 17.5%;
|
||||
--secondary-foreground: 210 40% 98%;
|
||||
|
||||
--accent: 217.2 32.6% 17.5%;
|
||||
--accent-foreground: 210 40% 98%;
|
||||
|
||||
--destructive: 0 62.8% 30.6%;
|
||||
--destructive-foreground: 210 40% 98%;
|
||||
|
||||
--ring: 212.7 26.8% 83.9;
|
||||
}
|
||||
|
||||
.theme-stone {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 20 14.3% 4.1%;
|
||||
|
||||
--muted: 60 4.8% 95.9%;
|
||||
--muted-foreground: 25 5.3% 44.7%;
|
||||
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 20 14.3% 4.1%;
|
||||
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 20 14.3% 4.1%;
|
||||
|
||||
--border: 20 5.9% 90%;
|
||||
--input: 20 5.9% 90%;
|
||||
|
||||
--primary: 24 9.8% 10%;
|
||||
--primary-foreground: 60 9.1% 97.8%;
|
||||
|
||||
--secondary: 60 4.8% 95.9%;
|
||||
--secondary-foreground: 24 9.8% 10%;
|
||||
|
||||
--accent: 60 4.8% 95.9%;
|
||||
--accent-foreground: 24 9.8% 10%;
|
||||
|
||||
--destructive: 0 84.2% 60.2%;
|
||||
--destructive-foreground: 60 9.1% 97.8%;
|
||||
|
||||
--ring: 20 14.3% 4.1%;
|
||||
|
||||
--radius: 0.95rem;
|
||||
}
|
||||
|
||||
.dark .theme-stone {
|
||||
--background: 20 14.3% 4.1%;
|
||||
--foreground: 60 9.1% 97.8%;
|
||||
|
||||
--muted: 12 6.5% 15.1%;
|
||||
--muted-foreground: 24 5.4% 63.9%;
|
||||
|
||||
--popover: 20 14.3% 4.1%;
|
||||
--popover-foreground: 60 9.1% 97.8%;
|
||||
|
||||
--card: 20 14.3% 4.1%;
|
||||
--card-foreground: 60 9.1% 97.8%;
|
||||
|
||||
--border: 12 6.5% 15.1%;
|
||||
--input: 12 6.5% 15.1%;
|
||||
|
||||
--primary: 60 9.1% 97.8%;
|
||||
--primary-foreground: 24 9.8% 10%;
|
||||
|
||||
--secondary: 12 6.5% 15.1%;
|
||||
--secondary-foreground: 60 9.1% 97.8%;
|
||||
|
||||
--accent: 12 6.5% 15.1%;
|
||||
--accent-foreground: 60 9.1% 97.8%;
|
||||
|
||||
--destructive: 0 62.8% 30.6%;
|
||||
--destructive-foreground: 60 9.1% 97.8%;
|
||||
|
||||
--ring: 24 5.7% 82.9%;
|
||||
}
|
||||
|
||||
.theme-gray {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 224 71.4% 4.1%;
|
||||
|
||||
--muted: 220 14.3% 95.9%;
|
||||
--muted-foreground: 220 8.9% 46.1%;
|
||||
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 224 71.4% 4.1%;
|
||||
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 224 71.4% 4.1%;
|
||||
|
||||
--border: 220 13% 91%;
|
||||
--input: 220 13% 91%;
|
||||
|
||||
--primary: 220.9 39.3% 11%;
|
||||
--primary-foreground: 210 20% 98%;
|
||||
|
||||
--secondary: 220 14.3% 95.9%;
|
||||
--secondary-foreground: 220.9 39.3% 11%;
|
||||
|
||||
--accent: 220 14.3% 95.9%;
|
||||
--accent-foreground: 220.9 39.3% 11%;
|
||||
|
||||
--destructive: 0 84.2% 60.2%;
|
||||
--destructive-foreground: 210 20% 98%;
|
||||
|
||||
--ring: 224 71.4% 4.1%;
|
||||
|
||||
--radius: 0.35rem;
|
||||
}
|
||||
|
||||
.dark .theme-gray {
|
||||
--background: 224 71.4% 4.1%;
|
||||
--foreground: 210 20% 98%;
|
||||
|
||||
--muted: 215 27.9% 16.9%;
|
||||
--muted-foreground: 217.9 10.6% 64.9%;
|
||||
|
||||
--popover: 224 71.4% 4.1%;
|
||||
--popover-foreground: 210 20% 98%;
|
||||
|
||||
--card: 224 71.4% 4.1%;
|
||||
--card-foreground: 210 20% 98%;
|
||||
|
||||
--border: 215 27.9% 16.9%;
|
||||
--input: 215 27.9% 16.9%;
|
||||
|
||||
--primary: 210 20% 98%;
|
||||
--primary-foreground: 220.9 39.3% 11%;
|
||||
|
||||
--secondary: 215 27.9% 16.9%;
|
||||
--secondary-foreground: 210 20% 98%;
|
||||
|
||||
--accent: 215 27.9% 16.9%;
|
||||
--accent-foreground: 210 20% 98%;
|
||||
|
||||
--destructive: 0 62.8% 30.6%;
|
||||
--destructive-foreground: 210 20% 98%;
|
||||
|
||||
--ring: 216 12.2% 83.9%;
|
||||
}
|
||||
|
||||
.theme-neutral {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 0 0% 3.9%;
|
||||
|
||||
--muted: 0 0% 96.1%;
|
||||
--muted-foreground: 0 0% 45.1%;
|
||||
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 0 0% 3.9%;
|
||||
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 0 0% 3.9%;
|
||||
|
||||
--border: 0 0% 89.8%;
|
||||
--input: 0 0% 89.8%;
|
||||
|
||||
--primary: 0 0% 9%;
|
||||
--primary-foreground: 0 0% 98%;
|
||||
|
||||
--secondary: 0 0% 96.1%;
|
||||
--secondary-foreground: 0 0% 9%;
|
||||
|
||||
--accent: 0 0% 96.1%;
|
||||
--accent-foreground: 0 0% 9%;
|
||||
|
||||
--destructive: 0 84.2% 60.2%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
|
||||
--ring: 0 0% 3.9%;
|
||||
|
||||
--radius: ;
|
||||
}
|
||||
|
||||
.dark .theme-neutral {
|
||||
--background: 0 0% 3.9%;
|
||||
--foreground: 0 0% 98%;
|
||||
|
||||
--muted: 0 0% 14.9%;
|
||||
--muted-foreground: 0 0% 63.9%;
|
||||
|
||||
--popover: 0 0% 3.9%;
|
||||
--popover-foreground: 0 0% 98%;
|
||||
|
||||
--card: 0 0% 3.9%;
|
||||
--card-foreground: 0 0% 98%;
|
||||
|
||||
--border: 0 0% 14.9%;
|
||||
--input: 0 0% 14.9%;
|
||||
|
||||
--primary: 0 0% 98%;
|
||||
--primary-foreground: 0 0% 9%;
|
||||
|
||||
--secondary: 0 0% 14.9%;
|
||||
--secondary-foreground: 0 0% 98%;
|
||||
|
||||
--accent: 0 0% 14.9%;
|
||||
--accent-foreground: 0 0% 98%;
|
||||
|
||||
--destructive: 0 62.8% 30.6%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
|
||||
--ring: 0 0% 83.1%;
|
||||
}
|
||||
|
||||
.theme-red {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 0 0% 3.9%;
|
||||
|
||||
--muted: 0 0% 96.1%;
|
||||
--muted-foreground: 0 0% 45.1%;
|
||||
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 0 0% 3.9%;
|
||||
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 0 0% 3.9%;
|
||||
|
||||
--border: 0 0% 89.8%;
|
||||
--input: 0 0% 89.8%;
|
||||
|
||||
--primary: 0 72.2% 50.6%;
|
||||
--primary-foreground: 0 85.7% 97.3%;
|
||||
|
||||
--secondary: 0 0% 96.1%;
|
||||
--secondary-foreground: 0 0% 9%;
|
||||
|
||||
--accent: 0 0% 96.1%;
|
||||
--accent-foreground: 0 0% 9%;
|
||||
|
||||
--destructive: 0 84.2% 60.2%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
|
||||
--ring: 0 72.2% 50.6%;
|
||||
|
||||
--radius: 0.4rem;
|
||||
}
|
||||
|
||||
.dark .theme-red {
|
||||
--background: 0 0% 3.9%;
|
||||
--foreground: 0 0% 98%;
|
||||
|
||||
--muted: 0 0% 14.9%;
|
||||
--muted-foreground: 0 0% 63.9%;
|
||||
|
||||
--popover: 0 0% 3.9%;
|
||||
--popover-foreground: 0 0% 98%;
|
||||
|
||||
--card: 0 0% 3.9%;
|
||||
--card-foreground: 0 0% 98%;
|
||||
|
||||
--border: 0 0% 14.9%;
|
||||
--input: 0 0% 14.9%;
|
||||
|
||||
--primary: 0 72.2% 50.6%;
|
||||
--primary-foreground: 0 85.7% 97.3%;
|
||||
|
||||
--secondary: 0 0% 14.9%;
|
||||
--secondary-foreground: 0 0% 98%;
|
||||
|
||||
--accent: 0 0% 14.9%;
|
||||
--accent-foreground: 0 0% 98%;
|
||||
|
||||
--destructive: 0 62.8% 30.6%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
|
||||
--ring: 0 72.2% 50.6%;
|
||||
}
|
||||
|
||||
.theme-rose {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 240 10% 3.9%;
|
||||
|
||||
@@ -143,8 +399,8 @@
|
||||
--border: 240 5.9% 90%;
|
||||
--input: 240 5.9% 90%;
|
||||
|
||||
--primary: 87.6 61.2% 20.2%;
|
||||
--primary-foreground: 0 0% 98%;
|
||||
--primary: 346.8 77.2% 49.8%;
|
||||
--primary-foreground: 355.7 100% 97.3%;
|
||||
|
||||
--secondary: 240 4.8% 95.9%;
|
||||
--secondary-foreground: 240 5.9% 10%;
|
||||
@@ -155,38 +411,358 @@
|
||||
--destructive: 0 84.2% 60.2%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
|
||||
--ring: 240 5% 64.9%;
|
||||
--ring: 346.8 77.2% 49.8%;
|
||||
|
||||
--radius: 0.5rem;
|
||||
}
|
||||
|
||||
.dark .theme-lime {
|
||||
--background: 240 10% 3.9%;
|
||||
--foreground: 0 0% 98%;
|
||||
.dark .theme-rose {
|
||||
--background: 20 14.3% 4.1%;
|
||||
--foreground: 0 0% 95%;
|
||||
|
||||
--muted: 240 3.7% 15.9%;
|
||||
--muted: 0 0% 15%;
|
||||
--muted-foreground: 240 5% 64.9%;
|
||||
|
||||
--popover: 240 10% 3.9%;
|
||||
--popover-foreground: 0 0% 98%;
|
||||
--popover: 0 0% 9%;
|
||||
--popover-foreground: 0 0% 95%;
|
||||
|
||||
--card: 240 10% 3.9%;
|
||||
--card-foreground: 0 0% 98%;
|
||||
--card: 24 9.8% 10%;
|
||||
--card-foreground: 0 0% 95%;
|
||||
|
||||
--border: 240 3.7% 15.9%;
|
||||
--input: 240 3.7% 15.9%;
|
||||
|
||||
--primary: 82 84.5% 67.1%;
|
||||
--primary-foreground: 240 5.9% 10%;
|
||||
--primary: 346.8 77.2% 49.8%;
|
||||
--primary-foreground: 355.7 100% 97.3%;
|
||||
|
||||
--secondary: 240 3.7% 15.9%;
|
||||
--secondary-foreground: 0 0% 98%;
|
||||
|
||||
--accent: 240 3.7% 15.9%;
|
||||
--accent: 12 6.5% 15.1%;
|
||||
--accent-foreground: 0 0% 98%;
|
||||
|
||||
--destructive: 0 62.8% 30.6%;
|
||||
--destructive-foreground: 0 85.7% 97.3%;
|
||||
|
||||
--ring: 240 3.7% 15.9%;
|
||||
--ring: 346.8 77.2% 49.8%;
|
||||
}
|
||||
|
||||
.theme-orange {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 20 14.3% 4.1%;
|
||||
|
||||
--muted: 60 4.8% 95.9%;
|
||||
--muted-foreground: 25 5.3% 44.7%;
|
||||
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 20 14.3% 4.1%;
|
||||
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 20 14.3% 4.1%;
|
||||
|
||||
--border: 20 5.9% 90%;
|
||||
--input: 20 5.9% 90%;
|
||||
|
||||
--primary: 24.6 95% 53.1%;
|
||||
--primary-foreground: 60 9.1% 97.8%;
|
||||
|
||||
--secondary: 60 4.8% 95.9%;
|
||||
--secondary-foreground: 24 9.8% 10%;
|
||||
|
||||
--accent: 60 4.8% 95.9%;
|
||||
--accent-foreground: 24 9.8% 10%;
|
||||
|
||||
--destructive: 0 84.2% 60.2%;
|
||||
--destructive-foreground: 60 9.1% 97.8%;
|
||||
|
||||
--ring: 24.6 95% 53.1%;
|
||||
|
||||
--radius: 0.95rem;
|
||||
}
|
||||
|
||||
.dark .theme-orange {
|
||||
--background: 20 14.3% 4.1%;
|
||||
--foreground: 60 9.1% 97.8%;
|
||||
|
||||
--muted: 12 6.5% 15.1%;
|
||||
--muted-foreground: 24 5.4% 63.9%;
|
||||
|
||||
--popover: 20 14.3% 4.1%;
|
||||
--popover-foreground: 60 9.1% 97.8%;
|
||||
|
||||
--card: 20 14.3% 4.1%;
|
||||
--card-foreground: 60 9.1% 97.8%;
|
||||
|
||||
--border: 12 6.5% 15.1%;
|
||||
--input: 12 6.5% 15.1%;
|
||||
|
||||
--primary: 20.5 90.2% 48.2%;
|
||||
--primary-foreground: 60 9.1% 97.8%;
|
||||
|
||||
--secondary: 12 6.5% 15.1%;
|
||||
--secondary-foreground: 60 9.1% 97.8%;
|
||||
|
||||
--accent: 12 6.5% 15.1%;
|
||||
--accent-foreground: 60 9.1% 97.8%;
|
||||
|
||||
--destructive: 0 72.2% 50.6%;
|
||||
--destructive-foreground: 60 9.1% 97.8%;
|
||||
|
||||
--ring: 20.5 90.2% 48.2%;
|
||||
}
|
||||
|
||||
.theme-green {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 240 10% 3.9%;
|
||||
|
||||
--muted: 240 4.8% 95.9%;
|
||||
--muted-foreground: 240 3.8% 46.1%;
|
||||
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 240 10% 3.9%;
|
||||
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 240 10% 3.9%;
|
||||
|
||||
--border: 240 5.9% 90%;
|
||||
--input: 240 5.9% 90%;
|
||||
|
||||
--primary: 142.1 76.2% 36.3%;
|
||||
--primary-foreground: 355.7 100% 97.3%;
|
||||
|
||||
--secondary: 240 4.8% 95.9%;
|
||||
--secondary-foreground: 240 5.9% 10%;
|
||||
|
||||
--accent: 240 4.8% 95.9%;
|
||||
--accent-foreground: 240 5.9% 10%;
|
||||
|
||||
--destructive: 0 84.2% 60.2%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
|
||||
--ring: 142.1 76.2% 36.3%;
|
||||
|
||||
--radius: ;
|
||||
}
|
||||
|
||||
.dark .theme-green {
|
||||
--background: 20 14.3% 4.1%;
|
||||
--foreground: 0 0% 95%;
|
||||
|
||||
--muted: 0 0% 15%;
|
||||
--muted-foreground: 240 5% 64.9%;
|
||||
|
||||
--popover: 0 0% 9%;
|
||||
--popover-foreground: 0 0% 95%;
|
||||
|
||||
--card: 24 9.8% 10%;
|
||||
--card-foreground: 0 0% 95%;
|
||||
|
||||
--border: 240 3.7% 15.9%;
|
||||
--input: 240 3.7% 15.9%;
|
||||
|
||||
--primary: 142.1 70.6% 45.3%;
|
||||
--primary-foreground: 144.9 80.4% 10%;
|
||||
|
||||
--secondary: 240 3.7% 15.9%;
|
||||
--secondary-foreground: 0 0% 98%;
|
||||
|
||||
--accent: 12 6.5% 15.1%;
|
||||
--accent-foreground: 0 0% 98%;
|
||||
|
||||
--destructive: 0 62.8% 30.6%;
|
||||
--destructive-foreground: 0 85.7% 97.3%;
|
||||
|
||||
--ring: 142.4 71.8% 29.2%;
|
||||
}
|
||||
|
||||
.theme-blue {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 222.2 84% 4.9%;
|
||||
|
||||
--muted: 210 40% 96.1%;
|
||||
--muted-foreground: 215.4 16.3% 46.9%;
|
||||
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 222.2 84% 4.9%;
|
||||
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 222.2 84% 4.9%;
|
||||
|
||||
--border: 214.3 31.8% 91.4%;
|
||||
--input: 214.3 31.8% 91.4%;
|
||||
|
||||
--primary: 221.2 83.2% 53.3%;
|
||||
--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 84.2% 60.2%;
|
||||
--destructive-foreground: 210 40% 98%;
|
||||
|
||||
--ring: 221.2 83.2% 53.3%;
|
||||
|
||||
--radius: ;
|
||||
}
|
||||
|
||||
.dark .theme-blue {
|
||||
--background: 222.2 84% 4.9%;
|
||||
--foreground: 210 40% 98%;
|
||||
|
||||
--muted: 217.2 32.6% 17.5%;
|
||||
--muted-foreground: 215 20.2% 65.1%;
|
||||
|
||||
--popover: 222.2 84% 4.9%;
|
||||
--popover-foreground: 210 40% 98%;
|
||||
|
||||
--card: 222.2 84% 4.9%;
|
||||
--card-foreground: 210 40% 98%;
|
||||
|
||||
--border: 217.2 32.6% 17.5%;
|
||||
--input: 217.2 32.6% 17.5%;
|
||||
|
||||
--primary: 217.2 91.2% 59.8%;
|
||||
--primary-foreground: 222.2 47.4% 11.2%;
|
||||
|
||||
--secondary: 217.2 32.6% 17.5%;
|
||||
--secondary-foreground: 210 40% 98%;
|
||||
|
||||
--accent: 217.2 32.6% 17.5%;
|
||||
--accent-foreground: 210 40% 98%;
|
||||
|
||||
--destructive: 0 62.8% 30.6%;
|
||||
--destructive-foreground: 210 40% 98%;
|
||||
|
||||
--ring: 224.3 76.3% 48%;
|
||||
}
|
||||
|
||||
.theme-yellow {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 20 14.3% 4.1%;
|
||||
|
||||
--muted: 60 4.8% 95.9%;
|
||||
--muted-foreground: 25 5.3% 44.7%;
|
||||
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 20 14.3% 4.1%;
|
||||
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 20 14.3% 4.1%;
|
||||
|
||||
--border: 20 5.9% 90%;
|
||||
--input: 20 5.9% 90%;
|
||||
|
||||
--primary: 47.9 95.8% 53.1%;
|
||||
--primary-foreground: 26 83.3% 14.1%;
|
||||
|
||||
--secondary: 60 4.8% 95.9%;
|
||||
--secondary-foreground: 24 9.8% 10%;
|
||||
|
||||
--accent: 60 4.8% 95.9%;
|
||||
--accent-foreground: 24 9.8% 10%;
|
||||
|
||||
--destructive: 0 84.2% 60.2%;
|
||||
--destructive-foreground: 60 9.1% 97.8%;
|
||||
|
||||
--ring: 20 14.3% 4.1%;
|
||||
|
||||
--radius: 0.95rem;
|
||||
}
|
||||
|
||||
.dark .theme-yellow {
|
||||
--background: 20 14.3% 4.1%;
|
||||
--foreground: 60 9.1% 97.8%;
|
||||
|
||||
--muted: 12 6.5% 15.1%;
|
||||
--muted-foreground: 24 5.4% 63.9%;
|
||||
|
||||
--popover: 20 14.3% 4.1%;
|
||||
--popover-foreground: 60 9.1% 97.8%;
|
||||
|
||||
--card: 20 14.3% 4.1%;
|
||||
--card-foreground: 60 9.1% 97.8%;
|
||||
|
||||
--border: 12 6.5% 15.1%;
|
||||
--input: 12 6.5% 15.1%;
|
||||
|
||||
--primary: 47.9 95.8% 53.1%;
|
||||
--primary-foreground: 26 83.3% 14.1%;
|
||||
|
||||
--secondary: 12 6.5% 15.1%;
|
||||
--secondary-foreground: 60 9.1% 97.8%;
|
||||
|
||||
--accent: 12 6.5% 15.1%;
|
||||
--accent-foreground: 60 9.1% 97.8%;
|
||||
|
||||
--destructive: 0 62.8% 30.6%;
|
||||
--destructive-foreground: 60 9.1% 97.8%;
|
||||
|
||||
--ring: 35.5 91.7% 32.9%;
|
||||
}
|
||||
|
||||
.theme-violet {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 224 71.4% 4.1%;
|
||||
|
||||
--muted: 220 14.3% 95.9%;
|
||||
--muted-foreground: 220 8.9% 46.1%;
|
||||
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 224 71.4% 4.1%;
|
||||
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 224 71.4% 4.1%;
|
||||
|
||||
--border: 220 13% 91%;
|
||||
--input: 220 13% 91%;
|
||||
|
||||
--primary: 262.1 83.3% 57.8%;
|
||||
--primary-foreground: 210 20% 98%;
|
||||
|
||||
--secondary: 220 14.3% 95.9%;
|
||||
--secondary-foreground: 220.9 39.3% 11%;
|
||||
|
||||
--accent: 220 14.3% 95.9%;
|
||||
--accent-foreground: 220.9 39.3% 11%;
|
||||
|
||||
--destructive: 0 84.2% 60.2%;
|
||||
--destructive-foreground: 210 20% 98%;
|
||||
|
||||
--ring: 262.1 83.3% 57.8%;
|
||||
|
||||
--radius: ;
|
||||
}
|
||||
|
||||
.dark .theme-violet {
|
||||
--background: 224 71.4% 4.1%;
|
||||
--foreground: 210 20% 98%;
|
||||
|
||||
--muted: 215 27.9% 16.9%;
|
||||
--muted-foreground: 217.9 10.6% 64.9%;
|
||||
|
||||
--popover: 224 71.4% 4.1%;
|
||||
--popover-foreground: 210 20% 98%;
|
||||
|
||||
--card: 224 71.4% 4.1%;
|
||||
--card-foreground: 210 20% 98%;
|
||||
|
||||
--border: 215 27.9% 16.9%;
|
||||
--input: 215 27.9% 16.9%;
|
||||
|
||||
--primary: 263.4 70% 50.4%;
|
||||
--primary-foreground: 210 20% 98%;
|
||||
|
||||
--secondary: 215 27.9% 16.9%;
|
||||
--secondary-foreground: 210 20% 98%;
|
||||
|
||||
--accent: 215 27.9% 16.9%;
|
||||
--accent-foreground: 210 20% 98%;
|
||||
|
||||
--destructive: 0 62.8% 30.6%;
|
||||
--destructive-foreground: 210 20% 98%;
|
||||
|
||||
--ring: 263.4 70% 50.4%;
|
||||
}
|
||||
48
apps/www/public/registry/themes/gray.json
Normal file
48
apps/www/public/registry/themes/gray.json
Normal file
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"name": "gray",
|
||||
"label": "Gray",
|
||||
"cssVars": {
|
||||
"light": {
|
||||
"background": "0 0% 100%",
|
||||
"foreground": "224 71.4% 4.1%",
|
||||
"card": "0 0% 100%",
|
||||
"card-foreground": "224 71.4% 4.1%",
|
||||
"popover": "0 0% 100%",
|
||||
"popover-foreground": "224 71.4% 4.1%",
|
||||
"primary": "220.9 39.3% 11%",
|
||||
"primary-foreground": "210 20% 98%",
|
||||
"secondary": "220 14.3% 95.9%",
|
||||
"secondary-foreground": "220.9 39.3% 11%",
|
||||
"muted": "220 14.3% 95.9%",
|
||||
"muted-foreground": "220 8.9% 46.1%",
|
||||
"accent": "220 14.3% 95.9%",
|
||||
"accent-foreground": "220.9 39.3% 11%",
|
||||
"destructive": "0 84.2% 60.2%",
|
||||
"destructive-foreground": "210 20% 98%",
|
||||
"border": "220 13% 91%",
|
||||
"input": "220 13% 91%",
|
||||
"ring": "224 71.4% 4.1%"
|
||||
},
|
||||
"dark": {
|
||||
"background": "224 71.4% 4.1%",
|
||||
"foreground": "210 20% 98%",
|
||||
"card": "224 71.4% 4.1%",
|
||||
"card-foreground": "210 20% 98%",
|
||||
"popover": "224 71.4% 4.1%",
|
||||
"popover-foreground": "210 20% 98%",
|
||||
"primary": "210 20% 98%",
|
||||
"primary-foreground": "220.9 39.3% 11%",
|
||||
"secondary": "215 27.9% 16.9%",
|
||||
"secondary-foreground": "210 20% 98%",
|
||||
"muted": "215 27.9% 16.9%",
|
||||
"muted-foreground": "217.9 10.6% 64.9%",
|
||||
"accent": "215 27.9% 16.9%",
|
||||
"accent-foreground": "210 20% 98%",
|
||||
"destructive": "0 62.8% 30.6%",
|
||||
"destructive-foreground": "210 20% 98%",
|
||||
"border": "215 27.9% 16.9%",
|
||||
"input": "215 27.9% 16.9%",
|
||||
"ring": "216 12.2% 83.9%"
|
||||
}
|
||||
}
|
||||
}
|
||||
48
apps/www/public/registry/themes/neutral.json
Normal file
48
apps/www/public/registry/themes/neutral.json
Normal file
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"name": "neutral",
|
||||
"label": "Neutral",
|
||||
"cssVars": {
|
||||
"light": {
|
||||
"background": "0 0% 100%",
|
||||
"foreground": "0 0% 3.9%",
|
||||
"card": "0 0% 100%",
|
||||
"card-foreground": "0 0% 3.9%",
|
||||
"popover": "0 0% 100%",
|
||||
"popover-foreground": "0 0% 3.9%",
|
||||
"primary": "0 0% 9%",
|
||||
"primary-foreground": "0 0% 98%",
|
||||
"secondary": "0 0% 96.1%",
|
||||
"secondary-foreground": "0 0% 9%",
|
||||
"muted": "0 0% 96.1%",
|
||||
"muted-foreground": "0 0% 45.1%",
|
||||
"accent": "0 0% 96.1%",
|
||||
"accent-foreground": "0 0% 9%",
|
||||
"destructive": "0 84.2% 60.2%",
|
||||
"destructive-foreground": "0 0% 98%",
|
||||
"border": "0 0% 89.8%",
|
||||
"input": "0 0% 89.8%",
|
||||
"ring": "0 0% 3.9%"
|
||||
},
|
||||
"dark": {
|
||||
"background": "0 0% 3.9%",
|
||||
"foreground": "0 0% 98%",
|
||||
"card": "0 0% 3.9%",
|
||||
"card-foreground": "0 0% 98%",
|
||||
"popover": "0 0% 3.9%",
|
||||
"popover-foreground": "0 0% 98%",
|
||||
"primary": "0 0% 98%",
|
||||
"primary-foreground": "0 0% 9%",
|
||||
"secondary": "0 0% 14.9%",
|
||||
"secondary-foreground": "0 0% 98%",
|
||||
"muted": "0 0% 14.9%",
|
||||
"muted-foreground": "0 0% 63.9%",
|
||||
"accent": "0 0% 14.9%",
|
||||
"accent-foreground": "0 0% 98%",
|
||||
"destructive": "0 62.8% 30.6%",
|
||||
"destructive-foreground": "0 0% 98%",
|
||||
"border": "0 0% 14.9%",
|
||||
"input": "0 0% 14.9%",
|
||||
"ring": "0 0% 83.1%"
|
||||
}
|
||||
}
|
||||
}
|
||||
48
apps/www/public/registry/themes/slate.json
Normal file
48
apps/www/public/registry/themes/slate.json
Normal file
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"name": "slate",
|
||||
"label": "Slate",
|
||||
"cssVars": {
|
||||
"light": {
|
||||
"background": "0 0% 100%",
|
||||
"foreground": "222.2 84% 4.9%",
|
||||
"card": "0 0% 100%",
|
||||
"card-foreground": "222.2 84% 4.9%",
|
||||
"popover": "0 0% 100%",
|
||||
"popover-foreground": "222.2 84% 4.9%",
|
||||
"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%",
|
||||
"muted": "210 40% 96.1%",
|
||||
"muted-foreground": "215.4 16.3% 46.9%",
|
||||
"accent": "210 40% 96.1%",
|
||||
"accent-foreground": "222.2 47.4% 11.2%",
|
||||
"destructive": "0 84.2% 60.2%",
|
||||
"destructive-foreground": "210 40% 98%",
|
||||
"border": "214.3 31.8% 91.4%",
|
||||
"input": "214.3 31.8% 91.4%",
|
||||
"ring": "222.2 84% 4.9%"
|
||||
},
|
||||
"dark": {
|
||||
"background": "222.2 84% 4.9%",
|
||||
"foreground": "210 40% 98%",
|
||||
"card": "222.2 84% 4.9%",
|
||||
"card-foreground": "210 40% 98%",
|
||||
"popover": "222.2 84% 4.9%",
|
||||
"popover-foreground": "210 40% 98%",
|
||||
"primary": "210 40% 98%",
|
||||
"primary-foreground": "222.2 47.4% 11.2%",
|
||||
"secondary": "217.2 32.6% 17.5%",
|
||||
"secondary-foreground": "210 40% 98%",
|
||||
"muted": "217.2 32.6% 17.5%",
|
||||
"muted-foreground": "215 20.2% 65.1%",
|
||||
"accent": "217.2 32.6% 17.5%",
|
||||
"accent-foreground": "210 40% 98%",
|
||||
"destructive": "0 62.8% 30.6%",
|
||||
"destructive-foreground": "210 40% 98%",
|
||||
"border": "217.2 32.6% 17.5%",
|
||||
"input": "217.2 32.6% 17.5%",
|
||||
"ring": "212.7 26.8 83.9%"
|
||||
}
|
||||
}
|
||||
}
|
||||
48
apps/www/public/registry/themes/stone.json
Normal file
48
apps/www/public/registry/themes/stone.json
Normal file
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"name": "stone",
|
||||
"label": "Stone",
|
||||
"cssVars": {
|
||||
"light": {
|
||||
"background": "0 0% 100%",
|
||||
"foreground": "20 14.3% 4.1%",
|
||||
"card": "0 0% 100%",
|
||||
"card-foreground": "20 14.3% 4.1%",
|
||||
"popover": "0 0% 100%",
|
||||
"popover-foreground": "20 14.3% 4.1%",
|
||||
"primary": "24 9.8% 10%",
|
||||
"primary-foreground": "60 9.1% 97.8%",
|
||||
"secondary": "60 4.8% 95.9%",
|
||||
"secondary-foreground": "24 9.8% 10%",
|
||||
"muted": "60 4.8% 95.9%",
|
||||
"muted-foreground": "25 5.3% 44.7%",
|
||||
"accent": "60 4.8% 95.9%",
|
||||
"accent-foreground": "24 9.8% 10%",
|
||||
"destructive": "0 84.2% 60.2%",
|
||||
"destructive-foreground": "60 9.1% 97.8%",
|
||||
"border": "20 5.9% 90%",
|
||||
"input": "20 5.9% 90%",
|
||||
"ring": "20 14.3% 4.1%"
|
||||
},
|
||||
"dark": {
|
||||
"background": "20 14.3% 4.1%",
|
||||
"foreground": "60 9.1% 97.8%",
|
||||
"card": "20 14.3% 4.1%",
|
||||
"card-foreground": "60 9.1% 97.8%",
|
||||
"popover": "20 14.3% 4.1%",
|
||||
"popover-foreground": "60 9.1% 97.8%",
|
||||
"primary": "60 9.1% 97.8%",
|
||||
"primary-foreground": "24 9.8% 10%",
|
||||
"secondary": "12 6.5% 15.1%",
|
||||
"secondary-foreground": "60 9.1% 97.8%",
|
||||
"muted": "12 6.5% 15.1%",
|
||||
"muted-foreground": "24 5.4% 63.9%",
|
||||
"accent": "12 6.5% 15.1%",
|
||||
"accent-foreground": "60 9.1% 97.8%",
|
||||
"destructive": "0 62.8% 30.6%",
|
||||
"destructive-foreground": "60 9.1% 97.8%",
|
||||
"border": "12 6.5% 15.1%",
|
||||
"input": "12 6.5% 15.1%",
|
||||
"ring": "24 5.7% 82.9%"
|
||||
}
|
||||
}
|
||||
}
|
||||
48
apps/www/public/registry/themes/zinc.json
Normal file
48
apps/www/public/registry/themes/zinc.json
Normal file
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"name": "zinc",
|
||||
"label": "Zinc",
|
||||
"cssVars": {
|
||||
"light": {
|
||||
"background": "0 0% 100%",
|
||||
"foreground": "240 10% 3.9%",
|
||||
"card": "0 0% 100%",
|
||||
"card-foreground": "240 10% 3.9%",
|
||||
"popover": "0 0% 100%",
|
||||
"popover-foreground": "240 10% 3.9%",
|
||||
"primary": "240 5.9% 10%",
|
||||
"primary-foreground": "0 0% 98%",
|
||||
"secondary": "240 4.8% 95.9%",
|
||||
"secondary-foreground": "240 5.9% 10%",
|
||||
"muted": "240 4.8% 95.9%",
|
||||
"muted-foreground": "240 3.8% 46.1%",
|
||||
"accent": "240 4.8% 95.9%",
|
||||
"accent-foreground": "240 5.9% 10%",
|
||||
"destructive": "0 84.2% 60.2%",
|
||||
"destructive-foreground": "0 0% 98%",
|
||||
"border": "240 5.9% 90%",
|
||||
"input": "240 5.9% 90%",
|
||||
"ring": "240 10% 3.9%"
|
||||
},
|
||||
"dark": {
|
||||
"background": "240 10% 3.9%",
|
||||
"foreground": "0 0% 98%",
|
||||
"card": "240 10% 3.9%",
|
||||
"card-foreground": "0 0% 98%",
|
||||
"popover": "240 10% 3.9%",
|
||||
"popover-foreground": "0 0% 98%",
|
||||
"primary": "0 0% 98%",
|
||||
"primary-foreground": "240 5.9% 10%",
|
||||
"secondary": "240 3.7% 15.9%",
|
||||
"secondary-foreground": "0 0% 98%",
|
||||
"muted": "240 3.7% 15.9%",
|
||||
"muted-foreground": "240 5% 64.9%",
|
||||
"accent": "240 3.7% 15.9%",
|
||||
"accent-foreground": "0 0% 98%",
|
||||
"destructive": "0 62.8% 30.6%",
|
||||
"destructive-foreground": "0 0% 98%",
|
||||
"border": "240 3.7% 15.9%",
|
||||
"input": "240 3.7% 15.9%",
|
||||
"ring": "240 4.9% 83.9%"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -35,7 +35,7 @@ export const colors = {
|
||||
scale: 300,
|
||||
hex: "#cbd5e1",
|
||||
rgb: "rgb(203,213,225)",
|
||||
hsl: "hsl(212.7,26.8%,83.9)",
|
||||
hsl: "hsl(212.7,26.8%,83.9%)",
|
||||
},
|
||||
{
|
||||
scale: 400,
|
||||
@@ -1514,43 +1514,43 @@ export const colorMapping = {
|
||||
light: {
|
||||
background: "white",
|
||||
foreground: "{{base}}-950",
|
||||
muted: "{{base}}-100",
|
||||
"muted-foreground": "{{base}}-500",
|
||||
popover: "white",
|
||||
"popover-foreground": "{{base}}-950",
|
||||
border: "{{base}}-200",
|
||||
input: "{{base}}-200",
|
||||
card: "white",
|
||||
"card-foreground": "{{base}}-950",
|
||||
popover: "white",
|
||||
"popover-foreground": "{{base}}-950",
|
||||
primary: "{{base}}-900",
|
||||
"primary-foreground": "{{base}}-50",
|
||||
secondary: "{{base}}-100",
|
||||
"secondary-foreground": "{{base}}-900",
|
||||
muted: "{{base}}-100",
|
||||
"muted-foreground": "{{base}}-500",
|
||||
accent: "{{base}}-100",
|
||||
"accent-foreground": "{{base}}-900",
|
||||
destructive: "red-500",
|
||||
"destructive-foreground": "{{base}}-50",
|
||||
ring: "{{base}}-400",
|
||||
border: "{{base}}-200",
|
||||
input: "{{base}}-200",
|
||||
ring: "{{base}}-950",
|
||||
},
|
||||
dark: {
|
||||
background: "{{base}}-950",
|
||||
foreground: "{{base}}-50",
|
||||
muted: "{{base}}-800",
|
||||
"muted-foreground": "{{base}}-400",
|
||||
popover: "{{base}}-950",
|
||||
"popover-foreground": "{{base}}-50",
|
||||
border: "{{base}}-800",
|
||||
input: "{{base}}-800",
|
||||
card: "{{base}}-950",
|
||||
"card-foreground": "{{base}}-50",
|
||||
popover: "{{base}}-950",
|
||||
"popover-foreground": "{{base}}-50",
|
||||
primary: "{{base}}-50",
|
||||
"primary-foreground": "{{base}}-900",
|
||||
secondary: "{{base}}-800",
|
||||
"secondary-foreground": "{{base}}-50",
|
||||
muted: "{{base}}-800",
|
||||
"muted-foreground": "{{base}}-400",
|
||||
accent: "{{base}}-800",
|
||||
"accent-foreground": "{{base}}-50",
|
||||
destructive: "red-900",
|
||||
"destructive-foreground": "red-50",
|
||||
ring: "{{base}}-800",
|
||||
"destructive-foreground": "{{base}}-50",
|
||||
border: "{{base}}-800",
|
||||
input: "{{base}}-800",
|
||||
ring: "{{base}}-300",
|
||||
},
|
||||
} as const
|
||||
|
||||
@@ -34,17 +34,17 @@ export default function CardWithForm() {
|
||||
<Input id="name" placeholder="Name of your project" />
|
||||
</div>
|
||||
<div className="flex flex-col space-y-1.5">
|
||||
<Label htmlFor="name">Framework</Label>
|
||||
<Label htmlFor="framework">Framework</Label>
|
||||
<Select>
|
||||
<SelectTrigger>
|
||||
<SelectTrigger id="framework">
|
||||
<SelectValue placeholder="Select" />
|
||||
<SelectContent position="popper">
|
||||
<SelectItem value="next">Next.js</SelectItem>
|
||||
<SelectItem value="sveltekit">SvelteKit</SelectItem>
|
||||
<SelectItem value="astro">Astro</SelectItem>
|
||||
<SelectItem value="nuxt">Nuxt.js</SelectItem>
|
||||
</SelectContent>
|
||||
</SelectTrigger>
|
||||
<SelectContent position="popper">
|
||||
<SelectItem value="next">Next.js</SelectItem>
|
||||
<SelectItem value="sveltekit">SvelteKit</SelectItem>
|
||||
<SelectItem value="astro">Astro</SelectItem>
|
||||
<SelectItem value="nuxt">Nuxt.js</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
132
apps/www/registry/default/example/cards/activity-goal.tsx
Normal file
132
apps/www/registry/default/example/cards/activity-goal.tsx
Normal file
@@ -0,0 +1,132 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import { Minus, Plus } from "lucide-react"
|
||||
import { useTheme } from "next-themes"
|
||||
import { Bar, BarChart, ResponsiveContainer } from "recharts"
|
||||
|
||||
import { useConfig } from "@/hooks/use-config"
|
||||
import { Button } from "@/registry/default/ui/button"
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/registry/default/ui/card"
|
||||
import { themes } from "@/registry/themes"
|
||||
|
||||
const data = [
|
||||
{
|
||||
goal: 400,
|
||||
},
|
||||
{
|
||||
goal: 300,
|
||||
},
|
||||
{
|
||||
goal: 200,
|
||||
},
|
||||
{
|
||||
goal: 300,
|
||||
},
|
||||
{
|
||||
goal: 200,
|
||||
},
|
||||
{
|
||||
goal: 278,
|
||||
},
|
||||
{
|
||||
goal: 189,
|
||||
},
|
||||
{
|
||||
goal: 239,
|
||||
},
|
||||
{
|
||||
goal: 300,
|
||||
},
|
||||
{
|
||||
goal: 200,
|
||||
},
|
||||
{
|
||||
goal: 278,
|
||||
},
|
||||
{
|
||||
goal: 189,
|
||||
},
|
||||
{
|
||||
goal: 349,
|
||||
},
|
||||
]
|
||||
|
||||
export function CardsActivityGoal() {
|
||||
const { theme: mode } = useTheme()
|
||||
const [config] = useConfig()
|
||||
|
||||
const theme = themes.find((theme) => theme.name === config.theme)
|
||||
const [goal, setGoal] = React.useState(350)
|
||||
|
||||
function onClick(adjustment: number) {
|
||||
setGoal(Math.max(200, Math.min(400, goal + adjustment)))
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader className="pb-4">
|
||||
<CardTitle className="text-base">Move Goal</CardTitle>
|
||||
<CardDescription>Set your daily activity goal.</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="pb-2">
|
||||
<div className="flex items-center justify-center space-x-2">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="icon"
|
||||
className="h-8 w-8 shrink-0 rounded-full"
|
||||
onClick={() => onClick(-10)}
|
||||
disabled={goal <= 200}
|
||||
>
|
||||
<Minus className="h-4 w-4" />
|
||||
<span className="sr-only">Decrease</span>
|
||||
</Button>
|
||||
<div className="flex-1 text-center">
|
||||
<div className="text-5xl font-bold tracking-tighter">{goal}</div>
|
||||
<div className="text-[0.70rem] uppercase text-muted-foreground">
|
||||
Calories/day
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="icon"
|
||||
className="h-8 w-8 shrink-0 rounded-full"
|
||||
onClick={() => onClick(10)}
|
||||
disabled={goal >= 400}
|
||||
>
|
||||
<Plus className="h-4 w-4" />
|
||||
<span className="sr-only">Increase</span>
|
||||
</Button>
|
||||
</div>
|
||||
<div className="my-3 h-[60px]">
|
||||
<ResponsiveContainer width="100%" height="100%">
|
||||
<BarChart data={data}>
|
||||
<Bar
|
||||
dataKey="goal"
|
||||
style={
|
||||
{
|
||||
fill: "var(--theme-primary)",
|
||||
opacity: 0.2,
|
||||
"--theme-primary": `hsl(${
|
||||
theme?.cssVars[mode === "dark" ? "dark" : "light"].primary
|
||||
})`,
|
||||
} as React.CSSProperties
|
||||
}
|
||||
/>
|
||||
</BarChart>
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<Button className="w-full">Set Goal</Button>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
26
apps/www/registry/default/example/cards/calendar.tsx
Normal file
26
apps/www/registry/default/example/cards/calendar.tsx
Normal file
@@ -0,0 +1,26 @@
|
||||
"use client"
|
||||
|
||||
import { addDays } from "date-fns"
|
||||
|
||||
import { Calendar } from "@/registry/default/ui/calendar"
|
||||
import { Card, CardContent } from "@/registry/default/ui/card"
|
||||
|
||||
const start = new Date(2023, 5, 5)
|
||||
|
||||
export function CardsCalendar() {
|
||||
return (
|
||||
<Card className="max-w-[280px]">
|
||||
<CardContent className="p-0">
|
||||
<Calendar
|
||||
numberOfMonths={1}
|
||||
mode="range"
|
||||
defaultMonth={start}
|
||||
selected={{
|
||||
from: start,
|
||||
to: addDays(start, 8),
|
||||
}}
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
260
apps/www/registry/default/example/cards/chat.tsx
Normal file
260
apps/www/registry/default/example/cards/chat.tsx
Normal file
@@ -0,0 +1,260 @@
|
||||
import * as React from "react"
|
||||
import { Check, Plus, Send } from "lucide-react"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
import {
|
||||
Avatar,
|
||||
AvatarFallback,
|
||||
AvatarImage,
|
||||
} from "@/registry/default/ui/avatar"
|
||||
import { Button } from "@/registry/default/ui/button"
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
} from "@/registry/default/ui/card"
|
||||
import {
|
||||
Command,
|
||||
CommandEmpty,
|
||||
CommandGroup,
|
||||
CommandInput,
|
||||
CommandItem,
|
||||
CommandList,
|
||||
} from "@/registry/default/ui/command"
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from "@/registry/default/ui/dialog"
|
||||
import { Input } from "@/registry/default/ui/input"
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipProvider,
|
||||
TooltipTrigger,
|
||||
} from "@/registry/default/ui/tooltip"
|
||||
|
||||
const users = [
|
||||
{
|
||||
name: "Olivia Martin",
|
||||
email: "m@example.com",
|
||||
avatar: "/avatars/01.png",
|
||||
},
|
||||
{
|
||||
name: "Isabella Nguyen",
|
||||
email: "isabella.nguyen@email.com",
|
||||
avatar: "/avatars/03.png",
|
||||
},
|
||||
{
|
||||
name: "Emma Wilson",
|
||||
email: "emma@example.com",
|
||||
avatar: "/avatars/05.png",
|
||||
},
|
||||
{
|
||||
name: "Jackson Lee",
|
||||
email: "lee@example.com",
|
||||
avatar: "/avatars/02.png",
|
||||
},
|
||||
{
|
||||
name: "William Kim",
|
||||
email: "will@email.com",
|
||||
avatar: "/avatars/04.png",
|
||||
},
|
||||
] as const
|
||||
|
||||
type User = (typeof users)[number]
|
||||
|
||||
export function CardsChat() {
|
||||
const [open, setOpen] = React.useState(false)
|
||||
const [selectedUsers, setSelectedUsers] = React.useState<User[]>([])
|
||||
|
||||
const [messages, setMessages] = React.useState([
|
||||
{
|
||||
role: "agent",
|
||||
content: "Hi, how can I help you today?",
|
||||
},
|
||||
{
|
||||
role: "user",
|
||||
content: "Hey, I'm having trouble with my account.",
|
||||
},
|
||||
{
|
||||
role: "agent",
|
||||
content: "What seems to be the problem?",
|
||||
},
|
||||
{
|
||||
role: "user",
|
||||
content: "I can't log in.",
|
||||
},
|
||||
])
|
||||
const [input, setInput] = React.useState("")
|
||||
const inputLength = input.trim().length
|
||||
|
||||
return (
|
||||
<>
|
||||
<Card>
|
||||
<CardHeader className="flex flex-row items-center">
|
||||
<div className="flex items-center space-x-4">
|
||||
<Avatar>
|
||||
<AvatarImage src="/avatars/01.png" alt="Image" />
|
||||
<AvatarFallback>OM</AvatarFallback>
|
||||
</Avatar>
|
||||
<div>
|
||||
<p className="text-sm font-medium leading-none">Sofia Davis</p>
|
||||
<p className="text-sm text-muted-foreground">m@example.com</p>
|
||||
</div>
|
||||
</div>
|
||||
<TooltipProvider delayDuration={0}>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
size="icon"
|
||||
variant="outline"
|
||||
className="ml-auto rounded-full"
|
||||
onClick={() => setOpen(true)}
|
||||
>
|
||||
<Plus className="h-4 w-4" />
|
||||
<span className="sr-only">New message</span>
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent sideOffset={10}>New message</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-4">
|
||||
{messages.map((message, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={cn(
|
||||
"flex w-max max-w-[75%] flex-col gap-2 rounded-lg px-3 py-2 text-sm",
|
||||
message.role === "user"
|
||||
? "ml-auto bg-primary text-primary-foreground"
|
||||
: "bg-muted"
|
||||
)}
|
||||
>
|
||||
{message.content}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<form
|
||||
onSubmit={(event) => {
|
||||
event.preventDefault()
|
||||
if (inputLength === 0) return
|
||||
setMessages([
|
||||
...messages,
|
||||
{
|
||||
role: "user",
|
||||
content: input,
|
||||
},
|
||||
])
|
||||
setInput("")
|
||||
}}
|
||||
className="flex w-full items-center space-x-2"
|
||||
>
|
||||
<Input
|
||||
id="message"
|
||||
placeholder="Type your message..."
|
||||
className="flex-1"
|
||||
autoComplete="off"
|
||||
value={input}
|
||||
onChange={(event) => setInput(event.target.value)}
|
||||
/>
|
||||
<Button type="submit" size="icon" disabled={inputLength === 0}>
|
||||
<Send className="h-4 w-4" />
|
||||
<span className="sr-only">Send</span>
|
||||
</Button>
|
||||
</form>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
<Dialog open={open} onOpenChange={setOpen}>
|
||||
<DialogContent className="gap-0 p-0 outline-none">
|
||||
<DialogHeader className="px-4 pb-4 pt-5">
|
||||
<DialogTitle>New message</DialogTitle>
|
||||
<DialogDescription>
|
||||
Invite a user to this thread. This will create a new group
|
||||
message.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<Command className="overflow-hidden rounded-t-none border-t">
|
||||
<CommandInput placeholder="Search user..." />
|
||||
<CommandList>
|
||||
<CommandEmpty>No users found.</CommandEmpty>
|
||||
<CommandGroup className="p-2">
|
||||
{users.map((user) => (
|
||||
<CommandItem
|
||||
key={user.email}
|
||||
className="flex items-center px-2"
|
||||
onSelect={() => {
|
||||
if (selectedUsers.includes(user)) {
|
||||
return setSelectedUsers(
|
||||
selectedUsers.filter(
|
||||
(selectedUser) => selectedUser !== user
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
return setSelectedUsers(
|
||||
[...users].filter((u) =>
|
||||
[...selectedUsers, user].includes(u)
|
||||
)
|
||||
)
|
||||
}}
|
||||
>
|
||||
<Avatar>
|
||||
<AvatarImage src={user.avatar} alt="Image" />
|
||||
<AvatarFallback>{user.name[0]}</AvatarFallback>
|
||||
</Avatar>
|
||||
<div className="ml-2">
|
||||
<p className="text-sm font-medium leading-none">
|
||||
{user.name}
|
||||
</p>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{user.email}
|
||||
</p>
|
||||
</div>
|
||||
{selectedUsers.includes(user) ? (
|
||||
<Check className="ml-auto flex h-5 w-5 text-primary" />
|
||||
) : null}
|
||||
</CommandItem>
|
||||
))}
|
||||
</CommandGroup>
|
||||
</CommandList>
|
||||
</Command>
|
||||
<DialogFooter className="flex items-center border-t p-4 sm:justify-between">
|
||||
{selectedUsers.length > 0 ? (
|
||||
<div className="flex -space-x-2 overflow-hidden">
|
||||
{selectedUsers.map((user) => (
|
||||
<Avatar
|
||||
key={user.email}
|
||||
className="inline-block border-2 border-background"
|
||||
>
|
||||
<AvatarImage src={user.avatar} />
|
||||
<AvatarFallback>{user.name[0]}</AvatarFallback>
|
||||
</Avatar>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Select users to add to this thread.
|
||||
</p>
|
||||
)}
|
||||
<Button
|
||||
disabled={selectedUsers.length < 2}
|
||||
onClick={() => {
|
||||
setOpen(false)
|
||||
}}
|
||||
>
|
||||
Continue
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</>
|
||||
)
|
||||
}
|
||||
60
apps/www/registry/default/example/cards/cookie-settings.tsx
Normal file
60
apps/www/registry/default/example/cards/cookie-settings.tsx
Normal file
@@ -0,0 +1,60 @@
|
||||
"use client"
|
||||
|
||||
import { Button } from "@/registry/default/ui/button"
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/registry/default/ui/card"
|
||||
import { Label } from "@/registry/default/ui/label"
|
||||
import { Switch } from "@/registry/default/ui/switch"
|
||||
|
||||
export function CardsCookieSettings() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Cookie Settings</CardTitle>
|
||||
<CardDescription>Manage your cookie settings here.</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="grid gap-6">
|
||||
<div className="flex items-center justify-between space-x-4">
|
||||
<Label htmlFor="necessary" className="flex flex-col space-y-1">
|
||||
<span>Strictly Necessary</span>
|
||||
<span className="text-xs font-normal leading-snug text-muted-foreground">
|
||||
These cookies are essential in order to use the website and use
|
||||
its features.
|
||||
</span>
|
||||
</Label>
|
||||
<Switch id="necessary" defaultChecked aria-label="Necessary" />
|
||||
</div>
|
||||
<div className="flex items-center justify-between space-x-4">
|
||||
<Label htmlFor="functional" className="flex flex-col space-y-1">
|
||||
<span>Functional Cookies</span>
|
||||
<span className="text-xs font-normal leading-snug text-muted-foreground">
|
||||
These cookies allow the website to provide personalized
|
||||
functionality.
|
||||
</span>
|
||||
</Label>
|
||||
<Switch id="functional" aria-label="Functional" />
|
||||
</div>
|
||||
<div className="flex items-center justify-between space-x-4">
|
||||
<Label htmlFor="performance" className="flex flex-col space-y-1">
|
||||
<span>Performance Cookies</span>
|
||||
<span className="text-xs font-normal leading-snug text-muted-foreground">
|
||||
These cookies help to improve the performance of the website.
|
||||
</span>
|
||||
</Label>
|
||||
<Switch id="performance" aria-label="Performance" />
|
||||
</div>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<Button variant="outline" className="w-full">
|
||||
Save preferences
|
||||
</Button>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
60
apps/www/registry/default/example/cards/create-account.tsx
Normal file
60
apps/www/registry/default/example/cards/create-account.tsx
Normal file
@@ -0,0 +1,60 @@
|
||||
"use client"
|
||||
|
||||
import { Icons } from "@/components/icons"
|
||||
import { Button } from "@/registry/default/ui/button"
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/registry/default/ui/card"
|
||||
import { Input } from "@/registry/default/ui/input"
|
||||
import { Label } from "@/registry/default/ui/label"
|
||||
|
||||
export function CardsCreateAccount() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader className="space-y-1">
|
||||
<CardTitle className="text-2xl">Create an account</CardTitle>
|
||||
<CardDescription>
|
||||
Enter your email below to create your account
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="grid gap-4">
|
||||
<div className="grid grid-cols-2 gap-6">
|
||||
<Button variant="outline">
|
||||
<Icons.gitHub className="mr-2 h-4 w-4" />
|
||||
Github
|
||||
</Button>
|
||||
<Button variant="outline">
|
||||
<Icons.google className="mr-2 h-4 w-4" />
|
||||
Google
|
||||
</Button>
|
||||
</div>
|
||||
<div className="relative">
|
||||
<div className="absolute inset-0 flex items-center">
|
||||
<span className="w-full border-t" />
|
||||
</div>
|
||||
<div className="relative flex justify-center text-xs uppercase">
|
||||
<span className="bg-background px-2 text-muted-foreground">
|
||||
Or continue with
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid gap-2">
|
||||
<Label htmlFor="email">Email</Label>
|
||||
<Input id="email" type="email" placeholder="m@example.com" />
|
||||
</div>
|
||||
<div className="grid gap-2">
|
||||
<Label htmlFor="password">Password</Label>
|
||||
<Input id="password" type="password" />
|
||||
</div>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<Button className="w-full">Create account</Button>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
332
apps/www/registry/default/example/cards/data-table.tsx
Normal file
332
apps/www/registry/default/example/cards/data-table.tsx
Normal file
@@ -0,0 +1,332 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import {
|
||||
CaretSortIcon,
|
||||
ChevronDownIcon,
|
||||
DotsHorizontalIcon,
|
||||
} from "@radix-ui/react-icons"
|
||||
import {
|
||||
ColumnDef,
|
||||
ColumnFiltersState,
|
||||
SortingState,
|
||||
VisibilityState,
|
||||
flexRender,
|
||||
getCoreRowModel,
|
||||
getFilteredRowModel,
|
||||
getPaginationRowModel,
|
||||
getSortedRowModel,
|
||||
useReactTable,
|
||||
} from "@tanstack/react-table"
|
||||
|
||||
import { Button } from "@/registry/default/ui/button"
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/registry/default/ui/card"
|
||||
import { Checkbox } from "@/registry/default/ui/checkbox"
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuCheckboxItem,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuLabel,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/registry/default/ui/dropdown-menu"
|
||||
import { Input } from "@/registry/default/ui/input"
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "@/registry/default/ui/table"
|
||||
|
||||
const data: Payment[] = [
|
||||
{
|
||||
id: "m5gr84i9",
|
||||
amount: 316,
|
||||
status: "success",
|
||||
email: "ken99@yahoo.com",
|
||||
},
|
||||
{
|
||||
id: "3u1reuv4",
|
||||
amount: 242,
|
||||
status: "success",
|
||||
email: "Abe45@gmail.com",
|
||||
},
|
||||
{
|
||||
id: "derv1ws0",
|
||||
amount: 837,
|
||||
status: "processing",
|
||||
email: "Monserrat44@gmail.com",
|
||||
},
|
||||
{
|
||||
id: "5kma53ae",
|
||||
amount: 874,
|
||||
status: "success",
|
||||
email: "Silas22@gmail.com",
|
||||
},
|
||||
{
|
||||
id: "bhqecj4p",
|
||||
amount: 721,
|
||||
status: "failed",
|
||||
email: "carmella@hotmail.com",
|
||||
},
|
||||
]
|
||||
|
||||
export type Payment = {
|
||||
id: string
|
||||
amount: number
|
||||
status: "pending" | "processing" | "success" | "failed"
|
||||
email: string
|
||||
}
|
||||
|
||||
export const columns: ColumnDef<Payment>[] = [
|
||||
{
|
||||
id: "select",
|
||||
header: ({ table }) => (
|
||||
<Checkbox
|
||||
checked={table.getIsAllPageRowsSelected()}
|
||||
onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
|
||||
aria-label="Select all"
|
||||
/>
|
||||
),
|
||||
cell: ({ row }) => (
|
||||
<Checkbox
|
||||
checked={row.getIsSelected()}
|
||||
onCheckedChange={(value) => row.toggleSelected(!!value)}
|
||||
aria-label="Select row"
|
||||
/>
|
||||
),
|
||||
enableSorting: false,
|
||||
enableHiding: false,
|
||||
},
|
||||
{
|
||||
accessorKey: "status",
|
||||
header: "Status",
|
||||
cell: ({ row }) => (
|
||||
<div className="capitalize">{row.getValue("status")}</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: "email",
|
||||
header: ({ column }) => {
|
||||
return (
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
|
||||
>
|
||||
Email
|
||||
<CaretSortIcon className="ml-2 h-4 w-4" />
|
||||
</Button>
|
||||
)
|
||||
},
|
||||
cell: ({ row }) => <div className="lowercase">{row.getValue("email")}</div>,
|
||||
},
|
||||
{
|
||||
accessorKey: "amount",
|
||||
header: () => <div className="text-right">Amount</div>,
|
||||
cell: ({ row }) => {
|
||||
const amount = parseFloat(row.getValue("amount"))
|
||||
|
||||
// Format the amount as a dollar amount
|
||||
const formatted = new Intl.NumberFormat("en-US", {
|
||||
style: "currency",
|
||||
currency: "USD",
|
||||
}).format(amount)
|
||||
|
||||
return <div className="text-right font-medium">{formatted}</div>
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "actions",
|
||||
enableHiding: false,
|
||||
cell: ({ row }) => {
|
||||
const payment = row.original
|
||||
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="ghost" className="h-8 w-8 p-0">
|
||||
<span className="sr-only">Open menu</span>
|
||||
<DotsHorizontalIcon className="h-4 w-4" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
<DropdownMenuLabel>Actions</DropdownMenuLabel>
|
||||
<DropdownMenuItem
|
||||
onClick={() => navigator.clipboard.writeText(payment.id)}
|
||||
>
|
||||
Copy payment ID
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem>View customer</DropdownMenuItem>
|
||||
<DropdownMenuItem>View payment details</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
)
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
export function CardsDataTable() {
|
||||
const [sorting, setSorting] = React.useState<SortingState>([])
|
||||
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
|
||||
[]
|
||||
)
|
||||
const [columnVisibility, setColumnVisibility] =
|
||||
React.useState<VisibilityState>({})
|
||||
const [rowSelection, setRowSelection] = React.useState({})
|
||||
|
||||
const table = useReactTable({
|
||||
data,
|
||||
columns,
|
||||
onSortingChange: setSorting,
|
||||
onColumnFiltersChange: setColumnFilters,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
getPaginationRowModel: getPaginationRowModel(),
|
||||
getSortedRowModel: getSortedRowModel(),
|
||||
getFilteredRowModel: getFilteredRowModel(),
|
||||
onColumnVisibilityChange: setColumnVisibility,
|
||||
onRowSelectionChange: setRowSelection,
|
||||
state: {
|
||||
sorting,
|
||||
columnFilters,
|
||||
columnVisibility,
|
||||
rowSelection,
|
||||
},
|
||||
})
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Payments</CardTitle>
|
||||
<CardDescription>Manage your payments.</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="mb-4 flex items-center gap-4">
|
||||
<Input
|
||||
placeholder="Filter emails..."
|
||||
value={(table.getColumn("email")?.getFilterValue() as string) ?? ""}
|
||||
onChange={(event) =>
|
||||
table.getColumn("email")?.setFilterValue(event.target.value)
|
||||
}
|
||||
className="max-w-sm"
|
||||
/>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="outline" className="ml-auto">
|
||||
Columns <ChevronDownIcon className="ml-2 h-4 w-4" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
{table
|
||||
.getAllColumns()
|
||||
.filter((column) => column.getCanHide())
|
||||
.map((column) => {
|
||||
return (
|
||||
<DropdownMenuCheckboxItem
|
||||
key={column.id}
|
||||
className="capitalize"
|
||||
checked={column.getIsVisible()}
|
||||
onCheckedChange={(value) =>
|
||||
column.toggleVisibility(!!value)
|
||||
}
|
||||
>
|
||||
{column.id}
|
||||
</DropdownMenuCheckboxItem>
|
||||
)
|
||||
})}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
<div className="rounded-md border">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
{table.getHeaderGroups().map((headerGroup) => (
|
||||
<TableRow key={headerGroup.id}>
|
||||
{headerGroup.headers.map((header) => {
|
||||
return (
|
||||
<TableHead
|
||||
key={header.id}
|
||||
className="[&:has([role=checkbox])]:pl-3"
|
||||
>
|
||||
{header.isPlaceholder
|
||||
? null
|
||||
: flexRender(
|
||||
header.column.columnDef.header,
|
||||
header.getContext()
|
||||
)}
|
||||
</TableHead>
|
||||
)
|
||||
})}
|
||||
</TableRow>
|
||||
))}
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{table.getRowModel().rows?.length ? (
|
||||
table.getRowModel().rows.map((row) => (
|
||||
<TableRow
|
||||
key={row.id}
|
||||
data-state={row.getIsSelected() && "selected"}
|
||||
>
|
||||
{row.getVisibleCells().map((cell) => (
|
||||
<TableCell
|
||||
key={cell.id}
|
||||
className="[&:has([role=checkbox])]:pl-3"
|
||||
>
|
||||
{flexRender(
|
||||
cell.column.columnDef.cell,
|
||||
cell.getContext()
|
||||
)}
|
||||
</TableCell>
|
||||
))}
|
||||
</TableRow>
|
||||
))
|
||||
) : (
|
||||
<TableRow>
|
||||
<TableCell
|
||||
colSpan={columns.length}
|
||||
className="h-24 text-center"
|
||||
>
|
||||
No results.
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
<div className="flex items-center justify-end space-x-2 pt-4">
|
||||
<div className="flex-1 text-sm text-muted-foreground">
|
||||
{table.getFilteredSelectedRowModel().rows.length} of{" "}
|
||||
{table.getFilteredRowModel().rows.length} row(s) selected.
|
||||
</div>
|
||||
<div className="space-x-2">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => table.previousPage()}
|
||||
disabled={!table.getCanPreviousPage()}
|
||||
>
|
||||
Previous
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => table.nextPage()}
|
||||
disabled={!table.getCanNextPage()}
|
||||
>
|
||||
Next
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
63
apps/www/registry/default/example/cards/index.tsx
Normal file
63
apps/www/registry/default/example/cards/index.tsx
Normal file
@@ -0,0 +1,63 @@
|
||||
import { CardsActivityGoal } from "@/registry/default/example/cards/activity-goal"
|
||||
import { CardsCalendar } from "@/registry/default/example/cards/calendar"
|
||||
import { CardsChat } from "@/registry/default/example/cards/chat"
|
||||
import { CardsCookieSettings } from "@/registry/default/example/cards/cookie-settings"
|
||||
import { CardsCreateAccount } from "@/registry/default/example/cards/create-account"
|
||||
import { CardsDataTable } from "@/registry/default/example/cards/data-table"
|
||||
import { CardsMetric } from "@/registry/default/example/cards/metric"
|
||||
import { CardsPaymentMethod } from "@/registry/default/example/cards/payment-method"
|
||||
import { CardsReportIssue } from "@/registry/default/example/cards/report-issue"
|
||||
import { CardsShare } from "@/registry/default/example/cards/share"
|
||||
import { CardsStats } from "@/registry/default/example/cards/stats"
|
||||
import { CardsTeamMembers } from "@/registry/default/example/cards/team-members"
|
||||
|
||||
export default function CardsDemo() {
|
||||
return (
|
||||
<div className="md:grids-col-2 grid md:gap-4 lg:grid-cols-10 xl:grid-cols-11 xl:gap-4">
|
||||
<div className="space-y-4 lg:col-span-4 xl:col-span-6 xl:space-y-4">
|
||||
<CardsStats />
|
||||
<div className="grid gap-1 sm:grid-cols-[280px_1fr] md:hidden">
|
||||
<CardsCalendar />
|
||||
<div className="pt-3 sm:pl-2 sm:pt-0 xl:pl-4">
|
||||
<CardsActivityGoal />
|
||||
</div>
|
||||
<div className="pt-3 sm:col-span-2 xl:pt-4">
|
||||
<CardsMetric />
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-1 xl:grid-cols-2">
|
||||
<div className="space-y-4 xl:space-y-4">
|
||||
<CardsTeamMembers />
|
||||
<CardsCookieSettings />
|
||||
<CardsPaymentMethod />
|
||||
</div>
|
||||
<div className="space-y-4 xl:space-y-4">
|
||||
<CardsChat />
|
||||
<CardsCreateAccount />
|
||||
<div className="hidden xl:block">
|
||||
<CardsReportIssue />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-4 lg:col-span-6 xl:col-span-5 xl:space-y-4">
|
||||
<div className="hidden gap-1 sm:grid-cols-[280px_1fr] md:grid">
|
||||
<CardsCalendar />
|
||||
<div className="pt-3 sm:pl-2 sm:pt-0 xl:pl-3">
|
||||
<CardsActivityGoal />
|
||||
</div>
|
||||
<div className="pt-3 sm:col-span-2 xl:pt-3">
|
||||
<CardsMetric />
|
||||
</div>
|
||||
</div>
|
||||
<div className="hidden md:block">
|
||||
<CardsDataTable />
|
||||
</div>
|
||||
<CardsShare />
|
||||
<div className="xl:hidden">
|
||||
<CardsReportIssue />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
142
apps/www/registry/default/example/cards/metric.tsx
Normal file
142
apps/www/registry/default/example/cards/metric.tsx
Normal file
@@ -0,0 +1,142 @@
|
||||
import { useTheme } from "next-themes"
|
||||
import { Line, LineChart, ResponsiveContainer, Tooltip } from "recharts"
|
||||
|
||||
import { useConfig } from "@/hooks/use-config"
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/registry/default/ui/card"
|
||||
import { themes } from "@/registry/themes"
|
||||
|
||||
const data = [
|
||||
{
|
||||
average: 400,
|
||||
today: 240,
|
||||
},
|
||||
{
|
||||
average: 300,
|
||||
today: 139,
|
||||
},
|
||||
{
|
||||
average: 200,
|
||||
today: 980,
|
||||
},
|
||||
{
|
||||
average: 278,
|
||||
today: 390,
|
||||
},
|
||||
{
|
||||
average: 189,
|
||||
today: 480,
|
||||
},
|
||||
{
|
||||
average: 239,
|
||||
today: 380,
|
||||
},
|
||||
{
|
||||
average: 349,
|
||||
today: 430,
|
||||
},
|
||||
]
|
||||
|
||||
export function CardsMetric() {
|
||||
const { theme: mode } = useTheme()
|
||||
const [config] = useConfig()
|
||||
|
||||
const theme = themes.find((theme) => theme.name === config.theme)
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Exercise Minutes</CardTitle>
|
||||
<CardDescription>
|
||||
Your excercise minutes are ahead of where you normally are.
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="pb-4">
|
||||
<div className="h-[200px]">
|
||||
<ResponsiveContainer width="100%" height="100%">
|
||||
<LineChart
|
||||
data={data}
|
||||
margin={{
|
||||
top: 5,
|
||||
right: 10,
|
||||
left: 10,
|
||||
bottom: 0,
|
||||
}}
|
||||
>
|
||||
<Tooltip
|
||||
content={({ active, payload }) => {
|
||||
if (active && payload && payload.length) {
|
||||
return (
|
||||
<div className="rounded-lg border bg-background p-2 shadow-sm">
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
<div className="flex flex-col">
|
||||
<span className="text-[0.70rem] uppercase text-muted-foreground">
|
||||
Average
|
||||
</span>
|
||||
<span className="font-bold text-muted-foreground">
|
||||
{payload[0].value}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<span className="text-[0.70rem] uppercase text-muted-foreground">
|
||||
Today
|
||||
</span>
|
||||
<span className="font-bold">
|
||||
{payload[1].value}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return null
|
||||
}}
|
||||
/>
|
||||
<Line
|
||||
type="monotone"
|
||||
strokeWidth={2}
|
||||
dataKey="average"
|
||||
activeDot={{
|
||||
r: 6,
|
||||
style: { fill: "var(--theme-primary)", opacity: 0.25 },
|
||||
}}
|
||||
style={
|
||||
{
|
||||
stroke: "var(--theme-primary)",
|
||||
opacity: 0.25,
|
||||
"--theme-primary": `hsl(${
|
||||
theme?.cssVars[mode === "dark" ? "dark" : "light"].primary
|
||||
})`,
|
||||
} as React.CSSProperties
|
||||
}
|
||||
/>
|
||||
<Line
|
||||
type="monotone"
|
||||
dataKey="today"
|
||||
strokeWidth={2}
|
||||
activeDot={{
|
||||
r: 8,
|
||||
style: { fill: "var(--theme-primary)" },
|
||||
}}
|
||||
style={
|
||||
{
|
||||
stroke: "var(--theme-primary)",
|
||||
"--theme-primary": `hsl(${
|
||||
theme?.cssVars[mode === "dark" ? "dark" : "light"].primary
|
||||
})`,
|
||||
} as React.CSSProperties
|
||||
}
|
||||
/>
|
||||
</LineChart>
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
156
apps/www/registry/default/example/cards/payment-method.tsx
Normal file
156
apps/www/registry/default/example/cards/payment-method.tsx
Normal file
@@ -0,0 +1,156 @@
|
||||
"use client"
|
||||
|
||||
import { Icons } from "@/components/icons"
|
||||
import { Button } from "@/registry/default/ui/button"
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/registry/default/ui/card"
|
||||
import { Input } from "@/registry/default/ui/input"
|
||||
import { Label } from "@/registry/default/ui/label"
|
||||
import { RadioGroup, RadioGroupItem } from "@/registry/default/ui/radio-group"
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/registry/default/ui/select"
|
||||
|
||||
export function CardsPaymentMethod() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Payment Method</CardTitle>
|
||||
<CardDescription>
|
||||
Add a new payment method to your account.
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="grid gap-6">
|
||||
<RadioGroup defaultValue="card" className="grid grid-cols-3 gap-4">
|
||||
<div>
|
||||
<RadioGroupItem
|
||||
value="card"
|
||||
id="card"
|
||||
className="peer sr-only"
|
||||
aria-label="Card"
|
||||
/>
|
||||
<Label
|
||||
htmlFor="card"
|
||||
className="flex flex-col items-center justify-between rounded-md border-2 border-muted bg-transparent p-4 hover:bg-accent hover:text-accent-foreground peer-data-[state=checked]:border-primary [&:has([data-state=checked])]:border-primary"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
className="mb-3 h-6 w-6"
|
||||
>
|
||||
<rect width="20" height="14" x="2" y="5" rx="2" />
|
||||
<path d="M2 10h20" />
|
||||
</svg>
|
||||
Card
|
||||
</Label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<RadioGroupItem
|
||||
value="paypal"
|
||||
id="paypal"
|
||||
className="peer sr-only"
|
||||
aria-label="Paypal"
|
||||
/>
|
||||
<Label
|
||||
htmlFor="paypal"
|
||||
className="flex flex-col items-center justify-between rounded-md border-2 border-muted bg-transparent p-4 hover:bg-accent hover:text-accent-foreground peer-data-[state=checked]:border-primary [&:has([data-state=checked])]:border-primary"
|
||||
>
|
||||
<Icons.paypal className="mb-3 h-6 w-6" />
|
||||
Paypal
|
||||
</Label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<RadioGroupItem
|
||||
value="apple"
|
||||
id="apple"
|
||||
className="peer sr-only"
|
||||
aria-label="Apple"
|
||||
/>
|
||||
<Label
|
||||
htmlFor="apple"
|
||||
className="flex flex-col items-center justify-between rounded-md border-2 border-muted bg-transparent p-4 hover:bg-accent hover:text-accent-foreground peer-data-[state=checked]:border-primary [&:has([data-state=checked])]:border-primary"
|
||||
>
|
||||
<Icons.apple className="mb-3 h-6 w-6" />
|
||||
Apple
|
||||
</Label>
|
||||
</div>
|
||||
</RadioGroup>
|
||||
<div className="grid gap-2">
|
||||
<Label htmlFor="name">Name</Label>
|
||||
<Input id="name" placeholder="First Last" />
|
||||
</div>
|
||||
<div className="grid gap-2">
|
||||
<Label htmlFor="city">City</Label>
|
||||
<Input id="city" placeholder="" />
|
||||
</div>
|
||||
<div className="grid gap-2">
|
||||
<Label htmlFor="number">Card number</Label>
|
||||
<Input id="number" placeholder="" />
|
||||
</div>
|
||||
<div className="grid grid-cols-3 gap-4">
|
||||
<div className="grid gap-2">
|
||||
<Label htmlFor="month">Expires</Label>
|
||||
<Select>
|
||||
<SelectTrigger id="month" aria-label="Month">
|
||||
<SelectValue placeholder="Month" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="1">January</SelectItem>
|
||||
<SelectItem value="2">February</SelectItem>
|
||||
<SelectItem value="3">March</SelectItem>
|
||||
<SelectItem value="4">April</SelectItem>
|
||||
<SelectItem value="5">May</SelectItem>
|
||||
<SelectItem value="6">June</SelectItem>
|
||||
<SelectItem value="7">July</SelectItem>
|
||||
<SelectItem value="8">August</SelectItem>
|
||||
<SelectItem value="9">September</SelectItem>
|
||||
<SelectItem value="10">October</SelectItem>
|
||||
<SelectItem value="11">November</SelectItem>
|
||||
<SelectItem value="12">December</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="grid gap-2">
|
||||
<Label htmlFor="year">Year</Label>
|
||||
<Select>
|
||||
<SelectTrigger id="year" aria-label="Year">
|
||||
<SelectValue placeholder="Year" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{Array.from({ length: 10 }, (_, i) => (
|
||||
<SelectItem key={i} value={`${new Date().getFullYear() + i}`}>
|
||||
{new Date().getFullYear() + i}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="grid gap-2">
|
||||
<Label htmlFor="cvc">CVC</Label>
|
||||
<Input id="cvc" placeholder="CVC" />
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<Button className="w-full">Continue</Button>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
90
apps/www/registry/default/example/cards/report-issue.tsx
Normal file
90
apps/www/registry/default/example/cards/report-issue.tsx
Normal file
@@ -0,0 +1,90 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
|
||||
import { Button } from "@/registry/default/ui/button"
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/registry/default/ui/card"
|
||||
import { Input } from "@/registry/default/ui/input"
|
||||
import { Label } from "@/registry/default/ui/label"
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/registry/default/ui/select"
|
||||
import { Textarea } from "@/registry/default/ui/textarea"
|
||||
|
||||
export function CardsReportIssue() {
|
||||
const id = React.useId()
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Report an issue</CardTitle>
|
||||
<CardDescription>
|
||||
What area are you having problems with?
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="grid gap-6">
|
||||
<div className="grid gap-4 sm:grid-cols-2">
|
||||
<div className="grid gap-2">
|
||||
<Label htmlFor={`area-${id}`}>Area</Label>
|
||||
<Select defaultValue="billing">
|
||||
<SelectTrigger id={`area-${id}`} aria-label="Area">
|
||||
<SelectValue placeholder="Select" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="team">Team</SelectItem>
|
||||
<SelectItem value="billing">Billing</SelectItem>
|
||||
<SelectItem value="account">Account</SelectItem>
|
||||
<SelectItem value="deployments">Deployments</SelectItem>
|
||||
<SelectItem value="support">Support</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="grid gap-2">
|
||||
<Label htmlFor={`security-level-${id}`}>Security Level</Label>
|
||||
<Select defaultValue="2">
|
||||
<SelectTrigger
|
||||
id={`security-level-${id}`}
|
||||
className="line-clamp-1 w-full truncate"
|
||||
aria-label="Security Level"
|
||||
>
|
||||
<SelectValue placeholder="Select level" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="1">Severity 1 (Highest)</SelectItem>
|
||||
<SelectItem value="2">Severity 2</SelectItem>
|
||||
<SelectItem value="3">Severity 3</SelectItem>
|
||||
<SelectItem value="4">Severity 4 (Lowest)</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid gap-2">
|
||||
<Label htmlFor={`subject-${id}`}>Subject</Label>
|
||||
<Input id={`subject-${id}`} placeholder="I need help with..." />
|
||||
</div>
|
||||
<div className="grid gap-2">
|
||||
<Label htmlFor={`description-${id}`}>Description</Label>
|
||||
<Textarea
|
||||
id={`description-${id}`}
|
||||
placeholder="Please include all information relevant to your issue."
|
||||
/>
|
||||
</div>
|
||||
</CardContent>
|
||||
<CardFooter className="justify-between space-x-2">
|
||||
<Button variant="ghost">Cancel</Button>
|
||||
<Button>Submit</Button>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
128
apps/www/registry/default/example/cards/share.tsx
Normal file
128
apps/www/registry/default/example/cards/share.tsx
Normal file
@@ -0,0 +1,128 @@
|
||||
"use client"
|
||||
|
||||
import {
|
||||
Avatar,
|
||||
AvatarFallback,
|
||||
AvatarImage,
|
||||
} from "@/registry/default/ui/avatar"
|
||||
import { Button } from "@/registry/default/ui/button"
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/registry/default/ui/card"
|
||||
import { Input } from "@/registry/default/ui/input"
|
||||
import { Label } from "@/registry/default/ui/label"
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/registry/default/ui/select"
|
||||
import { Separator } from "@/registry/default/ui/separator"
|
||||
|
||||
export function CardsShare() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle>Share this document</CardTitle>
|
||||
<CardDescription>
|
||||
Anyone with the link can view this document.
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="flex space-x-2">
|
||||
<Label htmlFor="link" className="sr-only">
|
||||
Link
|
||||
</Label>
|
||||
<Input
|
||||
id="link"
|
||||
value="http://example.com/link/to/document"
|
||||
readOnly
|
||||
/>
|
||||
<Button variant="secondary" className="shrink-0">
|
||||
Copy Link
|
||||
</Button>
|
||||
</div>
|
||||
<Separator className="my-4" />
|
||||
<div className="space-y-4">
|
||||
<h4 className="text-sm font-medium">People with access</h4>
|
||||
<div className="grid gap-6">
|
||||
<div className="flex items-center justify-between space-x-4">
|
||||
<div className="flex items-center space-x-4">
|
||||
<Avatar>
|
||||
<AvatarImage src="/avatars/03.png" alt="Image" />
|
||||
<AvatarFallback>OM</AvatarFallback>
|
||||
</Avatar>
|
||||
<div>
|
||||
<p className="text-sm font-medium leading-none">
|
||||
Olivia Martin
|
||||
</p>
|
||||
<p className="text-sm text-muted-foreground">m@example.com</p>
|
||||
</div>
|
||||
</div>
|
||||
<Select defaultValue="edit">
|
||||
<SelectTrigger className="ml-auto w-[110px]" aria-label="Edit">
|
||||
<SelectValue placeholder="Select" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="edit">Can edit</SelectItem>
|
||||
<SelectItem value="view">Can view</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="flex items-center justify-between space-x-4">
|
||||
<div className="flex items-center space-x-4">
|
||||
<Avatar>
|
||||
<AvatarImage src="/avatars/05.png" alt="Image" />
|
||||
<AvatarFallback>IN</AvatarFallback>
|
||||
</Avatar>
|
||||
<div>
|
||||
<p className="text-sm font-medium leading-none">
|
||||
Isabella Nguyen
|
||||
</p>
|
||||
<p className="text-sm text-muted-foreground">b@example.com</p>
|
||||
</div>
|
||||
</div>
|
||||
<Select defaultValue="view">
|
||||
<SelectTrigger className="ml-auto w-[110px]" aria-label="Edit">
|
||||
<SelectValue placeholder="Select" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="edit">Can edit</SelectItem>
|
||||
<SelectItem value="view">Can view</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="flex items-center justify-between space-x-4">
|
||||
<div className="flex items-center space-x-4">
|
||||
<Avatar>
|
||||
<AvatarImage src="/avatars/01.png" alt="Image" />
|
||||
<AvatarFallback>SD</AvatarFallback>
|
||||
</Avatar>
|
||||
<div>
|
||||
<p className="text-sm font-medium leading-none">
|
||||
Sofia Davis
|
||||
</p>
|
||||
<p className="text-sm text-muted-foreground">p@example.com</p>
|
||||
</div>
|
||||
</div>
|
||||
<Select defaultValue="view">
|
||||
<SelectTrigger className="ml-auto w-[110px]" aria-label="Edit">
|
||||
<SelectValue placeholder="Select" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="edit">Can edit</SelectItem>
|
||||
<SelectItem value="view">Can view</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
131
apps/www/registry/default/example/cards/stats.tsx
Normal file
131
apps/www/registry/default/example/cards/stats.tsx
Normal file
@@ -0,0 +1,131 @@
|
||||
import { useTheme } from "next-themes"
|
||||
import { Bar, BarChart, Line, LineChart, ResponsiveContainer } from "recharts"
|
||||
|
||||
import { useConfig } from "@/hooks/use-config"
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/registry/default/ui/card"
|
||||
import { themes } from "@/registry/themes"
|
||||
|
||||
const data = [
|
||||
{
|
||||
revenue: 10400,
|
||||
subscription: 240,
|
||||
},
|
||||
{
|
||||
revenue: 14405,
|
||||
subscription: 300,
|
||||
},
|
||||
{
|
||||
revenue: 9400,
|
||||
subscription: 200,
|
||||
},
|
||||
{
|
||||
revenue: 8200,
|
||||
subscription: 278,
|
||||
},
|
||||
{
|
||||
revenue: 7000,
|
||||
subscription: 189,
|
||||
},
|
||||
{
|
||||
revenue: 9600,
|
||||
subscription: 239,
|
||||
},
|
||||
{
|
||||
revenue: 11244,
|
||||
subscription: 278,
|
||||
},
|
||||
{
|
||||
revenue: 26475,
|
||||
subscription: 189,
|
||||
},
|
||||
]
|
||||
|
||||
export function CardsStats() {
|
||||
const { theme: mode } = useTheme()
|
||||
const [config] = useConfig()
|
||||
|
||||
const theme = themes.find((theme) => theme.name === config.theme)
|
||||
|
||||
return (
|
||||
<div className="grid gap-4 sm:grid-cols-2 xl:grid-cols-2">
|
||||
<Card>
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<CardTitle className="text-base font-normal">Total Revenue</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">$15,231.89</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
+20.1% from last month
|
||||
</p>
|
||||
<div className="h-[80px]">
|
||||
<ResponsiveContainer width="100%" height="100%">
|
||||
<LineChart
|
||||
data={data}
|
||||
margin={{
|
||||
top: 5,
|
||||
right: 10,
|
||||
left: 10,
|
||||
bottom: 0,
|
||||
}}
|
||||
>
|
||||
<Line
|
||||
type="monotone"
|
||||
strokeWidth={2}
|
||||
dataKey="revenue"
|
||||
activeDot={{
|
||||
r: 6,
|
||||
style: { fill: "var(--theme-primary)", opacity: 0.25 },
|
||||
}}
|
||||
style={
|
||||
{
|
||||
stroke: "var(--theme-primary)",
|
||||
"--theme-primary": `hsl(${
|
||||
theme?.cssVars[mode === "dark" ? "dark" : "light"]
|
||||
.primary
|
||||
})`,
|
||||
} as React.CSSProperties
|
||||
}
|
||||
/>
|
||||
</LineChart>
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card>
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<CardTitle className="text-base font-normal">Subscriptions</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">+2350</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
+180.1% from last month
|
||||
</p>
|
||||
<div className="mt-4 h-[80px]">
|
||||
<ResponsiveContainer width="100%" height="100%">
|
||||
<BarChart data={data}>
|
||||
<Bar
|
||||
dataKey="subscription"
|
||||
style={
|
||||
{
|
||||
fill: "var(--theme-primary)",
|
||||
opacity: 1,
|
||||
"--theme-primary": `hsl(${
|
||||
theme?.cssVars[mode === "dark" ? "dark" : "light"]
|
||||
.primary
|
||||
})`,
|
||||
} as React.CSSProperties
|
||||
}
|
||||
/>
|
||||
</BarChart>
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
209
apps/www/registry/default/example/cards/team-members.tsx
Normal file
209
apps/www/registry/default/example/cards/team-members.tsx
Normal file
@@ -0,0 +1,209 @@
|
||||
"use client"
|
||||
|
||||
import { ChevronDownIcon } from "@radix-ui/react-icons"
|
||||
|
||||
import {
|
||||
Avatar,
|
||||
AvatarFallback,
|
||||
AvatarImage,
|
||||
} from "@/registry/default/ui/avatar"
|
||||
import { Button } from "@/registry/default/ui/button"
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/registry/default/ui/card"
|
||||
import {
|
||||
Command,
|
||||
CommandEmpty,
|
||||
CommandGroup,
|
||||
CommandInput,
|
||||
CommandItem,
|
||||
CommandList,
|
||||
} from "@/registry/default/ui/command"
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from "@/registry/default/ui/popover"
|
||||
|
||||
export function CardsTeamMembers() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Team Members</CardTitle>
|
||||
<CardDescription>
|
||||
Invite your team members to collaborate.
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="grid gap-6">
|
||||
<div className="flex items-center justify-between space-x-4">
|
||||
<div className="flex items-center space-x-4">
|
||||
<Avatar className="h-8 w-8">
|
||||
<AvatarImage src="/avatars/01.png" alt="Image" />
|
||||
<AvatarFallback>OM</AvatarFallback>
|
||||
</Avatar>
|
||||
<div>
|
||||
<p className="text-sm font-medium leading-none">Sofia Davis</p>
|
||||
<p className="text-sm text-muted-foreground">m@example.com</p>
|
||||
</div>
|
||||
</div>
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<Button variant="outline" size="sm" className="ml-auto">
|
||||
Owner{" "}
|
||||
<ChevronDownIcon className="ml-2 h-4 w-4 text-muted-foreground" />
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="p-0" align="end">
|
||||
<Command>
|
||||
<CommandInput placeholder="Select new role..." />
|
||||
<CommandList>
|
||||
<CommandEmpty>No roles found.</CommandEmpty>
|
||||
<CommandGroup>
|
||||
<CommandItem className="teamaspace-y-1 flex flex-col items-start px-4 py-2">
|
||||
<p>Viewer</p>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Can view and comment.
|
||||
</p>
|
||||
</CommandItem>
|
||||
<CommandItem className="teamaspace-y-1 flex flex-col items-start px-4 py-2">
|
||||
<p>Developer</p>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Can view, comment and edit.
|
||||
</p>
|
||||
</CommandItem>
|
||||
<CommandItem className="teamaspace-y-1 flex flex-col items-start px-4 py-2">
|
||||
<p>Billing</p>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Can view, comment and manage billing.
|
||||
</p>
|
||||
</CommandItem>
|
||||
<CommandItem className="teamaspace-y-1 flex flex-col items-start px-4 py-2">
|
||||
<p>Owner</p>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Admin-level access to all resources.
|
||||
</p>
|
||||
</CommandItem>
|
||||
</CommandGroup>
|
||||
</CommandList>
|
||||
</Command>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</div>
|
||||
<div className="flex items-center justify-between space-x-4">
|
||||
<div className="flex items-center space-x-4">
|
||||
<Avatar className="h-8 w-8">
|
||||
<AvatarImage src="/avatars/02.png" alt="Image" />
|
||||
<AvatarFallback>JL</AvatarFallback>
|
||||
</Avatar>
|
||||
<div>
|
||||
<p className="text-sm font-medium leading-none">Jackson Lee</p>
|
||||
<p className="text-sm text-muted-foreground">p@example.com</p>
|
||||
</div>
|
||||
</div>
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<Button variant="outline" size="sm" className="ml-auto">
|
||||
Member{" "}
|
||||
<ChevronDownIcon className="ml-2 h-4 w-4 text-muted-foreground" />
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="p-0" align="end">
|
||||
<Command>
|
||||
<CommandInput placeholder="Select new role..." />
|
||||
<CommandList>
|
||||
<CommandEmpty>No roles found.</CommandEmpty>
|
||||
<CommandGroup className="p-1.5">
|
||||
<CommandItem className="teamaspace-y-1 flex flex-col items-start px-4 py-2">
|
||||
<p>Viewer</p>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Can view and comment.
|
||||
</p>
|
||||
</CommandItem>
|
||||
<CommandItem className="teamaspace-y-1 flex flex-col items-start px-4 py-2">
|
||||
<p>Developer</p>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Can view, comment and edit.
|
||||
</p>
|
||||
</CommandItem>
|
||||
<CommandItem className="teamaspace-y-1 flex flex-col items-start px-4 py-2">
|
||||
<p>Billing</p>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Can view, comment and manage billing.
|
||||
</p>
|
||||
</CommandItem>
|
||||
<CommandItem className="teamaspace-y-1 flex flex-col items-start px-4 py-2">
|
||||
<p>Owner</p>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Admin-level access to all resources.
|
||||
</p>
|
||||
</CommandItem>
|
||||
</CommandGroup>
|
||||
</CommandList>
|
||||
</Command>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</div>
|
||||
<div className="flex items-center justify-between space-x-4">
|
||||
<div className="flex items-center space-x-4">
|
||||
<Avatar className="h-8 w-8">
|
||||
<AvatarImage src="/avatars/03.png" alt="Image" />
|
||||
<AvatarFallback>IN</AvatarFallback>
|
||||
</Avatar>
|
||||
<div>
|
||||
<p className="text-sm font-medium leading-none">
|
||||
Isabella Nguyen
|
||||
</p>
|
||||
<p className="text-sm text-muted-foreground">i@example.com</p>
|
||||
</div>
|
||||
</div>
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<Button variant="outline" size="sm" className="ml-auto">
|
||||
Member{" "}
|
||||
<ChevronDownIcon className="ml-2 h-4 w-4 text-muted-foreground" />
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="p-0" align="end">
|
||||
<Command>
|
||||
<CommandInput placeholder="Select new role..." />
|
||||
<CommandList>
|
||||
<CommandEmpty>No roles found.</CommandEmpty>
|
||||
<CommandGroup className="p-1.5">
|
||||
<CommandItem className="teamaspace-y-1 flex flex-col items-start px-4 py-2">
|
||||
<p>Viewer</p>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Can view and comment.
|
||||
</p>
|
||||
</CommandItem>
|
||||
<CommandItem className="teamaspace-y-1 flex flex-col items-start px-4 py-2">
|
||||
<p>Developer</p>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Can view, comment and edit.
|
||||
</p>
|
||||
</CommandItem>
|
||||
<CommandItem className="teamaspace-y-1 flex flex-col items-start px-4 py-2">
|
||||
<p>Billing</p>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Can view, comment and manage billing.
|
||||
</p>
|
||||
</CommandItem>
|
||||
<CommandItem className="teamaspace-y-1 flex flex-col items-start px-4 py-2">
|
||||
<p>Owner</p>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Admin-level access to all resources.
|
||||
</p>
|
||||
</CommandItem>
|
||||
</CommandGroup>
|
||||
</CommandList>
|
||||
</Command>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -100,10 +100,10 @@ export default function ComboboxForm() {
|
||||
<CommandGroup>
|
||||
{languages.map((language) => (
|
||||
<CommandItem
|
||||
value={language.value}
|
||||
value={language.label}
|
||||
key={language.value}
|
||||
onSelect={(value) => {
|
||||
form.setValue("language", value)
|
||||
onSelect={() => {
|
||||
form.setValue("language", language.value)
|
||||
}}
|
||||
>
|
||||
<Check
|
||||
|
||||
@@ -26,7 +26,8 @@ export default function CommandDialogDemo() {
|
||||
|
||||
React.useEffect(() => {
|
||||
const down = (e: KeyboardEvent) => {
|
||||
if (e.key === "j" && e.metaKey) {
|
||||
if (e.key === "j" && (e.metaKey || e.ctrlKey)) {
|
||||
e.preventDefault()
|
||||
setOpen((open) => !open)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,13 +29,21 @@ export default function DialogDemo() {
|
||||
<Label htmlFor="name" className="text-right">
|
||||
Name
|
||||
</Label>
|
||||
<Input id="name" value="Pedro Duarte" className="col-span-3" />
|
||||
<Input
|
||||
id="name"
|
||||
defaultValue="Pedro Duarte"
|
||||
className="col-span-3"
|
||||
/>
|
||||
</div>
|
||||
<div className="grid grid-cols-4 items-center gap-4">
|
||||
<Label htmlFor="username" className="text-right">
|
||||
Username
|
||||
</Label>
|
||||
<Input id="username" value="@peduarte" className="col-span-3" />
|
||||
<Input
|
||||
id="username"
|
||||
defaultValue="@peduarte"
|
||||
className="col-span-3"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
|
||||
@@ -13,12 +13,12 @@ export default function ScrollAreaDemo() {
|
||||
<div className="p-4">
|
||||
<h4 className="mb-4 text-sm font-medium leading-none">Tags</h4>
|
||||
{tags.map((tag) => (
|
||||
<React.Fragment>
|
||||
<div className="text-sm" key={tag}>
|
||||
<>
|
||||
<div key={tag} className="text-sm">
|
||||
{tag}
|
||||
</div>
|
||||
<Separator className="my-2" />
|
||||
</React.Fragment>
|
||||
</>
|
||||
))}
|
||||
</div>
|
||||
</ScrollArea>
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
"use client"
|
||||
|
||||
import Link from "next/link"
|
||||
import { zodResolver } from "@hookform/resolvers/zod"
|
||||
import { useForm } from "react-hook-form"
|
||||
import * as z from "zod"
|
||||
|
||||
import { Button } from "@/registry/default/ui/button"
|
||||
import { Checkbox } from "@/registry/default/ui/checkbox"
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
@@ -16,8 +14,6 @@ import {
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from "@/registry/default/ui/form"
|
||||
import { RadioGroup, RadioGroupItem } from "@/registry/default/ui/radio-group"
|
||||
import { Switch } from "@/registry/default/ui/switch"
|
||||
import { Textarea } from "@/registry/default/ui/textarea"
|
||||
import { toast } from "@/registry/default/ui/use-toast"
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import { cva, type VariantProps } from "class-variance-authority"
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
const alertVariants = cva(
|
||||
"relative w-full rounded-lg border p-4 [&:has(svg)]:pl-11 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground",
|
||||
"relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
|
||||
@@ -70,7 +70,7 @@ const CardFooter = React.forwardRef<
|
||||
>(({ className, ...props }, ref) => (
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn(" flex items-center p-6 pt-0", className)}
|
||||
className={cn("flex items-center p-6 pt-0", className)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
|
||||
@@ -19,7 +19,7 @@ const SelectTrigger = React.forwardRef<
|
||||
<SelectPrimitive.Trigger
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"flex h-10 w-full items-center justify-between rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
||||
"flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -10,7 +10,7 @@ const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
|
||||
return (
|
||||
<textarea
|
||||
className={cn(
|
||||
"flex min-h-[80px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
||||
"flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
||||
className
|
||||
)}
|
||||
ref={ref}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user