# @tagaddod-design/react > Modern, accessible React component library built on Radix UI primitives with comprehensive theming, RTL support, and TypeScript integration. Features 18+ production-ready components following WCAG 2.1 AA accessibility standards. This design system provides a complete solution for building consistent, accessible user interfaces with support for multiple brands (Tagaddod, GreenPan) and bi-directional languages (English LTR, Arabic RTL). All components are built on proven Radix UI primitives for maximum reliability and accessibility. ## Installation **NPM 7+ / PNPM / Yarn Berry:** ```bash npm i @tagaddod-design/react \ @radix-ui/react-avatar @radix-ui/react-checkbox @radix-ui/react-dialog \ @radix-ui/react-form @radix-ui/react-popover @radix-ui/react-radio-group \ @radix-ui/react-select @radix-ui/react-switch @radix-ui/react-tabs \ @tabler/icons-react @tanstack/react-table ``` **Yarn 1.x:** ```bash yarn add @tagaddod-design/react @radix-ui/react-avatar @radix-ui/react-checkbox @radix-ui/react-dialog @radix-ui/react-form @radix-ui/react-popover @radix-ui/react-radio-group @radix-ui/react-select @radix-ui/react-switch @radix-ui/react-tabs @tabler/icons-react @tanstack/react-table ``` **Required Setup:** ```jsx // 1. Import CSS (required) import '@tagaddod-design/react/styles.css'; // 2. Wrap app with ThemeProvider import { ThemeProvider } from '@tagaddod-design/react'; function App() { return ( ); } ``` **Google Fonts Setup (Required):** ```html ``` ## Components ### AspectRatio Maintains consistent proportions for content like images, videos, or embedded media. Ensures content keeps its aspect ratio when container dimensions change. **Category** | Layout **Status** | Stable | Prop | Type | Default | Description | | ---- | ---- | ------- | ----------- | | ratio | number | 1 | Width/height ratio (e.g., 16/9 = 1.78) | | children | ReactNode | - | Content to maintain aspect ratio | **Available Ratios:** 1:1 (square), 16:9 (video), 4:3 (photo), 3:2 (landscape) ```jsx
1:1 Square Content
``` --- ### Avatar Displays user profile pictures, initials, or fallback icons. Handles image loading states and provides accessible alternatives. **Category** | Data Display **Status** | Stable | Prop | Type | Default | Description | | ---- | ---- | ------- | ----------- | | type | 'image' \| 'initial' \| 'icon' | 'icon' | Avatar display type | | src | string | - | Image URL (when type='image') | | alt | string | - | Alt text for image | | initial | string | - | Single character (when type='initial') | | size | 'sm' \| 'md' \| 'lg' \| 'xl' | 'md' | Avatar size | | delayMs | number | 600 | Fallback delay in milliseconds | **Sizes:** sm (24px), md (32px), lg (40px), xl (64px) **RTL Support:** Automatic Arabic text alignment for initials ```jsx ``` --- ### Badge Compact status indicators for categorizing, labeling, or showing counts. High-contrast elements that stand out from surrounding content. **Category** | Data Display **Status** | Stable | Prop | Type | Default | Description | | ---- | ---- | ------- | ----------- | | children | ReactNode | - | Badge content | | tone | 'default' \| 'success' \| 'warning' \| 'critical' \| 'info' | 'default' | Visual tone | | size | 'sm' \| 'md' | 'md' | Badge size | **Tones:** default (brand), success (green), warning (orange), critical (red), info (blue) ```jsx Active Urgent Pending ``` --- ### Button Primary interactive element for triggering actions, form submissions, navigation, or selections. Supports multiple variants, states, and accessibility features. **Category** | Actions **Status** | Stable | Prop | Type | Default | Description | | ---- | ---- | ------- | ----------- | | variant | 'primary' \| 'secondary' \| 'tertiary' \| 'plain' | 'primary' | Button visual style | | tone | 'default' \| 'critical' \| 'success' \| 'neutral' \| 'magic' | 'default' | Color treatment | | size | 'micro' \| 'medium' \| 'large' | 'medium' | Button size | | loading | boolean | false | Shows loading spinner | | disabled | boolean | false | Disables interaction | | fullWidth | boolean | false | Expands to container width | | prefixIcon | ReactNode | - | Icon before text | | suffixIcon | ReactNode | - | Icon after text | **Variants:** primary (filled), secondary (outlined), tertiary (subtle), plain (minimal) **States:** default, hover, focus, loading, disabled **RTL Support:** Automatic icon positioning for Arabic ```jsx // Basic usage // With icons // Loading state ``` --- ### Checkbox Binary choice form control with checked, unchecked, and indeterminate states. Used in forms, settings, and multi-selection lists. **Category** | Form Controls **Status** | Stable | Prop | Type | Default | Description | | ---- | ---- | ------- | ----------- | | label | string | - | Checkbox label text | | helpText | string | - | Additional description | | errorMessage | string | - | Error message display | | checked | boolean | - | Controlled checked state | | defaultChecked | boolean | false | Initial checked state | | indeterminate | boolean | false | Indeterminate state | | disabled | boolean | false | Disables interaction | | required | boolean | false | Marks as required | **States:** unchecked, checked, indeterminate, disabled, error **Accessibility:** Full keyboard navigation and screen reader support ```jsx ``` --- ### Drawer Sliding panel overlay for supplementary content, forms, or detailed information while preserving main context visibility. **Category** | Overlays **Status** | Stable | Prop | Type | Default | Description | | ---- | ---- | ------- | ----------- | | open | boolean | - | Controls drawer visibility | | onOpenChange | function | - | Callback when state changes | | title | string | - | Drawer header title | | size | 'small' \| 'medium' \| 'large' | 'medium' | Drawer width | | position | 'left' \| 'right' | 'right' | Slide direction | | children | ReactNode | - | Drawer content | **Sizes:** small (320px), medium (480px), large (640px) **RTL Support:** Automatic position adjustment for Arabic layouts ```jsx

