├── .editorconfig ├── .eslintignore ├── .eslintrc.json ├── .gitignore ├── .prettierignore ├── .vscode └── settings.json ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── app ├── (auth) │ ├── layout.tsx │ ├── login │ │ └── page.tsx │ └── register │ │ └── page.tsx ├── (docs) │ ├── animated-badge-component │ │ └── page.tsx │ ├── animated-beam-component │ │ └── page.tsx │ ├── beam-card │ │ └── page.tsx │ ├── colored-button │ │ └── page.tsx │ ├── confetti-poll │ │ └── page.tsx │ ├── create-new-component │ │ └── page.tsx │ ├── designfast │ │ └── page.tsx │ ├── ez-SaaS │ │ └── page.tsx │ ├── ez-ai │ │ └── page.tsx │ ├── ez-beautiful │ │ └── page.tsx │ ├── ez-blog │ │ └── page.tsx │ ├── ez-chatbot │ │ └── page.tsx │ ├── ez-dashboard │ │ └── page.tsx │ ├── ez-design │ │ └── page.tsx │ ├── ez-docs │ │ └── page.tsx │ ├── ez-glow │ │ └── page.tsx │ ├── ez-grids │ │ └── page.tsx │ ├── ez-haze │ │ └── page.tsx │ ├── ez-indigo │ │ └── page.tsx │ ├── ez-landing-docs │ │ └── page.tsx │ ├── ez-marketplace │ │ └── page.tsx │ ├── ez-newsletter │ │ └── page.tsx │ ├── ez-nextui │ │ └── page.tsx │ ├── ez-notes │ │ └── page.tsx │ ├── ez-portfolio-2 │ │ └── page.tsx │ ├── ez-premium │ │ └── page.tsx │ ├── ez-red │ │ └── page.tsx │ ├── ez-shots │ │ └── page.tsx │ ├── ez-story │ │ └── page.tsx │ ├── ez-tmp │ │ └── page.tsx │ ├── ez-tmp2 │ │ └── page.tsx │ ├── ez-tmp3 │ │ └── page.tsx │ ├── ez-tmp4 │ │ └── page.tsx │ ├── ez-tmp5 │ │ └── page.tsx │ ├── ez-waitlist │ │ └── page.tsx │ ├── ezzzzz-portfolio │ │ └── page.tsx │ ├── feature-card-component │ │ └── page.tsx │ ├── file-upload │ │ └── page.tsx │ ├── firefly-button-component │ │ └── page.tsx │ ├── glitch-text-component │ │ └── page.tsx │ ├── hexagon-hero-component │ │ └── page.tsx │ ├── highlighter │ │ └── page.tsx │ ├── idea-form-component │ │ └── page.tsx │ ├── introduction │ │ └── page.tsx │ ├── key-button-component │ │ └── page.tsx │ ├── launchpad-component │ │ └── page.tsx │ ├── logo-particles-component │ │ └── page.tsx │ ├── pixel-card-component │ │ └── page.tsx │ ├── quotesai │ │ └── page.tsx │ ├── reaction-bar │ │ └── page.tsx │ ├── retro │ │ └── page.tsx │ ├── search-command-component │ │ └── page.tsx │ ├── signature-animation-component │ │ └── page.tsx │ ├── sparkle-button-component │ │ └── page.tsx │ ├── tilt-motion │ │ └── page.tsx │ └── transactionlist │ │ └── page.tsx ├── blog │ ├── [slug] │ │ ├── Comments.tsx │ │ ├── MDXContent.tsx │ │ ├── NextArticle.tsx │ │ ├── PostBody.tsx │ │ ├── RelatedPosts.tsx │ │ ├── ShareButtons.tsx │ │ ├── mdx-components.tsx │ │ ├── opengraph-image.tsx │ │ └── page.tsx │ └── page.tsx ├── component │ └── page.tsx ├── easy-mvp-pricing │ └── page.tsx ├── faqs │ └── page.tsx ├── features │ └── page.tsx ├── feed.xml │ └── route.ts ├── integrations │ └── page.tsx ├── layout-metadata.tsx ├── layout.tsx ├── page.tsx ├── pricing │ └── page.tsx ├── robots.ts ├── sitemap.xml │ └── route.tsx ├── templates │ └── page.tsx └── testimonials │ └── page.tsx ├── components.json ├── components ├── DisqusComments.tsx ├── DisqusCommentsWrapper.tsx ├── MDXImage.tsx ├── ROISection.tsx ├── ShareButtons.tsx ├── ad-banner.tsx ├── announcement.tsx ├── back-button.tsx ├── blog-lead-magnet-banner.tsx ├── callout.tsx ├── cta-section.tsx ├── easy-hero.tsx ├── easyui │ ├── animated-badge.tsx │ ├── animated-beam.tsx │ ├── beam-button.tsx │ ├── beam-card.tsx │ ├── colored-button.tsx │ ├── confetti-poll.tsx │ ├── create-new.tsx │ ├── feature-card.tsx │ ├── file-upload-card.tsx │ ├── firefly-button.tsx │ ├── glitch-text.tsx │ ├── hexagon-hero.tsx │ ├── highlighter.tsx │ ├── idea-form.tsx │ ├── key-button.tsx │ ├── launchpad.tsx │ ├── logo-particles.tsx │ ├── pixel-card.tsx │ ├── reaction-bar.tsx │ ├── search-command.tsx │ ├── signature-animation.tsx │ ├── sparkle-button.tsx │ ├── tilt-motion.tsx │ └── transaction-list.tsx ├── icons.tsx ├── magicui │ ├── animated-beam-multiple-outputs.tsx │ ├── animated-beam.tsx │ ├── animated-gradient-text.tsx │ ├── animated-shiny-text.tsx │ ├── animated-subscribe-button.tsx │ ├── avatar-circles.tsx │ ├── bento-grid.tsx │ ├── border-beam.tsx │ ├── linear-gradient.tsx │ ├── magic-card.tsx │ ├── marquee.tsx │ ├── orbiting-circles.tsx │ └── sparkles-text.tsx ├── main-nav.tsx ├── mdx-card.tsx ├── mdx-components.tsx ├── page-header.tsx ├── props-table-transactionlist.tsx ├── showcase.tsx ├── site-banner.tsx ├── site-footer.tsx ├── site-header.tsx ├── tailwind-indicator.tsx ├── theme-provider.tsx ├── theme-toggle.tsx └── ui │ ├── accordion.tsx │ ├── avatar.tsx │ ├── badge.tsx │ ├── button.tsx │ ├── calendar.tsx │ ├── card.tsx │ ├── checkbox.tsx │ ├── command.tsx │ ├── create-new.tsx │ ├── dialog.tsx │ ├── dropdown-menu.tsx │ ├── firefly-button.tsx │ ├── glitch-text.tsx │ ├── input.tsx │ ├── label.tsx │ ├── progress.tsx │ ├── rainbow-button.tsx │ ├── scroll-area.tsx │ ├── separator.tsx │ ├── sheet.tsx │ ├── sidebar.tsx │ ├── signature-animation.tsx │ ├── skeleton.tsx │ ├── slider.tsx │ ├── switch.tsx │ ├── table.tsx │ ├── tabs.tsx │ ├── toast.tsx │ ├── toaster.tsx │ ├── tooltip.tsx │ └── use-toast.ts ├── config └── site.ts ├── contentlayer.config.ts ├── hooks └── use-mobile.tsx ├── lib ├── blog-utils.ts ├── fonts.ts └── utils.ts ├── next-env.d.ts ├── next.config.mjs ├── package.json ├── pnpm-lock.yaml ├── postcss.config.cjs ├── posts ├── 50-free-website-templates.mdx ├── best-free-nextjs-website-templates-2025.mdx ├── best-react-components-easy-ui-2025.mdx ├── design-systems-2025-guide.mdx ├── easyui-diaries-designfast.mdx ├── free-react-ui-templates-2025.mdx └── ui-easy-nextui-templates-guide.mdx ├── prettier.config.js ├── public ├── AppStore-60x60@3x.svg ├── Books-60x60@3x 3.svg ├── Camera-Light-60x60@3x.svg ├── Dock.svg ├── FaceTime-Light-60x60@3x.svg ├── Files-Light-60x60@3x.svg ├── Maps-60x60@3x 4.svg ├── Option-1.svg ├── Option-2.svg ├── Option-3.svg ├── Option-4.svg ├── Option.svg ├── Reminders-60x60@3x 2.png ├── Reminders-60x60@3x 2.svg ├── Screenshot 2024-10-18 at 4.35.47 AM.png ├── analytics-blog-image.png ├── android-chrome-192x192.png ├── android-chrome-512x512.png ├── apple-touch-icon.png ├── bird.jpg ├── blog-images │ ├── design-system-1.jpg │ ├── design-system-2.png │ ├── design-system-3.png │ └── design-system-4.png ├── components-json │ ├── animated-badge.json │ ├── animated-beam.json │ ├── beam-button.json │ ├── beam-card.json │ ├── beam-code.json │ ├── colored-button.json │ ├── confetti-poll.json │ ├── create-new.json │ ├── feature-card.json │ ├── file-upload-card.json │ ├── firefly-button.json │ ├── glitch-text.json │ ├── hexagon-hero.json │ ├── highlighter.json │ ├── idea-form.json │ ├── key-button.json │ ├── launchpad.json │ ├── pixel-card.json │ ├── reaction-bar.json │ ├── search-command.json │ ├── signature-animation.json │ ├── sparkle-button.json │ ├── tilt-motion.json │ └── transaction-list.json ├── dashboard-dark.png ├── dashboard-light.png ├── designfast-img.png ├── easy-chatbot.png ├── easy-waitlist.png ├── ez-SaaS.png ├── ez-ai.png ├── ez-beautiful.png ├── ez-blog.png ├── ez-chatbot.png ├── ez-dashboard.png ├── ez-design.png ├── ez-designfast.png ├── ez-docs.png ├── ez-glow.png ├── ez-gloww.png ├── ez-grids.png ├── ez-haze.png ├── ez-indigo.png ├── ez-landing-docs.png ├── ez-marketplace.png ├── ez-newsletter.png ├── ez-nextui.png ├── ez-notes.png ├── ez-portfolio-2.png ├── ez-portfolio.png ├── ez-premium.png ├── ez-quotes.png ├── ez-red.png ├── ez-retro.png ├── ez-shots.png ├── ez-story.png ├── ez-tmp2.png ├── ez-tmp3.png ├── ez-tmp4.png ├── ez-tmp5.png ├── eztmp1-img.png ├── favicon copy.ico ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon.ico ├── logo.png ├── logo.svg ├── next copy.svg ├── next.svg ├── og.png ├── quotesai-img.png ├── retro.png ├── site.webmanifest ├── star-dark.svg ├── star-light.svg ├── testimonials │ ├── dally.jpeg │ ├── danny.jpeg │ ├── jerome.jpeg │ ├── marcello.jpeg │ └── sayed.jpeg ├── thirteen.svg ├── v0-preview │ ├── animated-badge.json │ ├── animated-beam.json │ ├── beam-card.json │ ├── colored-button.json │ ├── confetti-poll.json │ ├── create-new.json │ ├── feature-card.json │ ├── file-upload-card.json │ ├── firefly-button.json │ ├── glitch-text.json │ ├── hexagon-hero.json │ ├── highlighter.json │ ├── idea-form.json │ ├── key-button.json │ ├── pixel-card.json │ ├── reaction-bar.json │ ├── search-command.json │ ├── signature-animation.json │ ├── sparkle-button.json │ ├── tilt-motion.json │ └── transaction-list.json └── vercel.svg ├── scripts └── build.ts ├── styles └── globals.css ├── tailwind.config.js ├── tsconfig.json ├── tsconfig.tsbuildinfo └── types └── nav.ts /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 2 8 | indent_style = space 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | dist/* 2 | .cache 3 | public 4 | node_modules 5 | *.esm.js 6 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/eslintrc", 3 | "root": true, 4 | "extends": [ 5 | "next/core-web-vitals", 6 | "prettier", 7 | "plugin:tailwindcss/recommended" 8 | ], 9 | "plugins": ["tailwindcss"], 10 | "rules": { 11 | "@next/next/no-html-link-for-pages": "off", 12 | "react/jsx-key": "off", 13 | "tailwindcss/no-custom-classname": "off" 14 | }, 15 | "settings": { 16 | "tailwindcss": { 17 | "callees": ["cn"], 18 | "config": "tailwind.config.js" 19 | }, 20 | "next": { 21 | "rootDir": ["./"] 22 | } 23 | }, 24 | "overrides": [ 25 | { 26 | "files": ["*.ts", "*.tsx"], 27 | "parser": "@typescript-eslint/parser" 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules 5 | .pnp 6 | .pnp.js 7 | 8 | # testing 9 | coverage 10 | 11 | # next.js 12 | .next/ 13 | out/ 14 | build 15 | 16 | # misc 17 | .DS_Store 18 | *.pem 19 | 20 | # debug 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | .pnpm-debug.log* 25 | 26 | # local env files 27 | .env.local 28 | .env.development.local 29 | .env.test.local 30 | .env.production.local 31 | 32 | # turbo 33 | .turbo 34 | 35 | .contentlayer 36 | .env 37 | .env.* 38 | # Sentry Config File 39 | .env.sentry-build-plugin 40 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | cache 2 | .cache 3 | package.json 4 | package-lock.json 5 | public 6 | CHANGELOG.md 7 | .yarn 8 | dist 9 | node_modules 10 | .next 11 | build 12 | .contentlayer -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib", 3 | "typescript.enablePromptUseWorkspaceTsdk": true 4 | } 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to EasyUI 2 | 3 | Thank you for your interest in contributing to EasyUI! We appreciate your support and look forward to your contributions. This guide will help you understand the directory structure and provide detailed instructions on how to add a new component to EasyUI. 4 | 5 | **You only need to add 1 file + edit 1 file to add a new template** and it only takes around 10 minutes of work! 6 | 7 | Once done, open a pull request from your forked repo to the main repo [here](https://github.com/DarkInventor/easy-ui/compare). 8 | 9 | ## Getting Started 10 | 11 | ### Fork and Clone the Repository 12 | 13 | 1. **Fork this repository** 14 | 15 | Click [here](https://github.com/DarkInventor/easy-ui/fork) to fork the repository. 16 | 17 | 2. **Clone your forked repository to your local machine** 18 | 19 | ```bash 20 | git clone https://github.com//easy-ui.git 21 | ``` 22 | 23 | 3. **Navigate to the project directory** 24 | 25 | ```bash 26 | cd easy-ui 27 | ``` 28 | 29 | 4. **Create a new branch for your changes** 30 | 31 | ```bash 32 | git checkout -b my-new-branch 33 | ``` 34 | 35 | 5. **Install dependencies** 36 | 37 | ```bash 38 | pnpm i 39 | ``` 40 | 41 | 6. **Create a `.env.local` file** 42 | 43 | ```bash 44 | touch .env.local && echo "NEXT_PUBLIC_APP_URL=http://localhost:3000" > .env.local 45 | ``` 46 | 47 | 7. **Run the project** 48 | ```bash 49 | pnpm dev 50 | ``` 51 | 52 | ## Adding a New Template 53 | 54 | ### 1. To add your template docs to EasyUI 55 | 56 | you will need to add inside `typescript app/(docs)/`. 57 | 58 | ### 2. To add Your Template inside Templates section 59 | 60 | You have to update `/app/templates/page.tsx` 61 | 62 | This step require you to add a photo + video of your template. I use Screen Studio to record the video and Handbrake it to decrease the size of video and add it to Cloudflare R2 bucket. If you don't have Screenstudio and Handbreak access please mention it in the contribution. I will add the photo + video from my side. 63 | 64 | ```typescript 65 | (window.location.href = "/ez-")} 68 | onMouseEnter={handleMouseEnter} 69 | onMouseLeave={handleMouseLeave} 70 | > 71 |
72 | EasyWaitlist 77 |
78 | 85 |

86 | Easy NextUI 87 |

88 |

89 | Landing page built using NextUI 90 |

91 |
92 | ``` 93 | 94 | ## Ask for Help 95 | 96 | For any help or questions, please open a new GitHub issue. 97 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Easy UI 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 | ![easy-uiiii](https://github.com/DarkInventor/easy-ui/assets/67015517/d6865ba3-d092-4cfb-b859-7ce2a9be2570) 2 | 3 |

Easy UI

4 |

5 | High Quality Templates for Web Designers 6 |

7 |
8 | GitHub Repo stars 9 | Twitter Follow 10 | License 11 | Discord 12 |
13 | 14 | 15 | ## Documentation 16 | 17 | Visit https://www.easyui.pro/templates to view the templates. 18 | 19 | ## Contributing 20 | 21 | Visit our [contributing guide](https://github.com/DarkInventor/easy-ui/blob/main/CONTRIBUTING.md) to learn how to contribute. It only takes ~5 minutes to add your own! 22 | 23 | ## Let's talk 24 | Book us with Cal.com 25 | 26 | ## Authors 27 | 28 | 29 | 30 | 31 | 32 | ## Deploy 33 | 34 | [![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2FDarkInventor%2Feasy-ui) 35 | 36 | ## Stats 37 | 38 | ![Alt](https://repobeats.axiom.co/api/embed/f674d549a6903e82858b214c93f9fb3f3168d442.svg "Repobeats analytics image") 39 | 40 | ## License 41 | 42 | Licensed under the [MIT license](https://github.com/DarkInventor/easy-ui/blob/main/LICENSE.md). 43 | -------------------------------------------------------------------------------- /app/(auth)/layout.tsx: -------------------------------------------------------------------------------- 1 | interface AuthLayoutProps { 2 | children: React.ReactNode 3 | } 4 | 5 | export default function AuthLayout({ children }: AuthLayoutProps) { 6 | return
{children}
7 | } -------------------------------------------------------------------------------- /app/(auth)/login/page.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import Image from "next/image" 3 | import Link from "next/link" 4 | 5 | import { Button } from "@/components/ui/button" 6 | import { Input } from "@/components/ui/input" 7 | import { Label } from "@/components/ui/label" 8 | 9 | export default function LoginPage() { 10 | return ( 11 |
12 |
13 |
14 | Logo 15 |

Welcome back

16 |

17 | Login to your account 18 |

19 | 20 |
21 |
22 | 23 | 30 |
31 | 32 | 35 | {/* */} 38 |
39 |
40 | 41 | 42 | Don't have an account? Sign up 43 | 44 |
45 |
46 |
47 |
48 | Image 55 |
56 |
57 | ) 58 | } 59 | -------------------------------------------------------------------------------- /app/(auth)/register/page.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import Image from "next/image" 3 | import Link from "next/link" 4 | 5 | import { Button } from "@/components/ui/button" 6 | import { Input } from "@/components/ui/input" 7 | import { Label } from "@/components/ui/label" 8 | 9 | export default function LoginForm() { 10 | return ( 11 |
12 |
13 |
14 |
15 | Logo 16 |

Create an account

17 |

18 | Enter your email below to create your account 19 |

20 |
21 |
22 |
23 | 24 | 31 |
32 | {/*
33 |
34 | 35 | 39 | Forgot your password? 40 | 41 |
42 | 43 |
*/} 44 | 47 | {/* */} 50 |
51 |
52 | 53 | 54 | Don't have an account? Login 55 | 56 |
57 |
58 |
59 |
60 | {/* */} 66 |
67 |
68 | ) 69 | } -------------------------------------------------------------------------------- /app/blog/[slug]/Comments.tsx: -------------------------------------------------------------------------------- 1 | // import DisqusCommentsWrapper from '@/components/DisqusCommentsWrapper' 2 | // import { Post } from 'contentlayer/generated' 3 | 4 | // export default function Comments({ post }: { post: Post }) { 5 | // return ( 6 | // 11 | // ) 12 | // } 13 | 14 | import dynamic from 'next/dynamic' 15 | 16 | const DisqusComments = dynamic(() => import('@/components/DisqusComments'), { 17 | ssr: false, 18 | }) 19 | 20 | // @ts-ignore 21 | export default function Comments({ post }) { 22 | return ( 23 | 28 | ) 29 | } -------------------------------------------------------------------------------- /app/blog/[slug]/MDXContent.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { useMDXComponent } from 'next-contentlayer/hooks' 4 | import Image from 'next/image' 5 | 6 | const components = { 7 | img: ({ src, alt }: { src: string; alt: string }) => ( 8 | {alt} 15 | ), 16 | } 17 | 18 | interface MDXContentProps { 19 | code: string 20 | } 21 | 22 | export default function MDXContent({ code }: MDXContentProps) { 23 | const Component = useMDXComponent(code) 24 | // @ts-ignore 25 | return 26 | } 27 | -------------------------------------------------------------------------------- /app/blog/[slug]/NextArticle.tsx: -------------------------------------------------------------------------------- 1 | import Link from 'next/link' 2 | import { ChevronRight } from 'lucide-react' 3 | import { allPosts } from 'contentlayer/generated' 4 | 5 | interface NextArticleProps { 6 | currentSlug: string 7 | } 8 | 9 | export default function NextArticle({ currentSlug }: NextArticleProps) { 10 | const currentIndex = allPosts.findIndex( 11 | (post) => post._raw.flattenedPath === currentSlug 12 | ) 13 | const nextPost = allPosts[currentIndex + 1] || null 14 | 15 | if (!nextPost) return null 16 | 17 | return ( 18 | 23 |

