├── .eslintrc.cjs
├── .gitignore
├── LICENSE
├── README.md
├── components.json
├── index.html
├── jsconfig.json
├── package.json
├── pnpm-lock.yaml
├── postcss.config.js
├── public
├── ligtning.svg
└── vite.svg
├── src
├── App.css
├── App.jsx
├── ArtifactCode.jsx
├── assets
│ └── react.svg
├── components
│ └── ui
│ │ ├── accordion.jsx
│ │ ├── alert-dialog.jsx
│ │ ├── alert.jsx
│ │ ├── aspect-ratio.jsx
│ │ ├── avatar.jsx
│ │ ├── badge.jsx
│ │ ├── breadcrumb.jsx
│ │ ├── button.jsx
│ │ ├── calendar.jsx
│ │ ├── card.jsx
│ │ ├── carousel.jsx
│ │ ├── checkbox.jsx
│ │ ├── collapsible.jsx
│ │ ├── command.jsx
│ │ ├── context-menu.jsx
│ │ ├── dialog.jsx
│ │ ├── drawer.jsx
│ │ ├── dropdown-menu.jsx
│ │ ├── form.jsx
│ │ ├── hover-card.jsx
│ │ ├── input-otp.jsx
│ │ ├── input.jsx
│ │ ├── label.jsx
│ │ ├── menubar.jsx
│ │ ├── navigation-menu.jsx
│ │ ├── pagination.jsx
│ │ ├── popover.jsx
│ │ ├── progress.jsx
│ │ ├── radio-group.jsx
│ │ ├── resizable.jsx
│ │ ├── scroll-area.jsx
│ │ ├── select.jsx
│ │ ├── separator.jsx
│ │ ├── sheet.jsx
│ │ ├── skeleton.jsx
│ │ ├── slider.jsx
│ │ ├── sonner.jsx
│ │ ├── switch.jsx
│ │ ├── table.jsx
│ │ ├── tabs.jsx
│ │ ├── textarea.jsx
│ │ ├── toast.jsx
│ │ ├── toaster.jsx
│ │ ├── toggle-group.jsx
│ │ ├── toggle.jsx
│ │ ├── tooltip.jsx
│ │ └── use-toast.js
├── index.css
├── lib
│ └── utils.js
└── main.jsx
├── tailwind.config.js
└── vite.config.js
/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: { browser: true, es2020: true },
4 | extends: [
5 | "eslint:recommended",
6 | "plugin:react/recommended",
7 | "plugin:react/jsx-runtime",
8 | "plugin:react-hooks/recommended",
9 | ],
10 | ignorePatterns: ["dist", ".eslintrc.cjs"],
11 | parserOptions: { ecmaVersion: "latest", sourceType: "module" },
12 | settings: { react: { version: "18.2" } },
13 | plugins: ["react-refresh"],
14 | rules: {
15 | "react/jsx-no-target-blank": "off",
16 | "react-refresh/only-export-components": [
17 | "warn",
18 | { allowConstantExport: true },
19 | ],
20 | },
21 | };
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Rison Simon
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Claude Artifacts React - Deploy Claude Artifact code easily
2 |
3 | Claude Artifacts React is an open-source tool that simplifies the process of deploying React code snippets to Vercel or Cloudflare Pages. This project allows you to quickly test and share React code generated by Claude Artifacts without the need for complex setup or configuration.
4 |
5 | [](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Frisonsimon%2Fclaude-artifacts-react)
6 | [](https://deploy.workers.cloudflare.com/?url=https://github.com/risonsimon/claude-artifacts-react)
7 |
8 | ## Quick Start
9 |
10 | 1. Click on either the "Deploy with Vercel" or "Deploy to Cloudflare Pages" button above.
11 | 2. This will fork the repository to your account and start the deployment process.
12 | 3. Once deployed, you can edit the `src/ArtifactCode.jsx` file in your forked repository with the React code output from Claude.
13 | 4. Commit your changes, and your deployment will automatically update with the new code.
14 |
15 | ## Features
16 |
17 | - One-click deployment to Vercel or Cloudflare Pages
18 | - Easy editing of React code through `ArtifactCode.jsx`
19 | - Supports React code snippets and components from Claude
20 | - Minimal configuration required
21 | - All dependencies of Claude artifacts are already installed
22 | - Ideal for prototyping, sharing code examples, or quickly testing ideas
23 |
24 | ## Editing Your Code
25 |
26 | After deploying, follow these steps to update your React code:
27 |
28 | 1. Navigate to the `ArtifactCode.jsx` file in your forked repository.
29 | 2. Click on the edit button (pencil icon).
30 | 3. Paste the React code output from Claude into this file.
31 | 4. Commit your changes.
32 | 5. Your deployment will automatically update with the new code.
33 |
34 | ## Manual Setup
35 |
36 | If you prefer to set up the project manually:
37 |
38 | 1. Clone the repository:
39 |
40 | ```
41 | git clone https://github.com/risonsimon/claude-artifacts-react.git
42 | cd claude-artifacts-react
43 | ```
44 |
45 | 2. Install dependencies:
46 |
47 | ```
48 | pnpm install
49 | ```
50 |
51 | 3. Edit the `ArtifactCode.tsx` file with your React code.
52 |
53 | 4. Deploy to your preferred platform.
54 |
55 | ## License
56 |
57 | This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
58 |
59 | ## Support
60 |
61 | If you encounter any issues or have questions, please file an issue on the GitHub repository.
62 |
--------------------------------------------------------------------------------
/components.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://ui.shadcn.com/schema.json",
3 | "style": "default",
4 | "rsc": false,
5 | "tsx": false,
6 | "tailwind": {
7 | "config": "tailwind.config.js",
8 | "css": "src/index.css",
9 | "baseColor": "slate",
10 | "cssVariables": true,
11 | "prefix": ""
12 | },
13 | "aliases": {
14 | "components": "@/components",
15 | "utils": "@/lib/utils"
16 | }
17 | }
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
14 | Claude Artifacts React
15 |
16 |
17 |
18 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": ".",
4 | "paths": {
5 | "@/*": ["src/*"]
6 | }
7 | },
8 | "include": ["src"]
9 | }
10 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "claude-artifacts-react",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "vite build",
9 | "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
10 | "preview": "vite preview"
11 | },
12 | "dependencies": {
13 | "@hookform/resolvers": "^3.6.0",
14 | "@radix-ui/react-accordion": "^1.2.0",
15 | "@radix-ui/react-alert-dialog": "^1.1.1",
16 | "@radix-ui/react-aspect-ratio": "^1.1.0",
17 | "@radix-ui/react-avatar": "^1.1.0",
18 | "@radix-ui/react-checkbox": "^1.1.1",
19 | "@radix-ui/react-collapsible": "^1.1.0",
20 | "@radix-ui/react-context-menu": "^2.2.1",
21 | "@radix-ui/react-dialog": "^1.1.1",
22 | "@radix-ui/react-dropdown-menu": "^2.1.1",
23 | "@radix-ui/react-hover-card": "^1.1.1",
24 | "@radix-ui/react-label": "^2.1.0",
25 | "@radix-ui/react-menubar": "^1.1.1",
26 | "@radix-ui/react-navigation-menu": "^1.2.0",
27 | "@radix-ui/react-popover": "^1.1.1",
28 | "@radix-ui/react-progress": "^1.1.0",
29 | "@radix-ui/react-radio-group": "^1.2.0",
30 | "@radix-ui/react-scroll-area": "^1.1.0",
31 | "@radix-ui/react-select": "^2.1.1",
32 | "@radix-ui/react-separator": "^1.1.0",
33 | "@radix-ui/react-slider": "^1.2.0",
34 | "@radix-ui/react-slot": "^1.1.0",
35 | "@radix-ui/react-switch": "^1.1.0",
36 | "@radix-ui/react-tabs": "^1.1.0",
37 | "@radix-ui/react-toast": "^1.2.1",
38 | "@radix-ui/react-toggle": "^1.1.0",
39 | "@radix-ui/react-toggle-group": "^1.1.0",
40 | "@radix-ui/react-tooltip": "^1.1.2",
41 | "class-variance-authority": "^0.7.0",
42 | "clsx": "^2.1.1",
43 | "cmdk": "^1.0.0",
44 | "date-fns": "^3.6.0",
45 | "embla-carousel-react": "^8.1.6",
46 | "input-otp": "^1.2.4",
47 | "lucide-react": "^0.400.0",
48 | "next-themes": "^0.3.0",
49 | "react": "^18.3.1",
50 | "react-day-picker": "^8.10.1",
51 | "react-dom": "^18.3.1",
52 | "react-hook-form": "^7.52.1",
53 | "react-resizable-panels": "^2.0.19",
54 | "recharts": "^2.12.7",
55 | "sonner": "^1.5.0",
56 | "tailwind-merge": "^2.3.0",
57 | "tailwindcss-animate": "^1.0.7",
58 | "vaul": "^0.9.1",
59 | "zod": "^3.23.8"
60 | },
61 | "devDependencies": {
62 | "@types/react": "^18.3.3",
63 | "@types/react-dom": "^18.3.0",
64 | "@vitejs/plugin-react": "^4.3.1",
65 | "autoprefixer": "^10.4.19",
66 | "eslint": "^8.57.0",
67 | "eslint-plugin-react": "^7.34.2",
68 | "eslint-plugin-react-hooks": "^4.6.2",
69 | "eslint-plugin-react-refresh": "^0.4.7",
70 | "postcss": "^8.4.39",
71 | "tailwindcss": "^3.4.4",
72 | "vite": "^5.3.1"
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/public/ligtning.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/public/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 | #root {
2 | max-width: 1280px;
3 | margin: 0 auto;
4 | padding: 2rem;
5 | text-align: center;
6 | }
7 |
8 | .logo {
9 | height: 6em;
10 | padding: 1.5em;
11 | will-change: filter;
12 | transition: filter 300ms;
13 | }
14 | .logo:hover {
15 | filter: drop-shadow(0 0 2em #646cffaa);
16 | }
17 | .logo.react:hover {
18 | filter: drop-shadow(0 0 2em #61dafbaa);
19 | }
20 |
21 | @keyframes logo-spin {
22 | from {
23 | transform: rotate(0deg);
24 | }
25 | to {
26 | transform: rotate(360deg);
27 | }
28 | }
29 |
30 | @media (prefers-reduced-motion: no-preference) {
31 | a:nth-of-type(2) .logo {
32 | animation: logo-spin infinite 20s linear;
33 | }
34 | }
35 |
36 | .card {
37 | padding: 2em;
38 | }
39 |
40 | .read-the-docs {
41 | color: #888;
42 | }
43 |
--------------------------------------------------------------------------------
/src/App.jsx:
--------------------------------------------------------------------------------
1 | import "./App.css";
2 | import ArtifactCode from "./ArtifactCode";
3 |
4 | function App() {
5 | return (
6 | <>
7 |
8 | >
9 | );
10 | }
11 |
12 | export default App;
13 |
--------------------------------------------------------------------------------
/src/ArtifactCode.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import { Button } from "@/components/ui/button";
3 |
4 | const App = () => {
5 | const [count, setCount] = useState(0);
6 |
7 | const handleClick = () => {
8 | setCount(count + 1);
9 | };
10 |
11 | return (
12 |
13 |
14 |
Claude Artifacts React
15 |
21 |
Said Hi {count} times
22 |
23 |
24 | );
25 | };
26 |
27 | export default App;
28 |
--------------------------------------------------------------------------------
/src/assets/react.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/ui/accordion.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import * as AccordionPrimitive from "@radix-ui/react-accordion"
3 | import { ChevronDown } from "lucide-react"
4 |
5 | import { cn } from "@/lib/utils"
6 |
7 | const Accordion = AccordionPrimitive.Root
8 |
9 | const AccordionItem = React.forwardRef(({ className, ...props }, ref) => (
10 |
11 | ))
12 | AccordionItem.displayName = "AccordionItem"
13 |
14 | const AccordionTrigger = React.forwardRef(({ className, children, ...props }, ref) => (
15 |
16 | svg]:rotate-180",
20 | className
21 | )}
22 | {...props}>
23 | {children}
24 |
25 |
26 |
27 | ))
28 | AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName
29 |
30 | const AccordionContent = React.forwardRef(({ className, children, ...props }, ref) => (
31 |
35 | {children}
36 |
37 | ))
38 |
39 | AccordionContent.displayName = AccordionPrimitive.Content.displayName
40 |
41 | export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }
42 |
--------------------------------------------------------------------------------
/src/components/ui/alert-dialog.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog"
3 |
4 | import { cn } from "@/lib/utils"
5 | import { buttonVariants } from "@/components/ui/button"
6 |
7 | const AlertDialog = AlertDialogPrimitive.Root
8 |
9 | const AlertDialogTrigger = AlertDialogPrimitive.Trigger
10 |
11 | const AlertDialogPortal = AlertDialogPrimitive.Portal
12 |
13 | const AlertDialogOverlay = React.forwardRef(({ className, ...props }, ref) => (
14 |
21 | ))
22 | AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName
23 |
24 | const AlertDialogContent = React.forwardRef(({ className, ...props }, ref) => (
25 |
26 |
27 |
34 |
35 | ))
36 | AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName
37 |
38 | const AlertDialogHeader = ({
39 | className,
40 | ...props
41 | }) => (
42 |
45 | )
46 | AlertDialogHeader.displayName = "AlertDialogHeader"
47 |
48 | const AlertDialogFooter = ({
49 | className,
50 | ...props
51 | }) => (
52 |
55 | )
56 | AlertDialogFooter.displayName = "AlertDialogFooter"
57 |
58 | const AlertDialogTitle = React.forwardRef(({ className, ...props }, ref) => (
59 |
60 | ))
61 | AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName
62 |
63 | const AlertDialogDescription = React.forwardRef(({ className, ...props }, ref) => (
64 |
68 | ))
69 | AlertDialogDescription.displayName =
70 | AlertDialogPrimitive.Description.displayName
71 |
72 | const AlertDialogAction = React.forwardRef(({ className, ...props }, ref) => (
73 |
74 | ))
75 | AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName
76 |
77 | const AlertDialogCancel = React.forwardRef(({ className, ...props }, ref) => (
78 |
82 | ))
83 | AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName
84 |
85 | export {
86 | AlertDialog,
87 | AlertDialogPortal,
88 | AlertDialogOverlay,
89 | AlertDialogTrigger,
90 | AlertDialogContent,
91 | AlertDialogHeader,
92 | AlertDialogFooter,
93 | AlertDialogTitle,
94 | AlertDialogDescription,
95 | AlertDialogAction,
96 | AlertDialogCancel,
97 | }
98 |
--------------------------------------------------------------------------------
/src/components/ui/alert.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import { cva } from "class-variance-authority";
3 |
4 | import { cn } from "@/lib/utils"
5 |
6 | const alertVariants = cva(
7 | "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",
8 | {
9 | variants: {
10 | variant: {
11 | default: "bg-background text-foreground",
12 | destructive:
13 | "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive",
14 | },
15 | },
16 | defaultVariants: {
17 | variant: "default",
18 | },
19 | }
20 | )
21 |
22 | const Alert = React.forwardRef(({ className, variant, ...props }, ref) => (
23 |
28 | ))
29 | Alert.displayName = "Alert"
30 |
31 | const AlertTitle = React.forwardRef(({ className, ...props }, ref) => (
32 |
36 | ))
37 | AlertTitle.displayName = "AlertTitle"
38 |
39 | const AlertDescription = React.forwardRef(({ className, ...props }, ref) => (
40 |
44 | ))
45 | AlertDescription.displayName = "AlertDescription"
46 |
47 | export { Alert, AlertTitle, AlertDescription }
48 |
--------------------------------------------------------------------------------
/src/components/ui/aspect-ratio.jsx:
--------------------------------------------------------------------------------
1 | import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio"
2 |
3 | const AspectRatio = AspectRatioPrimitive.Root
4 |
5 | export { AspectRatio }
6 |
--------------------------------------------------------------------------------
/src/components/ui/avatar.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import * as AvatarPrimitive from "@radix-ui/react-avatar"
3 |
4 | import { cn } from "@/lib/utils"
5 |
6 | const Avatar = React.forwardRef(({ className, ...props }, ref) => (
7 |
11 | ))
12 | Avatar.displayName = AvatarPrimitive.Root.displayName
13 |
14 | const AvatarImage = React.forwardRef(({ className, ...props }, ref) => (
15 |
19 | ))
20 | AvatarImage.displayName = AvatarPrimitive.Image.displayName
21 |
22 | const AvatarFallback = React.forwardRef(({ className, ...props }, ref) => (
23 |
30 | ))
31 | AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName
32 |
33 | export { Avatar, AvatarImage, AvatarFallback }
34 |
--------------------------------------------------------------------------------
/src/components/ui/badge.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import { cva } from "class-variance-authority";
3 |
4 | import { cn } from "@/lib/utils"
5 |
6 | const badgeVariants = cva(
7 | "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
8 | {
9 | variants: {
10 | variant: {
11 | default:
12 | "border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
13 | secondary:
14 | "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
15 | destructive:
16 | "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
17 | outline: "text-foreground",
18 | },
19 | },
20 | defaultVariants: {
21 | variant: "default",
22 | },
23 | }
24 | )
25 |
26 | function Badge({
27 | className,
28 | variant,
29 | ...props
30 | }) {
31 | return ();
32 | }
33 |
34 | export { Badge, badgeVariants }
35 |
--------------------------------------------------------------------------------
/src/components/ui/breadcrumb.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import { Slot } from "@radix-ui/react-slot"
3 | import { ChevronRight, MoreHorizontal } from "lucide-react"
4 |
5 | import { cn } from "@/lib/utils"
6 |
7 | const Breadcrumb = React.forwardRef(
8 | ({ ...props }, ref) =>
9 | )
10 | Breadcrumb.displayName = "Breadcrumb"
11 |
12 | const BreadcrumbList = React.forwardRef(({ className, ...props }, ref) => (
13 |
20 | ))
21 | BreadcrumbList.displayName = "BreadcrumbList"
22 |
23 | const BreadcrumbItem = React.forwardRef(({ className, ...props }, ref) => (
24 |
28 | ))
29 | BreadcrumbItem.displayName = "BreadcrumbItem"
30 |
31 | const BreadcrumbLink = React.forwardRef(({ asChild, className, ...props }, ref) => {
32 | const Comp = asChild ? Slot : "a"
33 |
34 | return (
35 | ()
39 | );
40 | })
41 | BreadcrumbLink.displayName = "BreadcrumbLink"
42 |
43 | const BreadcrumbPage = React.forwardRef(({ className, ...props }, ref) => (
44 |
51 | ))
52 | BreadcrumbPage.displayName = "BreadcrumbPage"
53 |
54 | const BreadcrumbSeparator = ({
55 | children,
56 | className,
57 | ...props
58 | }) => (
59 | svg]:size-3.5", className)}
63 | {...props}>
64 | {children ?? }
65 |
66 | )
67 | BreadcrumbSeparator.displayName = "BreadcrumbSeparator"
68 |
69 | const BreadcrumbEllipsis = ({
70 | className,
71 | ...props
72 | }) => (
73 |
78 |
79 | More
80 |
81 | )
82 | BreadcrumbEllipsis.displayName = "BreadcrumbElipssis"
83 |
84 | export {
85 | Breadcrumb,
86 | BreadcrumbList,
87 | BreadcrumbItem,
88 | BreadcrumbLink,
89 | BreadcrumbPage,
90 | BreadcrumbSeparator,
91 | BreadcrumbEllipsis,
92 | }
93 |
--------------------------------------------------------------------------------
/src/components/ui/button.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import { Slot } from "@radix-ui/react-slot"
3 | import { cva } from "class-variance-authority";
4 |
5 | import { cn } from "@/lib/utils"
6 |
7 | const buttonVariants = cva(
8 | "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
9 | {
10 | variants: {
11 | variant: {
12 | default: "bg-primary text-primary-foreground hover:bg-primary/90",
13 | destructive:
14 | "bg-destructive text-destructive-foreground hover:bg-destructive/90",
15 | outline:
16 | "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
17 | secondary:
18 | "bg-secondary text-secondary-foreground hover:bg-secondary/80",
19 | ghost: "hover:bg-accent hover:text-accent-foreground",
20 | link: "text-primary underline-offset-4 hover:underline",
21 | },
22 | size: {
23 | default: "h-10 px-4 py-2",
24 | sm: "h-9 rounded-md px-3",
25 | lg: "h-11 rounded-md px-8",
26 | icon: "h-10 w-10",
27 | },
28 | },
29 | defaultVariants: {
30 | variant: "default",
31 | size: "default",
32 | },
33 | }
34 | )
35 |
36 | const Button = React.forwardRef(({ className, variant, size, asChild = false, ...props }, ref) => {
37 | const Comp = asChild ? Slot : "button"
38 | return (
39 | ()
43 | );
44 | })
45 | Button.displayName = "Button"
46 |
47 | export { Button, buttonVariants }
48 |
--------------------------------------------------------------------------------
/src/components/ui/calendar.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import { ChevronLeft, ChevronRight } from "lucide-react"
3 | import { DayPicker } from "react-day-picker"
4 |
5 | import { cn } from "@/lib/utils"
6 | import { buttonVariants } from "@/components/ui/button"
7 |
8 | function Calendar({
9 | className,
10 | classNames,
11 | showOutsideDays = true,
12 | ...props
13 | }) {
14 | return (
15 | ( ,
54 | IconRight: ({ ...props }) => ,
55 | }}
56 | {...props} />)
57 | );
58 | }
59 | Calendar.displayName = "Calendar"
60 |
61 | export { Calendar }
62 |
--------------------------------------------------------------------------------
/src/components/ui/card.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 |
3 | import { cn } from "@/lib/utils"
4 |
5 | const Card = React.forwardRef(({ className, ...props }, ref) => (
6 |
10 | ))
11 | Card.displayName = "Card"
12 |
13 | const CardHeader = React.forwardRef(({ className, ...props }, ref) => (
14 |
18 | ))
19 | CardHeader.displayName = "CardHeader"
20 |
21 | const CardTitle = React.forwardRef(({ className, ...props }, ref) => (
22 |
26 | ))
27 | CardTitle.displayName = "CardTitle"
28 |
29 | const CardDescription = React.forwardRef(({ className, ...props }, ref) => (
30 |
34 | ))
35 | CardDescription.displayName = "CardDescription"
36 |
37 | const CardContent = React.forwardRef(({ className, ...props }, ref) => (
38 |
39 | ))
40 | CardContent.displayName = "CardContent"
41 |
42 | const CardFooter = React.forwardRef(({ className, ...props }, ref) => (
43 |
47 | ))
48 | CardFooter.displayName = "CardFooter"
49 |
50 | export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
51 |
--------------------------------------------------------------------------------
/src/components/ui/carousel.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import useEmblaCarousel from "embla-carousel-react";
3 | import { ArrowLeft, ArrowRight } from "lucide-react"
4 |
5 | import { cn } from "@/lib/utils"
6 | import { Button } from "@/components/ui/button"
7 |
8 | const CarouselContext = React.createContext(null)
9 |
10 | function useCarousel() {
11 | const context = React.useContext(CarouselContext)
12 |
13 | if (!context) {
14 | throw new Error("useCarousel must be used within a ")
15 | }
16 |
17 | return context
18 | }
19 |
20 | const Carousel = React.forwardRef((
21 | {
22 | orientation = "horizontal",
23 | opts,
24 | setApi,
25 | plugins,
26 | className,
27 | children,
28 | ...props
29 | },
30 | ref
31 | ) => {
32 | const [carouselRef, api] = useEmblaCarousel({
33 | ...opts,
34 | axis: orientation === "horizontal" ? "x" : "y",
35 | }, plugins)
36 | const [canScrollPrev, setCanScrollPrev] = React.useState(false)
37 | const [canScrollNext, setCanScrollNext] = React.useState(false)
38 |
39 | const onSelect = React.useCallback((api) => {
40 | if (!api) {
41 | return
42 | }
43 |
44 | setCanScrollPrev(api.canScrollPrev())
45 | setCanScrollNext(api.canScrollNext())
46 | }, [])
47 |
48 | const scrollPrev = React.useCallback(() => {
49 | api?.scrollPrev()
50 | }, [api])
51 |
52 | const scrollNext = React.useCallback(() => {
53 | api?.scrollNext()
54 | }, [api])
55 |
56 | const handleKeyDown = React.useCallback((event) => {
57 | if (event.key === "ArrowLeft") {
58 | event.preventDefault()
59 | scrollPrev()
60 | } else if (event.key === "ArrowRight") {
61 | event.preventDefault()
62 | scrollNext()
63 | }
64 | }, [scrollPrev, scrollNext])
65 |
66 | React.useEffect(() => {
67 | if (!api || !setApi) {
68 | return
69 | }
70 |
71 | setApi(api)
72 | }, [api, setApi])
73 |
74 | React.useEffect(() => {
75 | if (!api) {
76 | return
77 | }
78 |
79 | onSelect(api)
80 | api.on("reInit", onSelect)
81 | api.on("select", onSelect)
82 |
83 | return () => {
84 | api?.off("select", onSelect)
85 | };
86 | }, [api, onSelect])
87 |
88 | return (
89 | (
101 |
108 | {children}
109 |
110 | )
111 | );
112 | })
113 | Carousel.displayName = "Carousel"
114 |
115 | const CarouselContent = React.forwardRef(({ className, ...props }, ref) => {
116 | const { carouselRef, orientation } = useCarousel()
117 |
118 | return (
119 | ()
129 | );
130 | })
131 | CarouselContent.displayName = "CarouselContent"
132 |
133 | const CarouselItem = React.forwardRef(({ className, ...props }, ref) => {
134 | const { orientation } = useCarousel()
135 |
136 | return (
137 | ()
147 | );
148 | })
149 | CarouselItem.displayName = "CarouselItem"
150 |
151 | const CarouselPrevious = React.forwardRef(({ className, variant = "outline", size = "icon", ...props }, ref) => {
152 | const { orientation, scrollPrev, canScrollPrev } = useCarousel()
153 |
154 | return (
155 | ()
168 | );
169 | })
170 | CarouselPrevious.displayName = "CarouselPrevious"
171 |
172 | const CarouselNext = React.forwardRef(({ className, variant = "outline", size = "icon", ...props }, ref) => {
173 | const { orientation, scrollNext, canScrollNext } = useCarousel()
174 |
175 | return (
176 | ()
189 | );
190 | })
191 | CarouselNext.displayName = "CarouselNext"
192 |
193 | export { Carousel, CarouselContent, CarouselItem, CarouselPrevious, CarouselNext };
194 |
--------------------------------------------------------------------------------
/src/components/ui/checkbox.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import * as CheckboxPrimitive from "@radix-ui/react-checkbox"
3 | import { Check } from "lucide-react"
4 |
5 | import { cn } from "@/lib/utils"
6 |
7 | const Checkbox = React.forwardRef(({ className, ...props }, ref) => (
8 |
15 |
16 |
17 |
18 |
19 | ))
20 | Checkbox.displayName = CheckboxPrimitive.Root.displayName
21 |
22 | export { Checkbox }
23 |
--------------------------------------------------------------------------------
/src/components/ui/collapsible.jsx:
--------------------------------------------------------------------------------
1 | import * as CollapsiblePrimitive from "@radix-ui/react-collapsible"
2 |
3 | const Collapsible = CollapsiblePrimitive.Root
4 |
5 | const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger
6 |
7 | const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent
8 |
9 | export { Collapsible, CollapsibleTrigger, CollapsibleContent }
10 |
--------------------------------------------------------------------------------
/src/components/ui/command.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import { Command as CommandPrimitive } from "cmdk"
3 | import { Search } from "lucide-react"
4 |
5 | import { cn } from "@/lib/utils"
6 | import { Dialog, DialogContent } from "@/components/ui/dialog"
7 |
8 | const Command = React.forwardRef(({ className, ...props }, ref) => (
9 |
16 | ))
17 | Command.displayName = CommandPrimitive.displayName
18 |
19 | const CommandDialog = ({
20 | children,
21 | ...props
22 | }) => {
23 | return (
24 | ()
32 | );
33 | }
34 |
35 | const CommandInput = React.forwardRef(({ className, ...props }, ref) => (
36 |
37 |
38 |
45 |
46 | ))
47 |
48 | CommandInput.displayName = CommandPrimitive.Input.displayName
49 |
50 | const CommandList = React.forwardRef(({ className, ...props }, ref) => (
51 |
55 | ))
56 |
57 | CommandList.displayName = CommandPrimitive.List.displayName
58 |
59 | const CommandEmpty = React.forwardRef((props, ref) => (
60 |
61 | ))
62 |
63 | CommandEmpty.displayName = CommandPrimitive.Empty.displayName
64 |
65 | const CommandGroup = React.forwardRef(({ className, ...props }, ref) => (
66 |
73 | ))
74 |
75 | CommandGroup.displayName = CommandPrimitive.Group.displayName
76 |
77 | const CommandSeparator = React.forwardRef(({ className, ...props }, ref) => (
78 |
79 | ))
80 | CommandSeparator.displayName = CommandPrimitive.Separator.displayName
81 |
82 | const CommandItem = React.forwardRef(({ className, ...props }, ref) => (
83 |
90 | ))
91 |
92 | CommandItem.displayName = CommandPrimitive.Item.displayName
93 |
94 | const CommandShortcut = ({
95 | className,
96 | ...props
97 | }) => {
98 | return (
99 | ()
102 | );
103 | }
104 | CommandShortcut.displayName = "CommandShortcut"
105 |
106 | export {
107 | Command,
108 | CommandDialog,
109 | CommandInput,
110 | CommandList,
111 | CommandEmpty,
112 | CommandGroup,
113 | CommandItem,
114 | CommandShortcut,
115 | CommandSeparator,
116 | }
117 |
--------------------------------------------------------------------------------
/src/components/ui/context-menu.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import * as ContextMenuPrimitive from "@radix-ui/react-context-menu"
3 | import { Check, ChevronRight, Circle } from "lucide-react"
4 |
5 | import { cn } from "@/lib/utils"
6 |
7 | const ContextMenu = ContextMenuPrimitive.Root
8 |
9 | const ContextMenuTrigger = ContextMenuPrimitive.Trigger
10 |
11 | const ContextMenuGroup = ContextMenuPrimitive.Group
12 |
13 | const ContextMenuPortal = ContextMenuPrimitive.Portal
14 |
15 | const ContextMenuSub = ContextMenuPrimitive.Sub
16 |
17 | const ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup
18 |
19 | const ContextMenuSubTrigger = React.forwardRef(({ className, inset, children, ...props }, ref) => (
20 |
28 | {children}
29 |
30 |
31 | ))
32 | ContextMenuSubTrigger.displayName = ContextMenuPrimitive.SubTrigger.displayName
33 |
34 | const ContextMenuSubContent = React.forwardRef(({ className, ...props }, ref) => (
35 |
42 | ))
43 | ContextMenuSubContent.displayName = ContextMenuPrimitive.SubContent.displayName
44 |
45 | const ContextMenuContent = React.forwardRef(({ className, ...props }, ref) => (
46 |
47 |
54 |
55 | ))
56 | ContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName
57 |
58 | const ContextMenuItem = React.forwardRef(({ className, inset, ...props }, ref) => (
59 |
67 | ))
68 | ContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName
69 |
70 | const ContextMenuCheckboxItem = React.forwardRef(({ className, children, checked, ...props }, ref) => (
71 |
79 |
80 |
81 |
82 |
83 |
84 | {children}
85 |
86 | ))
87 | ContextMenuCheckboxItem.displayName =
88 | ContextMenuPrimitive.CheckboxItem.displayName
89 |
90 | const ContextMenuRadioItem = React.forwardRef(({ className, children, ...props }, ref) => (
91 |
98 |
99 |
100 |
101 |
102 |
103 | {children}
104 |
105 | ))
106 | ContextMenuRadioItem.displayName = ContextMenuPrimitive.RadioItem.displayName
107 |
108 | const ContextMenuLabel = React.forwardRef(({ className, inset, ...props }, ref) => (
109 |
117 | ))
118 | ContextMenuLabel.displayName = ContextMenuPrimitive.Label.displayName
119 |
120 | const ContextMenuSeparator = React.forwardRef(({ className, ...props }, ref) => (
121 |
125 | ))
126 | ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName
127 |
128 | const ContextMenuShortcut = ({
129 | className,
130 | ...props
131 | }) => {
132 | return (
133 | ()
136 | );
137 | }
138 | ContextMenuShortcut.displayName = "ContextMenuShortcut"
139 |
140 | export {
141 | ContextMenu,
142 | ContextMenuTrigger,
143 | ContextMenuContent,
144 | ContextMenuItem,
145 | ContextMenuCheckboxItem,
146 | ContextMenuRadioItem,
147 | ContextMenuLabel,
148 | ContextMenuSeparator,
149 | ContextMenuShortcut,
150 | ContextMenuGroup,
151 | ContextMenuPortal,
152 | ContextMenuSub,
153 | ContextMenuSubContent,
154 | ContextMenuSubTrigger,
155 | ContextMenuRadioGroup,
156 | }
157 |
--------------------------------------------------------------------------------
/src/components/ui/dialog.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import * as DialogPrimitive from "@radix-ui/react-dialog"
3 | import { X } from "lucide-react"
4 |
5 | import { cn } from "@/lib/utils"
6 |
7 | const Dialog = DialogPrimitive.Root
8 |
9 | const DialogTrigger = DialogPrimitive.Trigger
10 |
11 | const DialogPortal = DialogPrimitive.Portal
12 |
13 | const DialogClose = DialogPrimitive.Close
14 |
15 | const DialogOverlay = React.forwardRef(({ className, ...props }, ref) => (
16 |
23 | ))
24 | DialogOverlay.displayName = DialogPrimitive.Overlay.displayName
25 |
26 | const DialogContent = React.forwardRef(({ className, children, ...props }, ref) => (
27 |
28 |
29 |
36 | {children}
37 |
39 |
40 | Close
41 |
42 |
43 |
44 | ))
45 | DialogContent.displayName = DialogPrimitive.Content.displayName
46 |
47 | const DialogHeader = ({
48 | className,
49 | ...props
50 | }) => (
51 |
54 | )
55 | DialogHeader.displayName = "DialogHeader"
56 |
57 | const DialogFooter = ({
58 | className,
59 | ...props
60 | }) => (
61 |
64 | )
65 | DialogFooter.displayName = "DialogFooter"
66 |
67 | const DialogTitle = React.forwardRef(({ className, ...props }, ref) => (
68 |
72 | ))
73 | DialogTitle.displayName = DialogPrimitive.Title.displayName
74 |
75 | const DialogDescription = React.forwardRef(({ className, ...props }, ref) => (
76 |
80 | ))
81 | DialogDescription.displayName = DialogPrimitive.Description.displayName
82 |
83 | export {
84 | Dialog,
85 | DialogPortal,
86 | DialogOverlay,
87 | DialogClose,
88 | DialogTrigger,
89 | DialogContent,
90 | DialogHeader,
91 | DialogFooter,
92 | DialogTitle,
93 | DialogDescription,
94 | }
95 |
--------------------------------------------------------------------------------
/src/components/ui/drawer.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import { Drawer as DrawerPrimitive } from "vaul"
3 |
4 | import { cn } from "@/lib/utils"
5 |
6 | const Drawer = ({
7 | shouldScaleBackground = true,
8 | ...props
9 | }) => (
10 |
11 | )
12 | Drawer.displayName = "Drawer"
13 |
14 | const DrawerTrigger = DrawerPrimitive.Trigger
15 |
16 | const DrawerPortal = DrawerPrimitive.Portal
17 |
18 | const DrawerClose = DrawerPrimitive.Close
19 |
20 | const DrawerOverlay = React.forwardRef(({ className, ...props }, ref) => (
21 |
25 | ))
26 | DrawerOverlay.displayName = DrawerPrimitive.Overlay.displayName
27 |
28 | const DrawerContent = React.forwardRef(({ className, children, ...props }, ref) => (
29 |
30 |
31 |
38 |
39 | {children}
40 |
41 |
42 | ))
43 | DrawerContent.displayName = "DrawerContent"
44 |
45 | const DrawerHeader = ({
46 | className,
47 | ...props
48 | }) => (
49 |
52 | )
53 | DrawerHeader.displayName = "DrawerHeader"
54 |
55 | const DrawerFooter = ({
56 | className,
57 | ...props
58 | }) => (
59 |
60 | )
61 | DrawerFooter.displayName = "DrawerFooter"
62 |
63 | const DrawerTitle = React.forwardRef(({ className, ...props }, ref) => (
64 |
68 | ))
69 | DrawerTitle.displayName = DrawerPrimitive.Title.displayName
70 |
71 | const DrawerDescription = React.forwardRef(({ className, ...props }, ref) => (
72 |
76 | ))
77 | DrawerDescription.displayName = DrawerPrimitive.Description.displayName
78 |
79 | export {
80 | Drawer,
81 | DrawerPortal,
82 | DrawerOverlay,
83 | DrawerTrigger,
84 | DrawerClose,
85 | DrawerContent,
86 | DrawerHeader,
87 | DrawerFooter,
88 | DrawerTitle,
89 | DrawerDescription,
90 | }
91 |
--------------------------------------------------------------------------------
/src/components/ui/dropdown-menu.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"
3 | import { Check, ChevronRight, Circle } from "lucide-react"
4 |
5 | import { cn } from "@/lib/utils"
6 |
7 | const DropdownMenu = DropdownMenuPrimitive.Root
8 |
9 | const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger
10 |
11 | const DropdownMenuGroup = DropdownMenuPrimitive.Group
12 |
13 | const DropdownMenuPortal = DropdownMenuPrimitive.Portal
14 |
15 | const DropdownMenuSub = DropdownMenuPrimitive.Sub
16 |
17 | const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup
18 |
19 | const DropdownMenuSubTrigger = React.forwardRef(({ className, inset, children, ...props }, ref) => (
20 |
28 | {children}
29 |
30 |
31 | ))
32 | DropdownMenuSubTrigger.displayName =
33 | DropdownMenuPrimitive.SubTrigger.displayName
34 |
35 | const DropdownMenuSubContent = React.forwardRef(({ className, ...props }, ref) => (
36 |
43 | ))
44 | DropdownMenuSubContent.displayName =
45 | DropdownMenuPrimitive.SubContent.displayName
46 |
47 | const DropdownMenuContent = React.forwardRef(({ className, sideOffset = 4, ...props }, ref) => (
48 |
49 |
57 |
58 | ))
59 | DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName
60 |
61 | const DropdownMenuItem = React.forwardRef(({ className, inset, ...props }, ref) => (
62 |
70 | ))
71 | DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName
72 |
73 | const DropdownMenuCheckboxItem = React.forwardRef(({ className, children, checked, ...props }, ref) => (
74 |
82 |
83 |
84 |
85 |
86 |
87 | {children}
88 |
89 | ))
90 | DropdownMenuCheckboxItem.displayName =
91 | DropdownMenuPrimitive.CheckboxItem.displayName
92 |
93 | const DropdownMenuRadioItem = React.forwardRef(({ className, children, ...props }, ref) => (
94 |
101 |
102 |
103 |
104 |
105 |
106 | {children}
107 |
108 | ))
109 | DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName
110 |
111 | const DropdownMenuLabel = React.forwardRef(({ className, inset, ...props }, ref) => (
112 |
116 | ))
117 | DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName
118 |
119 | const DropdownMenuSeparator = React.forwardRef(({ className, ...props }, ref) => (
120 |
124 | ))
125 | DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName
126 |
127 | const DropdownMenuShortcut = ({
128 | className,
129 | ...props
130 | }) => {
131 | return (
132 | ()
135 | );
136 | }
137 | DropdownMenuShortcut.displayName = "DropdownMenuShortcut"
138 |
139 | export {
140 | DropdownMenu,
141 | DropdownMenuTrigger,
142 | DropdownMenuContent,
143 | DropdownMenuItem,
144 | DropdownMenuCheckboxItem,
145 | DropdownMenuRadioItem,
146 | DropdownMenuLabel,
147 | DropdownMenuSeparator,
148 | DropdownMenuShortcut,
149 | DropdownMenuGroup,
150 | DropdownMenuPortal,
151 | DropdownMenuSub,
152 | DropdownMenuSubContent,
153 | DropdownMenuSubTrigger,
154 | DropdownMenuRadioGroup,
155 | }
156 |
--------------------------------------------------------------------------------
/src/components/ui/form.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import { Slot } from "@radix-ui/react-slot"
3 | import { Controller, FormProvider, useFormContext } from "react-hook-form";
4 |
5 | import { cn } from "@/lib/utils"
6 | import { Label } from "@/components/ui/label"
7 |
8 | const Form = FormProvider
9 |
10 | const FormFieldContext = React.createContext({})
11 |
12 | const FormField = (
13 | {
14 | ...props
15 | }
16 | ) => {
17 | return (
18 | (
19 |
20 | )
21 | );
22 | }
23 |
24 | const useFormField = () => {
25 | const fieldContext = React.useContext(FormFieldContext)
26 | const itemContext = React.useContext(FormItemContext)
27 | const { getFieldState, formState } = useFormContext()
28 |
29 | const fieldState = getFieldState(fieldContext.name, formState)
30 |
31 | if (!fieldContext) {
32 | throw new Error("useFormField should be used within ")
33 | }
34 |
35 | const { id } = itemContext
36 |
37 | return {
38 | id,
39 | name: fieldContext.name,
40 | formItemId: `${id}-form-item`,
41 | formDescriptionId: `${id}-form-item-description`,
42 | formMessageId: `${id}-form-item-message`,
43 | ...fieldState,
44 | }
45 | }
46 |
47 | const FormItemContext = React.createContext({})
48 |
49 | const FormItem = React.forwardRef(({ className, ...props }, ref) => {
50 | const id = React.useId()
51 |
52 | return (
53 | (
54 |
55 | )
56 | );
57 | })
58 | FormItem.displayName = "FormItem"
59 |
60 | const FormLabel = React.forwardRef(({ className, ...props }, ref) => {
61 | const { error, formItemId } = useFormField()
62 |
63 | return (
64 | ()
69 | );
70 | })
71 | FormLabel.displayName = "FormLabel"
72 |
73 | const FormControl = React.forwardRef(({ ...props }, ref) => {
74 | const { error, formItemId, formDescriptionId, formMessageId } = useFormField()
75 |
76 | return (
77 | ()
87 | );
88 | })
89 | FormControl.displayName = "FormControl"
90 |
91 | const FormDescription = React.forwardRef(({ className, ...props }, ref) => {
92 | const { formDescriptionId } = useFormField()
93 |
94 | return (
95 | ()
100 | );
101 | })
102 | FormDescription.displayName = "FormDescription"
103 |
104 | const FormMessage = React.forwardRef(({ className, children, ...props }, ref) => {
105 | const { error, formMessageId } = useFormField()
106 | const body = error ? String(error?.message) : children
107 |
108 | if (!body) {
109 | return null
110 | }
111 |
112 | return (
113 | (
118 | {body}
119 |
)
120 | );
121 | })
122 | FormMessage.displayName = "FormMessage"
123 |
124 | export {
125 | useFormField,
126 | Form,
127 | FormItem,
128 | FormLabel,
129 | FormControl,
130 | FormDescription,
131 | FormMessage,
132 | FormField,
133 | }
134 |
--------------------------------------------------------------------------------
/src/components/ui/hover-card.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import * as HoverCardPrimitive from "@radix-ui/react-hover-card"
3 |
4 | import { cn } from "@/lib/utils"
5 |
6 | const HoverCard = HoverCardPrimitive.Root
7 |
8 | const HoverCardTrigger = HoverCardPrimitive.Trigger
9 |
10 | const HoverCardContent = React.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
11 |
20 | ))
21 | HoverCardContent.displayName = HoverCardPrimitive.Content.displayName
22 |
23 | export { HoverCard, HoverCardTrigger, HoverCardContent }
24 |
--------------------------------------------------------------------------------
/src/components/ui/input-otp.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import { OTPInput, OTPInputContext } from "input-otp"
3 | import { Dot } from "lucide-react"
4 |
5 | import { cn } from "@/lib/utils"
6 |
7 | const InputOTP = React.forwardRef(({ className, containerClassName, ...props }, ref) => (
8 |
13 | ))
14 | InputOTP.displayName = "InputOTP"
15 |
16 | const InputOTPGroup = React.forwardRef(({ className, ...props }, ref) => (
17 |
18 | ))
19 | InputOTPGroup.displayName = "InputOTPGroup"
20 |
21 | const InputOTPSlot = React.forwardRef(({ index, className, ...props }, ref) => {
22 | const inputOTPContext = React.useContext(OTPInputContext)
23 | const { char, hasFakeCaret, isActive } = inputOTPContext.slots[index]
24 |
25 | return (
26 | (
34 | {char}
35 | {hasFakeCaret && (
36 |
40 | )}
41 |
)
42 | );
43 | })
44 | InputOTPSlot.displayName = "InputOTPSlot"
45 |
46 | const InputOTPSeparator = React.forwardRef(({ ...props }, ref) => (
47 |
48 |
49 |
50 | ))
51 | InputOTPSeparator.displayName = "InputOTPSeparator"
52 |
53 | export { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator }
54 |
--------------------------------------------------------------------------------
/src/components/ui/input.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 |
3 | import { cn } from "@/lib/utils"
4 |
5 | const Input = React.forwardRef(({ className, type, ...props }, ref) => {
6 | return (
7 | ()
15 | );
16 | })
17 | Input.displayName = "Input"
18 |
19 | export { Input }
20 |
--------------------------------------------------------------------------------
/src/components/ui/label.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import * as LabelPrimitive from "@radix-ui/react-label"
3 | import { cva } from "class-variance-authority";
4 |
5 | import { cn } from "@/lib/utils"
6 |
7 | const labelVariants = cva(
8 | "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
9 | )
10 |
11 | const Label = React.forwardRef(({ className, ...props }, ref) => (
12 |
13 | ))
14 | Label.displayName = LabelPrimitive.Root.displayName
15 |
16 | export { Label }
17 |
--------------------------------------------------------------------------------
/src/components/ui/menubar.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import * as MenubarPrimitive from "@radix-ui/react-menubar"
3 | import { Check, ChevronRight, Circle } from "lucide-react"
4 |
5 | import { cn } from "@/lib/utils"
6 |
7 | const MenubarMenu = MenubarPrimitive.Menu
8 |
9 | const MenubarGroup = MenubarPrimitive.Group
10 |
11 | const MenubarPortal = MenubarPrimitive.Portal
12 |
13 | const MenubarSub = MenubarPrimitive.Sub
14 |
15 | const MenubarRadioGroup = MenubarPrimitive.RadioGroup
16 |
17 | const Menubar = React.forwardRef(({ className, ...props }, ref) => (
18 |
25 | ))
26 | Menubar.displayName = MenubarPrimitive.Root.displayName
27 |
28 | const MenubarTrigger = React.forwardRef(({ className, ...props }, ref) => (
29 |
36 | ))
37 | MenubarTrigger.displayName = MenubarPrimitive.Trigger.displayName
38 |
39 | const MenubarSubTrigger = React.forwardRef(({ className, inset, children, ...props }, ref) => (
40 |
48 | {children}
49 |
50 |
51 | ))
52 | MenubarSubTrigger.displayName = MenubarPrimitive.SubTrigger.displayName
53 |
54 | const MenubarSubContent = React.forwardRef(({ className, ...props }, ref) => (
55 |
62 | ))
63 | MenubarSubContent.displayName = MenubarPrimitive.SubContent.displayName
64 |
65 | const MenubarContent = React.forwardRef((
66 | { className, align = "start", alignOffset = -4, sideOffset = 8, ...props },
67 | ref
68 | ) => (
69 |
70 |
80 |
81 | ))
82 | MenubarContent.displayName = MenubarPrimitive.Content.displayName
83 |
84 | const MenubarItem = React.forwardRef(({ className, inset, ...props }, ref) => (
85 |
93 | ))
94 | MenubarItem.displayName = MenubarPrimitive.Item.displayName
95 |
96 | const MenubarCheckboxItem = React.forwardRef(({ className, children, checked, ...props }, ref) => (
97 |
105 |
106 |
107 |
108 |
109 |
110 | {children}
111 |
112 | ))
113 | MenubarCheckboxItem.displayName = MenubarPrimitive.CheckboxItem.displayName
114 |
115 | const MenubarRadioItem = React.forwardRef(({ className, children, ...props }, ref) => (
116 |
123 |
124 |
125 |
126 |
127 |
128 | {children}
129 |
130 | ))
131 | MenubarRadioItem.displayName = MenubarPrimitive.RadioItem.displayName
132 |
133 | const MenubarLabel = React.forwardRef(({ className, inset, ...props }, ref) => (
134 |
138 | ))
139 | MenubarLabel.displayName = MenubarPrimitive.Label.displayName
140 |
141 | const MenubarSeparator = React.forwardRef(({ className, ...props }, ref) => (
142 |
146 | ))
147 | MenubarSeparator.displayName = MenubarPrimitive.Separator.displayName
148 |
149 | const MenubarShortcut = ({
150 | className,
151 | ...props
152 | }) => {
153 | return (
154 | ()
157 | );
158 | }
159 | MenubarShortcut.displayname = "MenubarShortcut"
160 |
161 | export {
162 | Menubar,
163 | MenubarMenu,
164 | MenubarTrigger,
165 | MenubarContent,
166 | MenubarItem,
167 | MenubarSeparator,
168 | MenubarLabel,
169 | MenubarCheckboxItem,
170 | MenubarRadioGroup,
171 | MenubarRadioItem,
172 | MenubarPortal,
173 | MenubarSubContent,
174 | MenubarSubTrigger,
175 | MenubarGroup,
176 | MenubarSub,
177 | MenubarShortcut,
178 | }
179 |
--------------------------------------------------------------------------------
/src/components/ui/navigation-menu.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import * as NavigationMenuPrimitive from "@radix-ui/react-navigation-menu"
3 | import { cva } from "class-variance-authority"
4 | import { ChevronDown } from "lucide-react"
5 |
6 | import { cn } from "@/lib/utils"
7 |
8 | const NavigationMenu = React.forwardRef(({ className, children, ...props }, ref) => (
9 |
16 | {children}
17 |
18 |
19 | ))
20 | NavigationMenu.displayName = NavigationMenuPrimitive.Root.displayName
21 |
22 | const NavigationMenuList = React.forwardRef(({ className, ...props }, ref) => (
23 |
30 | ))
31 | NavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName
32 |
33 | const NavigationMenuItem = NavigationMenuPrimitive.Item
34 |
35 | const navigationMenuTriggerStyle = cva(
36 | "group inline-flex h-10 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50"
37 | )
38 |
39 | const NavigationMenuTrigger = React.forwardRef(({ className, children, ...props }, ref) => (
40 |
44 | {children}{" "}
45 |
48 |
49 | ))
50 | NavigationMenuTrigger.displayName = NavigationMenuPrimitive.Trigger.displayName
51 |
52 | const NavigationMenuContent = React.forwardRef(({ className, ...props }, ref) => (
53 |
60 | ))
61 | NavigationMenuContent.displayName = NavigationMenuPrimitive.Content.displayName
62 |
63 | const NavigationMenuLink = NavigationMenuPrimitive.Link
64 |
65 | const NavigationMenuViewport = React.forwardRef(({ className, ...props }, ref) => (
66 |
67 |
74 |
75 | ))
76 | NavigationMenuViewport.displayName =
77 | NavigationMenuPrimitive.Viewport.displayName
78 |
79 | const NavigationMenuIndicator = React.forwardRef(({ className, ...props }, ref) => (
80 |
87 |
89 |
90 | ))
91 | NavigationMenuIndicator.displayName =
92 | NavigationMenuPrimitive.Indicator.displayName
93 |
94 | export {
95 | navigationMenuTriggerStyle,
96 | NavigationMenu,
97 | NavigationMenuList,
98 | NavigationMenuItem,
99 | NavigationMenuContent,
100 | NavigationMenuTrigger,
101 | NavigationMenuLink,
102 | NavigationMenuIndicator,
103 | NavigationMenuViewport,
104 | }
105 |
--------------------------------------------------------------------------------
/src/components/ui/pagination.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import { ChevronLeft, ChevronRight, MoreHorizontal } from "lucide-react"
3 |
4 | import { cn } from "@/lib/utils"
5 | import { buttonVariants } from "@/components/ui/button";
6 |
7 | const Pagination = ({
8 | className,
9 | ...props
10 | }) => (
11 |
16 | )
17 | Pagination.displayName = "Pagination"
18 |
19 | const PaginationContent = React.forwardRef(({ className, ...props }, ref) => (
20 |
24 | ))
25 | PaginationContent.displayName = "PaginationContent"
26 |
27 | const PaginationItem = React.forwardRef(({ className, ...props }, ref) => (
28 |
29 | ))
30 | PaginationItem.displayName = "PaginationItem"
31 |
32 | const PaginationLink = ({
33 | className,
34 | isActive,
35 | size = "icon",
36 | ...props
37 | }) => (
38 |
45 | )
46 | PaginationLink.displayName = "PaginationLink"
47 |
48 | const PaginationPrevious = ({
49 | className,
50 | ...props
51 | }) => (
52 |
57 |
58 | Previous
59 |
60 | )
61 | PaginationPrevious.displayName = "PaginationPrevious"
62 |
63 | const PaginationNext = ({
64 | className,
65 | ...props
66 | }) => (
67 |
72 | Next
73 |
74 |
75 | )
76 | PaginationNext.displayName = "PaginationNext"
77 |
78 | const PaginationEllipsis = ({
79 | className,
80 | ...props
81 | }) => (
82 |
86 |
87 | More pages
88 |
89 | )
90 | PaginationEllipsis.displayName = "PaginationEllipsis"
91 |
92 | export {
93 | Pagination,
94 | PaginationContent,
95 | PaginationEllipsis,
96 | PaginationItem,
97 | PaginationLink,
98 | PaginationNext,
99 | PaginationPrevious,
100 | }
101 |
--------------------------------------------------------------------------------
/src/components/ui/popover.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import * as PopoverPrimitive from "@radix-ui/react-popover"
3 |
4 | import { cn } from "@/lib/utils"
5 |
6 | const Popover = PopoverPrimitive.Root
7 |
8 | const PopoverTrigger = PopoverPrimitive.Trigger
9 |
10 | const PopoverContent = React.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
11 |
12 |
21 |
22 | ))
23 | PopoverContent.displayName = PopoverPrimitive.Content.displayName
24 |
25 | export { Popover, PopoverTrigger, PopoverContent }
26 |
--------------------------------------------------------------------------------
/src/components/ui/progress.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import * as ProgressPrimitive from "@radix-ui/react-progress"
3 |
4 | import { cn } from "@/lib/utils"
5 |
6 | const Progress = React.forwardRef(({ className, value, ...props }, ref) => (
7 |
11 |
14 |
15 | ))
16 | Progress.displayName = ProgressPrimitive.Root.displayName
17 |
18 | export { Progress }
19 |
--------------------------------------------------------------------------------
/src/components/ui/radio-group.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import * as RadioGroupPrimitive from "@radix-ui/react-radio-group"
3 | import { Circle } from "lucide-react"
4 |
5 | import { cn } from "@/lib/utils"
6 |
7 | const RadioGroup = React.forwardRef(({ className, ...props }, ref) => {
8 | return ();
9 | })
10 | RadioGroup.displayName = RadioGroupPrimitive.Root.displayName
11 |
12 | const RadioGroupItem = React.forwardRef(({ className, ...props }, ref) => {
13 | return (
14 | (
21 |
22 |
23 |
24 | )
25 | );
26 | })
27 | RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName
28 |
29 | export { RadioGroup, RadioGroupItem }
30 |
--------------------------------------------------------------------------------
/src/components/ui/resizable.jsx:
--------------------------------------------------------------------------------
1 | import { GripVertical } from "lucide-react"
2 | import * as ResizablePrimitive from "react-resizable-panels"
3 |
4 | import { cn } from "@/lib/utils"
5 |
6 | const ResizablePanelGroup = ({
7 | className,
8 | ...props
9 | }) => (
10 |
16 | )
17 |
18 | const ResizablePanel = ResizablePrimitive.Panel
19 |
20 | const ResizableHandle = ({
21 | withHandle,
22 | className,
23 | ...props
24 | }) => (
25 | div]:rotate-90",
28 | className
29 | )}
30 | {...props}>
31 | {withHandle && (
32 |
34 |
35 |
36 | )}
37 |
38 | )
39 |
40 | export { ResizablePanelGroup, ResizablePanel, ResizableHandle }
41 |
--------------------------------------------------------------------------------
/src/components/ui/scroll-area.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"
3 |
4 | import { cn } from "@/lib/utils"
5 |
6 | const ScrollArea = React.forwardRef(({ className, children, ...props }, ref) => (
7 |
11 |
12 | {children}
13 |
14 |
15 |
16 |
17 | ))
18 | ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName
19 |
20 | const ScrollBar = React.forwardRef(({ className, orientation = "vertical", ...props }, ref) => (
21 |
33 |
34 |
35 | ))
36 | ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName
37 |
38 | export { ScrollArea, ScrollBar }
39 |
--------------------------------------------------------------------------------
/src/components/ui/select.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import * as SelectPrimitive from "@radix-ui/react-select"
3 | import { Check, ChevronDown, ChevronUp } from "lucide-react"
4 |
5 | import { cn } from "@/lib/utils"
6 |
7 | const Select = SelectPrimitive.Root
8 |
9 | const SelectGroup = SelectPrimitive.Group
10 |
11 | const SelectValue = SelectPrimitive.Value
12 |
13 | const SelectTrigger = React.forwardRef(({ className, children, ...props }, ref) => (
14 | span]:line-clamp-1",
18 | className
19 | )}
20 | {...props}>
21 | {children}
22 |
23 |
24 |
25 |
26 | ))
27 | SelectTrigger.displayName = SelectPrimitive.Trigger.displayName
28 |
29 | const SelectScrollUpButton = React.forwardRef(({ className, ...props }, ref) => (
30 |
34 |
35 |
36 | ))
37 | SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName
38 |
39 | const SelectScrollDownButton = React.forwardRef(({ className, ...props }, ref) => (
40 |
44 |
45 |
46 | ))
47 | SelectScrollDownButton.displayName =
48 | SelectPrimitive.ScrollDownButton.displayName
49 |
50 | const SelectContent = React.forwardRef(({ className, children, position = "popper", ...props }, ref) => (
51 |
52 |
62 |
63 |
66 | {children}
67 |
68 |
69 |
70 |
71 | ))
72 | SelectContent.displayName = SelectPrimitive.Content.displayName
73 |
74 | const SelectLabel = React.forwardRef(({ className, ...props }, ref) => (
75 |
79 | ))
80 | SelectLabel.displayName = SelectPrimitive.Label.displayName
81 |
82 | const SelectItem = React.forwardRef(({ className, children, ...props }, ref) => (
83 |
90 |
91 |
92 |
93 |
94 |
95 |
96 | {children}
97 |
98 | ))
99 | SelectItem.displayName = SelectPrimitive.Item.displayName
100 |
101 | const SelectSeparator = React.forwardRef(({ className, ...props }, ref) => (
102 |
106 | ))
107 | SelectSeparator.displayName = SelectPrimitive.Separator.displayName
108 |
109 | export {
110 | Select,
111 | SelectGroup,
112 | SelectValue,
113 | SelectTrigger,
114 | SelectContent,
115 | SelectLabel,
116 | SelectItem,
117 | SelectSeparator,
118 | SelectScrollUpButton,
119 | SelectScrollDownButton,
120 | }
121 |
--------------------------------------------------------------------------------
/src/components/ui/separator.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import * as SeparatorPrimitive from "@radix-ui/react-separator"
3 |
4 | import { cn } from "@/lib/utils"
5 |
6 | const Separator = React.forwardRef((
7 | { className, orientation = "horizontal", decorative = true, ...props },
8 | ref
9 | ) => (
10 |
20 | ))
21 | Separator.displayName = SeparatorPrimitive.Root.displayName
22 |
23 | export { Separator }
24 |
--------------------------------------------------------------------------------
/src/components/ui/sheet.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import * as SheetPrimitive from "@radix-ui/react-dialog"
3 | import { cva } from "class-variance-authority";
4 | import { X } from "lucide-react"
5 |
6 | import { cn } from "@/lib/utils"
7 |
8 | const Sheet = SheetPrimitive.Root
9 |
10 | const SheetTrigger = SheetPrimitive.Trigger
11 |
12 | const SheetClose = SheetPrimitive.Close
13 |
14 | const SheetPortal = SheetPrimitive.Portal
15 |
16 | const SheetOverlay = React.forwardRef(({ className, ...props }, ref) => (
17 |
24 | ))
25 | SheetOverlay.displayName = SheetPrimitive.Overlay.displayName
26 |
27 | const sheetVariants = cva(
28 | "fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
29 | {
30 | variants: {
31 | side: {
32 | top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
33 | bottom:
34 | "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
35 | left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
36 | right:
37 | "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
38 | },
39 | },
40 | defaultVariants: {
41 | side: "right",
42 | },
43 | }
44 | )
45 |
46 | const SheetContent = React.forwardRef(({ side = "right", className, children, ...props }, ref) => (
47 |
48 |
49 |
50 | {children}
51 |
53 |
54 | Close
55 |
56 |
57 |
58 | ))
59 | SheetContent.displayName = SheetPrimitive.Content.displayName
60 |
61 | const SheetHeader = ({
62 | className,
63 | ...props
64 | }) => (
65 |
68 | )
69 | SheetHeader.displayName = "SheetHeader"
70 |
71 | const SheetFooter = ({
72 | className,
73 | ...props
74 | }) => (
75 |
78 | )
79 | SheetFooter.displayName = "SheetFooter"
80 |
81 | const SheetTitle = React.forwardRef(({ className, ...props }, ref) => (
82 |
86 | ))
87 | SheetTitle.displayName = SheetPrimitive.Title.displayName
88 |
89 | const SheetDescription = React.forwardRef(({ className, ...props }, ref) => (
90 |
94 | ))
95 | SheetDescription.displayName = SheetPrimitive.Description.displayName
96 |
97 | export {
98 | Sheet,
99 | SheetPortal,
100 | SheetOverlay,
101 | SheetTrigger,
102 | SheetClose,
103 | SheetContent,
104 | SheetHeader,
105 | SheetFooter,
106 | SheetTitle,
107 | SheetDescription,
108 | }
109 |
--------------------------------------------------------------------------------
/src/components/ui/skeleton.jsx:
--------------------------------------------------------------------------------
1 | import { cn } from "@/lib/utils"
2 |
3 | function Skeleton({
4 | className,
5 | ...props
6 | }) {
7 | return ();
8 | }
9 |
10 | export { Skeleton }
11 |
--------------------------------------------------------------------------------
/src/components/ui/slider.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import * as SliderPrimitive from "@radix-ui/react-slider"
3 |
4 | import { cn } from "@/lib/utils"
5 |
6 | const Slider = React.forwardRef(({ className, ...props }, ref) => (
7 |
11 |
13 |
14 |
15 |
17 |
18 | ))
19 | Slider.displayName = SliderPrimitive.Root.displayName
20 |
21 | export { Slider }
22 |
--------------------------------------------------------------------------------
/src/components/ui/sonner.jsx:
--------------------------------------------------------------------------------
1 | import { useTheme } from "next-themes"
2 | import { Toaster as Sonner } from "sonner"
3 |
4 | const Toaster = ({
5 | ...props
6 | }) => {
7 | const { theme = "system" } = useTheme()
8 |
9 | return (
10 | ()
25 | );
26 | }
27 |
28 | export { Toaster }
29 |
--------------------------------------------------------------------------------
/src/components/ui/switch.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import * as SwitchPrimitives from "@radix-ui/react-switch"
3 |
4 | import { cn } from "@/lib/utils"
5 |
6 | const Switch = React.forwardRef(({ className, ...props }, ref) => (
7 |
14 |
18 |
19 | ))
20 | Switch.displayName = SwitchPrimitives.Root.displayName
21 |
22 | export { Switch }
23 |
--------------------------------------------------------------------------------
/src/components/ui/table.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 |
3 | import { cn } from "@/lib/utils"
4 |
5 | const Table = React.forwardRef(({ className, ...props }, ref) => (
6 |
12 | ))
13 | Table.displayName = "Table"
14 |
15 | const TableHeader = React.forwardRef(({ className, ...props }, ref) => (
16 |
17 | ))
18 | TableHeader.displayName = "TableHeader"
19 |
20 | const TableBody = React.forwardRef(({ className, ...props }, ref) => (
21 |
25 | ))
26 | TableBody.displayName = "TableBody"
27 |
28 | const TableFooter = React.forwardRef(({ className, ...props }, ref) => (
29 | tr]:last:border-b-0", className)}
32 | {...props} />
33 | ))
34 | TableFooter.displayName = "TableFooter"
35 |
36 | const TableRow = React.forwardRef(({ className, ...props }, ref) => (
37 |
44 | ))
45 | TableRow.displayName = "TableRow"
46 |
47 | const TableHead = React.forwardRef(({ className, ...props }, ref) => (
48 | |
55 | ))
56 | TableHead.displayName = "TableHead"
57 |
58 | const TableCell = React.forwardRef(({ className, ...props }, ref) => (
59 | |
63 | ))
64 | TableCell.displayName = "TableCell"
65 |
66 | const TableCaption = React.forwardRef(({ className, ...props }, ref) => (
67 |
71 | ))
72 | TableCaption.displayName = "TableCaption"
73 |
74 | export {
75 | Table,
76 | TableHeader,
77 | TableBody,
78 | TableFooter,
79 | TableHead,
80 | TableRow,
81 | TableCell,
82 | TableCaption,
83 | }
84 |
--------------------------------------------------------------------------------
/src/components/ui/tabs.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import * as TabsPrimitive from "@radix-ui/react-tabs"
3 |
4 | import { cn } from "@/lib/utils"
5 |
6 | const Tabs = TabsPrimitive.Root
7 |
8 | const TabsList = React.forwardRef(({ className, ...props }, ref) => (
9 |
16 | ))
17 | TabsList.displayName = TabsPrimitive.List.displayName
18 |
19 | const TabsTrigger = React.forwardRef(({ className, ...props }, ref) => (
20 |
27 | ))
28 | TabsTrigger.displayName = TabsPrimitive.Trigger.displayName
29 |
30 | const TabsContent = React.forwardRef(({ className, ...props }, ref) => (
31 |
38 | ))
39 | TabsContent.displayName = TabsPrimitive.Content.displayName
40 |
41 | export { Tabs, TabsList, TabsTrigger, TabsContent }
42 |
--------------------------------------------------------------------------------
/src/components/ui/textarea.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 |
3 | import { cn } from "@/lib/utils"
4 |
5 | const Textarea = React.forwardRef(({ className, ...props }, ref) => {
6 | return (
7 | ()
14 | );
15 | })
16 | Textarea.displayName = "Textarea"
17 |
18 | export { Textarea }
19 |
--------------------------------------------------------------------------------
/src/components/ui/toast.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import * as ToastPrimitives from "@radix-ui/react-toast"
3 | import { cva } from "class-variance-authority";
4 | import { X } from "lucide-react"
5 |
6 | import { cn } from "@/lib/utils"
7 |
8 | const ToastProvider = ToastPrimitives.Provider
9 |
10 | const ToastViewport = React.forwardRef(({ className, ...props }, ref) => (
11 |
18 | ))
19 | ToastViewport.displayName = ToastPrimitives.Viewport.displayName
20 |
21 | const toastVariants = cva(
22 | "group pointer-events-auto relative flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-6 pr-8 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full",
23 | {
24 | variants: {
25 | variant: {
26 | default: "border bg-background text-foreground",
27 | destructive:
28 | "destructive group border-destructive bg-destructive text-destructive-foreground",
29 | },
30 | },
31 | defaultVariants: {
32 | variant: "default",
33 | },
34 | }
35 | )
36 |
37 | const Toast = React.forwardRef(({ className, variant, ...props }, ref) => {
38 | return (
39 | ()
43 | );
44 | })
45 | Toast.displayName = ToastPrimitives.Root.displayName
46 |
47 | const ToastAction = React.forwardRef(({ className, ...props }, ref) => (
48 |
55 | ))
56 | ToastAction.displayName = ToastPrimitives.Action.displayName
57 |
58 | const ToastClose = React.forwardRef(({ className, ...props }, ref) => (
59 |
67 |
68 |
69 | ))
70 | ToastClose.displayName = ToastPrimitives.Close.displayName
71 |
72 | const ToastTitle = React.forwardRef(({ className, ...props }, ref) => (
73 |
74 | ))
75 | ToastTitle.displayName = ToastPrimitives.Title.displayName
76 |
77 | const ToastDescription = React.forwardRef(({ className, ...props }, ref) => (
78 |
79 | ))
80 | ToastDescription.displayName = ToastPrimitives.Description.displayName
81 |
82 | export { ToastProvider, ToastViewport, Toast, ToastTitle, ToastDescription, ToastClose, ToastAction };
83 |
--------------------------------------------------------------------------------
/src/components/ui/toaster.jsx:
--------------------------------------------------------------------------------
1 | import {
2 | Toast,
3 | ToastClose,
4 | ToastDescription,
5 | ToastProvider,
6 | ToastTitle,
7 | ToastViewport,
8 | } from "@/components/ui/toast"
9 | import { useToast } from "@/components/ui/use-toast"
10 |
11 | export function Toaster() {
12 | const { toasts } = useToast()
13 |
14 | return (
15 | (
16 | {toasts.map(function ({ id, title, description, action, ...props }) {
17 | return (
18 | (
19 |
20 | {title && {title}}
21 | {description && (
22 | {description}
23 | )}
24 |
25 | {action}
26 |
27 | )
28 | );
29 | })}
30 |
31 | )
32 | );
33 | }
34 |
--------------------------------------------------------------------------------
/src/components/ui/toggle-group.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group"
3 |
4 | import { cn } from "@/lib/utils"
5 | import { toggleVariants } from "@/components/ui/toggle"
6 |
7 | const ToggleGroupContext = React.createContext({
8 | size: "default",
9 | variant: "default",
10 | })
11 |
12 | const ToggleGroup = React.forwardRef(({ className, variant, size, children, ...props }, ref) => (
13 |
17 |
18 | {children}
19 |
20 |
21 | ))
22 |
23 | ToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName
24 |
25 | const ToggleGroupItem = React.forwardRef(({ className, children, variant, size, ...props }, ref) => {
26 | const context = React.useContext(ToggleGroupContext)
27 |
28 | return (
29 | (
36 | {children}
37 | )
38 | );
39 | })
40 |
41 | ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName
42 |
43 | export { ToggleGroup, ToggleGroupItem }
44 |
--------------------------------------------------------------------------------
/src/components/ui/toggle.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import * as TogglePrimitive from "@radix-ui/react-toggle"
3 | import { cva } from "class-variance-authority";
4 |
5 | import { cn } from "@/lib/utils"
6 |
7 | const toggleVariants = cva(
8 | "inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground",
9 | {
10 | variants: {
11 | variant: {
12 | default: "bg-transparent",
13 | outline:
14 | "border border-input bg-transparent hover:bg-accent hover:text-accent-foreground",
15 | },
16 | size: {
17 | default: "h-10 px-3",
18 | sm: "h-9 px-2.5",
19 | lg: "h-11 px-5",
20 | },
21 | },
22 | defaultVariants: {
23 | variant: "default",
24 | size: "default",
25 | },
26 | }
27 | )
28 |
29 | const Toggle = React.forwardRef(({ className, variant, size, ...props }, ref) => (
30 |
34 | ))
35 |
36 | Toggle.displayName = TogglePrimitive.Root.displayName
37 |
38 | export { Toggle, toggleVariants }
39 |
--------------------------------------------------------------------------------
/src/components/ui/tooltip.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import * as TooltipPrimitive from "@radix-ui/react-tooltip"
3 |
4 | import { cn } from "@/lib/utils"
5 |
6 | const TooltipProvider = TooltipPrimitive.Provider
7 |
8 | const Tooltip = TooltipPrimitive.Root
9 |
10 | const TooltipTrigger = TooltipPrimitive.Trigger
11 |
12 | const TooltipContent = React.forwardRef(({ className, sideOffset = 4, ...props }, ref) => (
13 |
21 | ))
22 | TooltipContent.displayName = TooltipPrimitive.Content.displayName
23 |
24 | export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }
25 |
--------------------------------------------------------------------------------
/src/components/ui/use-toast.js:
--------------------------------------------------------------------------------
1 | // Inspired by react-hot-toast library
2 | import * as React from "react"
3 |
4 | const TOAST_LIMIT = 1
5 | const TOAST_REMOVE_DELAY = 1000000
6 |
7 | const actionTypes = {
8 | ADD_TOAST: "ADD_TOAST",
9 | UPDATE_TOAST: "UPDATE_TOAST",
10 | DISMISS_TOAST: "DISMISS_TOAST",
11 | REMOVE_TOAST: "REMOVE_TOAST"
12 | }
13 |
14 | let count = 0
15 |
16 | function genId() {
17 | count = (count + 1) % Number.MAX_SAFE_INTEGER
18 | return count.toString();
19 | }
20 |
21 | const toastTimeouts = new Map()
22 |
23 | const addToRemoveQueue = (toastId) => {
24 | if (toastTimeouts.has(toastId)) {
25 | return
26 | }
27 |
28 | const timeout = setTimeout(() => {
29 | toastTimeouts.delete(toastId)
30 | dispatch({
31 | type: "REMOVE_TOAST",
32 | toastId: toastId,
33 | })
34 | }, TOAST_REMOVE_DELAY)
35 |
36 | toastTimeouts.set(toastId, timeout)
37 | }
38 |
39 | export const reducer = (state, action) => {
40 | switch (action.type) {
41 | case "ADD_TOAST":
42 | return {
43 | ...state,
44 | toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT),
45 | };
46 |
47 | case "UPDATE_TOAST":
48 | return {
49 | ...state,
50 | toasts: state.toasts.map((t) =>
51 | t.id === action.toast.id ? { ...t, ...action.toast } : t),
52 | };
53 |
54 | case "DISMISS_TOAST": {
55 | const { toastId } = action
56 |
57 | // ! Side effects ! - This could be extracted into a dismissToast() action,
58 | // but I'll keep it here for simplicity
59 | if (toastId) {
60 | addToRemoveQueue(toastId)
61 | } else {
62 | state.toasts.forEach((toast) => {
63 | addToRemoveQueue(toast.id)
64 | })
65 | }
66 |
67 | return {
68 | ...state,
69 | toasts: state.toasts.map((t) =>
70 | t.id === toastId || toastId === undefined
71 | ? {
72 | ...t,
73 | open: false,
74 | }
75 | : t),
76 | };
77 | }
78 | case "REMOVE_TOAST":
79 | if (action.toastId === undefined) {
80 | return {
81 | ...state,
82 | toasts: [],
83 | }
84 | }
85 | return {
86 | ...state,
87 | toasts: state.toasts.filter((t) => t.id !== action.toastId),
88 | };
89 | }
90 | }
91 |
92 | const listeners = []
93 |
94 | let memoryState = { toasts: [] }
95 |
96 | function dispatch(action) {
97 | memoryState = reducer(memoryState, action)
98 | listeners.forEach((listener) => {
99 | listener(memoryState)
100 | })
101 | }
102 |
103 | function toast({
104 | ...props
105 | }) {
106 | const id = genId()
107 |
108 | const update = (props) =>
109 | dispatch({
110 | type: "UPDATE_TOAST",
111 | toast: { ...props, id },
112 | })
113 | const dismiss = () => dispatch({ type: "DISMISS_TOAST", toastId: id })
114 |
115 | dispatch({
116 | type: "ADD_TOAST",
117 | toast: {
118 | ...props,
119 | id,
120 | open: true,
121 | onOpenChange: (open) => {
122 | if (!open) dismiss()
123 | },
124 | },
125 | })
126 |
127 | return {
128 | id: id,
129 | dismiss,
130 | update,
131 | }
132 | }
133 |
134 | function useToast() {
135 | const [state, setState] = React.useState(memoryState)
136 |
137 | React.useEffect(() => {
138 | listeners.push(setState)
139 | return () => {
140 | const index = listeners.indexOf(setState)
141 | if (index > -1) {
142 | listeners.splice(index, 1)
143 | }
144 | };
145 | }, [state])
146 |
147 | return {
148 | ...state,
149 | toast,
150 | dismiss: (toastId) => dispatch({ type: "DISMISS_TOAST", toastId }),
151 | };
152 | }
153 |
154 | export { useToast, toast }
155 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | @layer base {
6 | :root {
7 | --background: 0 0% 100%;
8 | --foreground: 222.2 84% 4.9%;
9 |
10 | --card: 0 0% 100%;
11 | --card-foreground: 222.2 84% 4.9%;
12 |
13 | --popover: 0 0% 100%;
14 | --popover-foreground: 222.2 84% 4.9%;
15 |
16 | --primary: 222.2 47.4% 11.2%;
17 | --primary-foreground: 210 40% 98%;
18 |
19 | --secondary: 210 40% 96.1%;
20 | --secondary-foreground: 222.2 47.4% 11.2%;
21 |
22 | --muted: 210 40% 96.1%;
23 | --muted-foreground: 215.4 16.3% 46.9%;
24 |
25 | --accent: 210 40% 96.1%;
26 | --accent-foreground: 222.2 47.4% 11.2%;
27 |
28 | --destructive: 0 84.2% 60.2%;
29 | --destructive-foreground: 210 40% 98%;
30 |
31 | --border: 214.3 31.8% 91.4%;
32 | --input: 214.3 31.8% 91.4%;
33 | --ring: 222.2 84% 4.9%;
34 |
35 | --radius: 0.5rem;
36 | }
37 |
38 | .dark {
39 | --background: 222.2 84% 4.9%;
40 | --foreground: 210 40% 98%;
41 |
42 | --card: 222.2 84% 4.9%;
43 | --card-foreground: 210 40% 98%;
44 |
45 | --popover: 222.2 84% 4.9%;
46 | --popover-foreground: 210 40% 98%;
47 |
48 | --primary: 210 40% 98%;
49 | --primary-foreground: 222.2 47.4% 11.2%;
50 |
51 | --secondary: 217.2 32.6% 17.5%;
52 | --secondary-foreground: 210 40% 98%;
53 |
54 | --muted: 217.2 32.6% 17.5%;
55 | --muted-foreground: 215 20.2% 65.1%;
56 |
57 | --accent: 217.2 32.6% 17.5%;
58 | --accent-foreground: 210 40% 98%;
59 |
60 | --destructive: 0 62.8% 30.6%;
61 | --destructive-foreground: 210 40% 98%;
62 |
63 | --border: 217.2 32.6% 17.5%;
64 | --input: 217.2 32.6% 17.5%;
65 | --ring: 212.7 26.8% 83.9%;
66 | }
67 | }
68 |
69 | @layer base {
70 | * {
71 | @apply border-border;
72 | }
73 | body {
74 | @apply bg-background text-foreground;
75 | }
76 | }
--------------------------------------------------------------------------------
/src/lib/utils.js:
--------------------------------------------------------------------------------
1 | import { clsx } from "clsx"
2 | import { twMerge } from "tailwind-merge"
3 |
4 | export function cn(...inputs) {
5 | return twMerge(clsx(inputs))
6 | }
7 |
--------------------------------------------------------------------------------
/src/main.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom/client'
3 | import App from './App.jsx'
4 | import './index.css'
5 |
6 | ReactDOM.createRoot(document.getElementById('root')).render(
7 |
8 |
9 | ,
10 | )
11 |
--------------------------------------------------------------------------------
/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | module.exports = {
3 | darkMode: ["class"],
4 | content: [
5 | './pages/**/*.{js,jsx}',
6 | './components/**/*.{js,jsx}',
7 | './app/**/*.{js,jsx}',
8 | './src/**/*.{js,jsx}',
9 | ],
10 | prefix: "",
11 | theme: {
12 | container: {
13 | center: true,
14 | padding: "2rem",
15 | screens: {
16 | "2xl": "1400px",
17 | },
18 | },
19 | extend: {
20 | colors: {
21 | border: "hsl(var(--border))",
22 | input: "hsl(var(--input))",
23 | ring: "hsl(var(--ring))",
24 | background: "hsl(var(--background))",
25 | foreground: "hsl(var(--foreground))",
26 | primary: {
27 | DEFAULT: "hsl(var(--primary))",
28 | foreground: "hsl(var(--primary-foreground))",
29 | },
30 | secondary: {
31 | DEFAULT: "hsl(var(--secondary))",
32 | foreground: "hsl(var(--secondary-foreground))",
33 | },
34 | destructive: {
35 | DEFAULT: "hsl(var(--destructive))",
36 | foreground: "hsl(var(--destructive-foreground))",
37 | },
38 | muted: {
39 | DEFAULT: "hsl(var(--muted))",
40 | foreground: "hsl(var(--muted-foreground))",
41 | },
42 | accent: {
43 | DEFAULT: "hsl(var(--accent))",
44 | foreground: "hsl(var(--accent-foreground))",
45 | },
46 | popover: {
47 | DEFAULT: "hsl(var(--popover))",
48 | foreground: "hsl(var(--popover-foreground))",
49 | },
50 | card: {
51 | DEFAULT: "hsl(var(--card))",
52 | foreground: "hsl(var(--card-foreground))",
53 | },
54 | },
55 | borderRadius: {
56 | lg: "var(--radius)",
57 | md: "calc(var(--radius) - 2px)",
58 | sm: "calc(var(--radius) - 4px)",
59 | },
60 | keyframes: {
61 | "accordion-down": {
62 | from: { height: "0" },
63 | to: { height: "var(--radix-accordion-content-height)" },
64 | },
65 | "accordion-up": {
66 | from: { height: "var(--radix-accordion-content-height)" },
67 | to: { height: "0" },
68 | },
69 | },
70 | animation: {
71 | "accordion-down": "accordion-down 0.2s ease-out",
72 | "accordion-up": "accordion-up 0.2s ease-out",
73 | },
74 | },
75 | },
76 | plugins: [require("tailwindcss-animate")],
77 | }
--------------------------------------------------------------------------------
/vite.config.js:
--------------------------------------------------------------------------------
1 | import path from "path";
2 | import react from "@vitejs/plugin-react";
3 | import { defineConfig } from "vite";
4 |
5 | export default defineConfig({
6 | plugins: [react()],
7 | resolve: {
8 | alias: {
9 | "@": path.resolve(__dirname, "./src"),
10 | },
11 | },
12 | });
13 |
--------------------------------------------------------------------------------