Drawer content goes here

``` --- ### Listbox Selectable option list for dropdowns, menus, and selection interfaces. Supports rich content with icons, descriptions, and grouping. **Category** | Form Controls **Status** | Stable | Prop | Type | Default | Description | | ---- | ---- | ------- | ----------- | | options | Array | - | List of selectable options | | selectedValue | string | - | Currently selected option | | onSelect | function | - | Selection callback | | placeholder | string | - | Placeholder text | | disabled | boolean | false | Disables interaction | **Option Format:** `{ label: string, value: string, icon?: ReactNode, disabled?: boolean }` ```jsx }, { label: 'Analytics', value: 'analytics', icon: }, { label: 'Settings', value: 'settings', icon: } ]} selectedValue={selectedValue} onSelect={setSelectedValue} placeholder="Choose an option..." /> ``` --- ### Modal Focus-grabbing overlay for confirmations, alerts, forms, and important interactions without page navigation. **Category** | Overlays **Status** | Stable | Prop | Type | Default | Description | | ---- | ---- | ------- | ----------- | | trigger | ReactNode | - | Element that opens modal | | title | string | - | Modal header title | | showTitle | boolean | true | Display title header | | showFooter | boolean | true | Display action footer | | cancelLabel | string | 'Cancel' | Cancel button text | | confirmLabel | string | 'Confirm' | Confirm button text | | onCancel | function | - | Cancel callback | | onConfirm | function | - | Confirm callback | | children | ReactNode | - | Modal content | **Features:** Focus management, escape key handling, backdrop click closing **Accessibility:** ARIA dialog implementation with proper focus trapping ```jsx Delete Item} title="Confirm Deletion" cancelLabel="Keep" confirmLabel="Delete" onCancel={() => console.log('Cancelled')} onConfirm={() => console.log('Deleted')} >

This action cannot be undone. Are you sure?