24 | Next Article 25 |

26 |
27 |
28 |
29 |
30 | 31 | {nextPost.title} 32 | 33 | 34 |
35 |
36 | 37 | ) 38 | } -------------------------------------------------------------------------------- /app/blog/[slug]/PostBody.tsx: -------------------------------------------------------------------------------- 1 | // import React from 'react' 2 | 3 | // export default function PostBody({ children }: { children: React.ReactNode }) { 4 | // return ( 5 | //
6 | // {children} 7 | //
8 | // ) 9 | // } 10 | 11 | // @ts-ignore 12 | export default function PostBody({ children }) { 13 | return ( 14 |
15 | {children} 16 |
17 | ) 18 | } -------------------------------------------------------------------------------- /app/blog/[slug]/RelatedPosts.tsx: -------------------------------------------------------------------------------- 1 | import Link from 'next/link' 2 | import { allPosts } from 'contentlayer/generated' 3 | 4 | // @ts-ignore 5 | export default function RelatedPosts({ currentPost }) { 6 | const relatedPosts = allPosts 7 | // @ts-ignore 8 | .filter(p => p._id !== currentPost._id && p.tags.some(tag => currentPost.tags.includes(tag))) 9 | .slice(0, 3) 10 | 11 | if (relatedPosts.length === 0) return null 12 | 13 | return ( 14 |
15 |

Related Posts

16 |
    17 | {relatedPosts.map(post => ( 18 |
  • 19 | {post.title} 20 |
  • 21 | ))} 22 |
