wind-cedar-ui
v0.1.2
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, offering beautiful UI components that seamlessly integrate into your web applications.
Quick Start Guide
1. Install the Package
Choose one of the following commands based on your package manager:
# Using npm
npm install wind-cedar-ui
# Using yarn
yarn add wind-cedar-ui
# Using pnpm
pnpm add wind-cedar-ui2. Install Required Dependencies
npm install tailwindcss postcss autoprefixer
npx tailwindcss init -p3. Configure Tailwind CSS
Create or update your tailwind.config.js:
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./src/**/*.{js,jsx,ts,tsx}",
"./node_modules/wind-cedar-ui/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {
colors: {
border: "hsl(var(--border))",
input: "hsl(var(--input))",
ring: "hsl(var(--ring))",
background: "hsl(var(--background))",
foreground: "hsl(var(--foreground))",
primary: {
DEFAULT: "hsl(var(--primary))",
foreground: "hsl(var(--primary-foreground))",
},
// ...other theme colors
},
},
},
plugins: [],
};4. Import Styles
In your main CSS file (e.g., src/index.css or src/App.css):
@import "wind-cedar-ui/styles";5. Basic Component Usage
Here are the most commonly used components and how to use them:
Button Component
import { Button } from "wind-cedar-ui";
// Simple button
<Button>Click Me</Button>
// Variants
<Button variant="primary">Primary</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="outline">Outline</Button>
// Sizes
<Button size="sm">Small</Button>
<Button size="lg">Large</Button>Input Fields
import { Input } from "wind-cedar-ui";
// Basic input
<Input placeholder="Enter text..." />
// With label
<Input label="Username" placeholder="Enter username" />
// Password input
<Input type="password" label="Password" />Card Layout
import { Card, CardHeader, CardContent, CardFooter } from "wind-cedar-ui";
<Card>
<CardHeader>
<h3>Card Title</h3>
</CardHeader>
<CardContent>
<p>Your content here</p>
</CardContent>
<CardFooter>
<Button>Action</Button>
</CardFooter>
</Card>;Modal Dialog
import { Modal, Button } from "wind-cedar-ui";
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="Example Modal"
>
<p>Modal content here</p>
</Modal>
</>
);
}Dropdown Menu
import {
DropdownMenu,
DropdownMenuTrigger,
DropdownMenuContent,
DropdownMenuItem,
} from "wind-cedar-ui";
<DropdownMenu>
<DropdownMenuTrigger>
<Button>Menu</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem>Profile</DropdownMenuItem>
<DropdownMenuItem>Settings</DropdownMenuItem>
<DropdownMenuItem>Logout</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>;Framework Compatibility
WindCedar UI is designed to work seamlessly with various modern React frameworks. Here's how to use it with different frameworks:
Next.js
WindCedar UI provides first-class support for Next.js applications (both Pages and App Router):
- Install the package:
npm install wind-cedar-ui- Update your
next.config.js:
/** @type {import('next').NextConfig} */
const nextConfig = {
transpilePackages: ["wind-cedar-ui"],
};
module.exports = nextConfig;- For Next.js App Router, update your
app/layout.tsx:
import "wind-cedar-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 "wind-cedar-ui/styles";
export default function App({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />;
}Vite
- Install in your Vite project:
npm install wind-cedar-ui- Update your
vite.config.ts:
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [react()],
optimizeDeps: {
include: ["wind-cedar-ui"],
},
});- Import styles in your
main.tsxorApp.tsx:
import "wind-cedar-ui/styles";Remix
- Install the package:
npm install wind-cedar-ui- Import styles in your
app/root.tsx:
import type { LinksFunction } from "@remix-run/node";
import styles from "wind-cedar-ui/styles/index.css";
export const links: LinksFunction = () => [{ rel: "stylesheet", href: styles }];Gatsby
- Install the package:
npm install wind-cedar-ui- Update your
gatsby-browser.js:
import "wind-cedar-ui/styles";- Update
gatsby-config.jsto include Tailwind:
module.exports = {
plugins: [
"gatsby-plugin-postcss",
// ... other plugins
],
};Create React App (CRA)
- Install the package:
npm install wind-cedar-ui- Import styles in your
src/index.tsxorApp.tsx:
import "wind-cedar-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-ui/next";
export default function ServerComponent() {
return (
<Card>
<h1>Server Component Example</h1>
</Card>
);
}
// Client Component
("use client");
import { Button } from "wind-cedar-ui";
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 "wind-cedar-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>
);
}7. 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
Next.js Support
WindCedar UI provides first-class support for Next.js applications. You can import components either from the main entry point or use the Next.js-specific entry point for optimized imports:
// Using the main entry point
import { Button, Card } from "wind-cedar-ui";
// Using the Next.js specific entry point
import { Button, Card } from "wind-cedar-ui/next";Setup with Next.js
- Install the package:
npm install wind-cedar-ui- Add WindCedar UI to your Tailwind CSS configuration in
tailwind.config.js:
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
// ...other content paths
"./node_modules/wind-cedar-ui/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {
// ...existing theme
},
},
};- Import the styles in your
app/layout.tsxorpages/_app.tsx:
import "wind-cedar-ui/styles";- Start using components:
import { Button } from "wind-cedar-ui/next";
export default function Page() {
return <Button>Click me</Button>;
}Server Components Support
All WindCedar UI components are compatible with React Server Components in Next.js 13+. You can use them in both client and server components without any additional configuration.
// app/page.tsx (Server Component)
import { Card } from "wind-cedar-ui/next";
export default function Page() {
return (
<Card>
<h1>Server Component</h1>
</Card>
);
}Component Documentation
WindCedar UI provides the following components:
Avatar Component
import { Avatar } from "wind-cedar-ui";
// Basic avatar with image
<Avatar src="https://example.com/avatar.jpg" alt="User Avatar" />
// Avatar with fallback text
<Avatar fallback="JD" alt="John Doe" />
// Different sizes
<Avatar src="avatar.jpg" alt="User" size="sm" />
<Avatar src="avatar.jpg" alt="User" size="md" /> // default
<Avatar src="avatar.jpg" alt="User" size="lg" />Button Component
import { Button } from "wind-cedar-ui";
// Default button
<Button>Default Button</Button>
// Variants
<Button variant="default">Default</Button>
<Button variant="destructive">Destructive</Button>
<Button variant="outline">Outline</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="link">Link</Button>
// Sizes
<Button size="default">Default Size</Button>
<Button size="sm">Small</Button>
<Button size="lg">Large</Button>
<Button size="icon">🔍</Button>
// States
<Button disabled>Disabled Button</Button>Calendar Component
import { Calendar } from "wind-cedar-ui";
// Single date selection
<Calendar mode="single" selected={date} onSelect={(date) => setDate(date)} />
// Date range selection
<Calendar
mode="range"
selected={{ from: startDate, to: endDate }}
onSelect={(range) => setDateRange(range)}
/>
// Multiple date selection
<Calendar
mode="multiple"
selected={dates}
onSelect={(dates) => setDates(dates)}
/>Card Component
import {
Card,
CardHeader,
CardTitle,
CardDescription,
CardContent,
CardFooter,
} from "wind-cedar-ui";
<Card>
<CardHeader>
<CardTitle>Card Title</CardTitle>
<CardDescription>Card description or subtitle</CardDescription>
</CardHeader>
<CardContent>
<p>This is the main content of the card.</p>
</CardContent>
<CardFooter className="flex justify-between">
<Button variant="outline">Cancel</Button>
<Button>Submit</Button>
</CardFooter>
</Card>;Checkbox Component
import { Checkbox } from "wind-cedar-ui";
// Basic checkbox
<Checkbox label="Accept terms" />
// With description
<Checkbox
label="Marketing emails"
description="Receive updates about new products and features"
/>
// With error
<Checkbox label="Required field" error="This field is required" />
// Disabled state
<Checkbox label="Disabled option" disabled />DataTable Component
import { DataTable } from "wind-cedar-ui";
const columns = [
{ accessorKey: "name", header: "Name" },
{ accessorKey: "email", header: "Email" },
{ accessorKey: "role", header: "Role" },
];
const data = [
{ name: "John Doe", email: "[email protected]", role: "Admin" },
// ...more data
];
<DataTable columns={columns} data={data} />;DropdownMenu Component
import {
DropdownMenu,
DropdownMenuTrigger,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
} from "wind-cedar-ui";
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button>Open Menu</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuLabel>My Account</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem>Profile</DropdownMenuItem>
<DropdownMenuItem>Settings</DropdownMenuItem>
<DropdownMenuItem disabled>Disabled Item</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem className="text-destructive">Delete</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>;Input Component
import { Input } from "wind-cedar-ui";
// Basic input
<Input placeholder="Enter your text" />
// With label
<Input label="Username" placeholder="Enter username" />
// With error
<Input
label="Password"
type="password"
error="Password must be at least 8 characters"
/>
// Disabled state
<Input disabled placeholder="Disabled input" />
// Textarea
<Input
as="textarea"
label="Message"
placeholder="Type your message here..."
className="h-24"
/>Modal Component
import { Modal, Button } from "wind-cedar-ui";
function ModalExample() {
const [isOpen, setIsOpen] = useState(false);
return (
<>
<Button onClick={() => setIsOpen(true)}>Open Modal</Button>
<Modal
isOpen={isOpen}
onClose={() => setIsOpen(false)}
title="Example Modal"
description="This is a basic modal dialog"
>
<div className="py-4">
<p>Modal content goes here.</p>
</div>
<div className="flex justify-end space-x-2">
<Button variant="outline" onClick={() => setIsOpen(false)}>
Cancel
</Button>
<Button onClick={() => setIsOpen(false)}>Continue</Button>
</div>
</Modal>
</>
);
}Utility Functions
WindCedar UI provides useful utility functions for class name handling:
import { cn } from "wind-cedar-ui/utils";
// Merging class names conditionally
<div
className={cn(
"base-class",
isActive && "active-class",
variant === "primary" ? "primary-class" : "secondary-class"
)}
>
Content
</div>;CSS Variables
WindCedar UI uses CSS variables for theming. Add these variables to your global CSS file and customize them to match your brand:
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--primary: 221.2 83.2% 53.3%;
--primary-foreground: 210 40% 98%;
--secondary: 210 40% 96.1%;
--secondary-foreground: 222.2 47.4% 11.2%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 210 40% 98%;
--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;
--accent: 210 40% 96.1%;
--accent-foreground: 222.2 47.4% 11.2%;
--card: 0 0% 100%;
--card-foreground: 222.2 84% 4.9%;
--border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%;
--ring: 221.2 83.2% 53.3%;
--radius: 0.5rem;
}
.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;
--primary: 217.2 91.2% 59.8%;
--primary-foreground: 222.2 47.4% 11.2%;
--secondary: 217.2 32.6% 17.5%;
--secondary-foreground: 210 40% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 210 40% 98%;
--muted: 217.2 32.6% 17.5%;
--muted-foreground: 215 20.2% 65.1%;
--accent: 217.2 32.6% 17.5%;
--accent-foreground: 210 40% 98%;
--card: 222.2 84% 4.9%;
--card-foreground: 210 40% 98%;
--border: 217.2 32.6% 17.5%;
--input: 217.2 32.6% 17.5%;
--ring: 224.3 76.5% 48%;
}Documentation
For detailed documentation and interactive examples, run Storybook locally:
pnpm storybookThis will start a local Storybook server where you can explore all the components, their variants, and see live examples.
Troubleshooting
CSS Not Loading
If your components don't have any styling or you see errors like:
[plugin:@tailwindcss/vite:generate:serve] Can't resolve 'wind-cedar-ui/styles'Try the following solutions:
Ensure proper import order: Always import the styles before any components:
// First import the styles import "wind-cedar-ui/styles"; // Then import the components import { Button } from "wind-cedar-ui";Update to latest version: Ensure you're using the latest version of the library:
npm install wind-cedar-ui@latestCheck your Tailwind configuration: Verify that you've added the content path for the library in your
tailwind.config.jsas shown in the setup section.Rebuild your project: Sometimes a full rebuild is needed:
npm run build # or vite build
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
MIT
