windcedar
v0.3.0
Published
A reusable React component library using Tailwind CSS
Maintainers
Readme
WindCedar UI
A modern, fully customizable React component library built with TypeScript and Tailwind CSS. WindCedar UI offers beautiful, accessible UI components with powerful animation capabilities and advanced bundle optimization that seamlessly integrate into your web applications.
🌟 Features
- 🎨 Modern Design: Beautiful, clean components with thoughtful design patterns
- ♿ Accessibility First: WCAG compliant with proper ARIA attributes and keyboard navigation
- 🎭 Advanced Animations: GSAP-inspired animations including smooth scroll, parallax, and morphing effects
- 📱 Responsive: Mobile-first design with responsive breakpoints
- 🌙 Dark Mode: Built-in dark mode support with CSS variables
- ⚡ Performance: Optimized with React.memo, useCallback, and minimal re-renders
- 🔧 TypeScript: Full TypeScript support with comprehensive type definitions
- 🎯 Framework Agnostic: Works with Next.js, Vite, CRA, Remix, and Gatsby
- 📦 Tree Shakeable: Import only what you need for smaller bundle sizes
- 🚀 Bundle Optimized: Lazy loading for heavy components, modular exports, and minimal CSS
- 💡 Developer Experience: Multiple import patterns, excellent IntelliSense, and clear documentation
What's New in v0.3.0 - Tailwind CSS Vite Plugin & Universal Preset
Our latest release adds support for the new Tailwind CSS approach and fixes preset import issues:
🔌 Tailwind CSS Vite Plugin Support
- New Setup Method: Works seamlessly with
@tailwindcss/viteplugin - Simplified Configuration: Easier integration with fewer files
- Modern Workflow: Aligns with latest Tailwind CSS and Vite best practices
- Detailed Guides: Step-by-step instructions in
TAILWIND_VITE_GUIDE.md
🧩 Universal Preset Solution
- Cross-Environment Compatibility: Works in both ESM and CommonJS projects
- Multiple Import Paths: Flexible options to reference the preset
- Module Resolution Fixes: Solves "Cannot find module" errors
- Troubleshooting Guide: Comprehensive solutions in
PRESET_IMPORT_GUIDE.md
📚 Improved Documentation
- Updated Installation Guide: Clear instructions with both setup approaches
- Expanded Examples: New demos showing the Vite plugin integration
- Enhanced Troubleshooting: Solutions for common integration issues
What's New in v0.2.0 - Bundle Optimization Release
Our earlier release focused on performance and developer experience with major bundle optimization improvements:
🚀 Bundle Optimization Features
- Tree Shaking Support: Automatic dead code elimination with
sideEffects: false - Modular Exports: Import individual components for optimal bundle size
- Lazy Loading: Heavy dependencies (react-charts, embla-carousel, cmdk) load on demand
- Split Dependencies: Separates core and optional components for better optimization
- Minimal CSS: Option to import only essential styles
📦 New Import Patterns
// Main entry (tree-shakeable)
import { Button, Card } from 'wind-cedar';
// Modular imports (optimal for bundle size)
import { Button } from 'wind-cedar/button';
import { Chart } from 'wind-cedar/chart'; // Auto lazy-loads react-charts
// Framework-specific
import { Button } from 'wind-cedar/next';
// Animations
import { ScrollReveal } from 'wind-cedar/animations';
// Tailwind preset (v0.3.0+)
import windCedarPreset from 'windcedar/universal-preset';🔧 Tailwind CSS Integration (v0.3.0+)
// Traditional approach (tailwind.config.js)
import windCedarPreset from 'windcedar/universal-preset';
export default {
presets: [windCedarPreset],
content: [
// ...
"./node_modules/windcedar/dist/**/*.{js,ts,jsx,tsx}",
],
}// New Vite plugin approach (vite.config.js)
import tailwindcss from '@tailwindcss/vite';
import windCedarPreset from 'windcedar/universal-preset';
export default defineConfig({
plugins: [
tailwindcss({
config: {
presets: [windCedarPreset],
// ...
}
}),
],
})import { Button } from 'wind-cedar/next';
// Animations
import { ScrollReveal } from 'wind-cedar/animations';
// New Components
import { Rating } from 'wind-cedar/rating';
import { EnhancedButton } from 'wind-cedar/enhanced-button';🎯 Performance Improvements
- React.memo: Core components optimized with React.memo
- Lazy Components: Chart, Carousel, and Combobox automatically lazy load heavy dependencies
- Optimized Builds: Pre-configured for Vite, Webpack, and other bundlers
- CSS Optimization: Tailwind preset and minimal CSS options
Enhanced Button Component
- Ripple Effects: Beautiful ripple animations on click
- Performance Optimizations: React.memo and useCallback for better performance
- Improved Accessibility: Enhanced ARIA attributes and keyboard navigation
- Loading States: Built-in loading indicators
Advanced Input Component
- Clearable Inputs: Optional clear button for better UX
- Character Count: Real-time character counting with customizable limits
- Helper Text: Support for additional guidance text
- Better Validation: Improved error handling and display
Enhanced Modal Component
- Custom Animations: Configurable animation duration and effects
- Scroll Lock: Automatic body scroll prevention when open
- Custom Close Icons: Customizable close button styling
- Scrollable Content: Support for long-form content with internal scrolling
Improved TextAnimate Component
- More Animation Types: Extended animation library
- Intersection Observer: Performance-optimized viewport detection
- Better Performance: Reduced re-renders and optimized timing
Quick Start Guide
Install the Package
Choose one of the following commands based on your package manager:
# Using npm
npm install windcedar
# Using yarn
yarn add windcedar
# Using pnpm
pnpm add windcedarInstall Required Dependencies
npm install tailwindcss postcss autoprefixer
npx tailwindcss init -pConfigure Tailwind CSS (Recommended)
Use the WindCedar preset for optimal configuration:
/** @type {import('tailwindcss').Config} */
const windcedarPreset = require('windcedar/preset');
module.exports = {
presets: [windcedarPreset],
content: [
"./src/**/*.{js,jsx,ts,tsx}",
"./node_modules/windcedar/**/*.{js,ts,jsx,tsx}",
],
// Your custom overrides...
};Import Styles
Choose the import method that best fits your needs:
/* Full styles (recommended for most projects) */
@import "windcedar/styles";
/* Minimal styles (for better tree-shaking) */
@import "windcedar/styles/minimal";Start Using Components
import React from "react";
import { Button } from "windcedar";
export default function App() {
return (
<div className="p-4">
<Button>Click Me</Button>
</div>
);
}Optimization Tips
For optimal bundle size, use modular imports:
// ✅ Modular imports (best for bundle size)
import { Button } from "windcedar/button";
import { Card } from "windcedar/card";
// ✅ Still good (tree-shakeable)
import { Button, Card } from "windcedar";
// ✅ Heavy components auto-optimize
import { Chart } from "windcedar/chart"; // Lazy loads react-chartsComponent Examples
Button Component
WindCedar UI's Button component includes enhanced features like ripple effects, improved accessibility, and performance optimization:
import { Button } from "windcedar";
// Or for modular import: import { Button } from "windcedar/button";
// Basic button usage
<Button>Click Me</Button>
// Variants
<Button variant="primary">Primary</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="outline">Outline</Button>
<Button variant="destructive">Destructive</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="link">Link</Button>
// Sizes
<Button size="sm">Small</Button>
<Button size="md">Medium</Button>
<Button size="lg">Large</Button>
<Button size="icon">🔍</Button>
// Enhanced features (v0.1.4+)
<Button ripple={true}>Button with Ripple Effect</Button>
<Button loading={true}>Loading...</Button>
<Button disabled>Disabled</Button>Input Component
The Input component has been significantly enhanced with new features:
import { Input } from "wind-cedar";
// Basic input
<Input placeholder="Enter text..." />
// With label and helper text
<Input
label="Username"
placeholder="Enter username"
helperText="Must be at least 3 characters"
/>
// Enhanced features (v0.1.4+)
<Input
label="Search"
placeholder="Type to search..."
clearable={true}
maxLength={50}
showCharacterCount={true}
/>
// Password input with character count
<Input
type="password"
label="Password"
maxLength={20}
showCharacterCount={true}
helperText="8-20 characters required"
/>
// Error state
<Input
label="Email"
error="Please enter a valid email address"
placeholder="[email protected]"
/>Modal Component
The Modal component now includes enhanced animations and features:
import { Modal, Button } from "wind-cedar";
import { useState } from "react";
function App() {
const [isOpen, setIsOpen] = useState(false);
return (
<>
<Button onClick={() => setIsOpen(true)}>Open Modal</Button>
<Modal
isOpen={isOpen}
onClose={() => setIsOpen(false)}
title="Enhanced Modal"
description="Modal with improved features"
size="md"
animationDuration={300}
closeOnOverlayClick={true}
showCloseButton={true}
scrollable={true}
>
<div className="py-4">
<p>Modal content with scroll lock and enhanced animations.</p>
<div className="h-96 overflow-y-auto">
<p>Scrollable content area...</p>
</div>
</div>
</Modal>
</>
);
}Framework Integration
Using with Next.js
WindCedar UI provides first-class support for Next.js applications:
Install the package:
npm install windcedar-uiUpdate your
next.config.js:/** @type {import('next').NextConfig} */ const nextConfig = { transpilePackages: ["windcedar-ui"], }; module.exports = nextConfig;For Next.js App Router, update your
app/layout.tsx:import "windcedar-ui/styles"; export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( <html lang="en"> <body>{children}</body> </html> ); }For Pages Router, update your
pages/_app.tsx:import type { AppProps } from "next/app"; import "windcedar-ui/styles"; export default function App({ Component, pageProps }: AppProps) { return <Component {...pageProps} />; }
Using with Vite
Install in your Vite project:
npm install windcedar-uiUpdate your
vite.config.ts:import { defineConfig } from "vite"; import react from "@vitejs/plugin-react"; export default defineConfig({ plugins: [react()], optimizeDeps: { include: ["windcedar-ui"], }, });Import styles in your
src/index.tsxorApp.tsx:import "windcedar-ui/styles";
Using with Remix
Install the package:
npm install windcedar-uiImport styles in your
app/root.tsx:import type { LinksFunction } from "@remix-run/node"; import styles from "windcedar-ui/styles/index.css"; export const links: LinksFunction = () => [{ rel: "stylesheet", href: styles }];
Using with Gatsby
Install the package:
npm install windcedar-uiUpdate your
gatsby-browser.js:import "windcedar-ui/styles";Update
gatsby-config.jsto include Tailwind:module.exports = { plugins: [ "gatsby-plugin-postcss", // ... other plugins ], };
Using with Create React App (CRA)
Install the package:
npm install windcedar-uiImport styles in your
src/index.tsxorApp.tsx:import "windcedar-ui/styles";
Server Components Support
All WindCedar UI components are compatible with React Server Components (RSC) in frameworks that support them (like Next.js 13+). You can use them in both client and server components:
// Server Component
import { Card } from "wind-cedar/next";
export default function ServerComponent() {
return (
<Card>
<h1>Server Component Example</h1>
</Card>
);
}
// Client Component
("use client");
import { Button } from "windcedar";
export default function ClientComponent() {
return <Button onClick={() => alert("Hello!")}>Click Me</Button>;
}6. Complete Example
Here's a complete example combining multiple components:
import { Button, Card, Input, DropdownMenu } from "windcedar-ui";
function UserProfile() {
return (
<Card>
<CardHeader>
<h2>User Profile</h2>
</CardHeader>
<CardContent>
<div className="space-y-4">
<Input label="Full Name" placeholder="John Doe" />
<Input label="Email" type="email" placeholder="[email protected]" />
<DropdownMenu>
<DropdownMenuTrigger>
<Button>Settings</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem>Edit Profile</DropdownMenuItem>
<DropdownMenuItem>Change Password</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
</CardContent>
<CardFooter>
<Button>Save Changes</Button>
</CardFooter>
</Card>
);
}Troubleshooting
If you encounter any styling issues:
Make sure you've imported the styles correctly
Check that your Tailwind configuration includes the correct paths
Try clearing your cache and rebuilding:
npm run build
Advanced Configuration
Tailwind Preset Integration
WindCedar UI provides a preset file that makes integration easier:
Update your
tailwind.config.jsto use the preset:/** @type {import('tailwindcss').Config} */ module.exports = { content: [ "./src/**/*.{js,jsx,ts,tsx}", "./node_modules/windcedar-ui/**/*.{js,ts,jsx,tsx}", ], presets: [require("windcedar-ui/preset")], theme: { extend: { // Your additional theme extensions }, }, plugins: [], };Import the styles in your main application file:
import "windcedar-ui/styles";For Next.js projects, configure transpilation:
// next.config.js /** @type {import('next').NextConfig} */ const nextConfig = { transpilePackages: ["windcedar-ui"], }; module.exports = nextConfig;
Common Solutions
- forwardRef errors: Update to the latest version for proper React forwardRef implementation
- React prop warnings: Ensure you're using the latest version
- PurgeCSS issues: Add WindCedar UI paths to your Tailwind content configuration
// tailwind.config.js
module.exports = {
content: [
// ...existing content
"./node_modules/windcedar-ui/**/*.{js,ts,jsx,tsx}",
],
// ...rest of config
};Additional Component Examples
Card Layout
import { Card, CardHeader, CardContent, CardFooter } from "windcedar-ui";
<Card>
<CardHeader>
<h3>Card Title</h3>
</CardHeader>
<CardContent>
<p>Your content here</p>
</CardContent>
<CardFooter>
<Button>Action</Button>
</CardFooter>
</Card>;Dropdown Menu
import {
DropdownMenu,
DropdownMenuTrigger,
DropdownMenuContent,
DropdownMenuItem,
} from "windcedar-ui";
<DropdownMenu>
<DropdownMenuTrigger>
<Button>Menu</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem>Profile</DropdownMenuItem>
<DropdownMenuItem>Settings</DropdownMenuItem>
<DropdownMenuItem>Logout</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>;Complete Example
Here's a complete example combining multiple components:
import { Button, Card, Input, DropdownMenu } from "windcedar-ui";
function UserProfile() {
return (
<Card>
<CardHeader>
<h2>User Profile</h2>
</CardHeader>
<CardContent>
<div className="space-y-4">
<Input label="Full Name" placeholder="John Doe" />
<Input label="Email" type="email" placeholder="[email protected]" />
<DropdownMenu>
<DropdownMenuTrigger>
<Button>Settings</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem>Edit Profile</DropdownMenuItem>
<DropdownMenuItem>Change Password</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
</CardContent>
<CardFooter>
<Button>Save Changes</Button>
</CardFooter>
</Card>
);
}Advanced Animation Features
WindCedar UI now includes powerful animation capabilities inspired by GSAP (GreenSock Animation Platform), providing fluid motion and interactive experiences with minimal configuration.
Smooth Page Scrolling
Create buttery-smooth scrolling experiences with WindCedar's SmoothScroll component:
import { SmoothScroll } from "windcedar-ui/animations";
function App() {
return (
<SmoothScroll>
<div className="min-h-screen">{/* Your page content */}</div>
</SmoothScroll>
);
}Configuration options:
<SmoothScroll
ease={0.1} // Lower = smoother but slower, higher = faster but less smooth
friction={0.9} // Friction applied to the scrolling motion
breakpoint={768} // Disable smooth scrolling below this viewport width
/>Draggable Elements
Add drag-and-drop functionality to any element:
import { Draggable } from "windcedar-ui/animations";
// Basic draggable element
<Draggable>
<div className="w-32 h-32 bg-primary rounded-lg">
Drag me!
</div>
</Draggable>
// With axis constraints
<Draggable axis="x" bounds="parent">
<div className="cursor-grab">Horizontal drag only</div>
</Draggable>
// With drag events
<Draggable
onDragStart={() => console.log('Started dragging')}
onDragEnd={(position) => console.log('Final position:', position)}
>
<div>Drag with callbacks</div>
</Draggable>Scroll Animation
Create scroll-driven animations that reveal, transform, or animate elements as they enter the viewport:
import { ScrollReveal, ScrollParallax } from "windcedar-ui/animations";
// Fade elements in as they enter the viewport
<ScrollReveal>
<div className="py-8">
This content will fade in when scrolled into view
</div>
</ScrollReveal>
// With animation options
<ScrollReveal
animation="slide-up" // Options: fade, slide-up, slide-down, slide-left, slide-right, zoom
duration={0.8} // Animation duration in seconds
delay={0.2} // Delay before animation starts
threshold={0.3} // How much of element must be visible to trigger (0-1)
>
<div>Custom animation on scroll</div>
</ScrollReveal>
// Create parallax scrolling effects
<ScrollParallax speed={0.5}>
<img src="/background.jpg" alt="Parallax background" />
</ScrollParallax>Morphing Animations
Transform elements from one shape to another with fluid morphing animations:
import { Morph } from "windcedar-ui/animations";
import { useState } from "react";
function MorphExample() {
const [isCircle, setIsCircle] = useState(false);
return (
<div>
<Button onClick={() => setIsCircle(!isCircle)}>Toggle Shape</Button>
<Morph
duration={0.8}
ease="power2.inOut"
state={isCircle ? "circle" : "square"}
>
<div
className={cn(
"bg-primary w-32 h-32 transition-all",
isCircle ? "rounded-full" : "rounded-md"
)}
></div>
</Morph>
</div>
);
}Text Animation
Create engaging text animations for headings, titles, or any text element:
import { TextAnimate } from "windcedar-ui/animations";
// Split text animation (animates each character)
<TextAnimate type="split">
<h1 className="text-4xl font-bold">Animated Heading</h1>
</TextAnimate>
// With custom animation options
<TextAnimate
type="words" // Options: chars, words, lines
animation="fade-up" // Options: fade, fade-up, fade-down, wave
stagger={0.05} // Time between each element's animation
duration={0.8} // Animation duration
>
<p className="text-lg">
Each word in this sentence will animate separately.
</p>
</TextAnimate>Timeline Animations
Create complex multi-element animations with precise timing and sequencing:
import { Timeline, TimelineItem } from "windcedar-ui/animations";
<Timeline>
<TimelineItem position={0}>
<div className="bg-blue-500 h-20 w-20">First</div>
</TimelineItem>
<TimelineItem position={0.5}>
<div className="bg-green-500 h-20 w-20">Second (0.5s later)</div>
</TimelineItem>
<TimelineItem position="-=0.2">
<div className="bg-red-500 h-20 w-20">Third (0.2s before second ends)</div>
</TimelineItem>
</Timeline>;Integration with Scroll Containers
All animation components work seamlessly with custom scroll containers:
import { SmoothScroll, ScrollReveal } from "windcedar-ui/animations";
function CustomScrollContainer() {
return (
<SmoothScroll container="#custom-container">
<div id="custom-container" className="h-96 overflow-y-auto">
<ScrollReveal>
<div className="mb-8">Section 1</div>
</ScrollReveal>
<ScrollReveal>
<div className="mb-8">Section 2</div>
</ScrollReveal>
</div>
</SmoothScroll>
);
}Using with Existing WindCedar Components
All animation features integrate perfectly with existing WindCedar UI components:
import { Card, CardContent, Button } from "windcedar-ui";
import { ScrollReveal, Draggable } from "windcedar-ui/animations";
<ScrollReveal animation="fade-up">
<Card>
<CardContent>
<h3>Animated Card</h3>
<p>This entire card animates on scroll</p>
<Button>Action</Button>
</CardContent>
</Card>
</ScrollReveal>
<Draggable>
<Button>Draggable Button</Button>
</Draggable>Note on Performance
For optimal performance:
Use the
will-changeCSS property sparinglyFor long pages with many animations, consider using the
reusableprop:<ScrollReveal reusable={false}> {/* Once this animates, it won't animate again */} </ScrollReveal>For mobile optimization, use the responsive props:
<SmoothScroll enabled={{ base: false, md: true }}> {/* Smooth scrolling disabled on mobile */} </SmoothScroll>
These animation features are built with performance in mind and avoid layout thrashing by using requestAnimationFrame and transform/opacity properties where possible.
Configuration
Tailwind CSS Configuration
Add the Windcedar preset to your tailwind.config.js:
import windcedarPreset from "windcedar-ui/windcedar-preset";
/** @type {import('tailwindcss').Config} */
export default {
content: [
"./index.html",
"./src/**/*.{js,ts,jsx,tsx}",
// Add this line to include Windcedar UI components in your content
"./node_modules/windcedar-ui/src/**/*.{js,ts,jsx,tsx}",
],
presets: [windcedarPreset],
};Vite Configuration
For Vite projects, add the Windcedar animations plugin to your vite.config.js:
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { windcedarAnimations } from "windcedar/vite";
export default defineConfig({
plugins: [react(), windcedarAnimations()],
});🚀 Bundle Optimization Guide
WindCedar is designed with performance in mind. Here's how to get the best bundle size:
Import Strategies
// ✅ Best: Modular imports (tree-shakeable + modular)
import { Button } from 'windcedar/button';
import { Card } from 'windcedar/card';
// ✅ Good: Main entry (tree-shakeable)
import { Button, Card } from 'windcedar';
// ✅ Auto-optimized: Heavy components lazy load
import { Chart } from 'windcedar/chart'; // Lazy loads react-charts
import { Carousel } from 'windcedar/carousel'; // Lazy loads embla-carousel
import { Combobox } from 'windcedar/combobox'; // Lazy loads cmdkCSS Optimization
/* ✅ Minimal styles (recommended for optimal performance) */
@import 'windcedar/styles/minimal';
/* Or full styles if you use many components */
@import 'windcedar/styles';Bundle Analysis
Monitor your bundle size with these tools:
# Analyze bundle size
npm run build
npx bundlephobia windcedar
# Webpack Bundle Analyzer
npm install --save-dev webpack-bundle-analyzer
npx webpack-bundle-analyzer build/static/js/*.js
# Vite Bundle Analyzer
npm install --save-dev rollup-plugin-visualizerExpected Bundle Sizes (gzipped)
| Import Pattern | Bundle Size | Description | |---------------|-------------|-------------| | Individual components | 5-10KB | Button, Input, Card, etc. | | Heavy components | 15-25KB | Chart, Carousel (with lazy loading) | | Full library | 50-100KB | All components used |
Framework-Specific Optimization
Next.js App Router
import { Button } from 'wind-cedar/next';
// Optimized for React Server ComponentsVite
// vite.config.js
export default {
optimizeDeps: {
include: ['windcedar']
}
}Webpack
// webpack.config.js
module.exports = {
optimization: {
usedExports: true,
sideEffects: false
}
}🤝 Contributing
We welcome contributions! Please see our contributing guidelines for details.
📄 License
MIT © WindCedar UI
