Web Design System - Atomic Design components (Atoms, Molecules, Organisms) for React applications
npm install @umituz/web-design-system
# or
yarn add @umituz/web-design-system
# or
pnpm add @umituz/web-design-system// β
Use subpath imports (RECOMMENDED)
import { Button } from '@umituz/web-design-system/atoms';
import { Card } from '@umituz/web-design-system/organisms';
function App() {
return (
<Card>
<Button variant="primary">Click me</Button>
</Card>
);
}import {
Button,
Badge,
Input,
Text,
Icon,
Spinner
} from '@umituz/web-design-system/atoms';import {
FormField,
SearchBox,
Avatar,
Chip,
Toggle
} from '@umituz/web-design-system/molecules';import {
Card,
Alert,
Modal,
Navbar
} from '@umituz/web-design-system/organisms';import {
Form,
List,
Section,
PageLayout,
PageHeader,
ResponsiveContainer,
ProjectSkeleton
} from '@umituz/web-design-system/templates';import {
useTheme,
useMediaQuery,
useBreakpoint,
useLocalStorage,
useLanguage,
useClickOutside,
useKeyboard,
useEscape,
useDebounce,
useClipboard,
useToggle,
useScrollLock
} from '@umituz/web-design-system/hooks';import {
lightColorTokens,
darkColorTokens,
spacing,
fontSizes,
radii,
shadows
} from '@umituz/web-design-system/tokens';import type {
SizeVariant,
ColorVariant,
BaseProps
} from '@umituz/web-design-system/types';import {
validateInput,
validateEmail,
validateUrl,
sanitizeInput,
validateFileName,
CSP_CONFIG,
SECURITY_HEADERS,
VALIDATION_CONFIGS
} from '@umituz/web-design-system/security';
import { useFormValidation, COMMON_RULES } from '@umituz/web-design-system/security';import {
usePerformanceMonitor,
useLazyLoading,
useMemoryOptimization,
useLazyImage,
useLazyComponent,
useVirtualList
} from '@umituz/web-design-system/performance';import {
ErrorBoundary,
ErrorDisplay,
SuspenseWrapper,
NetworkError,
NotFoundError,
ApiError
} from '@umituz/web-design-system/error';import { Button } from '@umituz/web-design-system/atoms';
<Button variant="primary" size="md">Primary Button</Button>
<Button variant="secondary" size="lg">Secondary Button</Button>
<Button variant="success" size="sm">Success Button</Button>import { Card, CardHeader, CardTitle, CardDescription, CardContent } from '@umituz/web-design-system/organisms';
<Card>
<CardHeader>
<CardTitle>Card Title</CardTitle>
<CardDescription>Card description goes here</CardDescription>
</CardHeader>
<CardContent>
<p>Card content</p>
</CardContent>
</Card>import { Alert } from '@umituz/web-design-system/organisms';
<Alert variant="success">Success message!</Alert>
<Alert variant="warning">Warning message!</Alert>
<Alert variant="destructive">Error message!</Alert>import { useTheme } from '@umituz/web-design-system/hooks';
function ThemeToggle() {
const { theme, toggleTheme } = useTheme();
return (
<Button onClick={toggleTheme}>
Current: {theme}
</Button>
);
}import { useLanguage } from '@umituz/web-design-system/hooks';
function LanguageSelector() {
const { currentLanguage, changeLanguage, t, supportedLanguages } = useLanguage({
defaultLanguage: 'en-US',
supportedLanguages: {
'en-US': { name: 'English', flag: 'πΊπΈ' },
'tr-TR': { name: 'TΓΌrkΓ§e', flag: 'πΉπ·' },
'de-DE': { name: 'Deutsch', flag: 'π©πͺ' },
}
});
return (
<select value={currentLanguage} onChange={(e) => changeLanguage(e.target.value)}>
{Object.entries(supportedLanguages).map(([code, { name, flag }]) => (
<option key={code} value={code}>{flag} {name}</option>
))}
</select>
);
}import { useBreakpoint, useMediaQuery } from '@umituz/web-design-system/hooks';
function ResponsiveComponent() {
const breakpoint = useBreakpoint();
const isDesktop = useMediaQuery('lg');
const isTablet = useMediaQuery('md');
return (
<div>
Current breakpoint: {breakpoint || 'mobile'}
{isDesktop && <DesktopNavigation />}
{isTablet && !isDesktop && <TabletNavigation />}
</div>
);
}import { ResponsiveContainer } from '@umituz/web-design-system/templates';
// Auto-responsive container with different max widths per device
<ResponsiveContainer
mobileMaxWidth="full"
tabletMaxWidth="lg"
desktopMaxWidth="xl"
gradient
minHeight="screen"
>
<h1>Auto-responsive content</h1>
<p>This container automatically adjusts based on screen size</p>
</ResponsiveContainer>
// Custom responsive container
<ResponsiveContainer
mobilePadding={false}
tabletPadding={true}
desktopPadding={true}
centered={false}
>
<div>Custom responsive layout</div>
</ResponsiveContainer>import { lightColorTokens, darkColorTokens } from '@umituz/web-design-system/tokens';
// Light mode
const colors = lightColorTokens;
// {
// primary: 'hsl(187 75% 38%)',
// background: 'hsl(210 20% 98%)',
// ...
// }
// Dark mode
const darkColors = darkColorTokens;import { spacing } from '@umituz/web-design-system/tokens';
const gap = spacing['4']; // '1rem'import { fontSizes, fontWeights } from '@umituz/web-design-system/tokens';
const fontSize = fontSizes['lg']; // '1.125rem'
const fontWeight = fontWeights['semibold']; // '600'import { validateEmail, sanitizeInput, validateFileName } from '@umituz/web-design-system/security';
// Validate email
const result = validateEmail('user@example.com');
if (result.isValid) {
// Email is valid
}
// Sanitize user input
const clean = sanitizeInput(userInput);
// Validate file names
const fileResult = validateFileName(fileName);import { useFormValidation, COMMON_RULES } from '@umituz/web-design-system/security';
const MyForm = () => {
const { formData, errors, updateField, validateAllFields, isFormValid } = useFormValidation(
{ name: '', email: '' },
{
name: COMMON_RULES.name,
email: COMMON_RULES.email
}
);
return (
<form onSubmit={handleSubmit}>
<input
value={formData.name}
onChange={(e) => updateField('name', e.target.value)}
/>
{errors.name && <span className="error">{errors.name}</span>}
</form>
);
};import { usePerformanceMonitor } from '@umituz/web-design-system/performance';
const MyComponent = () => {
const { metrics, getPerformanceReport } = usePerformanceMonitor({
componentName: 'MyComponent',
trackRenders: true,
trackMemory: true
});
return <div>Render time: {metrics.renderTime}ms</div>;
};import { useLazyLoading, useLazyImage } from '@umituz/web-design-system/performance';
const LazyImage = () => {
const { targetRef, imageSrc, isLoaded } = useLazyImage('/large-image.jpg');
return (
<div ref={targetRef}>
{isLoaded ? <img src={imageSrc} alt="Lazy loaded" /> : <div>Loading...</div>}
</div>
);
};import { useMemoryOptimization } from '@umituz/web-design-system/performance';
const MyComponent = () => {
const { addEventListener, setTimeout, addCleanup, getMemoryStats } = useMemoryOptimization();
useEffect(() => {
const cleanup = addEventListener(window, 'resize', handleResize);
const timerId = setTimeout(() => {}, 1000);
return () => {
cleanup();
// Automatic cleanup on unmount
};
}, []);
return <div>Memory stats: {getMemoryStats().totalTrackedItems} items</div>;
};import { ErrorBoundary } from '@umituz/web-design-system/error';
<ErrorBoundary
level="page"
showDetails={true}
onError={(error, errorInfo) => console.error(error)}
>
<MyComponent />
</ErrorBoundary>import { ErrorDisplay, NetworkError, ApiError } from '@umituz/web-design-system/error';
<ErrorDisplay
error={error}
title="Something went wrong"
severity="error"
showRetry={true}
onRetry={retryFunction}
/>
<NetworkError onRetry={retry} />
<ApiError error={apiError} onRetry={retry} />import { SuspenseWrapper, PageSuspense } from '@umituz/web-design-system/error';
<PageSuspense loadingText="Loading page...">
<MyLazyComponent />
</PageSuspense>
<SuspenseWrapper variant="card" errorBoundaryLevel="feature">
<AsyncComponent />
</SuspenseWrapper>This package follows Atomic Design methodology:
- Atoms: Basic building blocks (Button, Input, Icon)
- Molecules: Simple combinations (FormField, SearchBox, Chip)
- Organisms: Complex components (Card, Modal, Navbar)
- Templates: Page structures (Form, List, Section)
This design system works seamlessly with Tailwind CSS. Make sure your Tailwind config includes the CSS variables:
/* Your global CSS */
@layer base {
:root {
--background: 210 20% 98%;
--foreground: 220 20% 12%;
--primary: 187 75% 38%;
--primary-foreground: 0 0% 100%;
/* ... more tokens */
}
.dark {
--background: 220 20% 7%;
--foreground: 210 20% 92%;
--primary: 187 85% 53%;
--primary-foreground: 220 20% 7%;
/* ... more tokens */
}
}MIT
This package is part of the @umituz organization. For issues and feature requests, please visit the GitHub repository.