# Atoms Components Library **Status:** โ Phase 1 Implementation Complete **Created:** 2026-04-03 **Foundation:** Atomic Design Pattern --- ## ๐ Overview Atoms are the basic building blocks of your UI. They are small, focused, reusable components that have no dependencies on other components (except potentially other atoms). **Key Principles:** - โ No business logic - โ No context/hooks (useAuth, useCart, etc.) - โ Pure props-based - โ Full TypeScript typing - โ CSS variables for theming - โ Accessible by default --- ## ๐ฏ Atoms Created ### Buttons (`buttons/`) #### **Button.tsx** Main interactive button component with multiple variants and sizes. **Props:** - `variant` - "primary" | "secondary" | "danger" | "ghost" (default: "primary") - `size` - "sm" | "md" | "lg" (default: "md") - `icon` - FontAwesome icon class (optional) - `iconPosition` - "left" | "right" (default: "left") - `disabled` - boolean - `children` - ReactNode - `className` - string (for custom overrides) - All standard HTML button attributes **Usage:** ```tsx import { Button } from "@/components/atoms"; Mua Cancel Delete ``` **Styling:** - Primary: Branded color with dark hover - Secondary: Border style with light background on hover - Danger: Red for destructive actions - Ghost: Transparent with light background on hover --- #### **IconButton.tsx** Button designed specifically for icon-only interactions. **Props:** - `variant` - "primary" | "secondary" | "danger" | "ghost" - `size` - "sm" (8x8) | "md" (10x10) | "lg" (12x12) - `icon` - FontAwesome icon class (required) - All standard HTML button attributes **Usage:** ```tsx import { IconButton } from "@/components/atoms"; ``` --- ### Inputs (`inputs/`) #### **TextInput.tsx** General text input field with optional label, error, and icon. **Props:** - `label` - string (optional) - `error` - string (optional, shows red border and error text) - `icon` - FontAwesome icon class (optional) - `onIconClick` - callback when icon is clicked - All standard HTML input attributes **Usage:** ```tsx import { TextInput } from "@/components/atoms"; ``` --- #### **SearchInput.tsx** Search input with built-in search icon and clear button. **Props:** - `value` - string (controlled input) - `onChange` - callback when text changes - `onClear` - callback for clear button (required for button to show) - `placeholder` - string - All standard HTML input attributes **Usage:** ```tsx import { SearchInput } from "@/components/atoms"; const [query, setQuery] = useState(""); setQuery(e.target.value)} onClear={() => setQuery("")} placeholder="Search products..." /> ``` --- #### **Textarea.tsx** Multi-line text input with optional label and error. **Props:** - `label` - string (optional) - `error` - string (optional) - All standard HTML textarea attributes **Usage:** ```tsx import { Textarea } from "@/components/atoms"; setReview(e.target.value)} /> ``` --- ### Typography (`typography/`) #### **Heading.tsx** Semantic heading component with level-based sizing. **Props:** - `level` - 1 | 2 | 3 | 4 | 5 | 6 (default: 2) - `children` - ReactNode - All standard HTML heading attributes **Sizing:** - Level 1: text-3xl font-bold - Level 2: text-2xl font-bold - Level 3: text-xl font-bold - Level 4: text-lg font-semibold - Level 5: text-base font-semibold - Level 6: text-sm font-semibold **Usage:** ```tsx import { Heading } from "@/components/atoms"; Page Title Section Subsection ``` --- #### **Text.tsx** Paragraph text with semantic variants. **Props:** - `variant` - "body1" | "body2" | "caption" | "label" (default: "body1") - `children` - ReactNode - All standard HTML paragraph attributes **Variants:** - body1: text-base (main content) - body2: text-sm (secondary content) - caption: text-xs (smallest text) - label: text-sm font-medium (form labels) **Usage:** ```tsx import { Text } from "@/components/atoms"; Main content paragraph Secondary information Small fine print Form label text ``` --- #### **Caption.tsx** Small caption/note text component. **Props:** - `children` - ReactNode - All standard HTML span attributes **Usage:** ```tsx import { Caption } from "@/components/atoms"; Last updated 2 hours ago * Required field ``` --- ### Badges (`badges/`) #### **Badge.tsx** Labeled badge component for highlighting information. **Props:** - `variant` - "primary" | "secondary" | "success" | "danger" | "warning" (default: "primary") - `size` - "sm" | "md" (default: "md") - `children` - ReactNode - All standard HTML span attributes **Variants:** - primary: Branded color - secondary: Light gray - success: Green - danger: Red - warning: Yellow **Usage:** ```tsx import { Badge } from "@/components/atoms"; New Active Expired ``` --- #### **PriceBadge.tsx** Specialized badge for displaying formatted prices. **Props:** - `price` - number - `currency` - string (default: "VND") - All standard HTML span attributes **Usage:** ```tsx import { PriceBadge } from "@/components/atoms"; ``` **Output:** - VND: "50.000 โซ" - USD: "$99.99" --- ### Dividers (`dividers/`) #### **Divider.tsx** Visual separator element. **Props:** - `orientation` - "horizontal" | "vertical" (default: "horizontal") - All standard HTML hr attributes **Usage:** ```tsx import { Divider } from "@/components/atoms"; {/* Horizontal line */} ``` --- ## ๐จ Theming All atoms use CSS variables for consistent theming: ```css /* Colors */ --color-primary --color-primary-dark --color-accent --color-accent-light --color-bg-card --color-text-primary --color-text-secondary --color-text-muted --color-border --color-border-light --color-shadow-sm --color-shadow-md ``` Change one variable in `globals.css` to update all atoms across the app. --- ## ๐ Import Patterns ### Individual Imports ```tsx import { Button } from "@/components/atoms/buttons"; import { TextInput, SearchInput } from "@/components/atoms/inputs"; import { Heading, Text, Caption } from "@/components/atoms/typography"; import { Badge, PriceBadge } from "@/components/atoms/badges"; import { Divider } from "@/components/atoms/dividers"; ``` ### Barrel Exports (Recommended) ```tsx import { Button, IconButton, TextInput, SearchInput, Textarea, Heading, Text, Caption, Badge, PriceBadge, Divider, } from "@/components/atoms"; ``` ### Type Imports ```tsx import type { ButtonProps, TextInputProps, HeadingProps } from "@/components/atoms"; ``` --- ## โ Usage Examples ### Form Field ```tsx Submit ``` ### Product Card ```tsx Product Name Product description Add to Cart ``` ### Rating Display ```tsx Reviews โญโญโญโญโญ 4.5/5 Based on 128 reviews ``` --- ## ๐งช Testing Atoms ### Props Validation ```tsx // โ Valid Click // โ Invalid (TypeScript will catch) Click Click ``` ### Accessibility All atoms include: - Semantic HTML - ARIA labels where appropriate - Keyboard navigation support - Focus visible states - Color contrast compliance --- ## ๐ File Structure ``` components/atoms/ โโโ buttons/ โ โโโ Button.tsx โ โโโ Button.types.ts โ โโโ IconButton.tsx โ โโโ index.ts โโโ inputs/ โ โโโ TextInput.tsx โ โโโ SearchInput.tsx โ โโโ Textarea.tsx โ โโโ Input.types.ts โ โโโ index.ts โโโ typography/ โ โโโ Heading.tsx โ โโโ Text.tsx โ โโโ Caption.tsx โ โโโ Typography.types.ts โ โโโ index.ts โโโ badges/ โ โโโ Badge.tsx โ โโโ Badge.types.ts โ โโโ PriceBadge.tsx โ โโโ index.ts โโโ dividers/ โ โโโ Divider.tsx โ โโโ index.ts โโโ index.ts (barrel export) โโโ ATOMS.md (this file) ``` --- ## ๐ Next Steps Once atoms are comfortable, the next phase is creating **Molecules** - combinations of atoms: - **ProductCard** - Image + Text + Badge + Button - **FormField** - Label + Input + Error Text - **SearchBar** - SearchInput + Button - **RatingInput** - Interactive 5-star rating - **PriceTag** - Price display with formatting - And more... See `OPTIMIZATION_PLAN.md` for the full roadmap. --- ## ๐ Notes - All atoms use TypeScript for type safety - No business logic in atoms - they're purely presentational - Components are optimized for reusability - Styling uses Tailwind + CSS variables for consistency - Accessibility is built-in by default --- **Status:** โ Complete & Ready for Use **Last Updated:** 2026-04-03 **Phase:** 1 of 5