@gmana/react
v2.0.2
Published
A comprehensive React component library built with Tailwind CSS, featuring 170+ beautifully crafted components for modern web applications.
Readme
gmana-react
A comprehensive React component library built with Tailwind CSS, featuring 170+ beautifully crafted components for modern web applications.
Features
- 🎨 170+ Components - Comprehensive set of UI components
- 🎭 Text Animations - 20+ text animation effects
- 🌈 Background Effects - Various background patterns and effects
- 📱 Responsive Design - Mobile-first approach
- 🎯 TypeScript - Full TypeScript support
- 🌙 Dark Mode - Built-in dark mode support
- ⚡ Performance - Optimized for speed and bundle size
- 🎪 Accessible - WCAG compliant components
Installation
bun add @gmana/react @gmana/utils @gmana/react-hooks @gmana/email-checkerQuick Start
1. Import CSS
Add the following to your main CSS file (e.g., app.css):
@import "tailwindcss";
@import "tw-animate-css";
@import "../../node_modules/@gmana/react/dist/gmana.css";
@import "@fontsource-variable/noto-sans-khmer";
@source "../../node_modules/@gmana/react/dist/**/*.js";
@custom-variant dark (&:is(.dark *));2. Use Components
import { Button, Card, TextGradient } from "@gmana/react"
function App() {
return (
<Card>
<TextGradient>Hello World</TextGradient>
<Button>Click me</Button>
</Card>
)
}Component Categories
🎨 UI Components
- Layout: Container, Grid, Flex, Section, Box
- Navigation: NavigationMenu, Breadcrumb, Pagination, Tabs
- Data Display: Table, Card, Badge, Avatar, Timeline
- Feedback: Alert, Toast, Progress, Skeleton, Loading
- Overlay: Dialog, Modal, Popover, Tooltip, Sheet, Drawer
📝 Form Components
- Inputs: Input, Textarea, Select, Checkbox, Radio, Switch, Slider
- Advanced: Combobox, MultiSelect, DatePicker, FileUpload, OTP
- Form Fields: Complete form field components with validation
- Smart Forms: Auto-generated forms with smart field detection
✨ Text Animations
- Effects: TextGradient, TextShimmer, TextTyping, TextReveal
- Morphing: TextMorph, TextFlip, TextRotate, TextWavy
- Interactive: TextPullUp, TextBlurIn, TextScramble
- Advanced: TextGenerateEffect, TextScrollVelocity
🎭 Background Effects
- Patterns: BgDots, BgBeams, BgMeteors, BgRipple
- Gradients: BgBorderGradient, CardGradient, LinkGradient
- Animations: BgRotate, DotPattern, Particles
🎪 Interactive Components
- Carousel: Image carousel with touch support
- Charts: Recharts integration with custom styling
- QR Code: QR code generator and scanner
- Image: Image cropper, magnifier, lens effects
- Social: Social authentication buttons
🛠️ Utility Components
- Theme: ThemeProvider, ThemeSwitcher, ThemeToggle
- Layout: Resizable panels, Scroll areas, Separators
- Icons: Custom icon set with Lucide integration
- Hooks: Custom React hooks for common patterns
Usage Examples
Text Animations
import { TextGradient, TextShimmer, TextTyping } from "@gmana/react"
function Hero() {
return (
<div>
<TextGradient className="text-6xl font-bold">Welcome to GMANA</TextGradient>
<TextTyping words={["React", "Components", "Tailwind CSS"]} className="mt-4 text-2xl" />
<TextShimmer className="text-lg">Beautiful animations made easy</TextShimmer>
</div>
)
}Form Components
import { Button, Form, FormFieldEmail, FormFieldText } from "@gmana/react"
function ContactForm() {
return (
<Form>
<FormFieldText name="name" label="Full Name" placeholder="Enter your name" />
<FormFieldEmail name="email" label="Email Address" placeholder="Enter your email" />
<Button type="submit">Send Message</Button>
</Form>
)
}Background Effects
import { BgDots, BgMeteors, CardGradient } from "@gmana/react"
function LandingPage() {
return (
<div className="relative min-h-screen">
<BgDots className="opacity-20" />
<BgMeteors />
<CardGradient />
</div>
)
}Performance
Use component-level imports so bundlers only evaluate the entries your route needs:
import { Button } from "@gmana/react/button"
import { Card, CardContent } from "@gmana/react/card"Keep heavier feature components, such as charts, data tables, carousels, image tools, and animated backgrounds, scoped to the route or feature that uses them. Import the package CSS once in your app stylesheet and keep the Tailwind @source pattern focused on @gmana/react/dist/**/*.js.
See the Performance Guide for import patterns, CSS setup, route-level loading, and measurement checks.
CSS Variables
The library includes a comprehensive set of CSS variables for theming:
@import "tailwindcss";
@import "tw-animate-css";
@import "../../node_modules/@gmana/react/dist/gmana.css";
@import "@fontsource-variable/noto-sans-khmer";
@source "../../node_modules/@gmana/react/dist/**/*.js";
@custom-variant dark (&:is(.dark *));
:root {
--background: oklch(1 0 0);
--foreground: oklch(0.3211 0 0);
--card: oklch(1 0 0);
--card-foreground: oklch(0.3211 0 0);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.3211 0 0);
--primary: oklch(0.6231 0.188 259.8145);
--primary-foreground: oklch(1 0 0);
--secondary: oklch(0.967 0.0029 264.5419);
--secondary-foreground: oklch(0.4461 0.0263 256.8018);
--muted: oklch(0.9846 0.0017 247.8389);
--muted-foreground: oklch(0.551 0.0234 264.3637);
--accent: oklch(0.9514 0.025 236.8242);
--accent-foreground: oklch(0.3791 0.1378 265.5222);
--destructive: oklch(0.6368 0.2078 25.3313);
--destructive-foreground: oklch(1 0 0);
--border: oklch(0.9276 0.0058 264.5313);
--input: oklch(0.9276 0.0058 264.5313);
--ring: oklch(0.6231 0.188 259.8145);
--chart-1: oklch(0.6231 0.188 259.8145);
--chart-2: oklch(0.5461 0.2152 262.8809);
--chart-3: oklch(0.4882 0.2172 264.3763);
--chart-4: oklch(0.4244 0.1809 265.6377);
--chart-5: oklch(0.3791 0.1378 265.5222);
--sidebar: oklch(0.9846 0.0017 247.8389);
--sidebar-foreground: oklch(0.3211 0 0);
--sidebar-primary: oklch(0.6231 0.188 259.8145);
--sidebar-primary-foreground: oklch(1 0 0);
--sidebar-accent: oklch(0.9514 0.025 236.8242);
--sidebar-accent-foreground: oklch(0.3791 0.1378 265.5222);
--sidebar-border: oklch(0.9276 0.0058 264.5313);
--sidebar-ring: oklch(0.6231 0.188 259.8145);
--radius: 0.25rem;
--shadow-2xs: 0 1px 3px 0px hsl(0 0% 0% / 0.05);
--shadow-xs: 0 1px 3px 0px hsl(0 0% 0% / 0.05);
--shadow-sm: 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 1px 2px -1px hsl(0 0% 0% / 0.1);
--shadow: 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 1px 2px -1px hsl(0 0% 0% / 0.1);
--shadow-md: 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 2px 4px -1px hsl(0 0% 0% / 0.1);
--shadow-lg: 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 4px 6px -1px hsl(0 0% 0% / 0.1);
--shadow-xl: 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 8px 10px -1px hsl(0 0% 0% / 0.1);
--shadow-2xl: 0 1px 3px 0px hsl(0 0% 0% / 0.25);
--tracking-normal: 0em;
--spacing: 0.25rem;
--selection: oklch(0.145 0 0);
--selection-foreground: oklch(1 0 0);
}
.dark {
--background: oklch(0.2046 0 0);
--foreground: oklch(0.9219 0 0);
--card: oklch(0.2046 0 0);
--card-foreground: oklch(0.9219 0 0);
--popover: oklch(0.2686 0 0);
--popover-foreground: oklch(0.9219 0 0);
--primary: oklch(0.6231 0.188 259.8145);
--primary-foreground: oklch(1 0 0);
--secondary: oklch(0.2686 0 0);
--secondary-foreground: oklch(0.9219 0 0);
--muted: oklch(0.2686 0 0);
--muted-foreground: oklch(0.7155 0 0);
--accent: oklch(0.3791 0.1378 265.5222);
--accent-foreground: oklch(0.8823 0.0571 254.1284);
--destructive: oklch(0.6368 0.2078 25.3313);
--destructive-foreground: oklch(1 0 0);
--border: oklch(0.371 0 0);
--input: oklch(0.371 0 0);
--ring: oklch(0.6231 0.188 259.8145);
--chart-1: oklch(0.7137 0.1434 254.624);
--chart-2: oklch(0.6231 0.188 259.8145);
--chart-3: oklch(0.5461 0.2152 262.8809);
--chart-4: oklch(0.4882 0.2172 264.3763);
--chart-5: oklch(0.4244 0.1809 265.6377);
--sidebar: oklch(0.2046 0 0);
--sidebar-foreground: oklch(0.9219 0 0);
--sidebar-primary: oklch(0.6231 0.188 259.8145);
--sidebar-primary-foreground: oklch(1 0 0);
--sidebar-accent: oklch(0.269 0 0);
--sidebar-accent-foreground: oklch(0.8823 0.0571 254.1284);
--sidebar-border: oklch(0.3715 0 0);
--sidebar-ring: oklch(0.6231 0.188 259.8145);
--radius: 0.25rem;
--shadow-2xs: 0 1px 3px 0px hsl(0 0% 0% / 0.05);
--shadow-xs: 0 1px 3px 0px hsl(0 0% 0% / 0.05);
--shadow-sm: 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 1px 2px -1px hsl(0 0% 0% / 0.1);
--shadow: 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 1px 2px -1px hsl(0 0% 0% / 0.1);
--shadow-md: 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 2px 4px -1px hsl(0 0% 0% / 0.1);
--shadow-lg: 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 4px 6px -1px hsl(0 0% 0% / 0.1);
--shadow-xl: 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 8px 10px -1px hsl(0 0% 0% / 0.1);
--shadow-2xl: 0 1px 3px 0px hsl(0 0% 0% / 0.25);
--selection: oklch(0.922 0 0);
--selection-foreground: oklch(0.205 0 0);
}
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
--color-popover: var(--popover);
--color-popover-foreground: var(--popover-foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-secondary: var(--secondary);
--color-secondary-foreground: var(--secondary-foreground);
--color-muted: var(--muted);
--color-muted-foreground: var(--muted-foreground);
--color-accent: var(--accent);
--color-accent-foreground: var(--accent-foreground);
--color-destructive: var(--destructive);
--color-destructive-foreground: var(--destructive-foreground);
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
--color-chart-1: var(--chart-1);
--color-chart-2: var(--chart-2);
--color-chart-3: var(--chart-3);
--color-chart-4: var(--chart-4);
--color-chart-5: var(--chart-5);
--color-sidebar: var(--sidebar);
--color-sidebar-foreground: var(--sidebar-foreground);
--color-sidebar-primary: var(--sidebar-primary);
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-ring: var(--sidebar-ring);
/*
;
--font-mono: var(--font-mono);
--font-serif: var(--font-serif); */
/* --font-sans: var(--font-noto-sans-khmer); */
--font-sans: "Noto Sans Khmer Variable", sans-serif;
--radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) + 4px);
--shadow-2xs: var(--shadow-2xs);
--shadow-xs: var(--shadow-xs);
--shadow-sm: var(--shadow-sm);
--shadow: var(--shadow);
--shadow-md: var(--shadow-md);
--shadow-lg: var(--shadow-lg);
--shadow-xl: var(--shadow-xl);
--shadow-2xl: var(--shadow-2xl);
--color-selection: var(--selection);
--color-selection-foreground: var(--selection-foreground);
}
@layer base {
* {
@apply border-border outline-ring/50;
}
::selection {
@apply bg-selection text-selection-foreground;
}
body {
font-synthesis-weight: none;
text-rendering: optimizeLegibility;
}
}TypeScript Support
All components are fully typed with TypeScript:
import { Button, type ButtonProps } from "@gmana/react"
const CustomButton: React.FC<ButtonProps> = ({ variant, size, ...props }) => {
return <Button variant={variant} size={size} {...props} />
}Contributing
We welcome contributions! Please see our Contributing Guide for details.
License
MIT © Sun Sreng