23 |
24 | ) 25 | } -------------------------------------------------------------------------------- /app/blog/[slug]/ShareButtons.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { Button } from "@/components/ui/button" 4 | import { Share2, Twitter } from 'lucide-react' 5 | 6 | interface ShareButtonsProps { 7 | title: string 8 | url: string 9 | } 10 | 11 | export default function ShareButtons({ title, url }: ShareButtonsProps) { 12 | const handleShare = () => { 13 | window.open(`https://twitter.com/intent/tweet?text=${encodeURIComponent(title)}&url=${encodeURIComponent(url)}`, '_blank') 14 | } 15 | 16 | return ( 17 |
18 | 22 |
23 | 26 |
27 |
28 | ) 29 | } -------------------------------------------------------------------------------- /app/blog/[slug]/mdx-components.tsx: -------------------------------------------------------------------------------- 1 | import Image from "next/image" 2 | // @ts-ignore 3 | import { MDXComponents } from "mdx/types" 4 | 5 | export const components: MDXComponents = { 6 | // @ts-ignore 7 | img: (props) => ( 8 | {props.alt 15 | ), 16 | // Add other custom components here 17 | } 18 | -------------------------------------------------------------------------------- /app/blog/[slug]/opengraph-image.tsx: -------------------------------------------------------------------------------- 1 | import { ImageResponse } from 'next/og' 2 | import { allPosts } from 'contentlayer/generated' 3 | 4 | export const size = { 5 | width: 1200, 6 | height: 630, 7 | } 8 | 9 | export const contentType = 'image/png' 10 | 11 | export default async function Image({ params }: { params: { slug: string } }) { 12 | const post = allPosts.find((post) => post._raw.flattenedPath === params.slug) 13 | // @ts-ignore 14 | if (!post) return new ImageResponse('Post not found') 15 | // @ts-ignore 16 | return new ImageResponse( 17 | // @ts-ignore 18 | ( 19 |
30 | {post.title} 31 |
32 | ), 33 | { ...size } 34 | ) 35 | } -------------------------------------------------------------------------------- /app/faqs/page.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import { 3 | Accordion, 4 | AccordionContent, 5 | AccordionItem, 6 | AccordionTrigger, 7 | } from "@/components/ui/accordion" 8 | 9 | export default function FaqPage() { 10 | return ( 11 | 12 | 13 | Is Easy UI 100% free and open-source? 14 | 15 | Yes, all our templates are completely free and open-source. 16 | 17 | 18 | 19 | How do I use the Easy UI templates? 20 | 21 | Browse and select a template, download it, or clone it from our GitHub repository, and start using it. 22 | 23 | 24 | 25 | What tech stack are these templates built with and how? 26 | 27 | Our templates are built with Next.js, React, MagicUI, ShadCNUI, Tailwind CSS, and Framer Motion, ensuring a modern, responsive, and seamless user experience. 28 | 29 | 30 | 31 | ) 32 | } 33 | -------------------------------------------------------------------------------- /app/feed.xml/route.ts: -------------------------------------------------------------------------------- 1 | import { allPosts } from "contentlayer/generated" 2 | import { siteConfig } from "@/config/site" 3 | 4 | function escapeXml(unsafe: string): string { 5 | return unsafe.replace(/[<>&'"]/g, (c) => { 6 | switch (c) { 7 | case "<": 8 | return "<" 9 | case ">": 10 | return ">" 11 | case "&": 12 | return "&" 13 | case "'": 14 | return "'" 15 | case '"': 16 | return """ 17 | } 18 | return c 19 | }) 20 | } 21 | 22 | export async function GET() { 23 | // Sort posts by date (newest first) 24 | const posts = allPosts.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime()) 25 | 26 | // Create RSS feed 27 | const rss = ` 28 | 29 | 30 | ${escapeXml(siteConfig.name)} Blog 31 | https://www.easyui.pro/blog 32 | ${escapeXml("Explore the latest insights, trends, and tutorials in UI design and web development.")} 33 | en 34 | ${new Date().toUTCString()} 35 | 36 | ${posts 37 | .map((post) => { 38 | return ` 39 | 40 | ${escapeXml(post.title)} 41 | https://www.easyui.pro/blog/${post._raw.flattenedPath} 42 | https://www.easyui.pro/blog/${post._raw.flattenedPath} 43 | 44 | ${new Date(post.date).toUTCString()} 45 | ${post.coverImage ? `` : ""} 46 | 47 | ` 48 | }) 49 | .join("")} 50 | 51 | ` 52 | 53 | // Return the RSS feed with proper headers 54 | return new Response(rss, { 55 | headers: { 56 | "Content-Type": "application/xml", 57 | "Cache-Control": "public, s-maxage=1200, stale-while-revalidate=600", 58 | }, 59 | }) 60 | } 61 | 62 | -------------------------------------------------------------------------------- /app/layout-metadata.tsx: -------------------------------------------------------------------------------- 1 | import { Metadata } from "next" 2 | import { siteConfig } from "@/config/site" 3 | 4 | export const metadata: Metadata = { 5 | metadataBase: new URL("https://www.easyui.pro/"), 6 | title: { 7 | default: siteConfig.name, 8 | template: `%s - ${siteConfig.name}`, 9 | }, 10 | description: siteConfig.description, 11 | themeColor: [ 12 | { media: "(prefers-color-scheme: light)", color: "white" }, 13 | { media: "(prefers-color-scheme: dark)", color: "black" }, 14 | ], 15 | icons: { 16 | icon: "/favicon-32x32.ico", 17 | shortcut: "/favicon-16x16.png", 18 | apple: "/apple-touch-icon.png", 19 | }, 20 | openGraph: { 21 | url: "https://www.easyui.pro/", 22 | title: siteConfig.name, 23 | description: siteConfig.description, 24 | images: [{ url: "https://pub-0cd6f9d4131f4f79ac40219248ae64db.r2.dev/og.png", width: 800, height: 600, alt: siteConfig.name }], 25 | siteName: siteConfig.name, 26 | }, 27 | twitter: { 28 | card: "summary_large_image", 29 | }, 30 | } -------------------------------------------------------------------------------- /app/robots.ts: -------------------------------------------------------------------------------- 1 | import type { MetadataRoute } from 'next' 2 | 3 | export default function robots(): MetadataRoute.Robots { 4 | return { 5 | rules: { 6 | userAgent: '*', 7 | allow: '/', 8 | }, 9 | sitemap: 'https://easyui.pro/sitemap.xml', 10 | } 11 | } -------------------------------------------------------------------------------- /components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "default", 4 | "tailwind": { 5 | "config": "tailwind.config.js", 6 | "css": "styles/globals.css", 7 | "baseColor": "slate", 8 | "cssVariables": true 9 | }, 10 | "rsc": false, 11 | "aliases": { 12 | "utils": "@/lib/utils", 13 | "components": "@/components" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /components/DisqusComments.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { DiscussionEmbed } from 'disqus-react' 4 | 5 | interface DisqusCommentsProps { 6 | url: string 7 | identifier: string 8 | title: string 9 | } 10 | 11 | export default function DisqusComments({ url, identifier, title }: DisqusCommentsProps) { 12 | return ( 13 | 21 | ) 22 | } -------------------------------------------------------------------------------- /components/DisqusCommentsWrapper.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import dynamic from 'next/dynamic' 4 | 5 | const DisqusComments = dynamic(() => import('@/components/DisqusComments'), { 6 | ssr: false, 7 | }) 8 | 9 | interface DisqusCommentsWrapperProps { 10 | url: string 11 | identifier: string 12 | title: string 13 | } 14 | 15 | export default function DisqusCommentsWrapper({ url, identifier, title }: DisqusCommentsWrapperProps) { 16 | return 17 | } 18 | 19 | -------------------------------------------------------------------------------- /components/MDXImage.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import Image from 'next/image' 4 | import { ImageProps } from 'next/image' 5 | 6 | interface MDXImageProps extends Omit { 7 | src: string 8 | alt: string 9 | } 10 | 11 | export default function MDXImage({ src, alt, ...props }: MDXImageProps) { 12 | return ( 13 | {alt} 20 | ) 21 | } -------------------------------------------------------------------------------- /components/ShareButtons.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { Button } from "@/components/ui/button" 4 | import { Share2, Twitter } from 'lucide-react' 5 | 6 | interface ShareButtonsProps { 7 | title: string 8 | url: string 9 | } 10 | 11 | export default function ShareButtons({ title, url }: ShareButtonsProps) { 12 | const handleShare = () => { 13 | window.open(`https://twitter.com/intent/tweet?text=${encodeURIComponent(title)}&url=${encodeURIComponent(url)}`, '_blank') 14 | } 15 | 16 | const handleProfileVisit = () => { 17 | window.open(`https://twitter.com/kathanmehtaa`, '_blank') 18 | } 19 | 20 | return ( 21 |
22 | 26 |
27 | 30 |
31 |
32 | ) 33 | } -------------------------------------------------------------------------------- /components/ad-banner.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import React, { useEffect, useState } from "react" 4 | import { AnimatePresence, motion } from "framer-motion" 5 | 6 | const AdBanner = () => { 7 | const [isVisible, setIsVisible] = useState(true) 8 | 9 | useEffect(() => { 10 | const timer = setTimeout(() => { 11 | setIsVisible(false) 12 | }, 10000) // Close after 10 seconds 13 | 14 | return () => clearTimeout(timer) 15 | }, []) 16 | 17 | const handleClose = () => { 18 | setIsVisible(false) 19 | } 20 | 21 | return ( 22 | 23 | {isVisible && ( 24 | 33 | 39 |
40 |
41 |

42 | Need Custom Development? 43 |

44 |

45 | We've got you covered! 46 |

47 |
    48 |
  • Custom landing pages
  • 49 |
  • Full-stack web applications
  • 50 |
  • Complete software solutions
  • 51 |
  • 24/7 expert support
  • 52 |
53 |
54 |
55 |
56 |

57 | Need Custom Development? 58 |

59 |

60 | We've got you covered! 61 |

62 |
63 | window.open("https://mvp.easyui.pro/", "_blank")} 68 | > 69 | Get Started 70 | 71 |
72 | window.open("https://mvp.easyui.pro/", "_blank")} 77 | > 78 | Get Started Now 79 | 80 |

81 | Simple pricing, no hidden fees 82 |

83 |
84 | 90 | ✕ 91 | 92 |
93 | )} 94 |
95 | ) 96 | } 97 | 98 | export default AdBanner -------------------------------------------------------------------------------- /components/announcement.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { cn } from "@/lib/utils"; 4 | import AnimatedGradientText from "@/components/magicui/animated-gradient-text"; 5 | import { ChevronRight } from "lucide-react"; 6 | 7 | export function Announcement() { 8 | return ( 9 | 10 | 11 | 🎉
{" "} 12 |
18 | Introducing Easy UI 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /components/back-button.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { useRouter } from 'next/navigation'; 4 | import { Button } from '@/components/ui/button'; 5 | 6 | export function BackButton() { 7 | const router = useRouter(); 8 | 9 | return ( 10 | 13 | ); 14 | } -------------------------------------------------------------------------------- /components/blog-lead-magnet-banner.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import { ArrowRight, Sparkles } from "lucide-react" 4 | import { Button } from "@/components/ui/button" 5 | import { Card, CardContent } from "@/components/ui/card" 6 | import { motion } from "framer-motion" 7 | 8 | export default function BlogLeadMagnetBanner() { 9 | return ( 10 | 16 | 17 | 18 | {/*
19 | 20 | Premium Templates 21 |
*/} 22 | 23 |
24 |

25 | Want to save time? Get beautifully designed website templates with Easy UI Premium. 26 |

27 |

28 | 30+ beautiful sections and templates built with React, Typescript, Tailwind CSS, and Framer Motion. 29 |

30 |
31 | 32 | 33 | 41 | 42 |
43 |
44 |
45 | ) 46 | } 47 | 48 | -------------------------------------------------------------------------------- /components/callout.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "@/lib/utils" 2 | 3 | interface CalloutProps { 4 | icon?: string 5 | children?: React.ReactNode 6 | type?: "default" | "warning" | "danger" 7 | } 8 | 9 | export function Callout({ 10 | children, 11 | icon, 12 | type = "default", 13 | ...props 14 | }: CalloutProps) { 15 | return ( 16 |
23 | {icon && {icon}} 24 |
{children}
25 |
26 | ) 27 | } -------------------------------------------------------------------------------- /components/cta-section.tsx: -------------------------------------------------------------------------------- 1 | import { buttonVariants } from "@/components/ui/button"; 2 | import { cn } from "@/lib/utils"; 3 | import { ChevronRight, HeartHandshake } from "lucide-react"; 4 | 5 | export default function CTASection() { 6 | return ( 7 |
8 |
9 |
10 |
11 | 12 |
13 |
14 |

15 | Looking for MVP instead? 16 |

17 | {/*

Check Out Easy MVP

*/} 18 | 28 | Check Out Easy MVP 29 | 30 | 31 |
32 |
33 |
34 |
35 |
36 | ); 37 | } -------------------------------------------------------------------------------- /components/easyui/animated-badge.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import React from 'react' 4 | import { cn } from '@/lib/utils' 5 | 6 | interface AnimatedBadgeProps extends React.HTMLAttributes { 7 | text: string 8 | bgColor?: string 9 | textColor?: string 10 | gradientColor?: string 11 | animationDuration?: string 12 | size?: 'sm' | 'md' | 'lg' 13 | } 14 | 15 | export default function AnimatedBadge({ 16 | text, 17 | bgColor = 'bg-green-900', 18 | textColor = 'text-green-300', 19 | gradientColor = 'from-transparent via-emerald-600 to-transparent', 20 | animationDuration = '4s', 21 | size = 'md', 22 | className, 23 | ...props 24 | }: AnimatedBadgeProps) { 25 | const sizeClasses = { 26 | sm: 'text-xs', 27 | md: 'text-sm', 28 | lg: 'text-base', 29 | } 30 | 31 | return ( 32 |
40 |
49 |
57 | {text} 58 |
59 |
60 | ) 61 | } 62 | 63 | -------------------------------------------------------------------------------- /components/easyui/beam-card.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import { motion, useMotionTemplate, useMotionValue } from "framer-motion" 5 | import { cn } from "@/lib/utils" 6 | 7 | interface BeamCardProps extends React.HTMLAttributes { 8 | beamColor?: string 9 | glowColor?: string 10 | borderColor?: string 11 | hoverColor?: string 12 | } 13 | 14 | export const BeamCard = React.forwardRef( 15 | ( 16 | { 17 | className, 18 | children, 19 | beamColor = "#3b82f6", 20 | glowColor = "rgba(59, 130, 246, 0.5)", 21 | borderColor = "bg-gray-300 dark:bg-gray-700", 22 | hoverColor = "rgba(59, 130, 246, 0.2)", 23 | ...props 24 | }, 25 | ref, 26 | ) => { 27 | const [hovered, setHovered] = React.useState(false) 28 | const mouseX = useMotionValue(0) 29 | const mouseY = useMotionValue(0) 30 | 31 | const handleMouseMove = (e: React.MouseEvent) => { 32 | const rect = e.currentTarget.getBoundingClientRect() 33 | mouseX.set(e.clientX - rect.left) 34 | mouseY.set(e.clientY - rect.top) 35 | } 36 | 37 | const glowStyle = useMotionTemplate`radial-gradient( 38 | 150px circle at ${mouseX}px ${mouseY}px, 39 | ${glowColor}, 40 | transparent 80% 41 | )` 42 | 43 | return ( 44 | // @ts-ignore 45 | setHovered(true)} 55 | onMouseLeave={() => setHovered(false)} 56 | animate={{ background: hovered ? hoverColor : borderColor }} 57 | {...props} 58 | > 59 | 64 | 80 |
{children}
81 |
82 | ) 83 | }, 84 | ) 85 | BeamCard.displayName = "BeamCard" 86 | 87 | -------------------------------------------------------------------------------- /components/easyui/colored-button.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import { motion } from "framer-motion" 5 | import { Button } from "@/components/ui/button" 6 | import type { ButtonProps } from "@/components/ui/button" 7 | 8 | export interface RainbowButtonProps extends ButtonProps { 9 | rainbowIntensity?: number 10 | rainbowDuration?: number 11 | } 12 | 13 | export function ColoredButton({ children, rainbowIntensity = 1, rainbowDuration = 3, ...props }: RainbowButtonProps) { 14 | const [isHovered, setIsHovered] = React.useState(false) 15 | 16 | return ( 17 | setIsHovered(true)} 20 | onHoverEnd={() => setIsHovered(false)} 21 | > 22 | {isHovered && ( 23 | 30 | 45 | 46 | )} 47 | 55 | 56 | ) 57 | } 58 | 59 | -------------------------------------------------------------------------------- /components/easyui/feature-card.tsx: -------------------------------------------------------------------------------- 1 | export default function FeatureCard() { 2 | return ( 3 |
4 |
5 |
6 | {/* Card 1 */} 7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | 18 | {/* Card 2 */} 19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | 30 | {/* Card 3 */} 31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | 43 |
44 |

Social

45 |

Write once, share with your friends

46 |
47 |
48 |
49 | ) 50 | } -------------------------------------------------------------------------------- /components/easyui/glitch-text.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import React, { useEffect, useState } from "react" 4 | 5 | interface GlitchTextProps { 6 | text: string 7 | textSize: string 8 | className?: string 9 | fontWeight?: React.CSSProperties["fontWeight"] 10 | } 11 | 12 | export default function GlitchText({ 13 | text, 14 | textSize, 15 | className = "", 16 | fontWeight = "normal", 17 | }: GlitchTextProps) { 18 | const [displayedText, setDisplayedText] = useState("") 19 | 20 | useEffect(() => { 21 | let currentIndex = 0 22 | const fullText = text 23 | const typingInterval = setInterval(() => { 24 | if (currentIndex <= fullText.length) { 25 | setDisplayedText(fullText.slice(0, currentIndex)) 26 | currentIndex++ 27 | } else { 28 | clearInterval(typingInterval) 29 | } 30 | }, 100) 31 | return () => clearInterval(typingInterval) 32 | }, [text]) 33 | 34 | return ( 35 |
39 |
40 | {displayedText} 41 |
42 | 99 |
100 | ) 101 | } 102 | -------------------------------------------------------------------------------- /components/easyui/hexagon-hero.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import { useEffect, useRef, useState } from 'react' 4 | import { Youtube } from 'lucide-react' 5 | 6 | export default function HexagonHero() { 7 | const patternRef = useRef(null) 8 | const [mousePosition, setMousePosition] = useState({ x: 50, y: -10 }) 9 | 10 | useEffect(() => { 11 | const patternElement = patternRef.current 12 | if (!patternElement) return 13 | 14 | const countY = Math.ceil(patternElement.clientHeight / 40) + 10 15 | const countX = Math.ceil(patternElement.clientWidth / 108) + 60 16 | 17 | for (let i = 0; i < countY; i++) { 18 | for (let j = 0; j < countX; j++) { 19 | const hexagon = document.createElement("div") 20 | hexagon.className = "absolute w-11 h-[50px] bg-no-repeat bg-contain" 21 | hexagon.style.backgroundImage = "url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODciIGhlaWdodD0iMTAwIiB2aWV3Qm94PSIwIDAgODcgMTAwIiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgo8cGF0aCBkPSJNMi4xOTg3MyAyNi4xNTQ3TDQzLjUgMi4zMDk0TDg0LjgwMTMgMjYuMTU0N1Y3My44NDUzTDQzLjUgOTcuNjkwNkwyLjE5ODczIDczLjg0NTNWMjYuMTU0N1oiIGZpbGw9IiMxMzEyMTciIHN0cm9rZT0iIzEzMTIxNyIgc3Ryb2tlLXdpZHRoPSI0Ii8+Cjwvc3ZnPgo=')" 22 | hexagon.style.top = `${i * 40}px` 23 | hexagon.style.left = `${j * 48 + ((i * 24) % 48)}px` 24 | patternElement.appendChild(hexagon) 25 | } 26 | } 27 | 28 | const handleMouseMove = (e: MouseEvent) => { 29 | setMousePosition({ x: e.clientX, y: e.clientY }) 30 | } 31 | 32 | document.addEventListener("mousemove", handleMouseMove) 33 | 34 | return () => { 35 | document.removeEventListener("mousemove", handleMouseMove) 36 | } 37 | }, []) 38 | 39 | return ( 40 |
41 |

Hexagons

42 |
50 |
51 | 62 |
63 | ) 64 | } 65 | 66 | -------------------------------------------------------------------------------- /components/easyui/highlighter.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { useEffect, useRef } from "react"; 4 | import { annotate } from "rough-notation"; 5 | import type { RoughAnnotation } from "rough-notation/lib/model"; 6 | import type React from "react"; 7 | 8 | interface HighlighterProps { 9 | children: React.ReactNode; 10 | action?: "highlight" | "circle"; 11 | color?: string; 12 | } 13 | 14 | export default function Highlighter({ 15 | children, 16 | action = "highlight", 17 | color = "#ffd1dc", // Default pink color 18 | }: HighlighterProps) { 19 | const elementRef = useRef(null); 20 | const annotationRef = useRef(null); 21 | 22 | useEffect(() => { 23 | if (elementRef.current) { 24 | const annotation = annotate(elementRef.current, { 25 | type: action === "circle" ? "circle" : "highlight", 26 | color: color, 27 | multiline: true, 28 | padding: action === "circle" ? 8 : 2, 29 | iterations: 2, // More iterations for a natural effect 30 | animationDuration: 500, 31 | }); 32 | 33 | annotationRef.current = annotation; 34 | annotation.show(); 35 | } 36 | 37 | return () => { 38 | annotationRef.current?.remove(); 39 | }; 40 | }, [action, color, elementRef.current]); // Added elementRef.current dependency 41 | 42 | return ( 43 | 44 | {children} 45 | 46 | ); 47 | } 48 | -------------------------------------------------------------------------------- /components/easyui/key-button.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import React from "react" 4 | import { Button } from "@/components/ui/button" 5 | 6 | 7 | interface KeyButtonProps { 8 | text: string 9 | size: any 10 | variant: any 11 | } 12 | 13 | function KeyButton({ text, size, variant }: KeyButtonProps) { 14 | return ( 15 |
16 | 17 | 48 |
49 | ) 50 | } 51 | 52 | export default KeyButton 53 | -------------------------------------------------------------------------------- /components/easyui/tilt-motion.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import type React from "react" 4 | import { useState, useRef, useEffect } from "react" 5 | import { motion, useMotionValue, useSpring, useTransform } from "framer-motion" 6 | 7 | interface TiltMotionProps { 8 | children: React.ReactNode 9 | tiltFactor?: number 10 | perspective?: number 11 | scale?: number 12 | transitionDuration?: number 13 | } 14 | 15 | export const TiltMotion: React.FC = ({ 16 | children, 17 | tiltFactor = 15, 18 | perspective = 1000, 19 | scale = 1.05, 20 | transitionDuration = 0.5, 21 | }) => { 22 | const [isHovering, setIsHovering] = useState(false) 23 | const ref = useRef(null) 24 | const [elementSize, setElementSize] = useState({ width: 0, height: 0 }) 25 | 26 | const x = useMotionValue(0) 27 | const y = useMotionValue(0) 28 | 29 | const springConfig = { damping: 30, stiffness: 400, mass: 0.5 } 30 | const xSpring = useSpring(x, springConfig) 31 | const ySpring = useSpring(y, springConfig) 32 | 33 | const rotateX = useTransform(ySpring, [-elementSize.height / 2, elementSize.height / 2], [tiltFactor, -tiltFactor]) 34 | const rotateY = useTransform(xSpring, [-elementSize.width / 2, elementSize.width / 2], [-tiltFactor, tiltFactor]) 35 | 36 | useEffect(() => { 37 | const updateSize = () => { 38 | if (ref.current) { 39 | setElementSize({ 40 | width: ref.current.offsetWidth, 41 | height: ref.current.offsetHeight, 42 | }) 43 | } 44 | } 45 | 46 | updateSize() 47 | window.addEventListener("resize", updateSize) 48 | return () => window.removeEventListener("resize", updateSize) 49 | }, []) 50 | 51 | const handleMouseMove = (event: React.MouseEvent) => { 52 | if (!ref.current) return 53 | const rect = ref.current.getBoundingClientRect() 54 | const mouseX = event.clientX - rect.left 55 | const mouseY = event.clientY - rect.top 56 | const centerX = elementSize.width / 2 57 | const centerY = elementSize.height / 2 58 | x.set(mouseX - centerX) 59 | y.set(mouseY - centerY) 60 | } 61 | 62 | const handleMouseEnter = () => setIsHovering(true) 63 | const handleMouseLeave = () => { 64 | setIsHovering(false) 65 | x.set(0) 66 | y.set(0) 67 | } 68 | 69 | return ( 70 | 80 | 93 | {children} 94 | 95 | 96 | ) 97 | } 98 | 99 | -------------------------------------------------------------------------------- /components/icons.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | LucideProps, 3 | Moon, 4 | SunMedium, 5 | Twitter, 6 | ExternalLink, 7 | Github, 8 | Linkedin, 9 | // @ts-ignore 10 | type Icon as LucideIcon, 11 | } from "lucide-react" 12 | import { DiscordLogoIcon } from '@radix-ui/react-icons' 13 | export type Icon = LucideIcon 14 | 15 | export const Icons = { 16 | sun: SunMedium, 17 | moon: Moon, 18 | twitter: Twitter, 19 | externalLink: ExternalLink, 20 | github: Github, 21 | linkedin: Linkedin, 22 | discord: DiscordLogoIcon, 23 | 24 | logo: (props: LucideProps) => ( 25 | 26 | 30 | 31 | ), 32 | gitHub: (props: LucideProps) => ( 33 | 34 | 38 | 39 | ), 40 | } 41 | -------------------------------------------------------------------------------- /components/magicui/animated-gradient-text.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "@/lib/utils"; 2 | import { ReactNode } from "react"; 3 | 4 | export default function AnimatedGradientText({ 5 | children, 6 | className, 7 | }: { 8 | children: ReactNode; 9 | className?: string; 10 | }) { 11 | return ( 12 |
18 |
21 | 22 | {children} 23 |
24 | ); 25 | } 26 | -------------------------------------------------------------------------------- /components/magicui/animated-shiny-text.tsx: -------------------------------------------------------------------------------- 1 | // import { cn } from "@/lib/utils"; 2 | // import { CSSProperties, FC, ReactNode } from "react"; 3 | 4 | // interface AnimatedShinyTextProps { 5 | // children: ReactNode; 6 | // className?: string; 7 | // shimmerWidth?: number; 8 | // } 9 | 10 | // const AnimatedShinyText: FC = ({ 11 | // children, 12 | // className, 13 | // shimmerWidth = 100, 14 | // }) => { 15 | // return ( 16 | //

