@thorprovider/components
v2.1.0
Published
Shared React component library for Thor Commerce. Tailwind CSS 4 + shadcn/ui patterns. L3 design system layer.
Maintainers
Readme
@thorprovider/components
Shared React component library for Thor Commerce ecommerce platform. A complete, production-ready UI component system built with React 19, Tailwind CSS 4, and shadcn/ui patterns.
Overview
@thorprovider/components is the L3 design system layer that provides 55+ reusable, accessible, and well-documented components for building Thor Commerce storefronts, dashboards, and admin interfaces. All components are framework-agnostic (pure React) and follow accessibility best practices.
Key Features
- ✅ 55+ Components - Complete UI kit from buttons to complex ecommerce patterns
- ✅ TypeScript First - Full type safety with comprehensive JSDoc documentation
- ✅ Tailwind CSS 4 - Modern styling with CSS custom properties for theming
- ✅ shadcn/ui Patterns - Familiar architecture for developers
- ✅ Accessible - WCAG 2.1 AA compliant with proper ARIA roles
- ✅ ESM + CommonJS - Works everywhere (Next.js, Vite, etc.)
- ✅ Zero Dependencies - Only React as peer dependency
- ✅ Ecommerce Ready - ProductCard, CartItem, VariantSelector, and more
Installation
npm install @thorprovider/components react react-domEnsure your project has Tailwind CSS configured. If not, follow the Tailwind CSS installation guide.
Quick Start
1. Import Styles
In your app's root layout or entry file:
// app/layout.tsx (Next.js)
import '@thorprovider/components/styles.css';
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html>
<body>{children}</body>
</html>
);
}2. Use Components
import { Button, Card, CardHeader, CardContent, Input, Label } from '@thorprovider/components';
export function LoginForm() {
return (
<Card>
<CardHeader>
<h2>Sign In</h2>
</CardHeader>
<CardContent className="space-y-4">
<div>
<Label>Email</Label>
<Input type="email" placeholder="[email protected]" />
</div>
<Button className="w-full">Sign In</Button>
</CardContent>
</Card>
);
}Component Categories
TIER 1: Base Atomic Components (15 components)
Foundation building blocks for creating UIs.
| Component | Purpose |
|-----------|---------|
| Button | Primary interactive element |
| Input | Text input field |
| Label | Form label |
| Badge | Status indicator |
| Checkbox | Checkbox input |
| Radio | Radio button input |
| Card | Container with heading/footer slots |
| Heading | Typography - headings |
| Text | Typography - body text |
| Link | Navigation link |
| Select | Dropdown selector |
| Textarea | Multi-line text input |
| FormField | Form group wrapper |
| Dialog | Modal dialog |
| Alert | Alert message |
| Skeleton | Loading placeholder |
TIER 2: Composite Components (10 components)
Higher-level components combining multiple elements.
| Component | Purpose |
|-----------|---------|
| SearchInput | Search with icon and clear |
| PriceInput | Currency input with formatting |
| ProductImage | Image with fallback |
| Rating | Star rating display |
| TagInput | Multi-tag input |
| Pagination | Page navigation |
| StatisticsCard | Stat display card |
| Breadcrumb | Navigation breadcrumb |
| Tooltip | Hover tooltip |
| Tabs | Tab navigation |
TIER 3: Ecommerce Components (10 components)
Specialized components for ecommerce functionality.
| Component | Purpose |
|-----------|---------|
| ProductCard | Product display card |
| CartItem | Cart line item |
| CartSummary | Order summary |
| ProductFilter | Advanced filtering |
| PriceDisplay | Price with discounts |
| FormError | Validation error |
| LoadingSpinner | Loading indicator |
| EmptyState | Empty state message |
| ReviewStars | Product reviews |
| QuantitySelector | Qty increment/decrement |
TIER 4: shadcn-compatible Primitives (20 components)
Advanced UI primitives for complex interactions.
| Component | Purpose |
|-----------|---------|
| Avatar | User avatar |
| DropdownMenu | Dropdown menu |
| Popover | Floating popover |
| AlertDialog | Confirmation dialog |
| Sheet | Slide-out drawer |
| ScrollArea | Custom scrollbar |
| Separator | Visual divider |
| NavigationMenu | Navigation menu |
| Progress | Progress bar |
| Switch | Toggle switch |
| Toggle | Toggle button |
| HoverCard | Hover preview card |
| Accordion | Expandable sections |
| AspectRatio | Aspect ratio container |
| RadioGroup | Radio group |
| CartDrawer | Slide-out cart |
| ProductQuickView | Quick product preview |
| VariantSelector | Product variant picker |
| CheckoutStepIndicator | Checkout steps |
| WishlistToggle | Wishlist heart icon |
Usage Examples
Form with Validation
import { FormField, Input, Label, Button, FormError } from '@thorprovider/components';
import { useState } from 'react';
export function ContactForm() {
const [error, setError] = useState('');
return (
<form className="space-y-4">
<FormField>
<Label htmlFor="email">Email</Label>
<Input id="email" type="email" placeholder="[email protected]" />
{error && <FormError>{error}</FormError>}
</FormField>
<Button type="submit">Send</Button>
</form>
);
}Product Grid with Cards
import { ProductCard, Badge, Rating } from '@thorprovider/components';
interface Product {
id: string;
name: string;
price: number;
image: string;
rating: number;
isNew?: boolean;
}
export function ProductGrid({ products }: { products: Product[] }) {
return (
<div className="grid grid-cols-1 gap-4 md:grid-cols-3 lg:grid-cols-4">
{products.map((product) => (
<ProductCard
key={product.id}
title={product.name}
price={product.price}
image={product.image}
badge={product.isNew ? <Badge>New</Badge> : undefined}
rating={<Rating rating={product.rating} />}
onAddToCart={() => console.log('Added', product.id)}
/>
))}
</div>
);
}Modal Dialog
import {
Dialog,
DialogHeader,
DialogTitle,
DialogContent,
DialogFooter,
Button,
} from '@thorprovider/components';
import { useState } from 'react';
export function ConfirmDialog() {
const [open, setOpen] = useState(false);
return (
<>
<Button onClick={() => setOpen(true)}>Delete Item</Button>
<Dialog open={open} onOpenChange={setOpen}>
<DialogHeader>
<DialogTitle>Confirm Delete</DialogTitle>
</DialogHeader>
<DialogContent>Are you sure you want to delete this item?</DialogContent>
<DialogFooter>
<Button variant="outline" onClick={() => setOpen(false)}>
Cancel
</Button>
<Button variant="destructive">Delete</Button>
</DialogFooter>
</Dialog>
</>
);
}Customization
Theming with CSS Variables
Override default colors in your CSS:
:root {
--color-primary: #2563eb;
--color-primary-hover: #1d4ed8;
--color-success: #059669;
--color-error: #dc2626;
}Tailwind CSS Configuration
Ensure your tailwind.config.ts includes the components package:
import type { Config } from 'tailwindcss';
export default {
content: [
'./app/**/*.{js,ts,jsx,tsx}',
'./node_modules/@thorprovider/components/**/*.{js,mjs}',
],
theme: {
extend: {},
},
plugins: [],
} satisfies Config;TypeScript Support
All components export their prop types:
import { Button, type ButtonProps } from '@thorprovider/components';
const MyButton: React.FC<ButtonProps> = (props) => {
return <Button {...props} />;
};Accessibility
Every component follows WCAG 2.1 AA standards:
- Proper semantic HTML (button, input, etc.)
- ARIA labels and roles where needed
- Keyboard navigation support
- Focus management
- Screen reader friendly
Architecture
packages/components/
├── src/
│ ├── components/ # 55 React components
│ ├── utils/
│ │ └── cn.ts # Class merging utility
│ ├── styles.css # Global styles + design tokens
│ └── index.ts # Barrel exports
├── package.json
├── tsconfig.json
└── tsup.config.tsBuilding
# Development with watch
pnpm dev
# Production build
pnpm build
# Type checking
pnpm type-checkPerformance
- Minimal Dependencies: Only React, clsx, and tailwind-merge
- Tree-shakeable: Each component is individually exported
- Optimized: Components use forwardRef and proper memoization
- Fast: Simple component compositions without complex abstractions
Contributing
All components must:
- ✅ Be presentational (no business logic)
- ✅ Use TypeScript with proper types
- ✅ Include JSDoc documentation
- ✅ Support all required props via interface
- ✅ Use
cn()utility for class merging - ✅ Be accessible (WCAG 2.1 AA)
- ✅ Work across all Thor Commerce starters
License
MIT - See LICENSE file in repository
