تمبندی
نحوه سفارشیسازی و ایجاد تمهای سفارشی در دیزاین سیستم پرتو
سیستم تمبندی پرتو به شما امکان میدهد به راحتی بین تمهای مختلف جابجا شوید و حتی تمهای سفارشی خود را ایجاد کنید. سیستم ما بر اساس CSS Variables و Tailwind CSS ساخته شده است که انعطافپذیری کامل را فراهم میکند.
تغییر تم
برای تست تمهای مختلف، از سوئیچ زیر استفاده کنید:
تمهای پیشفرض
دیزاین سیستم پرتو با 2 تم پیشفرض عرضه میشود:
تم روشن (Light)
تم پیشفرض برای محیطهای روشن با پالت رنگی سفید و خاکستری روشن.
/* globals.css — تم روشن همیشه در :root تعریف میشود */
:root {
--background-default: 0deg 0% 100%;
--foreground-default: 222.2deg 47.4% 11.2%;
--foreground-light: 215.4deg 16.3% 46.9%;
--foreground-lighter: 216deg 12.2% 83.9%;
--foreground-muted: 220deg 8.9% 46.1%;
/* ... */
}بهترین برای:
- وبسایتهای عمومی
- اپلیکیشنهای اداری
- محیطهای با نور زیاد
تم تاریک (Dark)
تم مدرن برای محیطهای کمنور با پالت رنگی تیره و خاکستری تاریک.
/* theme-dark.css */
.dark {
--background-default: 222.2deg 84% 4.9%;
--foreground-default: 210deg 40% 98%;
--foreground-light: 217.9deg 10.6% 64.9%;
--foreground-lighter: 215deg 20.2% 65.1%;
--foreground-muted: 215.4deg 16.3% 46.9%;
/* ... */
}بهترین برای:
- کار طولانیمدت
- محیطهای کمنور
- کاربران حساس به نور
نحوه پیادهسازی تمبندی
استفاده پایه
دیزاین سیستم پرتو با next-themes کار میکند. تم روشن پیشفرض است (:root) و نیازی به class ندارد. برای تغییر تم، ThemeProvider را راهاندازی کنید:
// app/layout.tsx
import { ThemeProvider } from 'next-themes'
export default function RootLayout({ children }) {
return (
<html lang="fa" dir="rtl" suppressHydrationWarning>
<body>
<ThemeProvider attribute="class" defaultTheme="light" themes={['light', 'dark']}>
{children}
</ThemeProvider>
</body>
</html>
)
}تغییر دینامیک تم
برای تغییر دینامیک تم، از hook ارائهشده توسط next-themes استفاده کنید:
'use client'
import { useTheme } from 'next-themes'
import { Button } from '@parto-system-design/ui'
export function ThemeSwitcher() {
const { theme, setTheme } = useTheme()
return (
<div className="flex gap-2">
<Button variant={theme === 'light' ? 'default' : 'outline'} onClick={() => setTheme('light')}>
روشن
</Button>
<Button variant={theme === 'dark' ? 'default' : 'outline'} onClick={() => setTheme('dark')}>
تاریک
</Button>
</div>
)
}تشخیص تم سیستم
برای تشخیص خودکار تم بر اساس تنظیمات سیستم:
'use client'
import { useEffect, useState } from 'react'
export function useSystemTheme() {
const [theme, setTheme] = useState<'light' | 'dark'>('light')
useEffect(() => {
// تشخیص تم سیستم
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
setTheme(mediaQuery.matches ? 'dark' : 'light')
// گوش دادن به تغییرات
const handler = (e: MediaQueryListEvent) => {
setTheme(e.matches ? 'dark' : 'light')
}
mediaQuery.addEventListener('change', handler)
return () => mediaQuery.removeEventListener('change', handler)
}, [])
return theme
}ساخت تم سفارشی
ایجاد فایل تم
برای ایجاد تم سفارشی، یک فایل CSS جدید بسازید:
/* theme-custom.css */
.custom-theme {
/* رنگهای پسزمینه */
--background-default: 280deg 40% 10%;
--background-200: 280deg 40% 12%;
--background-alternative-default: 260deg 40% 15%;
--background-alternative-200: 260deg 40% 18%;
/* سطوح */
--background-surface-75: 280deg 35% 15%;
--background-surface-100: 280deg 35% 18%;
--background-surface-200: 280deg 35% 22%;
--background-surface-300: 280deg 35% 26%;
--background-surface-400: 280deg 35% 30%;
/* رنگهای متن */
--foreground-default: 280deg 20% 95%;
--foreground-light: 280deg 15% 75%;
--foreground-lighter: 280deg 10% 60%;
--foreground-muted: 280deg 8% 50%;
--foreground-contrast: 0deg 0% 100%;
/* حاشیهها */
--border-default: 280deg 30% 25%;
--border-strong: 280deg 30% 35%;
--border-stronger: 280deg 30% 45%;
--border-overlay: 280deg 25% 30%;
--border-control: 280deg 25% 28%;
/* رنگ برند */
--brand-default: 280deg 80% 60%;
--brand-200: 280deg 80% 70%;
--brand-300: 280deg 80% 65%;
--brand-400: 280deg 80% 55%;
--brand-500: 280deg 80% 50%;
--brand-600: 280deg 80% 45%;
/* هشدار */
--warning-default: 45deg 95% 60%;
--warning-200: 45deg 95% 75%;
--warning-300: 45deg 95% 70%;
--warning-400: 45deg 95% 55%;
--warning-500: 45deg 95% 50%;
--warning-600: 45deg 95% 45%;
/* خطر */
--destructive-default: 0deg 85% 60%;
--destructive-200: 0deg 85% 75%;
--destructive-300: 0deg 85% 70%;
--destructive-400: 0deg 85% 55%;
--destructive-500: 0deg 85% 50%;
--destructive-600: 0deg 85% 45%;
}وارد کردن تم سفارشی
فایل تم را در globals.css وارد کنید:
/* app/globals.css */
@import '@parto-system-design/ui/styles.css';
@import './theme-custom.css'; /* تم سفارشی شما */استفاده از تم سفارشی
<html lang="fa" dir="rtl" className="custom-theme">
<body>{children}</body>
</html>متغیرهای رنگی اصلی
تمام تمها باید این متغیرهای اصلی را تعریف کنند:
پسزمینهها
--background-default
--background-200
--background-alternative-default
--background-alternative-200
--background-selection
--background-control
--background-surface-75
--background-surface-100
--background-surface-200
--background-surface-300
--background-surface-400
--background-overlay-default
--background-overlay-hover
--background-button-default
--background-dialog-default
--background-sidebar
--background-canvasمتن (Foreground)
--foreground-default
--foreground-light
--foreground-lighter
--foreground-muted
--foreground-contrastحاشیهها
--border-default
--border-strong
--border-stronger
--border-overlay
--border-control
--border-alternative
--border-secondary
--border-button-default
--border-button-hoverرنگهای سمانتیک
--brand-default
--brand-200
--brand-300
--brand-400
--brand-500
--brand-600
--warning-default
--warning-200
--warning-300
--warning-400
--warning-500
--warning-600
--destructive-default
--destructive-200
--destructive-300
--destructive-400
--destructive-500
--destructive-600نکات مهم در طراحی تم
کنتراست مناسب
همیشه اطمینان حاصل کنید که رنگهای متن و پسزمینه کنتراست کافی دارند (WCAG AA حداقل 4.5:1):
// استفاده از ابزار محاسبه کنتراست
function calculateContrast(color1: string, color2: string): number {
// محاسبه contrast ratio
// باید حداقل 4.5:1 باشد
}سازگاری با Brand Colors
رنگهای برند باید در تمام تمها قابل تشخیص باشند:
/* تم روشن */
:root {
--brand-default: 153deg 60% 53%;
}
/* تم تاریک */
.dark {
--brand-default: 155deg 78% 40%;
}تست در شرایط واقعی
قبل از نهایی کردن تم:
- تست در دستگاههای مختلف
- تست با محتوای واقعی
- تست accessibility
- تست در نورهای مختلف
مستندسازی تم
برای هر تم سفارشی، موارد زیر را مستند کنید:
# تم سفارشی من
**هدف:** برای داشبورد مدیریتی
**پالت اصلی:** بنفش و آبی
**بهترین برای:** کار شبانه
## رنگهای اصلی
- Primary: #7C3AED (بنفش)
- Secondary: #3B82F6 (آبی)
- Background: #1A1B2E (تیره)
## نکات استفاده
- بهتر است در محیطهای کمنور استفاده شود
- برای متنهای طولانی مناسب نیستمثال کامل: راهاندازی با next-themes
// app/layout.tsx
import { ThemeProvider } from 'next-themes'
import '@parto-system-design/ui/styles.css'
export default function RootLayout({ children }) {
return (
<html lang="fa" dir="rtl" suppressHydrationWarning>
<body>
<ThemeProvider attribute="class" defaultTheme="light" themes={['light', 'dark']} enableSystem={false}>
{children}
</ThemeProvider>
</body>
</html>
)
}// components/theme-switcher.tsx
'use client'
import { useTheme } from 'next-themes'
import { Button } from '@parto-system-design/ui'
export function ThemeSwitcher() {
const { theme, setTheme } = useTheme()
return (
<div className="flex gap-2">
<Button variant={theme === 'light' ? 'default' : 'outline'} size="small" onClick={() => setTheme('light')}>
روشن
</Button>
<Button variant={theme === 'dark' ? 'default' : 'outline'} size="small" onClick={() => setTheme('dark')}>
تاریک
</Button>
</div>
)
}Troubleshooting
مشکل: تم تغییر نمیکند
مطمئن شوید که ThemeProvider از next-themes به درستی راهاندازی شده و attribute="class" دارد. کلاس .dark باید روی <html> ظاهر شود.
مشکل: Flash of wrong theme در بارگذاری
مطمئن شوید که suppressHydrationWarning روی تگ <html> وجود دارد — این ویژگی برای جلوگیری از خطای hydration هنگام تغییر تم قبل از رندر سمت کلاینت لازم است.
مشکل: تم کلاسیک تاریک کار نمیکند
بررسی کنید که darkMode: ['class', '[data-theme*="dark"]'] در tailwind.config.ts تنظیم شده باشد.
منابع مرتبط
- رنگها - راهنمای کامل رنگبندی
- پالتهای رنگی - پالت کامل رنگی
- کلاسهای Tailwind - لیست کامل کلاسها