34 | // {children} 35 | //

36 | // ); 37 | // }; 38 | 39 | // export default AnimatedShinyText; 40 | 41 | 42 | 43 | import { cn } from "@/lib/utils"; 44 | // import AnimatedGradientText from "@/registry/components/magicui/animated-gradient-text"; 45 | import { ChevronRight } from "lucide-react"; 46 | import AnimatedGradientText from "./animated-gradient-text"; 47 | 48 | export default function AnimatedGradientTextDemo() { 49 | return ( 50 | //
51 | 52 | 🎉
{" "} 53 | 58 | Introducing Magic UI 59 | 60 | 61 | 62 |
63 | //
64 | ); 65 | } -------------------------------------------------------------------------------- /components/magicui/animated-subscribe-button.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { AnimatePresence, motion } from "framer-motion"; 4 | import React, { useState } from "react"; 5 | import { useTheme } from 'next-themes'; 6 | 7 | interface AnimatedSubscribeButtonProps { 8 | buttonTextColor?: string; 9 | subscribeStatus: boolean; 10 | initialText: React.ReactElement | string; 11 | changeText: React.ReactElement | string; 12 | } 13 | 14 | export const AnimatedSubscribeButton: React.FC< 15 | AnimatedSubscribeButtonProps 16 | > = ({ 17 | subscribeStatus, 18 | buttonTextColor, 19 | changeText, 20 | initialText, 21 | }) => { 22 | const [isSubscribed, setIsSubscribed] = useState(subscribeStatus); 23 | const { theme, systemTheme, resolvedTheme } = useTheme(); 24 | 25 | // Adjust button color based on the effective theme, defaulting to white for dark themes or unspecified themes, and black for light themes 26 | const effectiveTheme = resolvedTheme || (theme === 'system' ? systemTheme : theme); 27 | const buttonColor = effectiveTheme === "light" ? "#000000" : "#ffffff"; // Button color changes based on theme 28 | const textColor = effectiveTheme === "light" ? "#ffffff" : "#000000"; // Text color is inverted based on theme for contrast 29 | 30 | return ( 31 | 32 | {isSubscribed ? ( 33 | setIsSubscribed(false)} 36 | initial={{ opacity: 0 }} 37 | animate={{ opacity: 1 }} 38 | exit={{ opacity: 0 }} 39 | style={{ backgroundColor: buttonColor, color: textColor, borderColor: textColor }} 40 | > 41 | 47 | {changeText} 48 | 49 | 50 | ) : ( 51 | setIsSubscribed(true)} 55 | initial={{ opacity: 0 }} 56 | animate={{ opacity: 1 }} 57 | exit={{ opacity: 0 }} 58 | > 59 | 65 | {initialText} 66 | 67 | 68 | )} 69 | 70 | ); 71 | }; 72 | 73 | -------------------------------------------------------------------------------- /components/magicui/avatar-circles.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { cn } from "@/lib/utils"; 4 | import React from "react"; 5 | 6 | interface AvatarCirclesProps { 7 | className?: string; 8 | numPeople?: number; 9 | avatarUrls: string[]; 10 | } 11 | 12 | const AvatarCircles = ({ numPeople, className, avatarUrls }: AvatarCirclesProps) => { 13 | return ( 14 |
15 | {avatarUrls.map((url, index) => ( 16 | {`Avatar 24 | ))} 25 | 29 | +{numPeople} 30 | 31 |
32 | ); 33 | }; 34 | 35 | export default AvatarCircles; 36 | -------------------------------------------------------------------------------- /components/magicui/bento-grid.tsx: -------------------------------------------------------------------------------- 1 | import { Button } from "@/components/ui/button"; 2 | import { cn } from "@/lib/utils"; 3 | import { ArrowRightIcon } from "@radix-ui/react-icons"; 4 | import { ReactNode } from "react"; 5 | 6 | const BentoGrid = ({ 7 | children, 8 | className, 9 | }: { 10 | children: ReactNode; 11 | className?: string; 12 | }) => { 13 | return ( 14 |
20 | {children} 21 |
22 | ); 23 | }; 24 | 25 | const BentoCard = ({ 26 | name, 27 | className, 28 | background, 29 | Icon, 30 | description, 31 | href, 32 | cta, 33 | }: { 34 | name: string; 35 | className: string; 36 | background: ReactNode; 37 | Icon: any; 38 | description: string; 39 | href: string; 40 | cta: string; 41 | }) => ( 42 |
53 |
{background}
54 |
55 | 56 |

57 | {name} 58 |

59 |

{description}

60 |
61 | 62 |
67 | 73 |
74 |
75 |
76 | ); 77 | 78 | export { BentoCard, BentoGrid }; 79 | -------------------------------------------------------------------------------- /components/magicui/border-beam.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "@/lib/utils"; 2 | 3 | interface BorderBeamProps { 4 | className?: string; 5 | size?: number; 6 | duration?: number; 7 | borderWidth?: number; 8 | anchor?: number; 9 | colorFrom?: string; 10 | colorTo?: string; 11 | delay?: number; 12 | } 13 | 14 | export const BorderBeamm = ({ 15 | className, 16 | size = 200, 17 | duration = 15, 18 | anchor = 90, 19 | borderWidth = 1.5, 20 | colorFrom = "#ffaa40", 21 | colorTo = "#9c40ff", 22 | delay = 0, 23 | }: BorderBeamProps) => { 24 | return ( 25 |
49 | ); 50 | }; 51 | -------------------------------------------------------------------------------- /components/magicui/linear-gradient.tsx: -------------------------------------------------------------------------------- 1 | import { CSSProperties } from "react"; 2 | 3 | type Direction = 4 | | "top" 5 | | "bottom" 6 | | "left" 7 | | "right" 8 | | "top left" 9 | | "top right" 10 | | "bottom left" 11 | | "bottom right"; 12 | 13 | interface LinearGradientProps { 14 | /** 15 | * The color to transition from 16 | * @default #00000000 17 | * @type string 18 | * */ 19 | from?: string; 20 | 21 | /** 22 | * The color to transition to 23 | * @default #290A5C 24 | * @type string 25 | * */ 26 | to?: string; 27 | 28 | /** 29 | * The width of the gradient 30 | * @default 100% 31 | * @type string 32 | * */ 33 | width?: string; 34 | 35 | /** 36 | * The height of the gradient 37 | * @default 100% 38 | * @type string 39 | * */ 40 | height?: string; 41 | 42 | /** 43 | * The direction of the gradient 44 | * @default bottom 45 | * @type string 46 | * */ 47 | direction?: Direction; 48 | 49 | /** 50 | * The point at which the transition occurs 51 | * @default 50% 52 | * @type string 53 | * */ 54 | transitionPoint?: string; 55 | 56 | /** 57 | * The class name to apply to the gradient 58 | * @default "" 59 | * @type string 60 | * */ 61 | className?: string; 62 | } 63 | 64 | const LinearGradient = ({ 65 | from = "#00000000", 66 | to = "rgba(120,119,198,0.3)", 67 | width = "100%", 68 | height = "100%", 69 | transitionPoint = "50%", 70 | direction = "bottom", 71 | className, 72 | }: LinearGradientProps) => { 73 | const styles: CSSProperties = { 74 | position: "absolute", 75 | pointerEvents: "none", 76 | inset: 0, 77 | width: width, 78 | height: height, 79 | background: `linear-gradient(to ${direction}, ${from}, ${transitionPoint}, ${to})`, 80 | }; 81 | return
; 82 | }; 83 | 84 | export default LinearGradient; 85 | -------------------------------------------------------------------------------- /components/magicui/marquee.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "@/lib/utils"; 2 | 3 | interface MarqueeProps { 4 | className?: string; 5 | reverse?: boolean; 6 | pauseOnHover?: boolean; 7 | children?: React.ReactNode; 8 | vertical?: boolean; 9 | repeat?: number; 10 | [key: string]: any; 11 | } 12 | 13 | export default function Marquee({ 14 | className, 15 | reverse, 16 | pauseOnHover = false, 17 | children, 18 | vertical = false, 19 | repeat = 4, 20 | ...props 21 | }: MarqueeProps) { 22 | return ( 23 |
34 | {Array(repeat) 35 | .fill(0) 36 | .map((_, i) => ( 37 |
46 | {children} 47 |
48 | ))} 49 |
50 | ); 51 | } 52 | -------------------------------------------------------------------------------- /components/magicui/orbiting-circles.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "@/lib/utils"; 2 | 3 | export default function OrbitingCircles({ 4 | className, 5 | children, 6 | reverse, 7 | duration = 20, 8 | delay = 10, 9 | radius = 50, 10 | path = true, 11 | }: { 12 | className?: string; 13 | children?: React.ReactNode; 14 | reverse?: boolean; 15 | duration?: number; 16 | delay?: number; 17 | radius?: number; 18 | path?: boolean; 19 | }) { 20 | return ( 21 | <> 22 | {path && ( 23 | 28 | 36 | 37 | )} 38 | 39 |
53 | {children} 54 |
55 | 56 | ); 57 | } 58 | -------------------------------------------------------------------------------- /components/mdx-card.tsx: -------------------------------------------------------------------------------- 1 | import Link from "next/link" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | interface CardProps extends React.HTMLAttributes { 6 | href?: string 7 | disabled?: boolean 8 | } 9 | 10 | export default function MdxCard({ 11 | href, 12 | className, 13 | children, 14 | disabled, 15 | ...props 16 | }: CardProps) { 17 | return ( 18 |
26 |
27 |
28 | {children} 29 |
30 |
31 | {href && ( 32 | 33 | View 34 | 35 | )} 36 |
37 | ) 38 | } -------------------------------------------------------------------------------- /components/page-header.tsx: -------------------------------------------------------------------------------- 1 | import Balance from "react-wrap-balancer" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | function PageHeader({ 6 | className, 7 | children, 8 | ...props 9 | }: React.HTMLAttributes) { 10 | return ( 11 |
18 | {children} 19 |
20 | ) 21 | } 22 | 23 | function PageHeaderHeading({ 24 | className, 25 | ...props 26 | }: React.HTMLAttributes) { 27 | return ( 28 |

35 | ) 36 | } 37 | 38 | function PageHeaderDescription({ 39 | className, 40 | ...props 41 | }: React.HTMLAttributes) { 42 | return ( 43 | 50 | ) 51 | } 52 | 53 | function PageActions({ 54 | className, 55 | ...props 56 | }: React.HTMLAttributes) { 57 | return ( 58 |
65 | ) 66 | } 67 | 68 | export { PageHeader, PageHeaderHeading, PageHeaderDescription, PageActions } -------------------------------------------------------------------------------- /components/site-banner.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { ChevronRight } from "lucide-react"; 4 | import Link from "next/link"; 5 | // import posthog from "posthog-js"; 6 | 7 | export function SiteBanner() { 8 | return ( 9 |
10 |
11 | 16 | ✨{" "} 17 | 18 | {" "} 19 | Introducing Easy UI Premium - 100+ Blocks and Templates to build your landing page in minutes 20 | {" "} 21 | 22 | 23 |
24 |
25 |
26 | ); 27 | } -------------------------------------------------------------------------------- /components/site-footer.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { siteConfig } from "@/config/site" 4 | import { cn } from "@/lib/utils" 5 | import { Icons } from "@/components/icons" 6 | // import { ModeToggle } from "@/components/mode-toggle" 7 | 8 | export function SiteFooter({ className }: React.HTMLAttributes) { 9 | return ( 10 |
11 |
12 |
13 | {/* */} 14 |

15 | Brought to you by{" "} 16 | 22 | kathan. 23 | 24 | 25 |

26 |
27 | {/* */} 28 |
29 |
30 | ) 31 | } -------------------------------------------------------------------------------- /components/tailwind-indicator.tsx: -------------------------------------------------------------------------------- 1 | export function TailwindIndicator() { 2 | if (process.env.NODE_ENV === "production") return null 3 | 4 | return ( 5 |
6 |
xs
7 |
sm
8 |
md
9 |
lg
10 |
xl
11 |
2xl
12 |
13 | ) 14 | } 15 | -------------------------------------------------------------------------------- /components/theme-provider.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import { ThemeProvider as NextThemesProvider } from "next-themes" 5 | import { type ThemeProviderProps } from "next-themes/dist/types" 6 | 7 | export function ThemeProvider({ children, ...props }: ThemeProviderProps) { 8 | return {children} 9 | } 10 | -------------------------------------------------------------------------------- /components/theme-toggle.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import { Moon, Sun } from "lucide-react" 5 | import { useTheme } from "next-themes" 6 | 7 | import { Button } from "@/components/ui/button" 8 | 9 | export function ThemeToggle() { 10 | const { setTheme, theme } = useTheme() 11 | 12 | return ( 13 | 22 | ) 23 | } 24 | -------------------------------------------------------------------------------- /components/ui/accordion.tsx: -------------------------------------------------------------------------------- 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< 10 | React.ElementRef, 11 | React.ComponentPropsWithoutRef 12 | >(({ className, ...props }, ref) => ( 13 | 18 | )) 19 | AccordionItem.displayName = "AccordionItem" 20 | 21 | const AccordionTrigger = React.forwardRef< 22 | React.ElementRef, 23 | React.ComponentPropsWithoutRef 24 | >(({ className, children, ...props }, ref) => ( 25 | 26 | svg]:rotate-180", 30 | className 31 | )} 32 | {...props} 33 | > 34 | {children} 35 | 36 | 37 | 38 | )) 39 | AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName 40 | 41 | const AccordionContent = React.forwardRef< 42 | React.ElementRef, 43 | React.ComponentPropsWithoutRef 44 | >(({ className, children, ...props }, ref) => ( 45 | 50 |
{children}
51 |
52 | )) 53 | 54 | AccordionContent.displayName = AccordionPrimitive.Content.displayName 55 | 56 | export { Accordion, AccordionItem, AccordionTrigger, AccordionContent } 57 | -------------------------------------------------------------------------------- /components/ui/avatar.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as AvatarPrimitive from "@radix-ui/react-avatar" 5 | 6 | import { cn } from "@/lib/utils" 7 | 8 | const Avatar = React.forwardRef< 9 | React.ElementRef, 10 | React.ComponentPropsWithoutRef 11 | >(({ className, ...props }, ref) => ( 12 | 20 | )) 21 | Avatar.displayName = AvatarPrimitive.Root.displayName 22 | 23 | const AvatarImage = React.forwardRef< 24 | React.ElementRef, 25 | React.ComponentPropsWithoutRef 26 | >(({ className, ...props }, ref) => ( 27 | 32 | )) 33 | AvatarImage.displayName = AvatarPrimitive.Image.displayName 34 | 35 | const AvatarFallback = React.forwardRef< 36 | React.ElementRef, 37 | React.ComponentPropsWithoutRef 38 | >(({ className, ...props }, ref) => ( 39 | 47 | )) 48 | AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName 49 | 50 | export { Avatar, AvatarImage, AvatarFallback } 51 | -------------------------------------------------------------------------------- /components/ui/badge.tsx: -------------------------------------------------------------------------------- 1 | import { cva, type VariantProps } from "class-variance-authority"; 2 | import * as React from "react"; 3 | 4 | import { cn } from "@/lib/utils"; 5 | 6 | const badgeVariants = cva( 7 | "inline-flex items-center rounded-md 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 shadow 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 shadow hover:bg-destructive/80", 17 | green: 18 | "border-transparent bg-green-600 text-destructive-foreground shadow hover:bg-destructive/80", 19 | outline: "text-foreground", 20 | }, 21 | }, 22 | defaultVariants: { 23 | variant: "default", 24 | }, 25 | }, 26 | ); 27 | 28 | export interface BadgeProps 29 | extends React.HTMLAttributes, 30 | VariantProps {} 31 | 32 | function Badge({ className, variant, ...props }: BadgeProps) { 33 | return ( 34 |
35 | ); 36 | } 37 | 38 | export { Badge, badgeVariants }; -------------------------------------------------------------------------------- /components/ui/button.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import { Slot } from "@radix-ui/react-slot" 3 | import { cva, type VariantProps } from "class-variance-authority" 4 | 5 | import { cn } from "@/lib/utils" 6 | 7 | const buttonVariants = cva( 8 | "inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background", 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 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: "underline-offset-4 hover:underline text-primary", 21 | }, 22 | size: { 23 | default: "h-10 py-2 px-4", 24 | sm: "h-9 px-3 rounded-md", 25 | lg: "h-11 px-8 rounded-md", 26 | icon: "h-10 w-10", 27 | }, 28 | }, 29 | defaultVariants: { 30 | variant: "default", 31 | size: "default", 32 | }, 33 | } 34 | ) 35 | 36 | export interface ButtonProps 37 | extends React.ButtonHTMLAttributes, 38 | VariantProps { 39 | asChild?: boolean 40 | } 41 | 42 | const Button = React.forwardRef( 43 | ({ className, variant, size, asChild = false, ...props }, ref) => { 44 | const Comp = asChild ? Slot : "button" 45 | return ( 46 | 51 | ) 52 | } 53 | ) 54 | Button.displayName = "Button" 55 | 56 | export { Button, buttonVariants } 57 | -------------------------------------------------------------------------------- /components/ui/calendar.tsx: -------------------------------------------------------------------------------- 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 | export type CalendarProps = React.ComponentProps 9 | 10 | function Calendar({ 11 | className, 12 | classNames, 13 | showOutsideDays = true, 14 | ...props 15 | }: CalendarProps) { 16 | return ( 17 | , 57 | IconRight: ({ ...props }) => , 58 | }} 59 | {...props} 60 | /> 61 | ) 62 | } 63 | Calendar.displayName = "Calendar" 64 | 65 | export { Calendar } 66 | -------------------------------------------------------------------------------- /components/ui/card.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | const Card = React.forwardRef< 6 | HTMLDivElement, 7 | React.HTMLAttributes 8 | >(({ className, ...props }, ref) => ( 9 |
17 | )) 18 | Card.displayName = "Card" 19 | 20 | const CardHeader = React.forwardRef< 21 | HTMLDivElement, 22 | React.HTMLAttributes 23 | >(({ className, ...props }, ref) => ( 24 |
29 | )) 30 | CardHeader.displayName = "CardHeader" 31 | 32 | const CardTitle = React.forwardRef< 33 | HTMLParagraphElement, 34 | React.HTMLAttributes 35 | >(({ className, ...props }, ref) => ( 36 |

44 | )) 45 | CardTitle.displayName = "CardTitle" 46 | 47 | const CardDescription = React.forwardRef< 48 | HTMLParagraphElement, 49 | React.HTMLAttributes 50 | >(({ className, ...props }, ref) => ( 51 |

56 | )) 57 | CardDescription.displayName = "CardDescription" 58 | 59 | const CardContent = React.forwardRef< 60 | HTMLDivElement, 61 | React.HTMLAttributes 62 | >(({ className, ...props }, ref) => ( 63 |

64 | )) 65 | CardContent.displayName = "CardContent" 66 | 67 | const CardFooter = React.forwardRef< 68 | HTMLDivElement, 69 | React.HTMLAttributes 70 | >(({ className, ...props }, ref) => ( 71 |
76 | )) 77 | CardFooter.displayName = "CardFooter" 78 | 79 | export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } 80 | -------------------------------------------------------------------------------- /components/ui/checkbox.tsx: -------------------------------------------------------------------------------- 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< 8 | React.ElementRef, 9 | React.ComponentPropsWithoutRef 10 | >(({ className, ...props }, ref) => ( 11 | 19 | 22 | 23 | 24 | 25 | )) 26 | Checkbox.displayName = CheckboxPrimitive.Root.displayName 27 | 28 | export { Checkbox } 29 | -------------------------------------------------------------------------------- /components/ui/dialog.tsx: -------------------------------------------------------------------------------- 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< 16 | React.ElementRef, 17 | React.ComponentPropsWithoutRef 18 | >(({ className, ...props }, ref) => ( 19 | 27 | )) 28 | DialogOverlay.displayName = DialogPrimitive.Overlay.displayName 29 | 30 | const DialogContent = React.forwardRef< 31 | React.ElementRef, 32 | React.ComponentPropsWithoutRef 33 | >(({ className, children, ...props }, ref) => ( 34 | 35 | 36 | 44 | {children} 45 | 46 | 47 | Close 48 | 49 | 50 | 51 | )) 52 | DialogContent.displayName = DialogPrimitive.Content.displayName 53 | 54 | const DialogHeader = ({ 55 | className, 56 | ...props 57 | }: React.HTMLAttributes) => ( 58 |
65 | ) 66 | DialogHeader.displayName = "DialogHeader" 67 | 68 | const DialogFooter = ({ 69 | className, 70 | ...props 71 | }: React.HTMLAttributes) => ( 72 |
79 | ) 80 | DialogFooter.displayName = "DialogFooter" 81 | 82 | const DialogTitle = React.forwardRef< 83 | React.ElementRef, 84 | React.ComponentPropsWithoutRef 85 | >(({ className, ...props }, ref) => ( 86 | 94 | )) 95 | DialogTitle.displayName = DialogPrimitive.Title.displayName 96 | 97 | const DialogDescription = React.forwardRef< 98 | React.ElementRef, 99 | React.ComponentPropsWithoutRef 100 | >(({ className, ...props }, ref) => ( 101 | 106 | )) 107 | DialogDescription.displayName = DialogPrimitive.Description.displayName 108 | 109 | export { 110 | Dialog, 111 | DialogPortal, 112 | DialogOverlay, 113 | DialogClose, 114 | DialogTrigger, 115 | DialogContent, 116 | DialogHeader, 117 | DialogFooter, 118 | DialogTitle, 119 | DialogDescription, 120 | } 121 | -------------------------------------------------------------------------------- /components/ui/glitch-text.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react" 2 | 3 | interface GlitchTextProps { 4 | text: string 5 | textSize: string 6 | className?: string 7 | fontWeight?: React.CSSProperties["fontWeight"] 8 | } 9 | 10 | export default function GlitchText({ 11 | text, 12 | textSize, 13 | className = "", 14 | fontWeight = "normal", 15 | }: GlitchTextProps) { 16 | const [displayedText, setDisplayedText] = useState("") 17 | 18 | useEffect(() => { 19 | let currentIndex = 0 20 | const fullText = text 21 | const typingInterval = setInterval(() => { 22 | if (currentIndex <= fullText.length) { 23 | setDisplayedText(fullText.slice(0, currentIndex)) 24 | currentIndex++ 25 | } else { 26 | clearInterval(typingInterval) 27 | } 28 | }, 100) 29 | return () => clearInterval(typingInterval) 30 | }, [text]) 31 | 32 | return ( 33 |
37 |
38 | {displayedText} 39 |
40 | 97 |
98 | ) 99 | } 100 | -------------------------------------------------------------------------------- /components/ui/input.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | export interface InputProps 6 | extends React.InputHTMLAttributes {} 7 | 8 | const Input = React.forwardRef( 9 | ({ className, type, ...props }, ref) => { 10 | return ( 11 | 20 | ) 21 | } 22 | ) 23 | Input.displayName = "Input" 24 | 25 | export { Input } 26 | -------------------------------------------------------------------------------- /components/ui/label.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import * as LabelPrimitive from "@radix-ui/react-label" 3 | import { cva, type VariantProps } 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< 12 | React.ElementRef, 13 | React.ComponentPropsWithoutRef & 14 | VariantProps 15 | >(({ className, ...props }, ref) => ( 16 | 21 | )) 22 | Label.displayName = LabelPrimitive.Root.displayName 23 | 24 | export { Label } 25 | -------------------------------------------------------------------------------- /components/ui/progress.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as ProgressPrimitive from "@radix-ui/react-progress" 5 | 6 | import { cn } from "@/lib/utils" 7 | 8 | const Progress = React.forwardRef< 9 | React.ElementRef, 10 | React.ComponentPropsWithoutRef 11 | >(({ className, value, ...props }, ref) => ( 12 | 20 | 24 | 25 | )) 26 | Progress.displayName = ProgressPrimitive.Root.displayName 27 | 28 | export { Progress } 29 | -------------------------------------------------------------------------------- /components/ui/rainbow-button.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import { cn } from "@/lib/utils"; 4 | interface RainbowButtonProps 5 | extends React.ButtonHTMLAttributes {} 6 | 7 | export function RainbowButton({ 8 | children, 9 | className, 10 | ...props 11 | }: RainbowButtonProps) { 12 | return ( 13 | 32 | ); 33 | } 34 | -------------------------------------------------------------------------------- /components/ui/scroll-area.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area" 5 | 6 | import { cn } from "@/lib/utils" 7 | 8 | const ScrollArea = React.forwardRef< 9 | React.ElementRef, 10 | React.ComponentPropsWithoutRef 11 | >(({ className, children, ...props }, ref) => ( 12 | 17 | 18 | {children} 19 | 20 | 21 | 22 | 23 | )) 24 | ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName 25 | 26 | const ScrollBar = React.forwardRef< 27 | React.ElementRef, 28 | React.ComponentPropsWithoutRef 29 | >(({ className, orientation = "vertical", ...props }, ref) => ( 30 | 43 | 44 | 45 | )) 46 | ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName 47 | 48 | export { ScrollArea, ScrollBar } 49 | -------------------------------------------------------------------------------- /components/ui/separator.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as SeparatorPrimitive from "@radix-ui/react-separator" 5 | 6 | import { cn } from "@/lib/utils" 7 | 8 | const Separator = React.forwardRef< 9 | React.ElementRef, 10 | React.ComponentPropsWithoutRef 11 | >( 12 | ( 13 | { className, orientation = "horizontal", decorative = true, ...props }, 14 | ref 15 | ) => ( 16 | 27 | ) 28 | ) 29 | Separator.displayName = SeparatorPrimitive.Root.displayName 30 | 31 | export { Separator } 32 | -------------------------------------------------------------------------------- /components/ui/skeleton.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "@/lib/utils" 2 | 3 | function Skeleton({ 4 | className, 5 | ...props 6 | }: React.HTMLAttributes) { 7 | return ( 8 |
12 | ) 13 | } 14 | 15 | export { Skeleton } 16 | -------------------------------------------------------------------------------- /components/ui/slider.tsx: -------------------------------------------------------------------------------- 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< 7 | React.ElementRef, 8 | React.ComponentPropsWithoutRef 9 | >(({ className, ...props }, ref) => ( 10 | 18 | 19 | 20 | 21 | 22 | 23 | )) 24 | Slider.displayName = SliderPrimitive.Root.displayName 25 | 26 | export { Slider } 27 | -------------------------------------------------------------------------------- /components/ui/switch.tsx: -------------------------------------------------------------------------------- 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< 7 | React.ElementRef, 8 | React.ComponentPropsWithoutRef 9 | >(({ className, ...props }, ref) => ( 10 | 18 | 23 | 24 | )) 25 | Switch.displayName = SwitchPrimitives.Root.displayName 26 | 27 | export { Switch } 28 | -------------------------------------------------------------------------------- /components/ui/table.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | const Table = React.forwardRef< 6 | HTMLTableElement, 7 | React.HTMLAttributes 8 | >(({ className, ...props }, ref) => ( 9 |
10 | 15 | 16 | )) 17 | Table.displayName = "Table" 18 | 19 | const TableHeader = React.forwardRef< 20 | HTMLTableSectionElement, 21 | React.HTMLAttributes 22 | >(({ className, ...props }, ref) => ( 23 | 24 | )) 25 | TableHeader.displayName = "TableHeader" 26 | 27 | const TableBody = React.forwardRef< 28 | HTMLTableSectionElement, 29 | React.HTMLAttributes 30 | >(({ className, ...props }, ref) => ( 31 | 36 | )) 37 | TableBody.displayName = "TableBody" 38 | 39 | const TableFooter = React.forwardRef< 40 | HTMLTableSectionElement, 41 | React.HTMLAttributes 42 | >(({ className, ...props }, ref) => ( 43 | tr]:last:border-b-0", 47 | className 48 | )} 49 | {...props} 50 | /> 51 | )) 52 | TableFooter.displayName = "TableFooter" 53 | 54 | const TableRow = React.forwardRef< 55 | HTMLTableRowElement, 56 | React.HTMLAttributes 57 | >(({ className, ...props }, ref) => ( 58 | 66 | )) 67 | TableRow.displayName = "TableRow" 68 | 69 | const TableHead = React.forwardRef< 70 | HTMLTableCellElement, 71 | React.ThHTMLAttributes 72 | >(({ className, ...props }, ref) => ( 73 |
81 | )) 82 | TableHead.displayName = "TableHead" 83 | 84 | const TableCell = React.forwardRef< 85 | HTMLTableCellElement, 86 | React.TdHTMLAttributes 87 | >(({ className, ...props }, ref) => ( 88 | 93 | )) 94 | TableCell.displayName = "TableCell" 95 | 96 | const TableCaption = React.forwardRef< 97 | HTMLTableCaptionElement, 98 | React.HTMLAttributes 99 | >(({ className, ...props }, ref) => ( 100 |
105 | )) 106 | TableCaption.displayName = "TableCaption" 107 | 108 | export { 109 | Table, 110 | TableHeader, 111 | TableBody, 112 | TableFooter, 113 | TableHead, 114 | TableRow, 115 | TableCell, 116 | TableCaption, 117 | } 118 | -------------------------------------------------------------------------------- /components/ui/tabs.tsx: -------------------------------------------------------------------------------- 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< 9 | React.ElementRef, 10 | React.ComponentPropsWithoutRef 11 | >(({ className, ...props }, ref) => ( 12 | 20 | )) 21 | TabsList.displayName = TabsPrimitive.List.displayName 22 | 23 | const TabsTrigger = React.forwardRef< 24 | React.ElementRef, 25 | React.ComponentPropsWithoutRef 26 | >(({ className, ...props }, ref) => ( 27 | 35 | )) 36 | TabsTrigger.displayName = TabsPrimitive.Trigger.displayName 37 | 38 | const TabsContent = React.forwardRef< 39 | React.ElementRef, 40 | React.ComponentPropsWithoutRef 41 | >(({ className, ...props }, ref) => ( 42 | 50 | )) 51 | TabsContent.displayName = TabsPrimitive.Content.displayName 52 | 53 | export { Tabs, TabsList, TabsTrigger, TabsContent } 54 | -------------------------------------------------------------------------------- /components/ui/toaster.tsx: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /components/ui/tooltip.tsx: -------------------------------------------------------------------------------- 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< 13 | React.ElementRef, 14 | React.ComponentPropsWithoutRef 15 | >(({ className, sideOffset = 4, ...props }, ref) => ( 16 | 25 | )) 26 | TooltipContent.displayName = TooltipPrimitive.Content.displayName 27 | 28 | export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } 29 | -------------------------------------------------------------------------------- /config/site.ts: -------------------------------------------------------------------------------- 1 | export type SiteConfig = typeof siteConfig 2 | 3 | export const siteConfig = { 4 | name: "Easy UI", 5 | description: 6 | "Beautifully designed website templates built with React and Tailwind CSS.", 7 | mainNav: [ 8 | { 9 | title: "Components", 10 | href: "/component", 11 | }, 12 | { 13 | title: "Pricing", 14 | href: "/easy-mvp-pricing", 15 | }, 16 | { 17 | title: "Blog", 18 | href: "/blog", 19 | }, 20 | { 21 | title: "Templates", 22 | href: "/templates", 23 | } 24 | ], 25 | links: { 26 | twitter: "https://twitter.com/kathanmehtaa", 27 | github: "https://github.com/DarkInventor/easy-ui", 28 | docs: "https://www.easyui.pro/introduction", 29 | }, 30 | } 31 | -------------------------------------------------------------------------------- /contentlayer.config.ts: -------------------------------------------------------------------------------- 1 | import { defineDocumentType, makeSource } from 'contentlayer/source-files' 2 | import rehypeAutolinkHeadings from 'rehype-autolink-headings' 3 | import rehypePrettyCode from 'rehype-pretty-code' 4 | import rehypeSlug from 'rehype-slug' 5 | import remarkGfm from 'remark-gfm' 6 | 7 | /** @type {import('rehype-pretty-code').Options} */ 8 | const rehypePrettyCodeOptions = { 9 | theme: 'github-dark', 10 | onVisitLine(node: any) { 11 | // Prevent lines from collapsing in `display: grid` mode, and 12 | // allow empty lines to be copy/pasted 13 | if (node.children.length === 0) { 14 | node.children = [{ type: 'text', value: ' ' }] 15 | } 16 | }, 17 | onVisitHighlightedLine(node: any) { 18 | node.properties.className.push('highlighted') 19 | }, 20 | onVisitHighlightedWord(node: any) { 21 | node.properties.className = ['word'] 22 | }, 23 | } 24 | 25 | export const Post = defineDocumentType(() => ({ 26 | name: 'Post', 27 | filePathPattern: `**/*.mdx`, 28 | contentType: 'mdx', 29 | fields: { 30 | title: { type: 'string', required: true }, 31 | date: { type: 'date', required: true }, 32 | description: { type: 'string', required: true }, 33 | tags: { type: 'list', of: { type: 'string' }, default: [] }, 34 | coverImage: { type: 'string' }, 35 | }, 36 | computedFields: { 37 | url: { type: 'string', resolve: (post) => `/blog/${post._raw.flattenedPath}` }, 38 | }, 39 | })) 40 | 41 | export default makeSource({ 42 | contentDirPath: 'posts', 43 | documentTypes: [Post], 44 | mdx: { 45 | remarkPlugins: [remarkGfm], 46 | rehypePlugins: [ 47 | rehypeSlug, 48 | [rehypeAutolinkHeadings, { behavior: 'wrap' }], 49 | // @ts-ignore 50 | [rehypePrettyCode, rehypePrettyCodeOptions], 51 | ], 52 | }, 53 | }) -------------------------------------------------------------------------------- /hooks/use-mobile.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | const MOBILE_BREAKPOINT = 768 4 | 5 | export function useIsMobile() { 6 | const [isMobile, setIsMobile] = React.useState(undefined) 7 | 8 | React.useEffect(() => { 9 | const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`) 10 | const onChange = () => { 11 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT) 12 | } 13 | mql.addEventListener("change", onChange) 14 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT) 15 | return () => mql.removeEventListener("change", onChange) 16 | }, []) 17 | 18 | return !!isMobile 19 | } 20 | -------------------------------------------------------------------------------- /lib/blog-utils.ts: -------------------------------------------------------------------------------- 1 | export function estimateReadingTime(text: string): number { 2 | const wordsPerMinute = 200; 3 | const numberOfWords = text.split(/\s/g).length; 4 | return Math.ceil(numberOfWords / wordsPerMinute); 5 | } -------------------------------------------------------------------------------- /lib/fonts.ts: -------------------------------------------------------------------------------- 1 | import { JetBrains_Mono as FontMono, Inter as FontSans } from "next/font/google" 2 | 3 | export const fontSans = FontSans({ 4 | subsets: ["latin"], 5 | variable: "--font-sans", 6 | }) 7 | 8 | export const fontMono = FontMono({ 9 | subsets: ["latin"], 10 | variable: "--font-mono", 11 | }) 12 | -------------------------------------------------------------------------------- /lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { clsx, type ClassValue } from "clsx" 2 | import { twMerge } from "tailwind-merge" 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)) 6 | } 7 | -------------------------------------------------------------------------------- /next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information. 6 | -------------------------------------------------------------------------------- /next.config.mjs: -------------------------------------------------------------------------------- 1 | // import createMDX from '@next/mdx'; 2 | import { withContentlayer } from "next-contentlayer"; 3 | 4 | const nextConfig = { 5 | reactStrictMode: true, 6 | pageExtensions: ['js', 'jsx', 'mdx', 'ts', 'tsx'], 7 | images: { 8 | domains: [ 9 | 'dev-to-uploads.s3.amazonaws.com', 10 | 'pub-0cd6f9d4131f4f79ac40219248ae64db.r2.dev', 11 | 'magicui.design', 12 | 'source.unsplash.com', // Added 'source.unsplash.com' to the list of domains 13 | ], 14 | }, 15 | }; 16 | 17 | export default withContentlayer(nextConfig); 18 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "next-template", 3 | "version": "0.0.2", 4 | "private": true, 5 | "type": "module", 6 | "scripts": { 7 | "dev": "next dev", 8 | "build": "next build", 9 | "build:registry": "npx bun ./scripts/build.ts", 10 | "start": "next start", 11 | "lint": "next lint", 12 | "lint:fix": "next lint --fix", 13 | "preview": "next build && next start", 14 | "typecheck": "tsc --noEmit", 15 | "format:write": "prettier --write \"**/*.{ts,tsx,mdx}\" --cache", 16 | "format:check": "prettier --check \"**/*.{ts,tsx,mdx}\" --cache" 17 | }, 18 | "dependencies": { 19 | "@emotion/is-prop-valid": "^1.3.1", 20 | "@mdx-js/loader": "^3.0.1", 21 | "@mdx-js/react": "^3.0.1", 22 | "@next/mdx": "^14.1.0", 23 | "@next/third-parties": "^14.1.0", 24 | "@radix-ui/react-accordion": "^1.1.2", 25 | "@radix-ui/react-avatar": "^1.1.0", 26 | "@radix-ui/react-checkbox": "^1.1.2", 27 | "@radix-ui/react-dialog": "^1.1.1", 28 | "@radix-ui/react-dropdown-menu": "^2.1.1", 29 | "@radix-ui/react-icons": "^1.3.0", 30 | "@radix-ui/react-label": "^2.0.2", 31 | "@radix-ui/react-navigation-menu": "^1.1.4", 32 | "@radix-ui/react-popover": "^1.0.7", 33 | "@radix-ui/react-progress": "^1.1.2", 34 | "@radix-ui/react-scroll-area": "^1.0.5", 35 | "@radix-ui/react-select": "^2.0.0", 36 | "@radix-ui/react-separator": "^1.0.3", 37 | "@radix-ui/react-slot": "^1.0.2", 38 | "@radix-ui/react-tabs": "^1.0.4", 39 | "@radix-ui/react-toast": "^1.1.5", 40 | "@radix-ui/react-toggle": "^1.0.3", 41 | "@radix-ui/react-tooltip": "^1.0.7", 42 | "@vercel/analytics": "^1.1.2", 43 | "canvas-confetti": "^1.9.3", 44 | "class-variance-authority": "^0.7.0", 45 | "clsx": "^2.1.0", 46 | "cmdk": "^1.0.4", 47 | "contentlayer": "^0.3.4", 48 | "date-fns": "^3.3.1", 49 | "framer-motion": "^11.0.3", 50 | "lucide-react": "^0.323.0", 51 | "next": "^14.1.0", 52 | "next-contentlayer": "^0.3.4", 53 | "next-themes": "^0.2.1", 54 | "react": "^18.2.0", 55 | "react-dom": "^18.2.0", 56 | "rehype-autolink-headings": "^7.1.0", 57 | "rehype-pretty-code": "^0.14.0", 58 | "rehype-slug": "^6.0.0", 59 | "remark-gfm": "^4.0.0", 60 | "rough-notation": "^0.5.1", 61 | "tailwind-merge": "^2.2.1", 62 | "tailwindcss-animate": "^1.0.7" 63 | }, 64 | "devDependencies": { 65 | "@radix-ui/react-slider": "^1.2.2", 66 | "@radix-ui/react-switch": "^1.1.2", 67 | "@types/canvas-confetti": "^1.9.0", 68 | "@types/node": "^20.11.16", 69 | "@types/react": "^18.2.52", 70 | "@types/react-dom": "^18.2.18", 71 | "autoprefixer": "^10.4.17", 72 | "disqus-react": "^1.1.5", 73 | "postcss": "^8.4.33", 74 | "prettier": "^3.2.4", 75 | "react-day-picker": "^9.5.1", 76 | "react-wrap-balancer": "^1.1.1", 77 | "tailwindcss": "^3.4.1", 78 | "typescript": "^5.3.3" 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /postcss.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('prettier').Config} */ 2 | module.exports = { 3 | endOfLine: "lf", 4 | semi: false, 5 | singleQuote: false, 6 | tabWidth: 2, 7 | trailingComma: "es5", 8 | importOrder: [ 9 | "^(react/(.*)$)|^(react$)", 10 | "^(next/(.*)$)|^(next$)", 11 | "", 12 | "", 13 | "^types$", 14 | "^@/types/(.*)$", 15 | "^@/config/(.*)$", 16 | "^@/lib/(.*)$", 17 | "^@/hooks/(.*)$", 18 | "^@/components/ui/(.*)$", 19 | "^@/components/(.*)$", 20 | "^@/styles/(.*)$", 21 | "^@/app/(.*)$", 22 | "", 23 | "^[./]", 24 | ], 25 | importOrderSeparation: false, 26 | importOrderSortSpecifiers: true, 27 | importOrderBuiltinModulesToTop: true, 28 | importOrderParserPlugins: ["typescript", "jsx", "decorators-legacy"], 29 | importOrderMergeDuplicateImports: true, 30 | importOrderCombineTypeAndValueImports: true, 31 | plugins: ["@ianvs/prettier-plugin-sort-imports"], 32 | } 33 | -------------------------------------------------------------------------------- /public/Reminders-60x60@3x 2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/Reminders-60x60@3x 2.png -------------------------------------------------------------------------------- /public/Screenshot 2024-10-18 at 4.35.47 AM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/Screenshot 2024-10-18 at 4.35.47 AM.png -------------------------------------------------------------------------------- /public/analytics-blog-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/analytics-blog-image.png -------------------------------------------------------------------------------- /public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/apple-touch-icon.png -------------------------------------------------------------------------------- /public/bird.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/bird.jpg -------------------------------------------------------------------------------- /public/blog-images/design-system-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/blog-images/design-system-1.jpg -------------------------------------------------------------------------------- /public/blog-images/design-system-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/blog-images/design-system-2.png -------------------------------------------------------------------------------- /public/blog-images/design-system-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/blog-images/design-system-3.png -------------------------------------------------------------------------------- /public/blog-images/design-system-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/blog-images/design-system-4.png -------------------------------------------------------------------------------- /public/components-json/animated-badge.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "animated-badge", 3 | "type": "registry:ui", 4 | "registryDependencies": [], 5 | "dependencies": [], 6 | "devDependencies": [], 7 | "tailwind": {}, 8 | "cssVars": { 9 | "light": {}, 10 | "dark": {} 11 | }, 12 | "files": [ 13 | { 14 | "path": "animated-badge.tsx", 15 | "content": "\"use client\";\n\nimport React from 'react'\nimport { cn } from '@/lib/utils'\n\ninterface AnimatedBadgeProps extends React.HTMLAttributes {\n text: string\n bgColor?: string\n textColor?: string\n gradientColor?: string\n animationDuration?: string\n size?: 'sm' | 'md' | 'lg'\n}\n\nexport default function AnimatedBadge({\n text,\n bgColor = 'bg-green-900',\n textColor = 'text-green-300',\n gradientColor = 'from-transparent via-emerald-600 to-transparent',\n animationDuration = '4s',\n size = 'md',\n className,\n ...props\n}: AnimatedBadgeProps) {\n const sizeClasses = {\n sm: 'text-xs',\n md: 'text-sm',\n lg: 'text-base',\n }\n\n return (\n \n \n \n {text}\n \n \n )\n}\n\n", 16 | "type": "registry:ui" 17 | } 18 | ], 19 | "install": { 20 | "before": [] 21 | } 22 | } -------------------------------------------------------------------------------- /public/components-json/beam-button.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "beam-button", 3 | "type": "registry:ui", 4 | "registryDependencies": [], 5 | "dependencies": [ 6 | "framer-motion", 7 | "@radix-ui", 8 | "class-variance-authority" 9 | ], 10 | "devDependencies": [], 11 | "tailwind": {}, 12 | "cssVars": { 13 | "light": {}, 14 | "dark": {} 15 | }, 16 | "files": [ 17 | { 18 | "path": "beam-button.tsx", 19 | "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { motion, useMotionTemplate, useMotionValue } from \"framer-motion\"\nimport { cn } from \"@/lib/utils\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nconst beamButtonVariants = cva(\n \"inline-flex items-center justify-center whitespace-nowrap font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-slate-950 disabled:pointer-events-none disabled:opacity-50 dark:focus-visible:ring-slate-300\",\n {\n variants: {\n variant: {\n default:\n \"bg-white text-slate-900 hover:bg-slate-100 dark:bg-black dark:text-slate-100 dark:hover:bg-slate-800 border border-slate-200 dark:border-slate-700 hover:\",\n outline:\n \"border border-slate-200 bg-white hover:bg-slate-100 hover:text-slate-900 dark:border-slate-700 dark:bg-black dark:hover:bg-slate-800 dark:hover:text-slate-50\",\n ghost:\n \"hover:bg-slate-100 hover:text-slate-900 dark:hover:bg-slate-800 dark:hover:text-slate-50 border border-transparent\",\n },\n size: {\n default: \"h-9 px-4 py-2\",\n sm: \"h-8 px-3 text-xs\",\n lg: \"h-10 px-8\",\n icon: \"h-9 w-9\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n },\n)\n\ninterface BeamButtonProps\n extends React.ButtonHTMLAttributes,\n VariantProps {\n asChild?: boolean\n beamProps?: {\n beamColor?: string\n glowColor?: string\n hoverColor?: string\n }\n}\n\nconst BeamButton = React.forwardRef(\n ({ className, variant, size, asChild = false, beamProps = {}, children, ...props }, ref) => {\n const Comp = asChild ? Slot : \"button\"\n const [hovered, setHovered] = React.useState(false)\n const mouseX = useMotionValue(0)\n const mouseY = useMotionValue(0)\n\n const {\n beamColor = \"#3b82f6\",\n glowColor = \"rgba(59, 130, 246, 0.5)\",\n hoverColor = \"rgba(59, 130, 246, 0.2)\",\n } = beamProps\n\n const handleMouseMove = (e: React.MouseEvent) => {\n const rect = e.currentTarget.getBoundingClientRect()\n mouseX.set(e.clientX - rect.left)\n mouseY.set(e.clientY - rect.top)\n }\n\n const glowStyle = useMotionTemplate`radial-gradient(\n 120px circle at ${mouseX}px ${mouseY}px,\n ${glowColor},\n transparent 80%\n )`\n\n return (\n setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n >\n \n \n {children}\n \n \n )\n },\n)\nBeamButton.displayName = \"BeamButton\"\n\nexport { BeamButton, beamButtonVariants }\n\n", 20 | "type": "registry:ui" 21 | } 22 | ], 23 | "install": { 24 | "before": [] 25 | } 26 | } -------------------------------------------------------------------------------- /public/components-json/colored-button.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "colored-button", 3 | "type": "registry:ui", 4 | "registryDependencies": [ 5 | "button" 6 | ], 7 | "dependencies": [ 8 | "framer-motion" 9 | ], 10 | "devDependencies": [], 11 | "tailwind": {}, 12 | "cssVars": { 13 | "light": {}, 14 | "dark": {} 15 | }, 16 | "files": [ 17 | { 18 | "path": "colored-button.tsx", 19 | "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { motion } from \"framer-motion\"\nimport { Button } from \"@/components/ui/button\"\nimport type { ButtonProps } from \"@/components/ui/button\"\n\nexport interface RainbowButtonProps extends ButtonProps {\n rainbowIntensity?: number\n rainbowDuration?: number\n}\n\nexport function ColoredButton({ children, rainbowIntensity = 1, rainbowDuration = 3, ...props }: RainbowButtonProps) {\n const [isHovered, setIsHovered] = React.useState(false)\n\n return (\n setIsHovered(true)}\n onHoverEnd={() => setIsHovered(false)}\n >\n {isHovered && (\n \n \n \n )}\n \n {children}\n \n \n )\n}\n\n", 20 | "type": "registry:ui" 21 | } 22 | ], 23 | "install": { 24 | "before": [ 25 | "npx shadcn@latest add button" 26 | ] 27 | } 28 | } -------------------------------------------------------------------------------- /public/components-json/feature-card.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "feature-card", 3 | "type": "registry:ui", 4 | "registryDependencies": [], 5 | "dependencies": [], 6 | "devDependencies": [], 7 | "tailwind": {}, 8 | "cssVars": { 9 | "light": {}, 10 | "dark": {} 11 | }, 12 | "files": [ 13 | { 14 | "path": "feature-card.tsx", 15 | "content": "export default function FeatureCard() {\n return (\n
\n
\n
\n {/* Card 1 */}\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n \n {/* Card 2 */}\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n \n {/* Card 3 */}\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n \n
\n

Social

\n

Write once, share with your friends

\n
\n
\n
\n )\n }", 16 | "type": "registry:ui" 17 | } 18 | ], 19 | "install": { 20 | "before": [] 21 | } 22 | } -------------------------------------------------------------------------------- /public/components-json/firefly-button.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "firefly-button", 3 | "type": "registry:ui", 4 | "registryDependencies": [], 5 | "dependencies": [ 6 | "framer-motion" 7 | ], 8 | "devDependencies": [], 9 | "tailwind": {}, 10 | "cssVars": { 11 | "light": {}, 12 | "dark": {} 13 | }, 14 | "files": [ 15 | { 16 | "path": "firefly-button.tsx", 17 | "content": "\"use client\"\n\nimport React from 'react'\nimport { motion } from 'framer-motion'\n\ninterface FireflyButtonProps {\n text: string;\n onClick?: () => void;\n backgroundColor?: string;\n textColor?: string;\n glowColor?: string;\n fireflyCount?: number;\n fontSize?: string;\n padding?: string;\n className?: string;\n}\n\nexport default function FireflyButton({\n text,\n onClick,\n backgroundColor = '#FFEB3B',\n textColor = '#000000',\n glowColor = '#FDFCA9',\n fireflyCount = 7,\n fontSize = '1rem',\n padding = '1rem 2rem',\n className = '',\n}: FireflyButtonProps) {\n const dotVariants = {\n hover: { x: 0, y: 0 },\n initial: (i: number) => ({\n x: `var(--starting-x-${i})`,\n y: `var(--starting-y-${i})`\n })\n }\n\n const fireflyVariants = {\n hover: {\n opacity: 1,\n scale: 1.2,\n transition: {\n duration: 0.2\n }\n },\n initial: {\n opacity: 0,\n scale: 1,\n transition: {\n duration: 0.2\n }\n }\n }\n\n const buttonVariants = {\n hover: {\n scale: 1.05,\n boxShadow: `0px 0px 30px 5px ${glowColor}, 0px 0px 30px 5px ${glowColor} inset`,\n transition: {\n duration: 0.3,\n yoyo: Infinity\n }\n },\n initial: {\n scale: 1,\n boxShadow: `0px 0px 24px 0px ${glowColor}, 0px 0px 23px 0px ${glowColor} inset, 0px 0px 8px 0px ${glowColor}42`\n }\n }\n\n return (\n \n {[...Array(fireflyCount)].map((_, i) => (\n \n \n \n ))}\n \n {text}\n \n \n )\n}", 18 | "type": "registry:ui" 19 | } 20 | ], 21 | "install": { 22 | "before": [] 23 | } 24 | } -------------------------------------------------------------------------------- /public/components-json/glitch-text.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "glitch-text", 3 | "type": "registry:ui", 4 | "registryDependencies": [], 5 | "dependencies": [], 6 | "devDependencies": [], 7 | "tailwind": {}, 8 | "cssVars": { 9 | "light": {}, 10 | "dark": {} 11 | }, 12 | "files": [ 13 | { 14 | "path": "glitch-text.tsx", 15 | "content": "\"use client\"\n\nimport React, { useEffect, useState } from \"react\"\n\ninterface GlitchTextProps {\n text: string\n textSize: string\n className?: string\n fontWeight?: React.CSSProperties[\"fontWeight\"]\n}\n\nexport default function GlitchText({\n text,\n textSize,\n className = \"\",\n fontWeight = \"normal\",\n}: GlitchTextProps) {\n const [displayedText, setDisplayedText] = useState(\"\")\n\n useEffect(() => {\n let currentIndex = 0\n const fullText = text\n const typingInterval = setInterval(() => {\n if (currentIndex <= fullText.length) {\n setDisplayedText(fullText.slice(0, currentIndex))\n currentIndex++\n } else {\n clearInterval(typingInterval)\n }\n }, 100)\n return () => clearInterval(typingInterval)\n }, [text])\n\n return (\n \n
\n {displayedText}\n
\n \n
\n )\n}\n", 16 | "type": "registry:ui" 17 | } 18 | ], 19 | "install": { 20 | "before": [] 21 | } 22 | } -------------------------------------------------------------------------------- /public/components-json/hexagon-hero.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hexagon-hero", 3 | "type": "registry:ui", 4 | "registryDependencies": [], 5 | "dependencies": [ 6 | "lucide-react" 7 | ], 8 | "devDependencies": [], 9 | "tailwind": {}, 10 | "cssVars": { 11 | "light": {}, 12 | "dark": {} 13 | }, 14 | "files": [ 15 | { 16 | "path": "hexagon-hero.tsx", 17 | "content": "\"use client\"\n\nimport { useEffect, useRef, useState } from 'react'\nimport { Youtube } from 'lucide-react'\n\nexport default function HexagonHero() {\n const patternRef = useRef(null)\n const [mousePosition, setMousePosition] = useState({ x: 50, y: -10 })\n\n useEffect(() => {\n const patternElement = patternRef.current\n if (!patternElement) return\n\n const countY = Math.ceil(patternElement.clientHeight / 40) + 10\n const countX = Math.ceil(patternElement.clientWidth / 108) + 60\n\n for (let i = 0; i < countY; i++) {\n for (let j = 0; j < countX; j++) {\n const hexagon = document.createElement(\"div\")\n hexagon.className = \"absolute w-11 h-[50px] bg-no-repeat bg-contain\"\n hexagon.style.backgroundImage = \"url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODciIGhlaWdodD0iMTAwIiB2aWV3Qm94PSIwIDAgODcgMTAwIiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgo8cGF0aCBkPSJNMi4xOTg3MyAyNi4xNTQ3TDQzLjUgMi4zMDk0TDg0LjgwMTMgMjYuMTU0N1Y3My44NDUzTDQzLjUgOTcuNjkwNkwyLjE5ODczIDczLjg0NTNWMjYuMTU0N1oiIGZpbGw9IiMxMzEyMTciIHN0cm9rZT0iIzEzMTIxNyIgc3Ryb2tlLXdpZHRoPSI0Ii8+Cjwvc3ZnPgo=')\"\n hexagon.style.top = `${i * 40}px`\n hexagon.style.left = `${j * 48 + ((i * 24) % 48)}px`\n patternElement.appendChild(hexagon)\n }\n }\n\n const handleMouseMove = (e: MouseEvent) => {\n setMousePosition({ x: e.clientX, y: e.clientY })\n }\n\n document.addEventListener(\"mousemove\", handleMouseMove)\n\n return () => {\n document.removeEventListener(\"mousemove\", handleMouseMove)\n }\n }, [])\n\n return (\n
\n

Hexagons

\n
\n
\n \n
\n )\n}\n\n", 18 | "type": "registry:ui" 19 | } 20 | ], 21 | "install": { 22 | "before": [] 23 | } 24 | } -------------------------------------------------------------------------------- /public/components-json/highlighter.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "highlighter", 3 | "type": "registry:ui", 4 | "registryDependencies": [], 5 | "dependencies": [ 6 | "rough-notation" 7 | ], 8 | "devDependencies": [], 9 | "tailwind": {}, 10 | "cssVars": { 11 | "light": {}, 12 | "dark": {} 13 | }, 14 | "files": [ 15 | { 16 | "path": "highlighter.tsx", 17 | "content": "\"use client\";\n\nimport { useEffect, useRef } from \"react\";\nimport { annotate } from \"rough-notation\";\nimport type { RoughAnnotation } from \"rough-notation/lib/model\";\nimport type React from \"react\";\n\ninterface HighlighterProps {\n children: React.ReactNode;\n action?: \"highlight\" | \"circle\";\n color?: string;\n}\n\nexport default function Highlighter({\n children,\n action = \"highlight\",\n color = \"#ffd1dc\", // Default pink color\n}: HighlighterProps) {\n const elementRef = useRef(null);\n const annotationRef = useRef(null);\n\n useEffect(() => {\n if (elementRef.current) {\n const annotation = annotate(elementRef.current, {\n type: action === \"circle\" ? \"circle\" : \"highlight\",\n color: color,\n multiline: true,\n padding: action === \"circle\" ? 8 : 2,\n iterations: 2, // More iterations for a natural effect\n animationDuration: 500,\n });\n\n annotationRef.current = annotation;\n annotation.show();\n }\n\n return () => {\n annotationRef.current?.remove();\n };\n }, [action, color, elementRef.current]); // Added elementRef.current dependency\n\n return (\n \n {children}\n \n );\n}\n", 18 | "type": "registry:ui" 19 | } 20 | ], 21 | "install": { 22 | "before": [] 23 | } 24 | } -------------------------------------------------------------------------------- /public/components-json/key-button.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "key-button", 3 | "type": "registry:ui", 4 | "registryDependencies": [ 5 | "button" 6 | ], 7 | "dependencies": [], 8 | "devDependencies": [], 9 | "tailwind": {}, 10 | "cssVars": { 11 | "light": {}, 12 | "dark": {} 13 | }, 14 | "files": [ 15 | { 16 | "path": "key-button.tsx", 17 | "content": "\"use client\"\n\nimport React from \"react\"\nimport { Button } from \"@/components/ui/button\"\n\n\ninterface KeyButtonProps {\n text: string\n size: any\n variant: any\n}\n\nfunction KeyButton({ text, size, variant }: KeyButtonProps) {\n return (\n
\n \n \n {text}\n
\n
\n \n \n \n
\n
\n \n
\n )\n}\n\nexport default KeyButton\n", 18 | "type": "registry:ui" 19 | } 20 | ], 21 | "install": { 22 | "before": [ 23 | "npx shadcn@latest add button" 24 | ] 25 | } 26 | } -------------------------------------------------------------------------------- /public/components-json/tilt-motion.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tilt-motion", 3 | "type": "registry:ui", 4 | "registryDependencies": [], 5 | "dependencies": [ 6 | "framer-motion" 7 | ], 8 | "devDependencies": [], 9 | "tailwind": {}, 10 | "cssVars": { 11 | "light": {}, 12 | "dark": {} 13 | }, 14 | "files": [ 15 | { 16 | "path": "tilt-motion.tsx", 17 | "content": "\"use client\"\n\nimport type React from \"react\"\nimport { useState, useRef, useEffect } from \"react\"\nimport { motion, useMotionValue, useSpring, useTransform } from \"framer-motion\"\n\ninterface TiltMotionProps {\n children: React.ReactNode\n tiltFactor?: number\n perspective?: number\n scale?: number\n transitionDuration?: number\n}\n\nexport const TiltMotion: React.FC = ({\n children,\n tiltFactor = 15,\n perspective = 1000,\n scale = 1.05,\n transitionDuration = 0.5,\n}) => {\n const [isHovering, setIsHovering] = useState(false)\n const ref = useRef(null)\n const [elementSize, setElementSize] = useState({ width: 0, height: 0 })\n\n const x = useMotionValue(0)\n const y = useMotionValue(0)\n\n const springConfig = { damping: 30, stiffness: 400, mass: 0.5 }\n const xSpring = useSpring(x, springConfig)\n const ySpring = useSpring(y, springConfig)\n\n const rotateX = useTransform(ySpring, [-elementSize.height / 2, elementSize.height / 2], [tiltFactor, -tiltFactor])\n const rotateY = useTransform(xSpring, [-elementSize.width / 2, elementSize.width / 2], [-tiltFactor, tiltFactor])\n\n useEffect(() => {\n const updateSize = () => {\n if (ref.current) {\n setElementSize({\n width: ref.current.offsetWidth,\n height: ref.current.offsetHeight,\n })\n }\n }\n\n updateSize()\n window.addEventListener(\"resize\", updateSize)\n return () => window.removeEventListener(\"resize\", updateSize)\n }, [])\n\n const handleMouseMove = (event: React.MouseEvent) => {\n if (!ref.current) return\n const rect = ref.current.getBoundingClientRect()\n const mouseX = event.clientX - rect.left\n const mouseY = event.clientY - rect.top\n const centerX = elementSize.width / 2\n const centerY = elementSize.height / 2\n x.set(mouseX - centerX)\n y.set(mouseY - centerY)\n }\n\n const handleMouseEnter = () => setIsHovering(true)\n const handleMouseLeave = () => {\n setIsHovering(false)\n x.set(0)\n y.set(0)\n }\n\n return (\n \n \n {children}\n \n \n )\n}\n\n", 18 | "type": "registry:ui" 19 | } 20 | ], 21 | "install": { 22 | "before": [] 23 | } 24 | } -------------------------------------------------------------------------------- /public/dashboard-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/dashboard-dark.png -------------------------------------------------------------------------------- /public/dashboard-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/dashboard-light.png -------------------------------------------------------------------------------- /public/designfast-img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/designfast-img.png -------------------------------------------------------------------------------- /public/easy-chatbot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/easy-chatbot.png -------------------------------------------------------------------------------- /public/easy-waitlist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/easy-waitlist.png -------------------------------------------------------------------------------- /public/ez-SaaS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/ez-SaaS.png -------------------------------------------------------------------------------- /public/ez-ai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/ez-ai.png -------------------------------------------------------------------------------- /public/ez-beautiful.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/ez-beautiful.png -------------------------------------------------------------------------------- /public/ez-blog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/ez-blog.png -------------------------------------------------------------------------------- /public/ez-chatbot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/ez-chatbot.png -------------------------------------------------------------------------------- /public/ez-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/ez-dashboard.png -------------------------------------------------------------------------------- /public/ez-design.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/ez-design.png -------------------------------------------------------------------------------- /public/ez-designfast.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/ez-designfast.png -------------------------------------------------------------------------------- /public/ez-docs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/ez-docs.png -------------------------------------------------------------------------------- /public/ez-glow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/ez-glow.png -------------------------------------------------------------------------------- /public/ez-gloww.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/ez-gloww.png -------------------------------------------------------------------------------- /public/ez-grids.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/ez-grids.png -------------------------------------------------------------------------------- /public/ez-haze.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/ez-haze.png -------------------------------------------------------------------------------- /public/ez-indigo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/ez-indigo.png -------------------------------------------------------------------------------- /public/ez-landing-docs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/ez-landing-docs.png -------------------------------------------------------------------------------- /public/ez-marketplace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/ez-marketplace.png -------------------------------------------------------------------------------- /public/ez-newsletter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/ez-newsletter.png -------------------------------------------------------------------------------- /public/ez-nextui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/ez-nextui.png -------------------------------------------------------------------------------- /public/ez-notes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/ez-notes.png -------------------------------------------------------------------------------- /public/ez-portfolio-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/ez-portfolio-2.png -------------------------------------------------------------------------------- /public/ez-portfolio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/ez-portfolio.png -------------------------------------------------------------------------------- /public/ez-premium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/ez-premium.png -------------------------------------------------------------------------------- /public/ez-quotes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/ez-quotes.png -------------------------------------------------------------------------------- /public/ez-red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/ez-red.png -------------------------------------------------------------------------------- /public/ez-retro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/ez-retro.png -------------------------------------------------------------------------------- /public/ez-shots.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/ez-shots.png -------------------------------------------------------------------------------- /public/ez-story.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/ez-story.png -------------------------------------------------------------------------------- /public/ez-tmp2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/ez-tmp2.png -------------------------------------------------------------------------------- /public/ez-tmp3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/ez-tmp3.png -------------------------------------------------------------------------------- /public/ez-tmp4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/ez-tmp4.png -------------------------------------------------------------------------------- /public/ez-tmp5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/ez-tmp5.png -------------------------------------------------------------------------------- /public/eztmp1-img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/eztmp1-img.png -------------------------------------------------------------------------------- /public/favicon copy.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/favicon copy.ico -------------------------------------------------------------------------------- /public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/favicon-16x16.png -------------------------------------------------------------------------------- /public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/favicon-32x32.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/favicon.ico -------------------------------------------------------------------------------- /public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/logo.png -------------------------------------------------------------------------------- /public/next copy.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/next.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/og.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/og.png -------------------------------------------------------------------------------- /public/quotesai-img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/quotesai-img.png -------------------------------------------------------------------------------- /public/retro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/retro.png -------------------------------------------------------------------------------- /public/site.webmanifest: -------------------------------------------------------------------------------- 1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} -------------------------------------------------------------------------------- /public/star-dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /public/star-light.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /public/testimonials/dally.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/testimonials/dally.jpeg -------------------------------------------------------------------------------- /public/testimonials/danny.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/testimonials/danny.jpeg -------------------------------------------------------------------------------- /public/testimonials/jerome.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/testimonials/jerome.jpeg -------------------------------------------------------------------------------- /public/testimonials/marcello.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/testimonials/marcello.jpeg -------------------------------------------------------------------------------- /public/testimonials/sayed.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkInventor/easy-ui/238c54a9345a50a710cf4d8e5f9d1f973eeb3e93/public/testimonials/sayed.jpeg -------------------------------------------------------------------------------- /public/thirteen.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/v0-preview/animated-badge.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "animated-badge", 3 | "type": "registry:ui", 4 | "registryDependencies": [], 5 | "dependencies": [], 6 | "files": [ 7 | { 8 | "path": "components/ui/animated-badge.tsx", 9 | "content": "\"use client\";\n\nimport React from 'react'\nimport { cn } from '@/lib/utils'\n\ninterface AnimatedBadgeProps extends React.HTMLAttributes {\n text: string\n bgColor?: string\n textColor?: string\n gradientColor?: string\n animationDuration?: string\n size?: 'sm' | 'md' | 'lg'\n}\n\nexport default function AnimatedBadge({\n text,\n bgColor = 'bg-green-900',\n textColor = 'text-green-300',\n gradientColor = 'from-transparent via-emerald-600 to-transparent',\n animationDuration = '4s',\n size = 'md',\n className,\n ...props\n}: AnimatedBadgeProps) {\n const sizeClasses = {\n sm: 'text-xs',\n md: 'text-sm',\n lg: 'text-base',\n }\n\n return (\n \n \n \n {text}\n
\n
\n )\n}\n\n", 10 | "type": "registry:component", 11 | "target": "components/ui/animated-badge.tsx" 12 | }, 13 | { 14 | "path": "page.tsx", 15 | "content": "import AnimatedBadge from '@/components/ui/animated-badge';\nimport React from 'react'\n\nfunction Home() {\n return (\n
\n \n \n \n \n \n \n \n \n \n
\n )\n}\n\nexport default Home", 16 | "type": "registry:component", 17 | "target": "page.tsx" 18 | } 19 | ], 20 | "author": "Kathan Mehta", 21 | "title": "Animated Badge" 22 | } 23 | 24 | -------------------------------------------------------------------------------- /public/v0-preview/colored-button.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "colored-ColoredButton", 3 | "type": "registry:ui", 4 | "registryDependencies": ["https://ui.shadcn.com/registry/styles/new-york/button.json"], 5 | "files": [ 6 | { 7 | "path": "components/ui/colored-button.tsx", 8 | "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { motion } from \"framer-motion\"\nimport { Button } from \"@/components/ui/button\"\nimport type { ButtonProps } from \"@/components/ui/button\"\n\nexport interface RainbowButtonProps extends ButtonProps {\n rainbowIntensity?: number\n rainbowDuration?: number\n}\n\nexport function ColoredButton({ children, rainbowIntensity = 1, rainbowDuration = 3, ...props }: RainbowButtonProps) {\n const [isHovered, setIsHovered] = React.useState(false)\n\n return (\n setIsHovered(true)}\n onHoverEnd={() => setIsHovered(false)}\n >\n {isHovered && (\n \n \n \n )}\n \n {children}\n \n \n )\n}\n\n", 9 | "type": "registry:ui", 10 | "target": "components/ui/colored-button.tsx" 11 | }, 12 | { 13 | "path": "page.tsx", 14 | "content": "import { ColoredButton } from \"@/components/ui/colored-button\"\nimport React from 'react'\n\nfunction Home() {\n return (\n
\n
\n Default Rainbow Button\n Secondary Variant\n Destructive Variant\n Outline Variant\n Ghost Variant\n Small Size\n Large Size\n Disabled Button\n \n Custom Rainbow (50% intensity, 5s duration)\n \n
\n
\n )\n}\n\nexport default Home", 15 | "type": "registry:component", 16 | "target": "page.tsx" 17 | } 18 | ], 19 | "author": "Kathan Mehta", 20 | "title": "Colored Button" 21 | } -------------------------------------------------------------------------------- /public/v0-preview/glitch-text.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "glitch-text", 3 | "type": "registry:component", 4 | "registryDependencies": [], 5 | "files": [ 6 | { 7 | "path": "components/ui/glitch-text.tsx", 8 | "content": "\"use client\"\n\nimport React, { useEffect, useState } from \"react\"\n\ninterface GlitchTextProps {\n text: string\n textSize: string\n className?: string\n fontWeight?: React.CSSProperties[\"fontWeight\"]\n}\n\nexport default function GlitchText({\n text,\n textSize,\n className = \"\",\n fontWeight = \"normal\",\n}: GlitchTextProps) {\n const [displayedText, setDisplayedText] = useState(\"\")\n\n useEffect(() => {\n let currentIndex = 0\n const fullText = text\n const typingInterval = setInterval(() => {\n if (currentIndex <= fullText.length) {\n setDisplayedText(fullText.slice(0, currentIndex))\n currentIndex++\n } else {\n clearInterval(typingInterval)\n }\n }, 100)\n return () => clearInterval(typingInterval)\n }, [text])\n\n return (\n \n
\n {displayedText}\n
\n \n
\n )\n}\n", 9 | "type": "registry:component", 10 | "target": "components/ui/glitch-text.tsx" 11 | }, 12 | { 13 | "path": "page.tsx", 14 | "content": "import GlitchText from '@/components/ui/glitch-text';\nimport React from 'react'\n\nfunction Home() {\n return (\n \n )\n}\n\nexport default Home\n", 15 | "type": "registry:component", 16 | "target": "page.tsx" 17 | } 18 | ], 19 | "author": "Kathan Mehta", 20 | "title": "Glitch Text" 21 | } -------------------------------------------------------------------------------- /public/v0-preview/hexagon-hero.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hexagon-hero", 3 | "type": "registry:ui", 4 | "registryDependencies": [], 5 | "dependencies": ["lucide-react"], 6 | "files": [ 7 | { 8 | "path": "components/ui/hexagon-hero.tsx", 9 | "content": "\"use client\"\n\nimport { useEffect, useRef, useState } from 'react'\nimport { Youtube } from 'lucide-react'\n\nexport default function HexagonHero() {\n const patternRef = useRef(null)\n const [mousePosition, setMousePosition] = useState({ x: 50, y: -10 })\n\n useEffect(() => {\n const patternElement = patternRef.current\n if (!patternElement) return\n\n const countY = Math.ceil(patternElement.clientHeight / 40) + 10\n const countX = Math.ceil(patternElement.clientWidth / 108) + 60\n\n for (let i = 0; i < countY; i++) {\n for (let j = 0; j < countX; j++) {\n const hexagon = document.createElement(\"div\")\n hexagon.className = \"absolute w-11 h-[50px] bg-no-repeat bg-contain\"\n hexagon.style.backgroundImage = \"url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODciIGhlaWdodD0iMTAwIiB2aWV3Qm94PSIwIDAgODcgMTAwIiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgo8cGF0aCBkPSJNMi4xOTg3MyAyNi4xNTQ3TDQzLjUgMi4zMDk0TDg0LjgwMTMgMjYuMTU0N1Y3My44NDUzTDQzLjUgOTcuNjkwNkwyLjE5ODczIDczLjg0NTNWMjYuMTU0N1oiIGZpbGw9IiMxMzEyMTciIHN0cm9rZT0iIzEzMTIxNyIgc3Ryb2tlLXdpZHRoPSI0Ii8+Cjwvc3ZnPgo=')\"\n hexagon.style.top = `${i * 40}px`\n hexagon.style.left = `${j * 48 + ((i * 24) % 48)}px`\n patternElement.appendChild(hexagon)\n }\n }\n\n const handleMouseMove = (e: MouseEvent) => {\n setMousePosition({ x: e.clientX, y: e.clientY })\n }\n\n document.addEventListener(\"mousemove\", handleMouseMove)\n\n return () => {\n document.removeEventListener(\"mousemove\", handleMouseMove)\n }\n }, [])\n\n return (\n
\n

Hexagons

\n
\n
\n \n
\n )\n}\n\n", 10 | "type": "registry:component", 11 | "target": "components/ui/hexagon-hero.tsx" 12 | }, 13 | { 14 | "path": "page.tsx", 15 | "content": "import HexagonHero from '@/components/ui/hexagon-hero';\nimport React from 'react'\n\nfunction Home() {\n\n return (\n \n )\n}\n\nexport default Home", 16 | "type": "registry:component", 17 | "target": "page.tsx" 18 | } 19 | ], 20 | "author": "Kathan Mehta", 21 | "title": "Hexagon Hero" 22 | } 23 | 24 | -------------------------------------------------------------------------------- /public/v0-preview/highlighter.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "highlighter", 3 | "type": "registry:ui", 4 | "registryDependencies": [], 5 | "dependencies": ["framer-motion"], 6 | "files": [ 7 | { 8 | "path": "components/ui/highlighter.tsx", 9 | "content": "\"use client\";\n\nimport { useEffect, useRef } from \"react\";\nimport { annotate } from \"rough-notation\";\nimport type { RoughAnnotation } from \"rough-notation/lib/model\";\nimport type React from \"react\";\n\ninterface HighlighterProps {\n children: React.ReactNode;\n action?: \"highlight\" | \"circle\";\n color?: string;\n}\n\nexport default function Highlighter({\n children,\n action = \"highlight\",\n color = \"#ffd1dc\", // Default pink color\n}: HighlighterProps) {\n const elementRef = useRef(null);\n const annotationRef = useRef(null);\n\n useEffect(() => {\n if (elementRef.current) {\n const annotation = annotate(elementRef.current, {\n type: action === \"circle\" ? \"circle\" : \"highlight\",\n color: color,\n multiline: true,\n padding: action === \"circle\" ? 8 : 2,\n iterations: 2, // More iterations for a natural effect\n animationDuration: 500,\n });\n\n annotationRef.current = annotation;\n annotation.show();\n }\n\n return () => {\n annotationRef.current?.remove();\n };\n }, [action, color, elementRef.current]); // Added elementRef.current dependency\n\n return (\n \n {children}\n \n );\n}\n", 10 | "type": "registry:component", 11 | "target": "components/ui/highlighter.tsx" 12 | }, 13 | { 14 | "path": "page.tsx", 15 | "content": "import Highlighter from '@/components/ui/highlighter'\nimport React from 'react'\n\nfunction MyComponent() {\n return (\n

\n This is the Easy UI Highlighter component, designed to make important text stand out effortlessly. Customize colors, actions, and styles to fit your needs. Try it out now!\n

\n )\n}\n\nexport default MyComponent\n", 16 | "type": "registry:component", 17 | "target": "page.tsx" 18 | } 19 | ], 20 | "author": "Kathan Mehta", 21 | "title": "Highlighter" 22 | } 23 | 24 | -------------------------------------------------------------------------------- /public/v0-preview/key-button.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "key-button", 3 | "type": "registry:ui", 4 | "registryDependencies": ["https://ui.shadcn.com/registry/styles/new-york/button.json"], 5 | "files": [ 6 | { 7 | "path": "components/ui/key-button.tsx", 8 | "content": "\"use client\"\n\nimport React from \"react\"\nimport { Button } from \"@/components/ui/button\"\n\n\ninterface KeyButtonProps {\n text: string\n size: any\n variant: any\n}\n\nfunction KeyButton({ text, size, variant }: KeyButtonProps) {\n return (\n
\n \n \n {text}\n
\n
\n \n \n \n
\n
\n \n
\n )\n}\n\nexport default KeyButton\n", 9 | "type": "registry:component", 10 | "target": "components/ui/key-button.tsx" 11 | }, 12 | { 13 | "path": "page.tsx", 14 | "content": "\"use client\"\n\nimport KeyButton from \"@/components/ui/key-button\"\nimport React from \"react\"\n\n\nfunction Home() {\n return (\n
\n \n
\n )\n}\n\nexport default Home\n", 15 | "type": "registry:component", 16 | "target": "page.tsx" 17 | } 18 | ], 19 | "author": "Kathan Mehta", 20 | "title": "Key Button" 21 | } 22 | 23 | -------------------------------------------------------------------------------- /public/v0-preview/tilt-motion.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tilt-motion", 3 | "type": "registry:ui", 4 | "registryDependencies": [], 5 | "dependencies": [ 6 | "framer-motion" 7 | ], 8 | "files": [ 9 | { 10 | "path": "components/ui/tilt-motion.tsx", 11 | "content": "\"use client\"\n\nimport type React from \"react\"\nimport { useState, useRef, useEffect } from \"react\"\nimport { motion, useMotionValue, useSpring, useTransform } from \"framer-motion\"\n\ninterface TiltMotionProps {\n children: React.ReactNode\n tiltFactor?: number\n perspective?: number\n scale?: number\n transitionDuration?: number\n}\n\nexport const TiltMotion: React.FC = ({\n children,\n tiltFactor = 15,\n perspective = 1000,\n scale = 1.05,\n transitionDuration = 0.5,\n}) => {\n const [isHovering, setIsHovering] = useState(false)\n const ref = useRef(null)\n const [elementSize, setElementSize] = useState({ width: 0, height: 0 })\n\n const x = useMotionValue(0)\n const y = useMotionValue(0)\n\n const springConfig = { damping: 30, stiffness: 400, mass: 0.5 }\n const xSpring = useSpring(x, springConfig)\n const ySpring = useSpring(y, springConfig)\n\n const rotateX = useTransform(ySpring, [-elementSize.height / 2, elementSize.height / 2], [tiltFactor, -tiltFactor])\n const rotateY = useTransform(xSpring, [-elementSize.width / 2, elementSize.width / 2], [-tiltFactor, tiltFactor])\n\n useEffect(() => {\n const updateSize = () => {\n if (ref.current) {\n setElementSize({\n width: ref.current.offsetWidth,\n height: ref.current.offsetHeight,\n })\n }\n }\n\n updateSize()\n window.addEventListener(\"resize\", updateSize)\n return () => window.removeEventListener(\"resize\", updateSize)\n }, [])\n\n const handleMouseMove = (event: React.MouseEvent) => {\n if (!ref.current) return\n const rect = ref.current.getBoundingClientRect()\n const mouseX = event.clientX - rect.left\n const mouseY = event.clientY - rect.top\n const centerX = elementSize.width / 2\n const centerY = elementSize.height / 2\n x.set(mouseX - centerX)\n y.set(mouseY - centerY)\n }\n\n const handleMouseEnter = () => setIsHovering(true)\n const handleMouseLeave = () => {\n setIsHovering(false)\n x.set(0)\n y.set(0)\n }\n\n return (\n \n \n {children}\n \n \n )\n}\n", 12 | "type": "registry:ui", 13 | "target": "components/ui/tilt-motion.tsx" 14 | }, 15 | { 16 | "path": "page.tsx", 17 | "content": "import { TiltMotion } from \"@/components/ui/tilt-motion\"\nimport React from 'react'\nimport { Card } from \"@/components/ui/card\"\n\nfunction Home() {\n return (\n
\n \n \n {/* Add your content here */}\n \n \n
\n )\n}\n\nexport default Home", 18 | "type": "registry:component", 19 | "target": "page.tsx" 20 | } 21 | ], 22 | "author": "Kathan Mehta", 23 | "title": "Tilt Motion" 24 | } -------------------------------------------------------------------------------- /public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": [ 4 | "dom", 5 | "dom.iterable", 6 | "esnext" 7 | ], 8 | "allowJs": true, 9 | "skipLibCheck": true, 10 | "strict": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "noEmit": true, 13 | "incremental": true, 14 | "esModuleInterop": true, 15 | "module": "esnext", 16 | "moduleResolution": "node", 17 | "resolveJsonModule": true, 18 | "isolatedModules": true, 19 | "jsx": "preserve", 20 | "baseUrl": ".", 21 | "paths": { 22 | "@/*": [ 23 | "./*" 24 | ], 25 | "contentlayer/generated": [ 26 | "./.contentlayer/generated" 27 | ] 28 | }, 29 | "plugins": [ 30 | { 31 | "name": "next" 32 | } 33 | ], 34 | "strictNullChecks": true, 35 | "target": "ES2017" 36 | }, 37 | "include": [ 38 | "next-env.d.ts", 39 | "**/*.ts", 40 | "**/*.tsx", 41 | ".next/types/**/*.ts", 42 | ".contentlayer/generated", 43 | "scripts/build.ts" 44 | , "app/(docs)/confetti-poll" ], 45 | "exclude": [ 46 | "node_modules", 47 | "app/blog/[slug]/page.tsx" 48 | ] 49 | } 50 | -------------------------------------------------------------------------------- /types/nav.ts: -------------------------------------------------------------------------------- 1 | export interface NavItem { 2 | title: string 3 | href?: string 4 | disabled?: boolean 5 | external?: boolean 6 | } 7 | --------------------------------------------------------------------------------