بالنسبة لمطوري الويب، البحث عن مجموعة أدوات واجهة المستخدم المثالية هو مسعى مستمر. لسنوات، اعتمد مطورو React على مكتبات المكونات التقليدية مثل Material-UI (MUI) وAnt Design وChakra UI. تقدم هذه المكتبات ثروة من المكونات المعدة مسبقًا، واعدة بتسريع عملية التطوير. ومع ذلك، غالبًا ما تأتي مع مقايضة: نقص في التحكم، وتجاوزات في الأنماط تبدو كمعركة، وأحجام حزمة (bundle) متضخمة.
ادخل إلى عالم Shadcn UI، وهو نهج يغير النموذج وقد اجتاح مجتمع React. إنها ليست مكتبة مكونات بالطريقة التي اعتدت عليها؛ إنها شيء أفضل. إنها مجموعة من المكونات المصممة بشكل جميل، والتي يمكن الوصول إليها، وقابلة لإعادة الاستخدام بلا حدود، والتي لا تقوم بتثبيتها من npm كاعتمادية - بل تقوم بنسخها مباشرة إلى مشروعك.
سيكون هذا البرنامج التعليمي الشامل، الذي يبلغ طوله 4000 كلمة، دليلك النهائي، حيث يأخذك من مبتدئ تمامًا إلى ممارس واثق في Shadcn UI. سنستكشف فلسفته التأسيسية، ونستعرض إعدادًا تفصيليًا، ونبني واجهات مستخدم معقدة، ونتقن التخصيص المتقدم للسمات (theming) والتعامل مع النماذج (form handling)، ونناقش أفضل الممارسات للتطبيقات واسعة النطاق. استعد لإعادة التفكير فيما تتوقعه من مجموعة أدوات واجهة المستخدم.
هل تريد منصة متكاملة وشاملة لفريق المطورين لديك للعمل معًا بأقصى إنتاجية؟
Apidog يلبي جميع متطلباتك، ويحل محل Postman بسعر معقول أكثر بكثير!
فلسفة Shadcn UI - طريقة جديدة للبناء
قبل كتابة سطر واحد من التعليمات البرمجية، من الضروري فهم لماذا يوجد Shadcn UI وما هي المشاكل التي يحلها. فهم هذه الفلسفة الأساسية هو مفتاح إطلاق كامل إمكاناته.
ما ليس Shadcn UI
- إنه ليس حزمة npm تقليدية. لن تجد
shadcn-ui
في قائمة الاعتماديات (dependencies) في ملفpackage.json
الخاص بك. هذا هو الفرق الأكثر أهمية. - إنه ليس مكتبة متجانسة (monolithic). لا يجبرك على تثبيت مئات المكونات عندما تحتاج فقط إلى زر وحقل إدخال.
- إنه ليس مقيدًا. لست مقيدًا أبدًا بجمالية تصميم معينة أو محدودًا بقدرات التخصيص (theming) التي يوفرها maintainers المكتبة.
ما هو Shadcn UI
- مجموعة من التعليمات البرمجية القابلة لإعادة الاستخدام: فكر فيها على أنها مجموعة من الوصفات المنسقة بخبرة. تختار الوصفة التي تريدها (على سبيل المثال، مكون
Card
)، ويتم إعطاؤك التعليمات (التعليمات البرمجية) لطهيها في مطبخك الخاص (مشروعك). - التزام بملكية التعليمات البرمجية: بمجرد إضافة مكون Shadcn، يتم وضع التعليمات البرمجية المصدر الخاصة به - ملف
.tsx
- مباشرة في قاعدة التعليمات البرمجية الخاصة بك، عادةً تحتcomponents/ui/
. إنه الآن مكونك أنت. يمكنك تغيير هيكله، أنماطه، منطقه - أي شيء. هذا يزيل التجربة المحبطة من الصراع مع تجاوزات CSS التي تتطلب!important
أو واجهات برمجة تطبيقات props معقدة لتحقيق تعديل بصري بسيط. - مبني على أساس حديث وقوي: Shadcn UI لا يعيد اختراع العجلة. إنه يقف على أكتاف العمالقة:
- Tailwind CSS: إطار عمل CSS يعتمد على الأدوات المساعدة (utility-first) ويوفر لبنات بناء منخفضة المستوى لإنشاء أي تصميم مباشرة في ترميزك. يتم تنسيق مكونات Shadcn حصريًا باستخدام Tailwind، مما يجعل تخصيصها سهلاً للغاية إذا كنت على دراية بالإطار.
- Radix UI: مكتبة من العناصر الأولية (primitives) لواجهة المستخدم غير المنسقة والتي يمكن الوصول إليها وذات مستوى منخفض. يتعامل Radix مع جميع الجوانب المعقدة والتي غالبًا ما يتم تجاهلها لمكونات واجهة المستخدم، مثل التنقل بلوحة المفاتيح، وإدارة التركيز (focus management)، وسمات ARIA لإمكانية الوصول (a11y). يأخذ Shadcn هذه العناصر الأولية القوية والرأسية (headless) ويضيف إليها تصميمًا جميلًا باستخدام Tailwind CSS.
الميزة الأساسية لهذا النموذج هي دمج **السرعة والتحكم**. تحصل على السرعة الأولية لاستخدام المكونات المعدة مسبقًا دون التضحية بالمرونة وقابلية الصيانة على المدى الطويل التي تأتي من امتلاك التعليمات البرمجية الخاصة بك.
إعداد المسرح - إعداد المشروع والتثبيت
دعنا ننتقل من النظرية إلى التطبيق العملي. سنقوم بإعداد مشروع جديد من الصفر. لهذا الدليل، سنستخدم بشكل أساسي **Next.js**، حيث تتوافق مكونات الخادم الخاصة به والتوجيه المستند إلى الملفات بشكل مثالي مع روح Shadcn UI. سنغطي أيضًا إعداد Vite باختصار.
الخطوة 1: المتطلبات الأساسية للبيئة
تأكد من أن بيئة التطوير لديك جاهزة. ستحتاج إلى:
- Node.js: يُنصح بأحدث إصدار دعم طويل الأمد (LTS). يمكنك تنزيله من موقع Node.js الرسمي.
- مدير حزم: سيستخدم هذا البرنامج التعليمي
npm
، والذي يأتي مدمجًا مع Node.js. يمكنك أيضًا استخدامyarn
أوpnpm
.
الخطوة 2: إنشاء تطبيق Next.js جديد
افتح الطرفية (terminal) ونفذ الأمر التالي لتهيئة مشروع Next.js جديد.Bash
npx create-next-app@latest my-pro-shadcn-app --typescript --tailwind --eslint
ينشئ هذا الأمر تطبيقًا جديدًا في مجلد باسم my-pro-shadcn-app
. لقد قمنا بتضمين بعض العلامات المهمة:
--typescript
: Shadcn UI مكتوب بلغة TypeScript ويعمل بشكل أفضل في بيئة TypeScript.--tailwind
: Tailwind CSS هو اعتمادية أساسية لتنسيق Shadcn UI.--eslint
: ممارسة جيدة دائمًا للحفاظ على جودة التعليمات البرمجية.
سيطلب منك المثبت بعض الأسئلة. هذه هي الخيارات الموصى بها لإعداد Next.js 14+ حديث:
✔ Would you like to use `src/` directory? … No / **Yes**
✔ Would you like to use App Router? (recommended) … No / **Yes**
✔ Would you like to customize the default import alias? … **No** / Yes
يُعد استخدام App Router ممارسة قياسية، ويساعد مجلد src/
في تنظيم التعليمات البرمجية. بمجرد الانتهاء، انتقل إلى مشروعك الجديد:Bash
cd my-pro-shadcn-app
الخطوة 3: الأمر init
- إضفاء الحياة على Shadcn UI
هذه هي الخطوة الأكثر أهمية. يوفر Shadcn UI أداة سطر أوامر (CLI) لتكوين مشروعك. قم بتشغيل الأمر التالي من الدليل الجذر لمشروعك:Bash
npx shadcn-ui@latest init
سيؤدي هذا إلى تشغيل استبيان تفاعلي لإعداد مشروعك. دعنا نفصل كل سؤال وأهميته:
- هل ترغب في استخدام TypeScript (موصى به)؟
Yes
. نحن في مشروع TypeScript. - أي نمط ترغب في استخدامه؟
Default
مقابلNew York
. هذان نمطان مرئيان محددان مسبقًا.Default
أكثر اتساعًا قليلاً، بينماNew York
أكثر إحكامًا. يمكنك رؤية أمثلة على موقع Shadcn UI. دعنا نختار **Default
**. - أي لون ترغب في استخدامه كلون أساسي؟ هذا يحدد لوحة الألوان الأساسية لواجهة المستخدم الخاصة بك. اللون الافتراضي هو
Slate
. دعنا نلتزم بـ **Slate
** في الوقت الحالي؛ سنتعلم كيفية تغيير ذلك لاحقًا. - أين يوجد ملف
global.css
الخاص بك؟ يكتشف CLI هذا بشكل صحيح فيsrc/app/globals.css
. هذا الملف هو المكان الذي سيتم فيه حقن متغيرات CSS الأساسية للسمات. - هل تريد استخدام متغيرات CSS للسمات؟
Yes
. هذا هو حجر الزاوية في نظام سمات Shadcn، مما يسمح بالتغييرات الديناميكية (مثل الوضع الداكن/الفاتح) والتخصيص السهل. - أين يقع ملف
tailwind.config.ts
الخاص بك؟ يكتشف CLIsrc/tailwind.config.ts
. سيتم تعديل هذا الملف لدمج إعدادات سمات Shadcn المسبقة. - تكوين اسم مستعار للاستيراد للمكونات:
@/components
. هذه أفضل ممارسة. هذا يعني أنه بغض النظر عن مدى تعمق تداخل الملف، يمكنك دائمًا استيراد مكون بمسار نظيف مثلimport { Button } from "@/components/ui/button";
. - تكوين اسم مستعار للاستيراد للأدوات المساعدة:
@/lib/utils
. نفس الشيء أعلاه، للدوال المساعدة. - هل تستخدم مكونات خادم React؟
Yes
. لقد اخترنا App Router، الذي يستخدم مكونات الخادم افتراضيًا. - كتابة التكوين إلى
components.json
؟Yes
. هذا ينشئ ملفًا حاسمًا يتذكر جميع اختياراتك، لذلك لن تضطر إلى الإجابة على هذه الأسئلة في كل مرة تقوم فيها بتشغيلnpx shadcn-ui@latest add ...
.
بعد التأكيد، يقوم CLI بسحره:
- تثبيت الاعتماديات: يضيف الحزم الضرورية مثل
tailwindcss-animate
وclass-variance-authority
. - إنشاء
components.json
: يخزن اختيارات التكوين الخاصة بك. - تحديث
tailwind.config.ts
: يحقن مكون Shadcn UI الإضافي وتكوين السمات. - تحديث
globals.css
: يضيف كتلة كبيرة من متغيرات CSS التي تحدد لوحة الألوان الكاملة، ونصف أقطار الحدود، والمزيد. - إنشاء
lib/utils.ts
: يصدر هذا الملف دالة مساعدةcn
، وهي أداة مساعدة ذكية لدمج فئات Tailwind CSS بشكل شرطي.
مشروعك الآن مُكوّن بالكامل.
(بديل: إعداد Vite)
إذا كنت تستخدم Vite مع React، فإن العملية مشابهة جدًا. بعد إعداد مشروع Vite + React + TS، ستقوم بتثبيت Tailwind CSS يدويًا ثم تشغيل npx shadcn-ui@latest init. أداة CLI ذكية بما يكفي لاكتشاف إعداد Vite وستطرح أسئلة مختلفة قليلاً حول مواقع الملفات (على سبيل المثال، index.css بدلاً من globals.css).
بناء واجهة مستخدم - من المكونات البسيطة إلى التخطيطات المعقدة
مع اكتمال الإعداد، دعنا نبدأ البناء. سير العمل الأساسي هو: **تحديد الحاجة، إضافة المكون، استخدامه.**
الخطوة 4: إضافة واستخدام مكوناتك الأولى
دعنا ننظف القالب الافتراضي لـ Next.js ونبني واجهة بسيطة.
1. إضافة زر:Bash
npx shadcn-ui@latest add button
لاحظ ما يحدث: يتم إنشاء ملف جديد، src/components/ui/button.tsx
. هذا هو زرّك. أنت تملكه.
2. إضافة بطاقة (Card):Bash
npx shadcn-ui@latest add card
هذا الأمر أكثر إثارة للاهتمام. ينشئ src/components/ui/card.tsx
. إذا فحصت هذا الملف، سترى أنه يصدر مكونات متعددة: Card
، CardHeader
، CardTitle
، CardDescription
، CardContent
، و CardFooter
. هذا نمط شائع للمكونات المركبة (compound components).
3. بناء واجهة المستخدم:
الآن، افتح src/app/page.tsx
واستبدل محتواه بما يلي:TypeScript
import { Button } from "@/components/ui/button";
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { Input } from "@/components/ui/input"; // We'll add this next
import { Label } from "@/components/ui/label"; // And this
export default function Home() {
return (
<main className="flex min-h-screen items-center justify-center bg-background p-8">
<Card className="w-full max-w-md">
<CardHeader>
<CardTitle className="text-2xl">Create Project</CardTitle>
<CardDescription>
Deploy your new project in one-click.
</CardDescription>
</CardHeader>
<CardContent className="grid gap-4">
<div className="grid gap-2">
<Label htmlFor="name">Name</Label>
<Input id="name" placeholder="Name of your project" />
</div>
<div className="grid gap-2">
<Label htmlFor="framework">Framework</Label>
{/* We'll replace this with a Select component later */}
<Input id="framework" placeholder="e.g. Next.js" />
</div>
</CardContent>
<CardFooter>
<Button className="w-full">Deploy</Button>
</CardFooter>
</Card>
</main>
);
}
لن يعمل الكود الخاص بنا بعد لأننا نفتقد مكوني Input
و Label
. دعنا نضيفهما:Bash
npx shadcn-ui@latest add input
npx shadcn-ui@latest add label
الآن، قم بتشغيل خادم التطوير الخاص بك:Bash
npm run dev
انتقل إلى http://localhost:3000
. سترى نموذجًا نظيفًا وذو مظهر احترافي داخل بطاقة. لاحظ كيف استخدمنا فئات الأدوات المساعدة (utility classes) مثل w-full
و max-w-md
و grid
مباشرة في JSX للتحكم في التخطيط. هذه هي قوة الجمع بين Shadcn وTailwind CSS.
الخطوة 5: تقديم مكونات أكثر تطوراً
المدخلات الثابتة جيدة، لكن التطبيقات الحقيقية تحتاج إلى عناصر تفاعلية. دعنا نحسن نموذجنا.
1. إضافة مكون Select
: يجب أن يكون حقل 'Framework' قائمة منسدلة. دعنا نضيف مكون Select
. هذا المكون أكثر تعقيدًا ويعتمد على مكونات أخرى. Bash
npx shadcn-ui@latest add select
أداة CLI ذكية. سترى أن Select
يتطلب مكون Popover
ليعمل وستطلب إذنك لتثبيته هو واعتمادياته أيضًا. هذه ميزة رائعة تمنعك من الاضطرار إلى تتبع الاعتماديات يدويًا.
2. دمج مكون Select
: استبدل حقل Input
الخاص بـ 'Framework' في src/app/page.tsx
بمكون Select
الجديد. TypeScript
// Add these imports at the top
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
// ... inside the CardContent
<div className="grid gap-2">
<Label htmlFor="framework">Framework</Label>
<Select>
<SelectTrigger id="framework">
<SelectValue placeholder="Select a framework" />
</SelectTrigger>
<SelectContent>
<SelectItem value="nextjs">Next.js</SelectItem>
<SelectItem value="sveltekit">SvelteKit</SelectItem>
<SelectItem value="astro">Astro</SelectItem>
<SelectItem value="nuxt">Nuxt.js</SelectItem>
</SelectContent>
</Select>
</div>
حدث صفحة المتصفح. لديك الآن قائمة منسدلة قابلة للتحديد وعملية بالكامل، مع رسوم متحركة وتنقل صحيح بلوحة المفاتيح، كل ذلك بفضل Radix UI الذي يعمل تحت الغطاء.
3. إضافة ملاحظات للمستخدم باستخدام Toast
: ماذا يحدث عندما ينقر المستخدم على 'Deploy'؟ يجب أن نقدم له بعض الملاحظات. مكون Toast
مثالي لذلك.
أولاً، أضفه:Bash
npx shadcn-ui@latest add toast
بعد ذلك، لاستخدام التنبيهات (toasts)، تحتاج إلى إضافة مكون <Toaster />
إلى تخطيطك الجذري (root layout) حتى يمكن عرضه في أي مكان في التطبيق. افتح src/app/layout.tsx
وقم بتعديله:TypeScript
import { Toaster } from "@/components/ui/toaster" // Import the Toaster
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
{children}
<Toaster /> {/* Add it here, just before closing body */}
</body>
</html>
)
}
الآن، نحتاج إلى طريقة لتشغيل التنبيه (toast). سنستخدم hook useToast
. دعنا نحدث src/app/page.tsx
لجعله مكون عميل (client component) والتعامل مع نقرة الزر. TypeScript
'use client'; // <-- Add this at the very top of the file
// ... other imports
import { useToast } from "@/components/ui/use-toast";
export default function Home() {
const { toast } = useToast(); // Get the toast function from the hook
function handleDeploy() {
toast({
title: "Deployment Scheduled!",
description: "Your project 'Name of your project' is being deployed.",
duration: 5000,
});
}
return (
<main className="flex min-h-screen items-center justify-center bg-background p-8">
<Card className="w-full max-w-md">
{/* ... CardHeader and CardContent ... */}
<CardFooter>
<Button className="w-full" onClick={handleDeploy}> {/* Add onClick handler */}
Deploy
</Button>
</CardFooter>
</Card>
</main>
);
}
الآن، عند النقر على زر 'Deploy'، سيظهر إشعار أنيق في زاوية الشاشة.
بناء نموذج احترافي مع التحقق من الصحة (Validation)
تتطلب معظم التطبيقات الواقعية معالجة قوية للنماذج، بما في ذلك التحقق من صحة البيانات من جانب العميل. الطريقة الرسمية للتعامل مع هذا باستخدام Shadcn UI هي دمجه مع react-hook-form
لإدارة الحالة و zod
للتحقق من صحة المخطط (schema). دعنا نبنيه.
الخطوة 6: تثبيت اعتماديات النموذج
أولاً، دعنا نثبت المكتبات الضرورية:Bash
npm install react-hook-form zod @hookform/resolvers
react-hook-form
: مكتبة نماذج عالية الأداء ومرنة وقابلة للتوسيع.zod
: مكتبة تعريف وتحقق من صحة المخطط (schema) تعتمد على TypeScript أولاً.@hookform/resolvers
: مكتبة جسر للسماح لـreact-hook-form
باستخدامzod
للتحقق من الصحة.
الخطوة 7: إضافة مكون Form
من Shadcn
يوفر Shadcn UI مكون Form
خاصًا يعمل كغلاف لربط react-hook-form
بسلاسة مع مكونات واجهة المستخدم الخاصة بك. Bash
npx shadcn-ui@latest add form
سيضيف هذا src/components/ui/form.tsx
. يوفر هذا الملف مجموعة من المكونات الواعية بالسياق (Form
، FormField
، FormItem
، FormLabel
، FormControl
، FormDescription
، FormMessage
) التي تقلل بشكل كبير من التعليمات البرمجية المتكررة (boilerplate).
الخطوة 8: إنشاء مخطط التحقق من الصحة (Validation Schema)
في ملف src/app/page.tsx
الخاص بك، دعنا نحدد شكل وقواعد بيانات نموذجنا باستخدام zod
. TypeScript
// Add these imports at the top
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form";
الآن، دعنا ننشئ المخطط فوق مكون Home
مباشرة:TypeScript
const formSchema = z.object({
projectName: z.string().min(2, {
message: "Project name must be at least 2 characters.",
}).max(50, {
message: "Project name must not exceed 50 characters.",
}),
framework: z.string({
required_error: "Please select a framework to display.",
}),
});
يحدد هذا المخطط حقلين: projectName
يجب أن يكون سلسلة نصية بين 2 و 50 حرفًا، و framework
هو سلسلة نصية مطلوبة.
الخطوة 9: ربط النموذج
الآن، دعنا نعيد هيكلة مكون Home
الخاص بنا لاستخدام كل هذه الأدوات الجديدة. TypeScript
export default function Home() {
const { toast } = useToast();
// 1. Define your form.
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
projectName: "",
},
});
// 2. Define a submit handler.
function onSubmit(values: z.infer<typeof formSchema>) {
// Do something with the form values.
// ✅ This will be type-safe and validated.
console.log(values);
toast({
title: "You submitted the following values:",
description: (
<pre className="mt-2 w-[340px] rounded-md bg-slate-950 p-4">
<code className="text-white">{JSON.stringify(values, null, 2)}</code>
</pre>
),
});
}
// 3. Build the JSX with Shadcn's Form components
return (
<main className="flex min-h-screen items-center justify-center bg-background p-8">
<Card className="w-full max-w-md">
<CardHeader>
<CardTitle className="text-2xl">Create Project</CardTitle>
<CardDescription>
Deploy your new project in one-click.
</CardDescription>
</CardHeader>
<CardContent>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
<FormField
control={form.control}
name="projectName"
render={({ field }) => (
<FormItem>
<FormLabel>Name</FormLabel>
<FormControl>
<Input placeholder="Name of your project" {...field} />
</FormControl>
<FormDescription>
This is your public display name.
</FormDescription>
<FormMessage /> {/* Displays validation errors */}
</FormItem>
)}
/>
<FormField
control={form.control}
name="framework"
render={({ field }) => (
<FormItem>
<FormLabel>Framework</FormLabel>
<Select onValueChange={field.onChange} defaultValue={field.value}>
<FormControl>
<SelectTrigger>
<SelectValue placeholder="Select a framework" />
</SelectTrigger>
</FormControl>
<SelectContent>
<SelectItem value="nextjs">Next.js</SelectItem>
<SelectItem value="sveltekit">SvelteKit</SelectItem>
<SelectItem value="astro">Astro</SelectItem>
<SelectItem value="nuxt">Nuxt.js</SelectItem>
</SelectContent>
</Select>
<FormDescription>
The framework you want to deploy.
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit" className="w-full">Deploy</Button>
</form>
</Form>
</CardContent>
</Card>
</main>
);
}
هذه قطعة كبيرة من التعليمات البرمجية، لكنها نمط قوي وقابل للتوسع بشكل لا يصدق. يتعامل مكون FormField
مع جميع اتصالات الحالة، ويعرض FormMessage
تلقائيًا خطأ التحقق الصحيح من مخطط zod
الخاص بك عندما يتفاعل المستخدم مع الحقل. حاول إرسال النموذج باسم مشروع فارغ لترى التحقق من الصحة عمليًا.
إتقان السمات والتخصيص
تُطلق القوة الحقيقية لـ Shadcn UI عندما تبدأ في جعله خاصًا بك.
الخطوة 10: التخصيص المتقدم للسمات باستخدام متغيرات CSS
يتم تعريف السمة الكاملة الخاصة بك بواسطة متغيرات CSS في src/app/globals.css
. افتح هذا الملف وابحث عن كتل :root
و .dark
. CSS
/* Example from globals.css */
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%;
/* ... and many more */
--radius: 0.5rem;
}
.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;
--primary: 210 40% 98%;
--primary-foreground: 222.2 47.4% 11.2%;
/* ... */
}
- تغيير الألوان: يتم تمثيل القيم كقيم HSL (Hue, Saturation, Lightness) بدون غلاف
hsl()
. هذا اختيار متعمد لتسهيل التلاعب. لتغيير لون علامتك التجارية الأساسي، تحتاج فقط إلى العثور على قيم HSL للون الخاص بك وتحديث متغيرات--primary
و--primary-foreground
. صفحة Shadcn UI Themes تحتوي على مولد رائع يتيح لك اختيار لون ونسخ ولصق كتلة السمة بأكملها. - تغيير نصف قطر الحدود (Border Radius): هل تريد زوايا أكثر حدة؟ قم بتغيير
--radius: 0.5rem;
إلى--radius: 0.2rem;
أو حتى0rem
. كل مكون يحتوي على زوايا دائرية يستخدم هذا المتغير، لذا سينتشر تغييرك عالميًا.
تطبيق الوضع الداكن:
تم تكوين Shadcn مسبقًا للوضع الداكن بفضل كتلة الفئة .dark واستراتيجية Tailwind darkMode: "class" في tailwind.config.ts. كل ما تحتاجه هو طريقة لتبديل فئة dark على عنصر <html>. مكتبة شائعة لهذا الغرض هي next-themes.
- قم بتثبيتها:
npm install next-themes
- أنشئ مكون ThemeProvider (
src/components/theme-provider.tsx
): TypeScript
"use client"
import * as React from "react"
import { ThemeProvider as NextThemesProvider } from "next-themes"
import { type ThemeProviderProps } from "next-themes/dist/types"
export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
return <NextThemesProvider {...props}>{children}</NextThemesProvider>
}
- قم بتغليف RootLayout الخاص بك بهذا المزود (
src/app/layout.tsx
): TypeScript
import { ThemeProvider } from "@/components/theme-provider"
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en" suppressHydrationWarning>
<body>
<ThemeProvider
attribute="class"
defaultTheme="system"
enableSystem
disableTransitionOnChange
>
{children}
<Toaster />
</ThemeProvider>
</body>
</html>
)
}
- أخيرًا، أنشئ زر تبديل (على سبيل المثال،
src/components/mode-toggle.tsx
): TypeScript
"use client"
import * as React from "react"
import { Moon, Sun } from "lucide-react"
import { useTheme } from "next-themes"
import { Button } from "@/components/ui/button"
export function ModeToggle() {
const { theme, setTheme } = useTheme()
return (
<Button
variant="outline"
size="icon"
onClick={() => setTheme(theme === "light" ? "dark" : "light")}
>
<Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
<Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
<span className="sr-only">Toggle theme</span>
</Button>
)
}
يمكنك الآن وضع <ModeToggle />
هذا في أي مكان في تطبيقك للحصول على تبديل للوضع الداكن يراعي النظام وقابل للتجاوز من قبل المستخدم.
الخطوة 11: تخصيص التعليمات البرمجية المصدر للمكون
هذه هي القوة الخارقة المطلقة. لنفترض أنك تريد نوعًا جديدًا للنجاح (success variant) لزرّك بخلفية خضراء.
افتح src/components/ui/button.tsx. ابحث عن تعريف buttonVariants. يستخدم cva (Class Variance Authority). ببساطة أضف نوعًا جديدًا:TypeScript
const buttonVariants = cva(
// ... base styles
{
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline",
success: "bg-green-600 text-white hover:bg-green-600/90", // Our new variant
},
// ... size variants
},
defaultVariants: {
variant: "default",
size: "default",
},
}
)
هذا كل شيء. يمكنك الآن استخدامه في التعليمات البرمجية الخاصة بك: <Button variant="success">Success</Button>
. لم تكن بحاجة لكتابة تجاوزات CSS معقدة. لقد قمت فقط بتحرير التعليمات البرمجية المصدر للمكون نفسه. سير العمل هذا بسيط، قابل للتنبؤ، وقوي بشكل لا يصدق.
الجزء 6: أفضل الممارسات والطريق إلى الأمام
مع نمو تطبيقك، إليك بعض أفضل الممارسات التي يجب وضعها في الاعتبار.
- تنظيم الملفات: بينما يضع CLI كل شيء في
components/ui
، يجب اعتبار هذا المجلد 'مجموعة أدوات واجهة المستخدم الأساسية' الخاصة بك. بالنسبة للمكونات الأكثر تعقيدًا التي تقوم بتركيبها بنفسك (على سبيل المثال،UserProfileCard
الذي يستخدمCard
وAvatar
وButton
من Shadcn)، قم بإنشائها في دليل مختلف، مثلcomponents/shared
أوcomponents/features
. هذا يحافظ على فصل واضح بين واجهة المستخدم الأساسية والمكونات الخاصة بالتطبيق. - تحديثات المكونات: كيف تحصل على التحديثات إذا تم تحسين مكون Shadcn UI الأصلي؟ أداة CLI تغطي ذلك. يمكنك تشغيل
npx shadcn-ui@latest add button
مرة أخرى. ستكتشف CLI أن لديك بالفعل ملفbutton.tsx
وستعرض لك مقارنةdiff
، مما يتيح لك إما الكتابة فوق ملفك أو قبول التغييرات يدويًا. إنها مثل نسخة مصغرة من نظام التحكم في الإصدار لمكوناتك. - الاستفادة من إمكانية الوصول: تذكر أن مكونات Shadcn يمكن الوصول إليها خارج الصندوق لأنها مبنية على عناصر Radix الأولية. عند تخصيصها، كن حذرًا لعدم كسر هذه الإمكانية. على سبيل المثال، إذا قمت بتغيير ألوان زر، تأكد من أن النص لا يزال يحتوي على تباين كافٍ. عند بناء مكونات جديدة، حاول اتباع الأنماط التي وضعها Shadcn/Radix للحفاظ على قابلية التنقل بلوحة المفاتيح ودعم قارئ الشاشة.
الخاتمة: أنت مؤلف المكتبة
لقد سافرت الآن من الفلسفة الأساسية لـ Shadcn UI إلى تطبيق أنماط متقدمة وعالمية واقعية. لقد رأيت أن ابتكاره الحقيقي ليس فقط في المكونات نفسها، بل في التحول النموذجي الذي يمثله. إنه ينقل المطورين من مجرد *مستهلكين* لمكتبة إلى *قائمين على التنسيق* و *مالكين* لمجموعة أدوات واجهة المستخدم الخاصة بهم.
من خلال منحك التعليمات البرمجية المصدر الخام، والبناء على الأسس القوية لـ Tailwind CSS و Radix UI، وتوفير تجربة CLI سلسة، يحقق Shadcn UI التوازن المثالي بين سرعة التطوير الأولية وقابلية الصيانة على المدى الطويل والحرية الإبداعية. لم تعد مقيدًا بنظام تصميم شخص آخر. المكونات في مشروعك هي ملكك - لتعديلها وتوسيعها وإتقانها.
مستقبل واجهة المستخدم لتطبيقك لم يعد في أيدي اعتمادية خارجية؛ إنه موجود هناك في مجلد components
الخاص بك. بناء سعيد.
هل تريد منصة متكاملة وشاملة لفريق المطورين لديك للعمل معًا بأقصى إنتاجية؟
Apidog يلبي جميع متطلباتك، ويحل محل Postman بسعر معقول أكثر بكثير!