``` --- ### Pagination Navigation component for large datasets split across multiple pages. Provides page numbers, prev/next controls, and page info. **Category** | Navigation **Status** | Stable | Prop | Type | Default | Description | | ---- | ---- | ------- | ----------- | | currentPage | number | 1 | Active page number | | totalPages | number | - | Total page count | | onPageChange | function | - | Page change callback | | showFirstLast | boolean | true | Show first/last buttons | | showPrevNext | boolean | true | Show prev/next buttons | | siblingCount | number | 1 | Adjacent page numbers shown | **Features:** Ellipsis for large page ranges, keyboard navigation, responsive design ```jsx ``` --- ### Popover Contextual content overlay anchored to trigger elements. Used for tooltips, menus, additional information, and quick actions. **Category** | Overlays **Status** | Stable | Prop | Type | Default | Description | | ---- | ---- | ------- | ----------- | | content | ReactNode | - | Popover content | | type | 'default' \| 'tooltip' | 'default' | Popover behavior type | | placement | string | 'bottom' | Positioning relative to trigger | | trigger | 'hover' \| 'click' | 'click' | Activation method | | children | ReactNode | - | Trigger element | **Placements:** top, bottom, left, right (with -start/-end variants) **Features:** Auto-positioning, collision detection, portal rendering ```jsx

