├── src ├── vite-env.d.ts ├── icon.png ├── reactwind.png ├── types │ ├── three-jsx.d.ts │ └── index.ts ├── lib │ └── utils.ts ├── assets │ └── animations │ │ ├── feature.json │ │ ├── analytics.json │ │ └── web-dev.json ├── components │ ├── ui │ │ ├── icons.tsx │ │ ├── button.tsx │ │ ├── badge.tsx │ │ ├── button-variants.ts │ │ ├── background-gradient.tsx │ │ ├── sidebar.tsx │ │ └── animated-beam.tsx │ ├── FullWidth.tsx │ ├── Header │ │ ├── Logo.tsx │ │ ├── index.tsx │ │ ├── MobileMenu.tsx │ │ └── Navigation.tsx │ ├── Footer │ │ ├── index.tsx │ │ ├── SocialLinks.tsx │ │ ├── FooterLinks.tsx │ │ ├── FooterSimple.tsx │ │ ├── FooterMinimal.tsx │ │ ├── FooterApp.tsx │ │ └── FooterNewsletter.tsx │ ├── ThemeToggle.tsx │ ├── MarqueeSlider.tsx │ ├── Marquee │ │ └── MarqueeContainer.tsx │ ├── sections │ │ ├── SocialLinks.tsx │ │ ├── MarqueeExamples.tsx │ │ ├── MarqueeText.tsx │ │ ├── SparklesText.tsx │ │ ├── DemoSection.tsx │ │ ├── FooterMinimal.tsx │ │ ├── HeroImages.tsx │ │ ├── Ecommerce1.tsx │ │ ├── FeatureSection.tsx │ │ ├── CardHoverEffect.tsx │ │ ├── GradientBlob.tsx │ │ ├── FooterApp2.tsx │ │ ├── HeroVideo.tsx │ │ ├── FooterNewsletter.tsx │ │ ├── ThreeDCard.tsx │ │ ├── AnimatedBeamSection.tsx │ │ ├── SaasHero.tsx │ │ ├── PricingTables.tsx │ │ ├── MarqueeImages2.tsx │ │ ├── EcommerceSlider.tsx │ │ ├── LogoTicker.tsx │ │ ├── ParticleField.tsx │ │ ├── MarqueeLogo.tsx │ │ ├── WavyBackground.tsx │ │ ├── GridGallery.tsx │ │ ├── GalleryExamples.tsx │ │ ├── Ecommerce2.tsx │ │ ├── HeaderExamples.tsx │ │ ├── Pricing2.tsx │ │ └── HeroSection.tsx │ ├── MarqueeSlider2.tsx │ ├── ScrollToTop.tsx │ ├── ErrorBoundary.tsx │ ├── ComponentSections.tsx │ ├── Hero │ │ ├── LottieAnimation.tsx │ │ └── index.tsx │ ├── CodeBlock.tsx │ ├── ComponentSection.tsx │ ├── CursorEffect.tsx │ └── ComponentSidebar.tsx ├── main.tsx ├── hooks │ └── useTheme.ts ├── pages │ └── Error404 │ │ ├── ErrorContent.tsx │ │ ├── index.tsx │ │ ├── ErrorActionButton.tsx │ │ ├── ErrorActions.tsx │ │ └── ErrorAnimation.tsx ├── context │ ├── ThemeContext.tsx │ └── ComponentThemeContext.tsx ├── styles │ └── darkMode.css ├── App.tsx └── index.css ├── reactwind.png ├── public ├── Demo1.gif ├── Demo2.gif └── Herowithvideo.png ├── vercel.json ├── postcss.config.js ├── .gitignore ├── vite.config.ts ├── components.json ├── tsconfig.node.json ├── tsconfig.app.json ├── tsconfig.json ├── eslint.config.js ├── index.html ├── package.json ├── README.md └── tailwind.config.js /src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /src/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GaneshVarma1/ReactWind/HEAD/src/icon.png -------------------------------------------------------------------------------- /reactwind.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GaneshVarma1/ReactWind/HEAD/reactwind.png -------------------------------------------------------------------------------- /public/Demo1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GaneshVarma1/ReactWind/HEAD/public/Demo1.gif -------------------------------------------------------------------------------- /public/Demo2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GaneshVarma1/ReactWind/HEAD/public/Demo2.gif -------------------------------------------------------------------------------- /src/reactwind.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GaneshVarma1/ReactWind/HEAD/src/reactwind.png -------------------------------------------------------------------------------- /vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "rewrites": [{ "source": "/(.*)", "destination": "/index.html" }] 3 | } 4 | -------------------------------------------------------------------------------- /public/Herowithvideo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GaneshVarma1/ReactWind/HEAD/public/Herowithvideo.png -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | 'postcss-import': {}, 4 | 'tailwindcss/nesting': {}, 5 | tailwindcss: {}, 6 | autoprefixer: {}, 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /src/types/three-jsx.d.ts: -------------------------------------------------------------------------------- 1 | import { ThreeElements } from '@react-three/fiber' 2 | 3 | declare global { 4 | namespace JSX { 5 | interface IntrinsicElements extends ThreeElements {} 6 | } 7 | } -------------------------------------------------------------------------------- /src/lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { type ClassValue, clsx } from "clsx" 2 | import { twMerge } from "tailwind-merge" 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)) 6 | } 7 | -------------------------------------------------------------------------------- /src/assets/animations/feature.json: -------------------------------------------------------------------------------- 1 | {"v":"5.7.1","fr":29.9700012207031,"ip":0,"op":180.00000733155,"w":800,"h":600,"nm":"Feature Animation","ddd":0,"assets":[{"id":"comp_0","layers":[]}],"layers":[],"markers":[]} -------------------------------------------------------------------------------- /src/components/ui/icons.tsx: -------------------------------------------------------------------------------- 1 | export const Icons = { 2 | notion: () => ( 3 | // ... Notion SVG code 4 | ), 5 | openai: () => ( 6 | // ... OpenAI SVG code 7 | ), 8 | // ... rest of the icons 9 | }; -------------------------------------------------------------------------------- /src/assets/animations/analytics.json: -------------------------------------------------------------------------------- 1 | {"v":"5.7.1","fr":29.9700012207031,"ip":0,"op":180.00000733155,"w":800,"h":600,"nm":"Analytics Animation","ddd":0,"assets":[{"id":"comp_0","layers":[]}],"layers":[],"markers":[]} -------------------------------------------------------------------------------- /src/main.tsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | import App from './App.tsx'; 4 | import './index.css'; 5 | 6 | createRoot(document.getElementById('root')!).render( 7 | 8 | 9 | 10 | ); 11 | -------------------------------------------------------------------------------- /src/types/index.ts: -------------------------------------------------------------------------------- 1 | export interface NavItem { 2 | title: string; 3 | href: string; 4 | } 5 | 6 | export interface FooterLink { 7 | title: string; 8 | items: { 9 | title: string; 10 | href: string; 11 | }[]; 12 | } 13 | 14 | export interface SocialLink { 15 | platform: string; 16 | href: string; 17 | icon: React.ComponentType; 18 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | .vercel 26 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite"; 2 | import react from "@vitejs/plugin-react"; 3 | import path from "path"; 4 | 5 | // https://vitejs.dev/config/ 6 | export default defineConfig({ 7 | plugins: [react()], 8 | optimizeDeps: { 9 | exclude: ["lucide-react"], 10 | }, 11 | css: { 12 | postcss: './postcss.config.js', 13 | }, 14 | resolve: { 15 | alias: { 16 | "@": path.resolve(__dirname, "./src"), 17 | }, 18 | }, 19 | }); 20 | -------------------------------------------------------------------------------- /src/components/FullWidth.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import styled from 'styled-components'; 3 | 4 | const FullWidthWrapper = styled.div` 5 | width: 100vw; 6 | position: relative; 7 | left: 50%; 8 | right: 50%; 9 | margin-left: -50vw; 10 | margin-right: -50vw; 11 | padding: 0 20px; 12 | `; 13 | 14 | const FullWidth: React.FC<{ children: React.ReactNode }> = ({ children }) => { 15 | return {children}; 16 | }; 17 | 18 | export default FullWidth; -------------------------------------------------------------------------------- /src/hooks/useTheme.ts: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from 'react'; 2 | 3 | export const useTheme = () => { 4 | const [theme] = useState<'dark'>('dark'); 5 | 6 | useEffect(() => { 7 | const root = window.document.documentElement; 8 | root.classList.remove('light'); 9 | root.classList.add('dark'); 10 | localStorage.setItem('theme', 'dark'); 11 | }, []); 12 | 13 | // Keep toggleTheme function but make it do nothing 14 | const toggleTheme = () => {}; 15 | 16 | return { theme, toggleTheme }; 17 | }; -------------------------------------------------------------------------------- /components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "new-york", 4 | "rsc": false, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "tailwind.config.js", 8 | "css": "src/index.css", 9 | "baseColor": "zinc", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils", 16 | "ui": "@/components/ui", 17 | "lib": "@/lib", 18 | "hooks": "@/hooks" 19 | }, 20 | "iconLibrary": "lucide" 21 | } -------------------------------------------------------------------------------- /src/components/Header/Logo.tsx: -------------------------------------------------------------------------------- 1 | import { Link } from "react-router-dom"; 2 | 3 | export const Logo = () => { 4 | return ( 5 | (window.location.href = "/")} 9 | > 10 | 11 | ReactWind 12 | 13 | 14 | ); 15 | }; 16 | -------------------------------------------------------------------------------- /src/components/Footer/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { FooterMinimal } from './FooterMinimal'; 3 | import { FooterApp } from './FooterApp'; 4 | import { FooterNewsletter } from './FooterNewsletter'; 5 | 6 | export const Footer = () => { 7 | const isComponentsPage = window.location.pathname === '/components'; 8 | 9 | if (isComponentsPage) { 10 | return ( 11 |
12 | 13 | 14 | 15 |
16 | ); 17 | } 18 | 19 | return ; 20 | }; -------------------------------------------------------------------------------- /tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "allowSyntheticDefaultImports": true, 8 | 9 | /* Bundler mode */ 10 | "allowImportingTsExtensions": true, 11 | "isolatedModules": true, 12 | "moduleDetection": "force", 13 | "noEmit": false, 14 | "outDir": "dist", 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noFallthroughCasesInSwitch": true 21 | }, 22 | "include": ["vite.config.ts"] 23 | } 24 | -------------------------------------------------------------------------------- /src/components/Header/index.tsx: -------------------------------------------------------------------------------- 1 | import { Logo } from './Logo'; 2 | import { Navigation } from './Navigation'; 3 | import { MobileMenu } from './MobileMenu'; 4 | 5 | export const Header = () => { 6 | return ( 7 |
8 |
9 |
10 | 11 | 12 |
13 | 14 |
15 |
16 |
17 |
18 | ); 19 | }; -------------------------------------------------------------------------------- /src/components/ThemeToggle.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Moon, Sun } from 'lucide-react'; 3 | import { useTheme } from '../hooks/useTheme'; 4 | 5 | export const ThemeToggle = () => { 6 | const { theme, toggleTheme } = useTheme(); 7 | 8 | return ( 9 | 20 | ); 21 | }; -------------------------------------------------------------------------------- /src/components/MarqueeSlider.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | interface MarqueeSliderProps { 4 | items: React.ReactNode[]; 5 | reverse?: boolean; 6 | } 7 | 8 | export const MarqueeSlider = ({ items, reverse = false }: MarqueeSliderProps) => { 9 | const content = [...items, ...items]; // Duplicate items for seamless loop 10 | 11 | return ( 12 |
13 |
14 | {content.map((item, index) => ( 15 |
16 | {item} 17 |
18 | ))} 19 |
20 |
21 | ); 22 | }; -------------------------------------------------------------------------------- /tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | "baseUrl": ".", 9 | "paths": { 10 | "@/*": ["./src/*"] 11 | }, 12 | 13 | /* Bundler mode */ 14 | "moduleResolution": "bundler", 15 | "allowImportingTsExtensions": true, 16 | "isolatedModules": true, 17 | "moduleDetection": "force", 18 | "noEmit": true, 19 | "jsx": "react-jsx", 20 | 21 | /* Linting */ 22 | "strict": true, 23 | "noUnusedLocals": true, 24 | "noUnusedParameters": true, 25 | "noFallthroughCasesInSwitch": true 26 | }, 27 | "include": ["src"] 28 | } 29 | -------------------------------------------------------------------------------- /src/pages/Error404/ErrorContent.tsx: -------------------------------------------------------------------------------- 1 | import { motion } from 'framer-motion'; 2 | 3 | export const ErrorContent = () => { 4 | return ( 5 | 11 |

12 | 404 13 |

14 |

15 | Page Not Found 16 |

17 |

18 | Oops! The page you're looking for seems to have wandered off into the digital wilderness. 🌲 19 |

20 |
21 | ); 22 | }; -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | "baseUrl": ".", 9 | "paths": { 10 | "@/*": ["src/*"] 11 | }, 12 | 13 | /* Bundler mode */ 14 | "moduleResolution": "bundler", 15 | "allowImportingTsExtensions": true, 16 | "resolveJsonModule": true, 17 | "isolatedModules": true, 18 | "noEmit": true, 19 | "jsx": "react-jsx", 20 | 21 | /* Linting */ 22 | "strict": true, 23 | "noUnusedLocals": true, 24 | "noUnusedParameters": true, 25 | "noFallthroughCasesInSwitch": true 26 | }, 27 | "include": ["src"], 28 | "references": [{ "path": "./tsconfig.node.json" }] 29 | } 30 | -------------------------------------------------------------------------------- /src/pages/Error404/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ErrorContent } from './ErrorContent'; 3 | import { ErrorActions } from './ErrorActions'; 4 | import { ErrorAnimation } from './ErrorAnimation'; 5 | 6 | export const Error404 = () => { 7 | return ( 8 |
9 |
10 |
11 |
12 | 13 | 14 |
15 | 16 |
17 |
18 |
19 | ); 20 | }; -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | import js from '@eslint/js'; 2 | import globals from 'globals'; 3 | import reactHooks from 'eslint-plugin-react-hooks'; 4 | import reactRefresh from 'eslint-plugin-react-refresh'; 5 | import tseslint from 'typescript-eslint'; 6 | 7 | export default tseslint.config( 8 | { ignores: ['dist'] }, 9 | { 10 | extends: [js.configs.recommended, ...tseslint.configs.recommended], 11 | files: ['**/*.{ts,tsx}'], 12 | languageOptions: { 13 | ecmaVersion: 2020, 14 | globals: globals.browser, 15 | }, 16 | plugins: { 17 | 'react-hooks': reactHooks, 18 | 'react-refresh': reactRefresh, 19 | }, 20 | rules: { 21 | ...reactHooks.configs.recommended.rules, 22 | 'react-refresh/only-export-components': [ 23 | 'warn', 24 | { allowConstantExport: true }, 25 | ], 26 | }, 27 | } 28 | ); 29 | -------------------------------------------------------------------------------- /src/components/ui/button.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { Slot } from "@radix-ui/react-slot"; 3 | import { type VariantProps } from "class-variance-authority"; 4 | import { cn } from "../../lib/utils"; 5 | import { buttonVariants } from "./button-variants"; 6 | 7 | export interface ButtonProps 8 | extends React.ButtonHTMLAttributes, 9 | VariantProps { 10 | asChild?: boolean; 11 | } 12 | 13 | const Button = React.forwardRef( 14 | ({ className, variant, size, asChild = false, ...props }, ref) => { 15 | const Comp = asChild ? Slot : "button"; 16 | return ( 17 | 22 | ); 23 | } 24 | ); 25 | Button.displayName = "Button"; 26 | 27 | export { Button }; 28 | -------------------------------------------------------------------------------- /src/components/Marquee/MarqueeContainer.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { motion } from 'framer-motion'; 3 | 4 | interface MarqueeContainerProps { 5 | children: React.ReactNode; 6 | direction?: 'left' | 'right'; 7 | duration?: number; 8 | className?: string; 9 | } 10 | 11 | export const MarqueeContainer = ({ 12 | children, 13 | direction = 'left', 14 | duration = 25, 15 | className = '', 16 | }: MarqueeContainerProps) => { 17 | return ( 18 |
19 | 33 | {children} 34 | 35 |
36 | ); 37 | }; -------------------------------------------------------------------------------- /src/pages/Error404/ErrorActionButton.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { motion } from 'framer-motion'; 3 | 4 | interface ErrorActionButtonProps { 5 | icon: React.ReactNode; 6 | label: string; 7 | onClick: () => void; 8 | primary?: boolean; 9 | } 10 | 11 | export const ErrorActionButton = ({ icon, label, onClick, primary }: ErrorActionButtonProps) => { 12 | return ( 13 | 25 | {icon} 26 | {label} 27 | 28 | ); 29 | }; -------------------------------------------------------------------------------- /src/pages/Error404/ErrorActions.tsx: -------------------------------------------------------------------------------- 1 | import { motion } from 'framer-motion'; 2 | import { useNavigate } from 'react-router-dom'; 3 | import { Home, HelpCircle } from 'lucide-react'; 4 | import { ErrorActionButton } from './ErrorActionButton'; 5 | 6 | export const ErrorActions = () => { 7 | const navigate = useNavigate(); 8 | 9 | const actions = [ 10 | { 11 | icon: , 12 | label: 'Go Home', 13 | onClick: () => navigate('/'), 14 | primary: true 15 | }, 16 | { 17 | icon: , 18 | label: 'Help', 19 | onClick: () => navigate('/docs'), 20 | } 21 | ]; 22 | 23 | return ( 24 | 30 | {actions.map((action) => ( 31 | 32 | ))} 33 | 34 | ); 35 | }; -------------------------------------------------------------------------------- /src/components/sections/SocialLinks.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Github, Twitter, Linkedin } from 'lucide-react'; 3 | import { motion } from 'framer-motion'; 4 | 5 | export const SocialLinks = () => { 6 | const socialLinks = [ 7 | { icon: Github, href: 'https://github.com/buildeasy', label: 'GitHub' }, 8 | { icon: Twitter, href: 'https://twitter.com/buildeasy', label: 'Twitter' }, 9 | { icon: Linkedin, href: 'https://linkedin.com/company/buildeasy', label: 'LinkedIn' }, 10 | ]; 11 | 12 | return ( 13 |
14 | {socialLinks.map(({ icon: Icon, href, label }) => ( 15 | 24 | 25 | 26 | ))} 27 |
28 | ); 29 | }; -------------------------------------------------------------------------------- /src/components/MarqueeSlider2.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { motion } from 'framer-motion'; 3 | 4 | interface MarqueeSlider2Props { 5 | items: React.ReactNode[]; 6 | direction?: 'left' | 'right'; 7 | speed?: number; 8 | } 9 | 10 | export const MarqueeSlider2: React.FC = ({ 11 | items, 12 | direction = 'left', 13 | speed = 25, 14 | }) => { 15 | const marqueeVariants = { 16 | animate: { 17 | x: direction === 'left' ? [0, -1035], 18 | transition: { 19 | x: { 20 | repeat: Infinity, 21 | repeatType: "loop", 22 | duration: 50/speed, 23 | ease: "linear", 24 | }, 25 | }, 26 | }, 27 | }; 28 | 29 | return ( 30 |
31 | 36 | {[...items, ...items].map((item, index) => ( 37 |
38 | {item} 39 |
40 | ))} 41 |
42 |
43 | ); 44 | }; -------------------------------------------------------------------------------- /src/components/ScrollToTop.tsx: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from "react"; 2 | import { ArrowUp } from "lucide-react"; 3 | 4 | export const ScrollToTop = () => { 5 | const [isVisible, setIsVisible] = useState(false); 6 | 7 | useEffect(() => { 8 | const toggleVisibility = () => { 9 | if (window.pageYOffset > 300) { 10 | setIsVisible(true); 11 | } else { 12 | setIsVisible(false); 13 | } 14 | }; 15 | 16 | window.addEventListener("scroll", toggleVisibility); 17 | return () => window.removeEventListener("scroll", toggleVisibility); 18 | }, []); 19 | 20 | const scrollToTop = () => { 21 | window.scrollTo({ 22 | top: 0, 23 | behavior: "smooth", 24 | }); 25 | }; 26 | 27 | return ( 28 | <> 29 | {isVisible && ( 30 | 37 | )} 38 | 39 | ); 40 | }; 41 | -------------------------------------------------------------------------------- /src/components/Footer/SocialLinks.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Github, Twitter, Linkedin } from 'lucide-react'; 3 | import { SocialLink } from '../../types'; 4 | 5 | const socialLinks: SocialLink[] = [ 6 | { 7 | platform: 'GitHub', 8 | href: 'https://github.com/buildeasy/components', 9 | icon: Github, 10 | }, 11 | { 12 | platform: 'Twitter', 13 | href: 'https://twitter.com/buildeasy', 14 | icon: Twitter, 15 | }, 16 | { 17 | platform: 'LinkedIn', 18 | href: 'https://linkedin.com/company/buildeasy', 19 | icon: Linkedin, 20 | }, 21 | ]; 22 | 23 | export const SocialLinks = () => { 24 | return ( 25 |
26 |

27 | {socialLinks.map(({ platform, href, icon: Icon }) => ( 28 | 36 | 37 | 38 | ))} 39 |
40 | ); 41 | }; 42 | -------------------------------------------------------------------------------- /src/pages/Error404/ErrorAnimation.tsx: -------------------------------------------------------------------------------- 1 | import { motion } from 'framer-motion'; 2 | import Lottie from 'lottie-react'; 3 | // Import Lottie JSON 4 | import lottieAnimation from '../../assets/lwlERW6itQ.json'; 5 | export const ErrorAnimation = () => { 6 | return ( 7 | 13 |
14 |
15 |
16 | 17 | 28 |
29 |
30 | 31 | ); 32 | }; -------------------------------------------------------------------------------- /src/components/ui/badge.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { cva, type VariantProps } from "class-variance-authority"; 3 | 4 | import { cn } from "../../lib/utils"; 5 | 6 | const badgeVariants = cva( 7 | "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", 8 | { 9 | variants: { 10 | variant: { 11 | default: 12 | "border-transparent bg-primary text-primary-foreground hover:bg-primary/80", 13 | secondary: 14 | "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80", 15 | destructive: 16 | "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80", 17 | outline: "text-foreground", 18 | }, 19 | }, 20 | defaultVariants: { 21 | variant: "default", 22 | }, 23 | } 24 | ); 25 | 26 | export interface BadgeProps 27 | extends React.HTMLAttributes, 28 | VariantProps {} 29 | 30 | function Badge({ className, variant, ...props }: BadgeProps) { 31 | return ( 32 |
33 | ); 34 | } 35 | 36 | export { Badge }; 37 | -------------------------------------------------------------------------------- /src/components/sections/MarqueeExamples.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { MarqueeImages2 } from './MarqueeImages2'; 3 | import { MarqueeText } from './MarqueeText'; 4 | import { MarqueeLogo } from './MarqueeLogo'; 5 | 6 | export const MarqueeExamples = () => { 7 | return ( 8 |
9 |
10 |

11 | Marquee Examples ✨ 12 |

13 | 14 | {/* Text Marquee */} 15 |
16 |

17 | Text Marquee 📝 18 |

19 | 20 |
21 | 22 | {/* Logo Marquee */} 23 |
24 |

25 | Logo Marquee 🎯 26 |

27 | 28 |
29 | 30 | {/* Image Marquee */} 31 |
32 |

33 | Image Marquee 🖼️ 34 |

35 | 36 |
37 |
38 |
39 | ); 40 | }; -------------------------------------------------------------------------------- /src/components/sections/MarqueeText.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { motion } from 'framer-motion'; 3 | 4 | const texts = [ 5 | "Beautiful React Components ✨", 6 | "Production Ready 🚀", 7 | "Fully Customizable 🎨", 8 | "Dark Mode Support 🌙", 9 | "Responsive Design 📱", 10 | "Modern & Clean UI 💅", 11 | ]; 12 | 13 | export const MarqueeText = () => { 14 | return ( 15 |
18 |
19 | 33 | {[...texts, ...texts].map((text, index) => ( 34 |
38 | {text} 39 |
40 | ))} 41 |
42 |
43 |
44 | ); 45 | } -------------------------------------------------------------------------------- /src/context/ThemeContext.tsx: -------------------------------------------------------------------------------- 1 | import React, { createContext, useContext, useEffect, useState } from 'react'; 2 | 3 | interface ThemeContextType { 4 | theme: 'light' | 'dark'; 5 | toggleTheme: () => void; 6 | } 7 | 8 | const ThemeContext = createContext(undefined); 9 | 10 | export const ThemeProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { 11 | const [theme, setTheme] = useState<'light' | 'dark'>('light'); 12 | 13 | useEffect(() => { 14 | const savedTheme = localStorage.getItem('theme') as 'light' | 'dark'; 15 | if (savedTheme) { 16 | setTheme(savedTheme); 17 | document.documentElement.classList.toggle('dark', savedTheme === 'dark'); 18 | } else if (window.matchMedia('(prefers-color-scheme: dark)').matches) { 19 | setTheme('dark'); 20 | document.documentElement.classList.add('dark'); 21 | } 22 | }, []); 23 | 24 | const toggleTheme = () => { 25 | const newTheme = theme === 'light' ? 'dark' : 'light'; 26 | setTheme(newTheme); 27 | localStorage.setItem('theme', newTheme); 28 | document.documentElement.classList.toggle('dark'); 29 | }; 30 | 31 | return ( 32 | 33 | {children} 34 | 35 | ); 36 | }; 37 | 38 | export const useComponentTheme = () => { 39 | const context = useContext(ThemeContext); 40 | if (context === undefined) { 41 | throw new Error('useComponentTheme must be used within a ThemeProvider'); 42 | } 43 | return context; 44 | }; -------------------------------------------------------------------------------- /src/context/ComponentThemeContext.tsx: -------------------------------------------------------------------------------- 1 | import { createContext, useContext, useState, ReactNode, useEffect } from 'react'; 2 | 3 | type Theme = 'dark' | 'light'; 4 | 5 | interface ComponentThemeContextType { 6 | theme: Theme; 7 | toggleTheme: () => void; 8 | } 9 | 10 | const ComponentThemeContext = createContext(undefined); 11 | 12 | export function ComponentThemeProvider({ children }: { children: ReactNode }) { 13 | const [theme, setTheme] = useState('dark'); 14 | 15 | const toggleTheme = () => { 16 | setTheme(prev => { 17 | const newTheme = prev === 'dark' ? 'light' : 'dark'; 18 | // Add or remove 'dark' class from HTML element 19 | if (newTheme === 'dark') { 20 | document.documentElement.classList.add('dark'); 21 | } else { 22 | document.documentElement.classList.remove('dark'); 23 | } 24 | return newTheme; 25 | }); 26 | }; 27 | 28 | // Set initial dark mode class 29 | useEffect(() => { 30 | if (theme === 'dark') { 31 | document.documentElement.classList.add('dark'); 32 | } 33 | }, []); 34 | 35 | return ( 36 | 37 | {children} 38 | 39 | ); 40 | } 41 | 42 | export const useComponentTheme = () => { 43 | const context = useContext(ComponentThemeContext); 44 | if (context === undefined) { 45 | throw new Error('useComponentTheme must be used within a ComponentThemeProvider'); 46 | } 47 | return context; 48 | }; -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | ReactWind - By Sri 9 | 13 | 14 | 15 | 16 | 20 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 34 | 38 | 39 | 40 |
41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/components/ErrorBoundary.tsx: -------------------------------------------------------------------------------- 1 | import React, { Component, ErrorInfo, ReactNode } from 'react'; 2 | 3 | interface Props { 4 | children: ReactNode; 5 | } 6 | 7 | interface State { 8 | hasError: boolean; 9 | error?: Error; 10 | } 11 | 12 | export class ErrorBoundary extends Component { 13 | public state: State = { 14 | hasError: false 15 | }; 16 | 17 | public static getDerivedStateFromError(error: Error): State { 18 | return { hasError: true, error }; 19 | } 20 | 21 | public componentDidCatch(error: Error, errorInfo: ErrorInfo) { 22 | console.error('Uncaught error:', error, errorInfo); 23 | } 24 | 25 | public render() { 26 | if (this.state.hasError) { 27 | return ( 28 |
29 |
30 |

31 | Oops! Something went wrong 32 |

33 |

34 | {this.state.error?.message || 'An unexpected error occurred'} 35 |

36 | 42 |
43 |
44 | ); 45 | } 46 | 47 | return this.props.children; 48 | } 49 | } -------------------------------------------------------------------------------- /src/components/ComponentSections.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import { Code2 } from "lucide-react"; 3 | import { motion, AnimatePresence } from "framer-motion"; 4 | import { CodeBlock } from "./CodeBlock"; 5 | 6 | interface ComponentSectionProps { 7 | title: string; 8 | children: React.ReactNode; 9 | code: string; 10 | } 11 | 12 | export const ComponentSection = ({ 13 | title, 14 | children, 15 | code, 16 | }: ComponentSectionProps) => { 17 | const [showCode, setShowCode] = useState(false); 18 | 19 | return ( 20 |
21 |
22 |

23 | {title} 24 |

25 | 32 |
33 | 34 | 35 | {showCode ? ( 36 | 42 | 43 | 44 | ) : null} 45 | 46 | 47 | {children} 48 |
49 | ); 50 | }; 51 | -------------------------------------------------------------------------------- /src/styles/darkMode.css: -------------------------------------------------------------------------------- 1 | @layer utilities { 2 | .dark { 3 | color-scheme: dark; 4 | } 5 | 6 | .dark .dark-card { 7 | @apply bg-gray-800 text-white border-gray-700; 8 | } 9 | 10 | .dark .text-gray-900 { 11 | @apply text-white; 12 | } 13 | 14 | .dark .text-gray-800 { 15 | @apply text-gray-100; 16 | } 17 | 18 | .dark .text-gray-700 { 19 | @apply text-gray-200; 20 | } 21 | 22 | .dark .text-gray-600 { 23 | @apply text-gray-300; 24 | } 25 | 26 | .dark .bg-white { 27 | @apply bg-gray-900; 28 | } 29 | 30 | .dark .border-gray-200 { 31 | @apply border-gray-700; 32 | } 33 | } 34 | 35 | /* Mouse gradient effect */ 36 | :root { 37 | --mouse-x: 50vw; 38 | --mouse-y: 50vh; 39 | } 40 | 41 | .mouse-gradient { 42 | background: radial-gradient( 43 | 800px circle at var(--mouse-x) var(--mouse-y), 44 | rgba(129, 140, 248, 0.15), 45 | transparent 40% 46 | ); 47 | } 48 | 49 | .dark .mouse-gradient { 50 | background: radial-gradient( 51 | 800px circle at var(--mouse-x) var(--mouse-y), 52 | rgba(129, 140, 248, 0.1), 53 | transparent 40% 54 | ); 55 | } 56 | 57 | /* Gradient text effect */ 58 | .gradient-text { 59 | @apply bg-clip-text text-transparent bg-gradient-to-r from-primary-500 to-secondary-500; 60 | } 61 | 62 | /* Button effects */ 63 | .fancy-button { 64 | @apply relative overflow-hidden transition-all duration-300 65 | bg-gradient-to-r from-primary-500 to-secondary-500 66 | hover:from-primary-600 hover:to-secondary-600 67 | text-white font-semibold rounded-lg 68 | transform hover:scale-105 hover:shadow-lg 69 | active:scale-95; 70 | } 71 | -------------------------------------------------------------------------------- /src/components/Header/MobileMenu.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import { Menu, X } from 'lucide-react'; 3 | import { NavLink } from 'react-router-dom'; 4 | import { NavItem } from '../../types'; 5 | 6 | const navItems: NavItem[] = [ 7 | { title: 'Home', href: '/' }, 8 | { title: 'Components', href: '/components' }, 9 | { title: 'Documentation', href: '/docs' }, 10 | { title: 'GitHub', href: 'https://github.com/buildeasy/components' }, 11 | ]; 12 | 13 | export const MobileMenu = () => { 14 | const [isOpen, setIsOpen] = useState(false); 15 | 16 | return ( 17 |
18 | 25 | 26 | {isOpen && ( 27 |
28 | 43 |
44 | )} 45 |
46 | ); 47 | }; -------------------------------------------------------------------------------- /src/components/Footer/FooterLinks.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link } from 'react-router-dom'; 3 | import { FooterLink } from '../../types'; 4 | 5 | const footerLinks: FooterLink[] = [ 6 | { 7 | title: 'Product', 8 | items: [ 9 | { title: 'Components', href: '/components' }, 10 | { title: 'Documentation', href: '/docs' }, 11 | { title: 'Changelog', href: '/changelog' }, 12 | ], 13 | }, 14 | { 15 | title: 'Resources', 16 | items: [ 17 | { title: 'GitHub', href: 'https://github.com/buildeasy/components' }, 18 | { title: 'Examples', href: '/examples' }, 19 | { title: 'Templates', href: '/templates' }, 20 | ], 21 | }, 22 | { 23 | title: 'Company', 24 | items: [ 25 | { title: 'About', href: '/about' }, 26 | { title: 'Blog', href: '/blog' }, 27 | { title: 'Contact', href: '/contact' }, 28 | ], 29 | }, 30 | ]; 31 | 32 | export const FooterLinks = () => { 33 | return ( 34 |
35 | {footerLinks.map((section) => ( 36 |
37 |

38 | {section.title} 39 |

40 |
    41 | {section.items.map((item) => ( 42 |
  • 43 | 47 | {item.title} 48 | 49 |
  • 50 | ))} 51 |
52 |
53 | ))} 54 |
55 | ); 56 | }; -------------------------------------------------------------------------------- /src/components/ui/button-variants.ts: -------------------------------------------------------------------------------- 1 | import { cva } from "class-variance-authority"; 2 | 3 | export const buttonVariants = cva( 4 | "inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50", 5 | { 6 | variants: { 7 | variant: { 8 | default: 9 | "bg-primary text-primary-foreground shadow hover:bg-primary/90", 10 | destructive: 11 | "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90", 12 | outline: 13 | "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground", 14 | secondary: 15 | "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80", 16 | ghost: "hover:bg-accent hover:text-accent-foreground", 17 | link: "text-primary underline-offset-4 hover:underline", 18 | success: "bg-green-500 text-white shadow-sm hover:bg-green-600", 19 | warning: "bg-yellow-500 text-black shadow-sm hover:bg-yellow-600", 20 | info: "bg-blue-500 text-white shadow-sm hover:bg-blue-600", 21 | subtle: "bg-muted text-muted-foreground hover:bg-muted/80", 22 | transparent: "bg-transparent text-primary hover:bg-primary/10", 23 | whiteOutline: 24 | "bg-transparent border border-white text-white hover:bg-white/10", // New variant 25 | }, 26 | size: { 27 | default: "h-9 px-4 py-2", 28 | sm: "h-8 rounded-md px-3 text-xs", 29 | lg: "h-10 rounded-md px-8", 30 | xl: "h-12 rounded-lg px-10 text-lg", 31 | xs: "h-7 rounded px-2 text-xs", 32 | icon: "h-9 w-9", 33 | wide: "h-9 px-6 py-2", 34 | }, 35 | }, 36 | defaultVariants: { 37 | variant: "default", 38 | size: "default", 39 | }, 40 | } 41 | ); 42 | -------------------------------------------------------------------------------- /src/components/sections/SparklesText.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | import { motion } from "framer-motion"; 3 | 4 | const Sparkles = ({ children }: { children: React.ReactNode }) => { 5 | const [sparkles, setSparkles] = useState< 6 | Array<{ id: number; x: number; y: number }> 7 | >([]); 8 | 9 | useEffect(() => { 10 | const interval = setInterval(() => { 11 | const sparkle = { 12 | id: Date.now(), 13 | x: Math.random() * 100, 14 | y: Math.random() * 100, 15 | }; 16 | setSparkles((prev) => [...prev, sparkle]); 17 | }, 500); 18 | 19 | return () => clearInterval(interval); 20 | }, []); 21 | 22 | useEffect(() => { 23 | const timeout = setTimeout(() => { 24 | setSparkles((prev) => prev.slice(1)); 25 | }, 1000); 26 | 27 | return () => clearTimeout(timeout); 28 | }, [sparkles]); 29 | 30 | return ( 31 | 32 | {sparkles.map((sparkle) => ( 33 | 45 | ))} 46 | {children} 47 | 48 | ); 49 | }; 50 | 51 | export const SparklesPreview = () => { 52 | return ( 53 |
54 |

55 | 56 | 57 | Magical Text ✨ 58 | 59 | 60 |

61 |
62 | ); 63 | }; 64 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "buildeasy", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "lint": "eslint .", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "@headlessui/react": "^2.2.0", 14 | "@heroicons/react": "^2.2.0", 15 | "@lottiefiles/react-lottie-player": "^3.5.3", 16 | "@radix-ui/react-slot": "^1.1.1", 17 | "@react-three/drei": "^9.99.5", 18 | "@react-three/fiber": "^8.15.16", 19 | "@react-three/postprocessing": "^2.15.1", 20 | "@vercel/analytics": "^1.4.1", 21 | "class-variance-authority": "^0.7.1", 22 | "framer-motion": "^11.18.1", 23 | "lottie-react": "^2.4.0", 24 | "lottie-web": "^5.12.2", 25 | "lucide-react": "^0.473.0", 26 | "ogl": "^1.0.11", 27 | "react": "^18.3.1", 28 | "react-dom": "^18.3.1", 29 | "react-router-dom": "^6.22.3", 30 | "react-scroll": "^1.9.0", 31 | "react-syntax-highlighter": "^15.6.1", 32 | "shadcn-ui": "^0.9.4", 33 | "three": "^0.161.0" 34 | }, 35 | "optionalDependencies": { 36 | "@rollup/rollup-darwin-arm64": "^4.28.1" 37 | }, 38 | "devDependencies": { 39 | "@eslint/js": "^9.9.1", 40 | "@shadcn/ui": "^0.0.4", 41 | "@types/node": "^22.10.7", 42 | "@types/react": "^18.3.5", 43 | "@types/react-dom": "^18.3.0", 44 | "@types/react-scroll": "^1.8.10", 45 | "@types/react-syntax-highlighter": "^15.5.13", 46 | "@vitejs/plugin-react": "^4.3.1", 47 | "autoprefixer": "^10.4.20", 48 | "clsx": "^2.1.1", 49 | "eslint": "^9.9.1", 50 | "eslint-plugin-react-hooks": "^5.1.0-rc.0", 51 | "eslint-plugin-react-refresh": "^0.4.11", 52 | "globals": "^15.9.0", 53 | "postcss": "^8.5.1", 54 | "postcss-import": "^16.1.0", 55 | "tailwind-merge": "^2.6.0", 56 | "tailwindcss": "^3.4.1", 57 | "tailwindcss-animate": "^1.0.7", 58 | "typescript": "^5.5.3", 59 | "typescript-eslint": "^8.3.0", 60 | "vite": "^5.4.2" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/components/Footer/FooterSimple.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { motion } from 'framer-motion'; 3 | import { Heart, Github, Twitter, Linkedin } from 'lucide-react'; 4 | import { Logo } from '../Header/Logo'; 5 | 6 | export const FooterSimple = () => { 7 | return ( 8 |
9 |
10 |
11 | 12 |

13 | Beautiful React components made with ✨ love ✨ for your next project 14 |

15 |
16 | 21 | 22 | 23 | 28 | 29 | 30 | 35 | 36 | 37 |
38 |
39 | Made with 40 | 41 | by Buildeasy Team 42 |
43 |
44 |
45 |
46 | ); 47 | }; -------------------------------------------------------------------------------- /src/components/sections/DemoSection.tsx: -------------------------------------------------------------------------------- 1 | import { motion } from "framer-motion"; 2 | 3 | export const DemoSection = () => { 4 | return ( 5 |
6 |
7 | 14 |

15 | See ReactWind in Action 16 |

17 |

18 | Watch how easy it is to build beautiful interfaces with our components 19 |

20 |
21 | 22 | 29 |
39 |