Rich content with actions

} >
``` --- ### RadioButton Single-selection form control for mutually exclusive options. Used in groups where only one option can be selected. **Category** | Form Controls **Status** | Stable | Prop | Type | Default | Description | | ---- | ---- | ------- | ----------- | | value | string | - | Radio button value | | label | string | - | Display label | | helpText | string | - | Additional description | | disabled | boolean | false | Disables interaction | **Usage Pattern:** Always use with RadioGroup wrapper for proper behavior ```jsx import { RadioGroup, RadioButtonItem } from '@tagaddod-design/react'; ``` --- ### Select Dropdown selection control for choosing from 4+ options. Provides search, grouping, and custom option rendering. **Category** | Form Controls **Status** | Stable | Prop | Type | Default | Description | | ---- | ---- | ------- | ----------- | | label | string | - | Field label | | placeholder | string | - | Placeholder text | | options | Array | - | Selectable options | | value | string | - | Selected value | | onChange | function | - | Selection callback | | disabled | boolean | false | Disables interaction | | required | boolean | false | Marks as required | | errorMessage | string | - | Error state message | **Option Format:** `{ value: string, label: string, group?: string }` **Features:** Keyboard navigation, search filtering, grouping support ```jsx const fruits = [ { value: 'apple', label: 'Apple', group: 'Common' }, { value: 'banana', label: 'Banana', group: 'Common' }, { value: 'dragonfruit', label: 'Dragon Fruit', group: 'Exotic' } ];
); } ``` ### Dashboard Interface ```jsx import { Tabs, TabsList, TabsTrigger, TabsContent, Table, Badge, Avatar, Button, Modal } from '@tagaddod-design/react'; function UserDashboard() { return ( Users Analytics Settings

Total Users

1,247

{/* More analytics cards */}
); } ``` ### Modal Workflows ```jsx import { Modal, Button, TextInput, Drawer } from '@tagaddod-design/react'; function ActionModals() { return (
{/* Confirmation Modal */} Delete Item} title="Confirm Deletion" cancelLabel="Keep Item" confirmLabel="Delete" onConfirm={handleDelete} >

This action cannot be undone. The item will be permanently deleted.

{/* Form Drawer */} Edit Profile} title="Edit Profile" size="medium" >
); } ``` ### Responsive Layouts ```jsx import { AspectRatio, Badge, Avatar, Separator } from '@tagaddod-design/react'; function ProductCard({ product }) { return (
{product.name}

{product.name}

{product.inStock ? 'In Stock' : 'Out of Stock'}

{product.description}

{product.seller.name}
); } ``` ## Theming & Customization ### Theme Provider Configuration ```jsx import { ThemeProvider, useTheme } from '@tagaddod-design/react'; function App() { return ( ); } function ThemeSwitcher() { const { theme, setTheme, direction, setDirection } = useTheme(); return (
); } ``` ### Custom CSS Variables ```css /* Access design tokens directly */ .custom-component { background-color: var(--t-color-surface-primary); padding: var(--t-space-400); border-radius: var(--t-border-radius-200); color: var(--t-color-text-primary); font-family: var(--t-font-family-primary); } /* Responsive utilities */ @media (max-width: 768px) { .custom-component { padding: var(--t-space-200); } } ``` ### Advanced Theming ```jsx // Programmatic theme detection function AppWithThemeDetection() { const prefersDark = useMediaQuery('(prefers-color-scheme: dark)'); const prefersRTL = useMediaQuery('(dir: rtl)'); return ( ); } ``` ## Accessibility Guidelines ### Keyboard Navigation - All interactive components support Tab/Shift+Tab navigation - Arrow keys for radio groups, tabs, and menus - Enter/Space for activation - Escape for closing modals/popovers ### Screen Reader Support - Semantic HTML structure with proper headings - ARIA labels, descriptions, and roles - Live regions for dynamic content updates - Focus management for overlays ### Visual Accessibility - WCAG 2.1 AA color contrast compliance - Focus indicators with 3px minimum thickness - No color-only information conveying - Reduced motion support via `prefers-reduced-motion` ### Implementation Examples ```jsx // Proper form labeling // Icon-only buttons require labels
``` ## TypeScript Integration ### Component Props ```tsx import type { ButtonProps, TextInputProps, SelectOption, TableColumn } from '@tagaddod-design/react'; // Extend component props interface CustomButtonProps extends ButtonProps { analyticsId?: string; } // Table column definitions const userColumns: TableColumn[] = [ { accessorKey: 'name', header: 'Name', cell: ({ getValue, row }) => (
().charAt(0)} size="sm" /> {getValue()}
) } ]; // Select options with proper typing const statusOptions: SelectOption[] = [ { value: 'active', label: 'Active User' }, { value: 'inactive', label: 'Inactive User' }, { value: 'pending', label: 'Pending Approval' } ]; ``` ### Theme Type Safety ```tsx import type { Theme, Direction } from '@tagaddod-design/react'; interface AppConfig { theme: Theme; // 'tagaddod' | 'greenpan' direction: Direction; // 'ltr' | 'rtl' locale: string; } // Theme-aware component function ThemedComponent({ config }: { config: AppConfig }) { return (
{/* Components automatically adapt */}
); } ``` ## Performance Optimization ### Tree Shaking ```jsx // ✅ Recommended: Named imports for tree shaking import { Button, TextInput, Modal } from '@tagaddod-design/react'; // ❌ Avoid: Imports entire library import * as TagaddodDesign from '@tagaddod-design/react'; ``` ### Bundle Size Optimization ```jsx // ✅ Import only needed components import { Button } from '@tagaddod-design/react'; // ✅ Lazy load heavy components const Table = lazy(() => import('@tagaddod-design/react').then(mod => ({ default: mod.Table })) ); function DataPage() { return ( Loading table...}>
); } ``` ### CSS Loading Strategy ```jsx // ✅ Load CSS once at app entry import '@tagaddod-design/react/styles.css'; // ✅ Or dynamic import for code splitting const loadStyles = () => import('@tagaddod-design/react/styles.css'); // Load styles when components are needed useEffect(() => { loadStyles(); }, []); ``` ## Framework Integration ### Next.js App Router ```jsx // app/layout.tsx import '@tagaddod-design/react/styles.css'; import { ThemeProvider } from '@tagaddod-design/react'; export default function RootLayout({ children }) { return ( {children} ); } ``` ### Vite + React ```jsx // main.tsx import '@tagaddod-design/react/styles.css'; import { ThemeProvider } from '@tagaddod-design/react'; ReactDOM.createRoot(document.getElementById('root')!).render( ); ``` ### Create React App ```jsx // src/index.js import '@tagaddod-design/react/styles.css'; import { ThemeProvider } from '@tagaddod-design/react'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( ); ``` ## Changelog See [CHANGELOG.md](https://github.com/ahmedamr-r/tagaddod-design-system/blob/main/packages/react/CHANGELOG.md) for detailed version history. ## License MIT - see [LICENSE](https://github.com/ahmedamr-r/tagaddod-design-system/blob/main/LICENSE) for details.