@alexourus/ui 0.3.0 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.mjs ADDED
@@ -0,0 +1,1675 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/index.ts
4
+ import { Command } from "commander";
5
+
6
+ // src/commands/init.ts
7
+ import path2 from "path";
8
+ import fs2 from "fs-extra";
9
+ import prompts from "prompts";
10
+ import ora from "ora";
11
+ import { execa } from "execa";
12
+
13
+ // src/utils/logger.ts
14
+ import {
15
+ cyan,
16
+ green,
17
+ yellow,
18
+ red,
19
+ bold,
20
+ dim,
21
+ magenta,
22
+ blue
23
+ } from "kolorist";
24
+ var logger = {
25
+ banner() {
26
+ console.log();
27
+ console.log(
28
+ bold(
29
+ cyan(" \u25B2 alexourus-ui ") + dim("v0.3.3 \u2014 Modern React & Tailwind Design System")
30
+ )
31
+ );
32
+ console.log(
33
+ dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")
34
+ );
35
+ console.log();
36
+ },
37
+ info(...args) {
38
+ console.log(cyan("\u2139"), ...args);
39
+ },
40
+ success(...args) {
41
+ console.log(green("\u2714"), bold(green(String(args[0]))), ...args.slice(1));
42
+ },
43
+ warn(...args) {
44
+ console.log(yellow("\u25B2"), yellow(String(args[0])), ...args.slice(1));
45
+ },
46
+ error(...args) {
47
+ console.log(red("\u2716"), bold(red(String(args[0]))), ...args.slice(1));
48
+ },
49
+ step(step, desc) {
50
+ console.log(` ${magenta(step)} ${desc}`);
51
+ },
52
+ item(title, desc) {
53
+ console.log(` ${blue("\u2022")} ${bold(title)}${desc ? dim(` \u2014 ${desc}`) : ""}`);
54
+ },
55
+ break() {
56
+ console.log();
57
+ }
58
+ };
59
+
60
+ // src/utils/get-package-manager.ts
61
+ import fs from "fs-extra";
62
+ import path from "path";
63
+ async function getPackageManager(cwd = process.cwd()) {
64
+ const userAgent = process.env.npm_config_user_agent || "";
65
+ if (userAgent.startsWith("pnpm")) return "pnpm";
66
+ if (userAgent.startsWith("bun")) return "bun";
67
+ if (userAgent.startsWith("yarn")) return "yarn";
68
+ if (userAgent.startsWith("npm")) return "npm";
69
+ if (await fs.pathExists(path.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
70
+ if (await fs.pathExists(path.join(cwd, "bun.lockb")) || await fs.pathExists(path.join(cwd, "bun.lock"))) return "bun";
71
+ if (await fs.pathExists(path.join(cwd, "yarn.lock"))) return "yarn";
72
+ if (await fs.pathExists(path.join(cwd, "package-lock.json"))) return "npm";
73
+ return "npm";
74
+ }
75
+ function getInstallCommand(pm, isDev = false) {
76
+ switch (pm) {
77
+ case "pnpm":
78
+ return isDev ? "pnpm add -D" : "pnpm add";
79
+ case "bun":
80
+ return isDev ? "bun add -d" : "bun add";
81
+ case "yarn":
82
+ return isDev ? "yarn add -D" : "yarn add";
83
+ case "npm":
84
+ default:
85
+ return isDev ? "npm install --save-dev" : "npm install";
86
+ }
87
+ }
88
+
89
+ // src/utils/templates.ts
90
+ var UTILS_TEMPLATE = `import { type ClassValue, clsx } from "clsx";
91
+ import { twMerge } from "tailwind-merge";
92
+
93
+ export function cn(...inputs: ClassValue[]) {
94
+ return twMerge(clsx(inputs));
95
+ }
96
+ `;
97
+ var COLOR_THEMES = {
98
+ zinc: {
99
+ light: { primary: "222 47% 11%", primaryForeground: "210 40% 98%", ring: "222 47% 11%" },
100
+ dark: { primary: "0 0% 96%", primaryForeground: "0 0% 6%", ring: "0 0% 60%" }
101
+ },
102
+ emerald: {
103
+ light: { primary: "142.1 76.2% 36.3%", primaryForeground: "355.7 100% 97.3%", ring: "142.1 76.2% 36.3%" },
104
+ dark: { primary: "142.1 70.6% 45.3%", primaryForeground: "144.9 80.4% 10%", ring: "142.4 71.8% 29.2%" }
105
+ },
106
+ violet: {
107
+ light: { primary: "262.1 83.3% 57.8%", primaryForeground: "210 20% 98%", ring: "262.1 83.3% 57.8%" },
108
+ dark: { primary: "263.4 70% 50.4%", primaryForeground: "210 20% 98%", ring: "263.4 70% 50.4%" }
109
+ },
110
+ rose: {
111
+ light: { primary: "346.8 77.2% 49.8%", primaryForeground: "355.7 100% 97.3%", ring: "346.8 77.2% 49.8%" },
112
+ dark: { primary: "346.8 77.2% 49.8%", primaryForeground: "355.7 100% 97.3%", ring: "346.8 77.2% 49.8%" }
113
+ },
114
+ blue: {
115
+ light: { primary: "221.2 83.2% 53.3%", primaryForeground: "210 40% 98%", ring: "221.2 83.2% 53.3%" },
116
+ dark: { primary: "217.2 91.2% 59.8%", primaryForeground: "222.2 47.4% 11.2%", ring: "224.3 76.3% 48%" }
117
+ },
118
+ amber: {
119
+ light: { primary: "24.6 95% 53.1%", primaryForeground: "60 9.1% 97.8%", ring: "24.6 95% 53.1%" },
120
+ dark: { primary: "20.5 90.2% 48.2%", primaryForeground: "60 9.1% 97.8%", ring: "20.5 90.2% 48.2%" }
121
+ },
122
+ cyan: {
123
+ light: { primary: "188 86% 40%", primaryForeground: "210 40% 98%", ring: "188 86% 40%" },
124
+ dark: { primary: "188 86% 53%", primaryForeground: "222 47% 11%", ring: "188 86% 53%" }
125
+ }
126
+ };
127
+ function getCssVariables(theme = "zinc", radius = "0.5rem") {
128
+ const defaultTheme = COLOR_THEMES.zinc;
129
+ const selected = COLOR_THEMES[theme] ?? defaultTheme;
130
+ return `@tailwind base;
131
+ @tailwind components;
132
+ @tailwind utilities;
133
+
134
+ @layer base {
135
+ :root {
136
+ --background: 0 0% 100%;
137
+ --foreground: 222 47% 11%;
138
+ --card: 0 0% 100%;
139
+ --card-foreground: 222 47% 11%;
140
+ --popover: 0 0% 100%;
141
+ --popover-foreground: 222 47% 11%;
142
+ --primary: ${selected.light.primary};
143
+ --primary-foreground: ${selected.light.primaryForeground};
144
+ --secondary: 210 40% 96%;
145
+ --secondary-foreground: 222 47% 11%;
146
+ --muted: 210 40% 96%;
147
+ --muted-foreground: 215 16% 47%;
148
+ --accent: 210 40% 96%;
149
+ --accent-foreground: 222 47% 11%;
150
+ --destructive: 0 84% 60%;
151
+ --destructive-foreground: 210 40% 98%;
152
+ --success: 142 71% 45%;
153
+ --success-foreground: 0 0% 100%;
154
+ --warning: 38 92% 50%;
155
+ --warning-foreground: 222 47% 11%;
156
+ --info: 217 91% 60%;
157
+ --info-foreground: 0 0% 100%;
158
+ --border: 214 32% 91%;
159
+ --input: 214 32% 91%;
160
+ --ring: ${selected.light.ring};
161
+ --radius: ${radius};
162
+ }
163
+
164
+ .dark {
165
+ --background: 0 0% 4%;
166
+ --foreground: 0 0% 96%;
167
+ --card: 0 0% 6%;
168
+ --card-foreground: 0 0% 96%;
169
+ --popover: 0 0% 6%;
170
+ --popover-foreground: 0 0% 96%;
171
+ --primary: ${selected.dark.primary};
172
+ --primary-foreground: ${selected.dark.primaryForeground};
173
+ --secondary: 0 0% 10%;
174
+ --secondary-foreground: 0 0% 90%;
175
+ --muted: 0 0% 10%;
176
+ --muted-foreground: 0 0% 55%;
177
+ --accent: 0 0% 10%;
178
+ --accent-foreground: 0 0% 96%;
179
+ --destructive: 0 63% 31%;
180
+ --destructive-foreground: 0 0% 96%;
181
+ --success: 142 69% 35%;
182
+ --success-foreground: 0 0% 100%;
183
+ --warning: 38 92% 40%;
184
+ --warning-foreground: 0 0% 100%;
185
+ --info: 217 91% 50%;
186
+ --info-foreground: 0 0% 100%;
187
+ --border: 0 0% 12%;
188
+ --input: 0 0% 12%;
189
+ --ring: ${selected.dark.ring};
190
+ }
191
+ }
192
+
193
+ @layer base {
194
+ * {
195
+ @apply border-border;
196
+ }
197
+ body {
198
+ @apply bg-background text-foreground;
199
+ }
200
+ }
201
+ `;
202
+ }
203
+
204
+ // src/commands/init.ts
205
+ async function runInit(options) {
206
+ const cwd = options.cwd || process.cwd();
207
+ logger.banner();
208
+ const pm = await getPackageManager(cwd);
209
+ const hasSrc = await fs2.pathExists(path2.join(cwd, "src"));
210
+ const candidateCss = [
211
+ "src/app/globals.css",
212
+ "app/globals.css",
213
+ "src/styles/globals.css",
214
+ "styles/globals.css",
215
+ "src/index.css",
216
+ "src/main.css",
217
+ "src/App.css"
218
+ ];
219
+ let detectedCss = null;
220
+ for (const file of candidateCss) {
221
+ if (await fs2.pathExists(path2.join(cwd, file))) {
222
+ detectedCss = file;
223
+ break;
224
+ }
225
+ }
226
+ let theme = "zinc";
227
+ let radius = "0.5rem";
228
+ let cssFile = detectedCss || (hasSrc ? "src/app/globals.css" : "app/globals.css");
229
+ let componentsDir = hasSrc ? "src/components/ui" : "components/ui";
230
+ let utilsFile = hasSrc ? "src/lib/utils.ts" : "lib/utils.ts";
231
+ if (detectedCss) {
232
+ logger.info("Proje yap\u0131s\u0131 otomatik alg\u0131land\u0131:");
233
+ console.log(` \u2713 Global CSS: ${cssFile}`);
234
+ console.log(` \u2713 Bile\u015Fenler: ${componentsDir}`);
235
+ console.log(` \u2713 Yard\u0131mc\u0131lar: ${utilsFile}`);
236
+ console.log();
237
+ }
238
+ if (!options.yes) {
239
+ const questions = [
240
+ {
241
+ type: "select",
242
+ name: "theme",
243
+ message: "Hangi temel renk temas\u0131n\u0131 kullanmak istersiniz?",
244
+ choices: [
245
+ { title: "Zinc (Varsay\u0131lan Monochrome)", value: "zinc" },
246
+ { title: "Emerald (Ye\u015Fil)", value: "emerald" },
247
+ { title: "Violet (Mor)", value: "violet" },
248
+ { title: "Rose (G\xFCl)", value: "rose" },
249
+ { title: "Blue (Mavi)", value: "blue" },
250
+ { title: "Amber (Kehribar)", value: "amber" },
251
+ { title: "Cyan (Turkuaz)", value: "cyan" }
252
+ ],
253
+ initial: 0
254
+ },
255
+ {
256
+ type: "select",
257
+ name: "radius",
258
+ message: "K\xF6\u015Fe yuvarlakl\u0131\u011F\u0131 (Border Radius) tercihiniz:",
259
+ choices: [
260
+ { title: "0 (Keskin)", value: "0" },
261
+ { title: "0.3rem (Kompakt)", value: "0.3rem" },
262
+ { title: "0.5rem (Dengeli / Varsay\u0131lan)", value: "0.5rem" },
263
+ { title: "0.75rem (Yuvarlak)", value: "0.75rem" },
264
+ { title: "1.0rem (Geni\u015F)", value: "1.0rem" }
265
+ ],
266
+ initial: 2
267
+ }
268
+ ];
269
+ if (!detectedCss) {
270
+ questions.push({
271
+ type: "text",
272
+ name: "cssFile",
273
+ message: "Global CSS dosyan\u0131z bulunamad\u0131. L\xFCtfen dosya yolunu girin:",
274
+ initial: cssFile
275
+ });
276
+ }
277
+ const response = await prompts(questions);
278
+ if (!response.theme) {
279
+ logger.warn("Kurulum iptal edildi.");
280
+ process.exit(0);
281
+ }
282
+ theme = response.theme;
283
+ radius = response.radius;
284
+ if (response.cssFile) {
285
+ cssFile = response.cssFile;
286
+ }
287
+ }
288
+ const spinner = ora("Proje yap\u0131land\u0131r\u0131l\u0131yor...").start();
289
+ try {
290
+ const config = {
291
+ $schema: "https://alexourus-ui.dev/schema.json",
292
+ style: "default",
293
+ tailwind: {
294
+ config: "tailwind.config.js",
295
+ css: cssFile,
296
+ baseColor: theme,
297
+ cssVariables: true,
298
+ prefix: ""
299
+ },
300
+ aliases: {
301
+ components: componentsDir.replace("/ui", ""),
302
+ utils: utilsFile.replace(/\.ts$/, ""),
303
+ ui: componentsDir
304
+ }
305
+ };
306
+ await fs2.writeJSON(path2.join(cwd, "components.json"), config, { spaces: 2 });
307
+ spinner.succeed("components.json olu\u015Fturuldu");
308
+ const utilsPath = path2.join(cwd, utilsFile);
309
+ await fs2.ensureDir(path2.dirname(utilsPath));
310
+ await fs2.writeFile(utilsPath, UTILS_TEMPLATE, "utf-8");
311
+ logger.success(`${utilsFile} olu\u015Fturuldu.`);
312
+ const cssPath = path2.join(cwd, cssFile);
313
+ await fs2.ensureDir(path2.dirname(cssPath));
314
+ if (!await fs2.pathExists(cssPath)) {
315
+ await fs2.writeFile(cssPath, getCssVariables(theme, radius), "utf-8");
316
+ logger.success(`${cssFile} olu\u015Fturuldu.`);
317
+ }
318
+ const installSpinner = ora(`Temel ba\u011F\u0131ml\u0131l\u0131klar y\xFCkleniyor (${pm})...`).start();
319
+ const coreDeps = ["clsx", "tailwind-merge", "lucide-react", "class-variance-authority", "tailwindcss-animate"];
320
+ try {
321
+ const isDev = false;
322
+ const cmdParts = getInstallCommand(pm, isDev).split(" ");
323
+ const [cmd, ...args] = cmdParts;
324
+ if (cmd) {
325
+ await execa(cmd, [...args, ...coreDeps], { cwd });
326
+ }
327
+ installSpinner.succeed("Ba\u011F\u0131ml\u0131l\u0131klar ba\u015Far\u0131yla y\xFCklendi.");
328
+ } catch {
329
+ installSpinner.warn("Ba\u011F\u0131ml\u0131l\u0131klar otomatik y\xFCklenemedi, l\xFCtfen elle \xE7al\u0131\u015Ft\u0131r\u0131n:");
330
+ console.log(` ${getInstallCommand(pm)} ${coreDeps.join(" ")}`);
331
+ }
332
+ logger.break();
333
+ logger.success("alexourus-ui ba\u015Far\u0131yla kuruldu ve yap\u0131land\u0131r\u0131ld\u0131! \u{1F389}");
334
+ logger.break();
335
+ console.log(" Bile\u015Fen eklemek i\xE7in:");
336
+ console.log(` $ npx @alexourus/ui add button alert input-otp`);
337
+ console.log();
338
+ } catch (error) {
339
+ spinner.fail("Kurulum s\u0131ras\u0131nda bir hata olu\u015Ftu.");
340
+ console.error(error);
341
+ process.exit(1);
342
+ }
343
+ }
344
+
345
+ // src/commands/add.ts
346
+ import path3 from "path";
347
+ import fs3 from "fs-extra";
348
+ import prompts2 from "prompts";
349
+ import ora2 from "ora";
350
+ import { execa as execa2 } from "execa";
351
+
352
+ // src/registry/index.ts
353
+ var REGISTRY = {
354
+ "accordion": {
355
+ "name": "accordion",
356
+ "type": "components:ui",
357
+ "category": "navigation",
358
+ "description": "Geni\u015Fletilebilir SSS ve akordeon blo\u011Fu",
359
+ "dependencies": [
360
+ "@radix-ui/react-accordion",
361
+ "lucide-react"
362
+ ],
363
+ "devDependencies": [],
364
+ "registryDependencies": [],
365
+ "files": [
366
+ {
367
+ "name": "accordion.tsx",
368
+ "content": '"use client";\n\nimport * as React from "react";\nimport * as AccordionPrimitive from "@radix-ui/react-accordion";\nimport { ChevronDown } from "lucide-react";\nimport { cn } from "@/lib/utils";\n\nconst Accordion = AccordionPrimitive.Root;\n\nconst AccordionItem = React.forwardRef<\n React.ElementRef<typeof AccordionPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>\n>(({ className, ...props }, ref) => (\n <AccordionPrimitive.Item\n ref={ref}\n className={cn("border-b border-border", className)}\n {...props}\n />\n));\nAccordionItem.displayName = "AccordionItem";\n\nconst AccordionTrigger = React.forwardRef<\n React.ElementRef<typeof AccordionPrimitive.Trigger>,\n React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>\n>(({ className, children, ...props }, ref) => (\n <AccordionPrimitive.Header className="flex">\n <AccordionPrimitive.Trigger\n ref={ref}\n className={cn(\n "flex flex-1 items-center justify-between py-4 text-sm font-medium",\n "transition-all duration-200",\n "hover:underline",\n "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",\n "[&[data-state=open]>svg]:rotate-180",\n className\n )}\n {...props}\n >\n {children}\n <ChevronDown className="h-4 w-4 shrink-0 text-muted-foreground transition-transform duration-200" />\n </AccordionPrimitive.Trigger>\n </AccordionPrimitive.Header>\n));\nAccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName;\n\nconst AccordionContent = React.forwardRef<\n React.ElementRef<typeof AccordionPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>\n>(({ className, children, ...props }, ref) => (\n <AccordionPrimitive.Content\n ref={ref}\n className="overflow-hidden text-sm data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down"\n {...props}\n >\n <div className={cn("pb-4 pt-0", className)}>{children}</div>\n </AccordionPrimitive.Content>\n));\nAccordionContent.displayName = AccordionPrimitive.Content.displayName;\n\nexport { Accordion, AccordionItem, AccordionTrigger, AccordionContent };\n'
369
+ }
370
+ ]
371
+ },
372
+ "alert": {
373
+ "name": "alert",
374
+ "type": "components:ui",
375
+ "category": "feedback",
376
+ "description": "Farkl\u0131 \xF6nem derecelerine g\xF6re renk ve ikonlu bildirim kutusu",
377
+ "dependencies": [
378
+ "class-variance-authority"
379
+ ],
380
+ "devDependencies": [],
381
+ "registryDependencies": [],
382
+ "files": [
383
+ {
384
+ "name": "alert.tsx",
385
+ "content": '"use client";\n\nimport * as React from "react";\nimport { cva, type VariantProps } from "class-variance-authority";\nimport { cn } from "@/lib/utils";\n\nconst alertVariants = cva(\n [\n "relative w-full rounded-xl border p-4 text-sm",\n "[&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground",\n "transition-colors duration-150",\n ],\n {\n variants: {\n variant: {\n default: "bg-background text-foreground border-border",\n info: "border-info/30 bg-info/10 text-foreground [&>svg]:text-info",\n success: "border-success/30 bg-success/10 text-foreground [&>svg]:text-success",\n warning: "border-warning/30 bg-warning/10 text-foreground [&>svg]:text-warning",\n destructive: "border-destructive/30 bg-destructive/10 text-foreground [&>svg]:text-destructive",\n outline: "bg-transparent text-foreground border-border",\n },\n },\n defaultVariants: {\n variant: "default",\n },\n }\n);\n\nexport interface AlertProps\n extends React.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof alertVariants> {}\n\nconst Alert = React.forwardRef<HTMLDivElement, AlertProps>(\n ({ className, variant, ...props }, ref) => (\n <div\n ref={ref}\n role="alert"\n className={cn(alertVariants({ variant }), className)}\n {...props}\n />\n )\n);\nAlert.displayName = "Alert";\n\nconst AlertTitle = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLHeadingElement>\n>(({ className, ...props }, ref) => (\n <h5\n ref={ref}\n className={cn("mb-1 font-semibold leading-none tracking-tight", className)}\n {...props}\n />\n));\nAlertTitle.displayName = "AlertTitle";\n\nconst AlertDescription = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn("text-xs leading-relaxed text-muted-foreground [&_p]:leading-relaxed", className)}\n {...props}\n />\n));\nAlertDescription.displayName = "AlertDescription";\n\nexport { Alert, AlertTitle, AlertDescription, alertVariants };\n'
386
+ }
387
+ ]
388
+ },
389
+ "alert-dialog": {
390
+ "name": "alert-dialog",
391
+ "type": "components:ui",
392
+ "category": "overlay",
393
+ "description": "Kritik silme ve onaylama modal\u0131",
394
+ "dependencies": [
395
+ "@radix-ui/react-alert-dialog"
396
+ ],
397
+ "devDependencies": [],
398
+ "registryDependencies": [],
399
+ "files": [
400
+ {
401
+ "name": "alert-dialog.tsx",
402
+ "content": '"use client";\n\nimport * as React from "react";\nimport * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog";\nimport { cn } from "@/lib/utils";\nimport { buttonVariants } from "@/components/ui/button";\n\nconst AlertDialog = AlertDialogPrimitive.Root;\nconst AlertDialogTrigger = AlertDialogPrimitive.Trigger;\nconst AlertDialogPortal = AlertDialogPrimitive.Portal;\n\nconst AlertDialogOverlay = React.forwardRef<\n React.ElementRef<typeof AlertDialogPrimitive.Overlay>,\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n <AlertDialogPrimitive.Overlay\n className={cn(\n "fixed inset-0 z-50 bg-black/50 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",\n className\n )}\n {...props}\n ref={ref}\n />\n));\nAlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName;\n\nconst AlertDialogContent = React.forwardRef<\n React.ElementRef<typeof AlertDialogPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Content>\n>(({ className, ...props }, ref) => (\n <AlertDialogPortal>\n <AlertDialogOverlay />\n <AlertDialogPrimitive.Content\n ref={ref}\n className={cn(\n "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border border-border bg-background p-6 shadow-overlay duration-200 sm:rounded-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]",\n className\n )}\n {...props}\n />\n </AlertDialogPortal>\n));\nAlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName;\n\nconst AlertDialogHeader = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn("flex flex-col space-y-2 text-center sm:text-left", className)}\n {...props}\n />\n);\nAlertDialogHeader.displayName = "AlertDialogHeader";\n\nconst AlertDialogFooter = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2 mt-2", className)}\n {...props}\n />\n);\nAlertDialogFooter.displayName = "AlertDialogFooter";\n\nconst AlertDialogTitle = React.forwardRef<\n React.ElementRef<typeof AlertDialogPrimitive.Title>,\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Title>\n>(({ className, ...props }, ref) => (\n <AlertDialogPrimitive.Title\n ref={ref}\n className={cn("text-lg font-semibold tracking-tight", className)}\n {...props}\n />\n));\nAlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;\n\nconst AlertDialogDescription = React.forwardRef<\n React.ElementRef<typeof AlertDialogPrimitive.Description>,\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Description>\n>(({ className, ...props }, ref) => (\n <AlertDialogPrimitive.Description\n ref={ref}\n className={cn("text-sm text-muted-foreground", className)}\n {...props}\n />\n));\nAlertDialogDescription.displayName =\n AlertDialogPrimitive.Description.displayName;\n\nconst AlertDialogAction = React.forwardRef<\n React.ElementRef<typeof AlertDialogPrimitive.Action>,\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Action> & {\n variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link";\n }\n>(({ className, variant = "default", ...props }, ref) => (\n <AlertDialogPrimitive.Action\n ref={ref}\n className={cn(buttonVariants({ variant }), className)}\n {...props}\n />\n));\nAlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName;\n\nconst AlertDialogCancel = React.forwardRef<\n React.ElementRef<typeof AlertDialogPrimitive.Cancel>,\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Cancel>\n>(({ className, ...props }, ref) => (\n <AlertDialogPrimitive.Cancel\n ref={ref}\n className={cn(buttonVariants({ variant: "outline" }), "mt-2 sm:mt-0", className)}\n {...props}\n />\n));\nAlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName;\n\nexport {\n AlertDialog,\n AlertDialogPortal,\n AlertDialogOverlay,\n AlertDialogTrigger,\n AlertDialogContent,\n AlertDialogHeader,\n AlertDialogFooter,\n AlertDialogTitle,\n AlertDialogDescription,\n AlertDialogAction,\n AlertDialogCancel,\n};\n'
403
+ }
404
+ ]
405
+ },
406
+ "aspect-ratio": {
407
+ "name": "aspect-ratio",
408
+ "type": "components:ui",
409
+ "category": "temel",
410
+ "description": "Responsive 16:9, 4:3, 1:1 medya \xE7er\xE7evesi",
411
+ "dependencies": [],
412
+ "devDependencies": [],
413
+ "registryDependencies": [],
414
+ "files": [
415
+ {
416
+ "name": "aspect-ratio.tsx",
417
+ "content": '"use client";\n\nimport * as React from "react";\nimport { cn } from "@/lib/utils";\n\nexport interface AspectRatioProps extends React.HTMLAttributes<HTMLDivElement> {\n ratio?: number;\n}\n\nconst AspectRatio = React.forwardRef<HTMLDivElement, AspectRatioProps>(\n ({ className, ratio = 16 / 9, style, children, ...props }, ref) => {\n return (\n <div\n ref={ref}\n style={{\n position: "relative",\n width: "100%",\n paddingBottom: `${(1 / ratio) * 100}%`,\n ...style,\n }}\n className={cn("overflow-hidden rounded-xl bg-muted", className)}\n {...props}\n >\n <div className="absolute inset-0 h-full w-full">{children}</div>\n </div>\n );\n }\n);\nAspectRatio.displayName = "AspectRatio";\n\nexport { AspectRatio };\n'
418
+ }
419
+ ]
420
+ },
421
+ "avatar": {
422
+ "name": "avatar",
423
+ "type": "components:ui",
424
+ "category": "temel",
425
+ "description": "AvatarImage, AvatarFallback, AvatarBadge ve grup saya\xE7l\u0131 profil avatar\u0131",
426
+ "dependencies": [
427
+ "@radix-ui/react-avatar"
428
+ ],
429
+ "devDependencies": [],
430
+ "registryDependencies": [],
431
+ "files": [
432
+ {
433
+ "name": "avatar.tsx",
434
+ "content": '"use client";\n\nimport * as React from "react";\nimport * as AvatarPrimitive from "@radix-ui/react-avatar";\nimport { cn } from "@/lib/utils";\n\nconst Avatar = React.forwardRef<\n React.ElementRef<typeof AvatarPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>\n>(({ className, ...props }, ref) => (\n <AvatarPrimitive.Root\n ref={ref}\n className={cn(\n "relative flex h-10 w-10 shrink-0 rounded-full select-none",\n className\n )}\n {...props}\n />\n));\nAvatar.displayName = AvatarPrimitive.Root.displayName;\n\nconst AvatarImage = React.forwardRef<\n React.ElementRef<typeof AvatarPrimitive.Image>,\n React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>\n>(({ className, ...props }, ref) => (\n <AvatarPrimitive.Image\n ref={ref}\n className={cn("aspect-square h-full w-full rounded-full object-cover", className)}\n {...props}\n />\n));\nAvatarImage.displayName = AvatarPrimitive.Image.displayName;\n\nconst AvatarFallback = React.forwardRef<\n React.ElementRef<typeof AvatarPrimitive.Fallback>,\n React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>\n>(({ className, ...props }, ref) => (\n <AvatarPrimitive.Fallback\n ref={ref}\n className={cn(\n "flex h-full w-full items-center justify-center rounded-full bg-muted text-muted-foreground text-sm font-medium border border-border/60",\n className\n )}\n {...props}\n />\n));\nAvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;\n\nexport interface AvatarBadgeProps extends React.HTMLAttributes<HTMLSpanElement> {\n /** Rozet rengi veya durumu (\xF6rn: "online", "busy", "away", "offline") */\n status?: "online" | "busy" | "away" | "offline";\n}\n\n/**\n * Avatar\u0131n sa\u011F alt k\xF6\u015Fesine durum (online/offline) veya bildirim noktas\u0131 ekler.\n */\nconst AvatarBadge = React.forwardRef<HTMLSpanElement, AvatarBadgeProps>(\n ({ className, status = "online", children, ...props }, ref) => {\n const statusClasses = {\n online: "bg-emerald-500",\n busy: "bg-rose-500",\n away: "bg-amber-500",\n offline: "bg-zinc-400 dark:bg-zinc-500",\n };\n\n return (\n <span\n ref={ref}\n className={cn(\n "absolute bottom-0 right-0 z-10 flex h-3 w-3 items-center justify-center rounded-full ring-2 ring-background shadow-xs",\n statusClasses[status],\n className\n )}\n {...props}\n >\n {children}\n </span>\n );\n }\n);\nAvatarBadge.displayName = "AvatarBadge";\n\n/**\n * Avatar grubunu yan yana g\xF6steren konteyner.\n * Negatif margin ile \xFCst \xFCste binen modern k\xFCme g\xF6r\xFCn\xFCm\xFC yarat\u0131r.\n */\nconst AvatarGroup = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n ({ className, children, ...props }, ref) => (\n <div\n ref={ref}\n className={cn("flex items-center -space-x-2.5 hover:space-x-1 transition-all duration-200", className)}\n {...props}\n >\n {children}\n </div>\n )\n);\nAvatarGroup.displayName = "AvatarGroup";\n\nexport interface AvatarGroupCountProps extends React.HTMLAttributes<HTMLDivElement> {\n count?: number | string;\n}\n\n/**\n * Avatar grubunda g\xF6sterilmeyen di\u011Fer kullan\u0131c\u0131lar\u0131n say\u0131s\u0131n\u0131 (+3, +5 vb.) belirten saya\xE7 balonu.\n */\nconst AvatarGroupCount = React.forwardRef<HTMLDivElement, AvatarGroupCountProps>(\n ({ className, count, children, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n "relative flex h-10 w-10 shrink-0 items-center justify-center rounded-full border-2 border-background bg-muted text-xs font-semibold text-muted-foreground ring-2 ring-background select-none",\n className\n )}\n {...props}\n >\n {children || (count ? `+${count}` : null)}\n </div>\n )\n);\nAvatarGroupCount.displayName = "AvatarGroupCount";\n\nexport {\n Avatar,\n AvatarImage,\n AvatarFallback,\n AvatarBadge,\n AvatarGroup,\n AvatarGroupCount,\n};\n'
435
+ }
436
+ ]
437
+ },
438
+ "background-pattern": {
439
+ "name": "background-pattern",
440
+ "type": "components:ui",
441
+ "category": "temel",
442
+ "description": "Hero ve SaaS alanlar\u0131 i\xE7in 8 haz\u0131r SVG arka plan deseni",
443
+ "dependencies": [],
444
+ "devDependencies": [],
445
+ "registryDependencies": [],
446
+ "files": [
447
+ {
448
+ "name": "background-pattern.tsx",
449
+ "content": '"use client";\n\nimport * as React from "react";\nimport { cn } from "@/lib/utils";\n\nexport type PatternType =\n | "dots"\n | "grid"\n | "cross"\n | "lines"\n | "blueprint"\n | "hexagon"\n | "circuit"\n | "radial-glow";\n\nexport interface BackgroundPatternProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Desen t\xFCr\xFC */\n pattern?: PatternType;\n /** Desen boyutu / aral\u0131\u011F\u0131 (varsay\u0131lan: 24) */\n size?: number;\n /** \xC7izgi veya nokta opakl\u0131\u011F\u0131 (0 - 1 aras\u0131, varsay\u0131lan: 0.08) */\n opacity?: number;\n /** \xD6zel renk (CSS rengi veya HSL de\u011Fi\u015Fkeni) */\n color?: string;\n /** Maske efekti: kenarlara do\u011Fru yumu\u015Fak silinme */\n mask?: "fade-out" | "radial" | "none";\n /** Arka plan rengi */\n backgroundColor?: string;\n /** Arka plan \xFCzerinde render edilecek i\xE7erik */\n children?: React.ReactNode;\n}\n\nexport const BackgroundPattern = React.forwardRef<HTMLDivElement, BackgroundPatternProps>(\n (\n {\n className,\n pattern = "grid",\n size = 24,\n opacity = 0.08,\n color,\n mask = "radial",\n backgroundColor,\n children,\n style,\n ...props\n },\n ref\n ) => {\n // Pattern SVG definitions based on pattern type\n const patternColor = color || "currentColor";\n\n const getPatternSvg = () => {\n switch (pattern) {\n case "dots":\n return (\n <svg className="absolute inset-0 h-full w-full" xmlns="http://www.w3.org/2000/svg">\n <defs>\n <pattern id={`pattern-dots-${size}`} width={size} height={size} patternUnits="userSpaceOnUse">\n <circle cx={size / 2} cy={size / 2} r={1.5} fill={patternColor} />\n </pattern>\n </defs>\n <rect width="100%" height="100%" fill={`url(#pattern-dots-${size})`} />\n </svg>\n );\n\n case "cross":\n const half = size / 2;\n const crossSize = Math.max(3, size / 6);\n return (\n <svg className="absolute inset-0 h-full w-full" xmlns="http://www.w3.org/2000/svg">\n <defs>\n <pattern id={`pattern-cross-${size}`} width={size} height={size} patternUnits="userSpaceOnUse">\n <path\n d={`M ${half - crossSize} ${half} H ${half + crossSize} M ${half} ${half - crossSize} V ${half + crossSize}`}\n stroke={patternColor}\n strokeWidth="1"\n />\n </pattern>\n </defs>\n <rect width="100%" height="100%" fill={`url(#pattern-cross-${size})`} />\n </svg>\n );\n\n case "lines":\n return (\n <svg className="absolute inset-0 h-full w-full" xmlns="http://www.w3.org/2000/svg">\n <defs>\n <pattern id={`pattern-lines-${size}`} width={size} height={size} patternUnits="userSpaceOnUse" patternTransform="rotate(45)">\n <line x1="0" y1="0" x2="0" y2={size} stroke={patternColor} strokeWidth="1" />\n </pattern>\n </defs>\n <rect width="100%" height="100%" fill={`url(#pattern-lines-${size})`} />\n </svg>\n );\n\n case "blueprint":\n return (\n <svg className="absolute inset-0 h-full w-full" xmlns="http://www.w3.org/2000/svg">\n <defs>\n <pattern id={`pattern-small-grid-${size}`} width={size / 4} height={size / 4} patternUnits="userSpaceOnUse">\n <path d={`M ${size / 4} 0 L 0 0 0 ${size / 4}`} fill="none" stroke={patternColor} strokeWidth="0.5" strokeOpacity="0.4" />\n </pattern>\n <pattern id={`pattern-blueprint-${size}`} width={size} height={size} patternUnits="userSpaceOnUse">\n <rect width={size} height={size} fill={`url(#pattern-small-grid-${size})`} />\n <path d={`M ${size} 0 L 0 0 0 ${size}`} fill="none" stroke={patternColor} strokeWidth="1" />\n </pattern>\n </defs>\n <rect width="100%" height="100%" fill={`url(#pattern-blueprint-${size})`} />\n </svg>\n );\n\n case "hexagon":\n const w = size * 1.5;\n const h = size * Math.sqrt(3);\n return (\n <svg className="absolute inset-0 h-full w-full" xmlns="http://www.w3.org/2000/svg">\n <defs>\n <pattern id={`pattern-hex-${size}`} width={w} height={h} patternUnits="userSpaceOnUse">\n <path\n d={`M ${w / 4} 0 L ${w * 0.75} 0 L ${w} ${h / 2} L ${w * 0.75} ${h} L ${w / 4} ${h} L 0 ${h / 2} Z`}\n fill="none"\n stroke={patternColor}\n strokeWidth="1"\n />\n </pattern>\n </defs>\n <rect width="100%" height="100%" fill={`url(#pattern-hex-${size})`} />\n </svg>\n );\n\n case "circuit":\n return (\n <svg className="absolute inset-0 h-full w-full" xmlns="http://www.w3.org/2000/svg">\n <defs>\n <pattern id={`pattern-circuit-${size}`} width={size * 2} height={size * 2} patternUnits="userSpaceOnUse">\n <path d={`M 0 ${size} H ${size} V 0`} fill="none" stroke={patternColor} strokeWidth="1" />\n <circle cx={size} cy={0} r="2" fill={patternColor} />\n <circle cx={0} cy={size} r="2" fill={patternColor} />\n <path d={`M ${size * 2} ${size} H ${size * 1.5} V ${size * 2}`} fill="none" stroke={patternColor} strokeWidth="1" />\n </pattern>\n </defs>\n <rect width="100%" height="100%" fill={`url(#pattern-circuit-${size})`} />\n </svg>\n );\n\n case "radial-glow":\n return (\n <div\n className="absolute inset-0"\n style={{\n background: `radial-gradient(circle at 50% 50%, ${patternColor} 0%, transparent 70%)`,\n }}\n />\n );\n\n case "grid":\n default:\n return (\n <svg className="absolute inset-0 h-full w-full" xmlns="http://www.w3.org/2000/svg">\n <defs>\n <pattern id={`pattern-grid-${size}`} width={size} height={size} patternUnits="userSpaceOnUse">\n <path d={`M ${size} 0 L 0 0 0 ${size}`} fill="none" stroke={patternColor} strokeWidth="1" />\n </pattern>\n </defs>\n <rect width="100%" height="100%" fill={`url(#pattern-grid-${size})`} />\n </svg>\n );\n }\n };\n\n const maskClass =\n mask === "radial"\n ? "[mask-image:radial-gradient(ellipse_at_center,black_40%,transparent_80%)]"\n : mask === "fade-out"\n ? "[mask-image:linear-gradient(to_bottom,black_60%,transparent_100%)]"\n : "";\n\n return (\n <div\n ref={ref}\n className={cn("relative overflow-hidden", className)}\n style={{\n backgroundColor,\n ...style,\n }}\n {...props}\n >\n {/* Pattern Layer */}\n <div\n className={cn(\n "pointer-events-none absolute inset-0 transition-opacity duration-300",\n maskClass\n )}\n style={{ opacity }}\n >\n {getPatternSvg()}\n </div>\n\n {/* Content */}\n {children && <div className="relative z-10">{children}</div>}\n </div>\n );\n }\n);\n\nBackgroundPattern.displayName = "BackgroundPattern";\n'
450
+ }
451
+ ]
452
+ },
453
+ "badge": {
454
+ "name": "badge",
455
+ "type": "components:ui",
456
+ "category": "temel",
457
+ "description": "Durum ve etiket rozetleri (success, warning, destructive, info, dot)",
458
+ "dependencies": [
459
+ "class-variance-authority"
460
+ ],
461
+ "devDependencies": [],
462
+ "registryDependencies": [],
463
+ "files": [
464
+ {
465
+ "name": "badge.tsx",
466
+ "content": '"use client";\n\nimport * as React from "react";\nimport { cva, type VariantProps } from "class-variance-authority";\nimport { cn } from "@/lib/utils";\n\nconst badgeVariants = cva(\n [\n "inline-flex items-center gap-1.5 rounded-full border px-2.5 py-0.5 text-xs font-semibold",\n "transition-colors duration-150",\n "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",\n ],\n {\n variants: {\n variant: {\n default:\n "border-transparent bg-primary text-primary-foreground",\n secondary:\n "border-transparent bg-secondary text-secondary-foreground",\n destructive:\n "border-transparent bg-destructive text-destructive-foreground",\n success:\n "border-transparent bg-success text-success-foreground",\n warning:\n "border-transparent bg-warning text-warning-foreground",\n info:\n "border-transparent bg-info text-info-foreground",\n outline:\n "border-border text-foreground",\n },\n },\n defaultVariants: {\n variant: "default",\n },\n }\n);\n\nexport interface BadgeProps\n extends React.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof badgeVariants> {\n /** Ba\u015F\u0131nda nokta g\xF6ster */\n dot?: boolean;\n}\n\nfunction Badge({ className, variant, dot = false, children, ...props }: BadgeProps) {\n return (\n <div className={cn(badgeVariants({ variant }), className)} {...props}>\n {dot && (\n <span\n className="size-1.5 rounded-full bg-current opacity-80"\n aria-hidden="true"\n />\n )}\n {children}\n </div>\n );\n}\n\nexport { Badge, badgeVariants };\n'
467
+ }
468
+ ]
469
+ },
470
+ "breadcrumb": {
471
+ "name": "breadcrumb",
472
+ "type": "components:ui",
473
+ "category": "navigation",
474
+ "description": "Sayfa hiyerar\u015Fi navigasyon yolu",
475
+ "dependencies": [
476
+ "@radix-ui/react-slot",
477
+ "lucide-react"
478
+ ],
479
+ "devDependencies": [],
480
+ "registryDependencies": [],
481
+ "files": [
482
+ {
483
+ "name": "breadcrumb.tsx",
484
+ "content": '"use client";\n\nimport * as React from "react";\nimport { Slot } from "@radix-ui/react-slot";\nimport { ChevronRight, MoreHorizontal } from "lucide-react";\nimport { cn } from "@/lib/utils";\n\nconst Breadcrumb = React.forwardRef<\n HTMLElement,\n React.ComponentPropsWithoutRef<"nav"> & {\n separator?: React.ReactNode;\n }\n>(({ ...props }, ref) => <nav ref={ref} aria-label="breadcrumb" {...props} />);\nBreadcrumb.displayName = "Breadcrumb";\n\nconst BreadcrumbList = React.forwardRef<\n HTMLOListElement,\n React.ComponentPropsWithoutRef<"ol">\n>(({ className, ...props }, ref) => (\n <ol\n ref={ref}\n className={cn(\n "flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5",\n className\n )}\n {...props}\n />\n));\nBreadcrumbList.displayName = "BreadcrumbList";\n\nconst BreadcrumbItem = React.forwardRef<\n HTMLLIElement,\n React.ComponentPropsWithoutRef<"li">\n>(({ className, ...props }, ref) => (\n <li\n ref={ref}\n className={cn("inline-flex items-center gap-1.5", className)}\n {...props}\n />\n));\nBreadcrumbItem.displayName = "BreadcrumbItem";\n\nconst BreadcrumbLink = React.forwardRef<\n HTMLAnchorElement,\n React.ComponentPropsWithoutRef<"a"> & {\n asChild?: boolean;\n }\n>(({ asChild, className, ...props }, ref) => {\n const Comp = asChild ? Slot : "a";\n\n return (\n <Comp\n ref={ref}\n className={cn("transition-colors hover:text-foreground", className)}\n {...props}\n />\n );\n});\nBreadcrumbLink.displayName = "BreadcrumbLink";\n\nconst BreadcrumbPage = React.forwardRef<\n HTMLSpanElement,\n React.ComponentPropsWithoutRef<"span">\n>(({ className, ...props }, ref) => (\n <span\n ref={ref}\n role="link"\n aria-disabled="true"\n aria-current="page"\n className={cn("font-medium text-foreground", className)}\n {...props}\n />\n));\nBreadcrumbPage.displayName = "BreadcrumbPage";\n\nconst BreadcrumbSeparator = ({\n children,\n className,\n ...props\n}: React.ComponentProps<"li">) => (\n <li\n role="presentation"\n aria-hidden="true"\n className={cn("[&>svg]:w-3.5 [&>svg]:h-3.5 text-muted-foreground/60", className)}\n {...props}\n >\n {children ?? <ChevronRight />}\n </li>\n);\nBreadcrumbSeparator.displayName = "BreadcrumbSeparator";\n\nconst BreadcrumbEllipsis = ({\n className,\n ...props\n}: React.ComponentProps<"span">) => (\n <span\n role="presentation"\n aria-hidden="true"\n className={cn("flex h-9 w-9 items-center justify-center", className)}\n {...props}\n >\n <MoreHorizontal className="h-4 w-4" />\n <span className="sr-only">Daha fazla</span>\n </span>\n);\nBreadcrumbEllipsis.displayName = "BreadcrumbEllipsis";\n\nexport {\n Breadcrumb,\n BreadcrumbList,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbPage,\n BreadcrumbSeparator,\n BreadcrumbEllipsis,\n};\n'
485
+ }
486
+ ]
487
+ },
488
+ "button": {
489
+ "name": "button",
490
+ "type": "components:ui",
491
+ "category": "temel",
492
+ "description": "6 varyant, 4 boyut ve loading durumlu buton bile\u015Feni",
493
+ "dependencies": [
494
+ "@radix-ui/react-slot",
495
+ "class-variance-authority"
496
+ ],
497
+ "devDependencies": [],
498
+ "registryDependencies": [],
499
+ "files": [
500
+ {
501
+ "name": "button.tsx",
502
+ "content": '"use client";\n\nimport * as React from "react";\nimport { Slot } from "@radix-ui/react-slot";\nimport { cva, type VariantProps } from "class-variance-authority";\nimport { cn } from "@/lib/utils";\n\nconst buttonVariants = cva(\n // Temel stiller\n [\n "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium",\n "transition-colors duration-150",\n "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",\n "disabled:pointer-events-none disabled:opacity-50",\n "[&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",\n ],\n {\n variants: {\n variant: {\n default:\n "bg-primary text-primary-foreground hover:bg-primary/90 active:bg-primary/80",\n destructive:\n "bg-destructive text-destructive-foreground hover:bg-destructive/90 active:bg-destructive/80",\n outline:\n "border border-input bg-background hover:bg-accent hover:text-accent-foreground active:bg-accent/80",\n secondary:\n "bg-secondary text-secondary-foreground hover:bg-secondary/80 active:bg-secondary/70",\n ghost:\n "hover:bg-accent hover:text-accent-foreground active:bg-accent/80",\n link: "text-primary underline-offset-4 hover:underline",\n },\n size: {\n default: "h-9 px-4 py-2",\n sm: "h-8 rounded-md px-3 text-xs",\n lg: "h-11 rounded-md px-8 text-base",\n icon: "h-9 w-9",\n },\n },\n defaultVariants: {\n variant: "default",\n size: "default",\n },\n }\n);\n\nexport interface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {\n /** Radix Slot ile \xE7al\u0131\u015Farak \xE7ocuk bile\u015Feni button gibi davrand\u0131r\u0131r */\n asChild?: boolean;\n /** Y\xFCklenme durumu \u2014 spinner g\xF6sterir ve butonu devre d\u0131\u015F\u0131 b\u0131rak\u0131r */\n loading?: boolean;\n}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n (\n { className, variant, size, asChild = false, loading = false, children, disabled, ...props },\n ref\n ) => {\n const Comp = asChild ? Slot : "button";\n return (\n <Comp\n className={cn(buttonVariants({ variant, size, className }))}\n ref={ref}\n disabled={disabled || loading}\n aria-disabled={disabled || loading}\n {...props}\n >\n {loading ? (\n <>\n <span\n className="size-4 animate-spin rounded-full border-2 border-current border-t-transparent"\n aria-hidden="true"\n />\n <span className="sr-only">Y\xFCkleniyor...</span>\n {children}\n </>\n ) : (\n children\n )}\n </Comp>\n );\n }\n);\n\nButton.displayName = "Button";\n\nexport { Button, buttonVariants };\n'
503
+ }
504
+ ]
505
+ },
506
+ "calendar": {
507
+ "name": "calendar",
508
+ "type": "components:ui",
509
+ "category": "form",
510
+ "description": "Tarih ve tarih aral\u0131\u011F\u0131 se\xE7im takvimi",
511
+ "dependencies": [
512
+ "lucide-react",
513
+ "react-day-picker"
514
+ ],
515
+ "devDependencies": [],
516
+ "registryDependencies": [],
517
+ "files": [
518
+ {
519
+ "name": "calendar.tsx",
520
+ "content": '"use client";\n\nimport * as React from "react";\nimport { ChevronLeft, ChevronRight } from "lucide-react";\nimport { DayPicker, type DayPickerProps } from "react-day-picker";\nimport { cn } from "@/lib/utils";\n\nexport type CalendarProps = DayPickerProps;\n\nfunction Calendar({\n className,\n classNames,\n showOutsideDays = true,\n ...props\n}: CalendarProps) {\n return (\n <DayPicker\n showOutsideDays={showOutsideDays}\n // navLayout="around" \u2192 oklar MonthCaption i\xE7inde < Ay Y\u0131l > konumlan\u0131r\n navLayout="around"\n className={cn(\n "w-[308px] select-none rounded-xl border border-border bg-card p-4 shadow-sm",\n className\n )}\n classNames={{\n /* \u2500\u2500 Ay yap\u0131s\u0131 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n months: "flex flex-col gap-4",\n month: "relative flex flex-col gap-3",\n\n /* \u2500\u2500 Ba\u015Fl\u0131k: < August 2026 > \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n month_caption:\n "flex items-center justify-center h-9 px-9",\n caption_label:\n "text-sm font-semibold text-foreground tracking-tight",\n\n /* \u2500\u2500 \xD6nceki / Sonraki butonlar (around modda\n bunlar MonthCaption i\xE7inde absolute olarak\n zaten renderlan\u0131r, biz sadece stilini at\u0131yoruz) */\n button_previous: cn(\n "absolute left-1 top-1",\n "inline-flex items-center justify-center rounded-md",\n "h-7 w-7 shrink-0",\n "text-muted-foreground border border-border bg-transparent",\n "hover:bg-muted hover:text-foreground",\n "disabled:opacity-30 disabled:cursor-not-allowed",\n "transition-colors duration-150"\n ),\n button_next: cn(\n "absolute right-1 top-1",\n "inline-flex items-center justify-center rounded-md",\n "h-7 w-7 shrink-0",\n "text-muted-foreground border border-border bg-transparent",\n "hover:bg-muted hover:text-foreground",\n "disabled:opacity-30 disabled:cursor-not-allowed",\n "transition-colors duration-150"\n ),\n\n /* \u2500\u2500 Hafta g\xFCn\xFC ba\u015Fl\u0131klar\u0131 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n weekdays: "grid grid-cols-7",\n weekday:\n "h-8 flex items-center justify-center text-[11px] font-medium text-muted-foreground/60 uppercase tracking-wider",\n\n /* \u2500\u2500 Hafta sat\u0131rlar\u0131 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n weeks: "flex flex-col gap-0.5",\n week: "grid grid-cols-7",\n\n /* \u2500\u2500 G\xFCn h\xFCcresi (td) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n day: "flex items-center justify-center",\n\n /* \u2500\u2500 G\xFCn butonu (button) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n day_button: cn(\n "flex items-center justify-center",\n "h-8 w-8 rounded-md",\n "text-[13px] font-normal leading-none",\n "text-foreground bg-transparent",\n "hover:bg-muted",\n "transition-colors duration-100",\n "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1"\n ),\n\n /* \u2500\u2500 Se\xE7ili g\xFCn \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n selected: cn(\n "[&>button]:bg-primary [&>button]:text-primary-foreground",\n "[&>button]:hover:bg-primary/90",\n "[&>button]:font-medium"\n ),\n\n /* \u2500\u2500 Bug\xFCn \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n today: cn(\n "[&:not([data-selected])>[button]]:ring-1",\n "[&:not([data-selected])>[button]]:ring-primary/50",\n "[&:not([data-selected])>[button]]:font-semibold",\n "[&:not([data-selected])>[button]]:text-primary"\n ),\n\n /* \u2500\u2500 Ay d\u0131\u015F\u0131 g\xFCnler \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n outside: "opacity-25 pointer-events-none",\n\n /* \u2500\u2500 Range \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n range_start:\n "[&>button]:bg-primary [&>button]:text-primary-foreground [&>button]:rounded-r-none",\n range_middle:\n "bg-primary/10 [&>button]:rounded-none [&>button]:text-foreground",\n range_end:\n "[&>button]:bg-primary [&>button]:text-primary-foreground [&>button]:rounded-l-none",\n\n /* \u2500\u2500 Di\u011Fer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n disabled: "opacity-25 cursor-not-allowed pointer-events-none",\n hidden: "invisible",\n ...classNames,\n }}\n components={{\n Chevron: ({ orientation }) =>\n orientation === "left" ? (\n <ChevronLeft className="h-3.5 w-3.5" />\n ) : (\n <ChevronRight className="h-3.5 w-3.5" />\n ),\n }}\n {...props}\n />\n );\n}\nCalendar.displayName = "Calendar";\n\nexport { Calendar };\n'
521
+ }
522
+ ]
523
+ },
524
+ "card": {
525
+ "name": "card",
526
+ "type": "components:ui",
527
+ "category": "temel",
528
+ "description": "Header, Content ve Footer b\xF6l\xFCml\xFC kutu konteyner bile\u015Feni",
529
+ "dependencies": [],
530
+ "devDependencies": [],
531
+ "registryDependencies": [],
532
+ "files": [
533
+ {
534
+ "name": "card.tsx",
535
+ "content": '"use client";\n\nimport * as React from "react";\nimport { cn } from "@/lib/utils";\n\nconst Card = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n ({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n "rounded-lg border border-border bg-card text-card-foreground shadow-subtle",\n className\n )}\n {...props}\n />\n )\n);\nCard.displayName = "Card";\n\nconst CardHeader = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n ({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn("flex flex-col space-y-1.5 p-6", className)}\n {...props}\n />\n )\n);\nCardHeader.displayName = "CardHeader";\n\nconst CardTitle = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLHeadingElement>\n>(({ className, ...props }, ref) => (\n <h3\n ref={ref}\n className={cn("text-lg font-semibold leading-none tracking-tight text-foreground", className)}\n {...props}\n />\n));\nCardTitle.displayName = "CardTitle";\n\nconst CardDescription = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => (\n <p\n ref={ref}\n className={cn("text-sm text-muted-foreground", className)}\n {...props}\n />\n));\nCardDescription.displayName = "CardDescription";\n\nconst CardContent = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n ({ className, ...props }, ref) => (\n <div ref={ref} className={cn("p-6 pt-0", className)} {...props} />\n )\n);\nCardContent.displayName = "CardContent";\n\nconst CardFooter = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n ({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn("flex items-center p-6 pt-0", className)}\n {...props}\n />\n )\n);\nCardFooter.displayName = "CardFooter";\n\nexport { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent };\n'
536
+ }
537
+ ]
538
+ },
539
+ "checkbox": {
540
+ "name": "checkbox",
541
+ "type": "components:ui",
542
+ "category": "form",
543
+ "description": "WAI-ARIA uyumlu onay kutusu",
544
+ "dependencies": [
545
+ "@radix-ui/react-checkbox",
546
+ "lucide-react"
547
+ ],
548
+ "devDependencies": [],
549
+ "registryDependencies": [],
550
+ "files": [
551
+ {
552
+ "name": "checkbox.tsx",
553
+ "content": '"use client";\n\nimport * as React from "react";\nimport * as CheckboxPrimitive from "@radix-ui/react-checkbox";\nimport { Check, Minus } from "lucide-react";\nimport { cn } from "@/lib/utils";\n\nconst Checkbox = React.forwardRef<\n React.ElementRef<typeof CheckboxPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>\n>(({ className, ...props }, ref) => (\n <CheckboxPrimitive.Root\n ref={ref}\n className={cn(\n "peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background",\n "transition-colors duration-150",\n "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",\n "disabled:cursor-not-allowed disabled:opacity-50",\n "data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",\n "data-[state=indeterminate]:bg-primary data-[state=indeterminate]:text-primary-foreground",\n className\n )}\n {...props}\n >\n <CheckboxPrimitive.Indicator\n className={cn("flex items-center justify-center text-current")}\n >\n {props.checked === "indeterminate" ? (\n <Minus className="h-3 w-3" />\n ) : (\n <Check className="h-3 w-3" />\n )}\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n));\nCheckbox.displayName = CheckboxPrimitive.Root.displayName;\n\nexport { Checkbox };\n'
554
+ }
555
+ ]
556
+ },
557
+ "collapsible": {
558
+ "name": "collapsible",
559
+ "type": "components:ui",
560
+ "category": "navigation",
561
+ "description": "A\xE7\u0131l\u0131r/kapan\u0131r i\xE7erik paneli",
562
+ "dependencies": [
563
+ "@radix-ui/react-collapsible"
564
+ ],
565
+ "devDependencies": [],
566
+ "registryDependencies": [],
567
+ "files": [
568
+ {
569
+ "name": "collapsible.tsx",
570
+ "content": '"use client";\n\nimport * as CollapsiblePrimitive from "@radix-ui/react-collapsible";\n\nconst Collapsible = CollapsiblePrimitive.Root;\nconst CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger;\nconst CollapsibleContent = CollapsiblePrimitive.CollapsibleContent;\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent };\n'
571
+ }
572
+ ]
573
+ },
574
+ "command": {
575
+ "name": "command",
576
+ "type": "components:ui",
577
+ "category": "overlay",
578
+ "description": "\u2318K h\u0131zl\u0131 komut ve arama paleti",
579
+ "dependencies": [
580
+ "@radix-ui/react-dialog",
581
+ "lucide-react",
582
+ "cmdk"
583
+ ],
584
+ "devDependencies": [],
585
+ "registryDependencies": [],
586
+ "files": [
587
+ {
588
+ "name": "command.tsx",
589
+ "content": '"use client";\n\nimport * as React from "react";\nimport { type DialogProps } from "@radix-ui/react-dialog";\nimport { Command as CommandPrimitive } from "cmdk";\nimport { Search } from "lucide-react";\n\nimport { cn } from "@/lib/utils";\nimport { Dialog, DialogContent } from "@/components/ui/dialog";\n\nconst Command = React.forwardRef<\n React.ElementRef<typeof CommandPrimitive>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive>\n>(({ className, ...props }, ref) => (\n <CommandPrimitive\n ref={ref}\n className={cn(\n "flex h-full w-full flex-col overflow-hidden rounded-lg bg-background text-foreground",\n className\n )}\n {...props}\n />\n));\nCommand.displayName = CommandPrimitive.displayName;\n\ninterface CommandDialogProps extends DialogProps {}\n\nconst CommandDialog = ({ children, ...props }: CommandDialogProps) => {\n return (\n <Dialog {...props}>\n <DialogContent className="overflow-hidden p-0 shadow-overlay sm:max-w-xl">\n <Command className="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-semibold [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-4 [&_[cmdk-input-wrapper]_svg]:w-4 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-3 [&_[cmdk-item]]:py-2 text-sm">\n {children}\n </Command>\n </DialogContent>\n </Dialog>\n );\n};\n\nconst CommandInput = React.forwardRef<\n React.ElementRef<typeof CommandPrimitive.Input>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>\n>(({ className, ...props }, ref) => (\n <div className="flex items-center border-b border-border px-3" cmdk-input-wrapper="">\n <Search className="mr-2 h-4 w-4 shrink-0 opacity-50" />\n <CommandPrimitive.Input\n ref={ref}\n className={cn(\n "flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",\n className\n )}\n {...props}\n />\n </div>\n));\nCommandInput.displayName = CommandPrimitive.Input.displayName;\n\nconst CommandList = React.forwardRef<\n React.ElementRef<typeof CommandPrimitive.List>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>\n>(({ className, ...props }, ref) => (\n <CommandPrimitive.List\n ref={ref}\n className={cn("max-h-[300px] overflow-y-auto overflow-x-hidden p-1", className)}\n {...props}\n />\n));\nCommandList.displayName = CommandPrimitive.List.displayName;\n\nconst CommandEmpty = React.forwardRef<\n React.ElementRef<typeof CommandPrimitive.Empty>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>\n>((props, ref) => (\n <CommandPrimitive.Empty\n ref={ref}\n className="py-6 text-center text-sm text-muted-foreground"\n {...props}\n />\n));\nCommandEmpty.displayName = CommandPrimitive.Empty.displayName;\n\nconst CommandGroup = React.forwardRef<\n React.ElementRef<typeof CommandPrimitive.Group>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive.Group>\n>(({ className, ...props }, ref) => (\n <CommandPrimitive.Group\n ref={ref}\n className={cn(\n "overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-semibold [&_[cmdk-group-heading]]:text-muted-foreground",\n className\n )}\n {...props}\n />\n));\nCommandGroup.displayName = CommandPrimitive.Group.displayName;\n\nconst CommandSeparator = React.forwardRef<\n React.ElementRef<typeof CommandPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <CommandPrimitive.Separator\n ref={ref}\n className={cn("-mx-1 h-px bg-border", className)}\n {...props}\n />\n));\nCommandSeparator.displayName = CommandPrimitive.Separator.displayName;\n\nconst CommandItem = React.forwardRef<\n React.ElementRef<typeof CommandPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>\n>(({ className, ...props }, ref) => (\n <CommandPrimitive.Item\n ref={ref}\n className={cn(\n "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none aria-selected:bg-accent aria-selected:text-accent-foreground data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 transition-colors",\n className\n )}\n {...props}\n />\n));\nCommandItem.displayName = CommandPrimitive.Item.displayName;\n\nconst CommandShortcut = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLSpanElement>) => {\n return (\n <span\n className={cn(\n "ml-auto text-xs tracking-widest text-muted-foreground font-mono",\n className\n )}\n {...props}\n />\n );\n};\nCommandShortcut.displayName = "CommandShortcut";\n\nexport {\n Command,\n CommandDialog,\n CommandInput,\n CommandList,\n CommandEmpty,\n CommandGroup,\n CommandItem,\n CommandShortcut,\n CommandSeparator,\n};\n'
590
+ }
591
+ ]
592
+ },
593
+ "context-menu": {
594
+ "name": "context-menu",
595
+ "type": "components:ui",
596
+ "category": "overlay",
597
+ "description": "Sa\u011F t\u0131k ba\u011Flam men\xFCs\xFC",
598
+ "dependencies": [
599
+ "@radix-ui/react-context-menu",
600
+ "lucide-react"
601
+ ],
602
+ "devDependencies": [],
603
+ "registryDependencies": [],
604
+ "files": [
605
+ {
606
+ "name": "context-menu.tsx",
607
+ "content": '"use client";\n\nimport * as React from "react";\nimport * as ContextMenuPrimitive from "@radix-ui/react-context-menu";\nimport { Check, ChevronRight, Circle } from "lucide-react";\nimport { cn } from "@/lib/utils";\n\nconst ContextMenu = ContextMenuPrimitive.Root;\nconst ContextMenuTrigger = ContextMenuPrimitive.Trigger;\nconst ContextMenuGroup = ContextMenuPrimitive.Group;\nconst ContextMenuPortal = ContextMenuPrimitive.Portal;\nconst ContextMenuSub = ContextMenuPrimitive.Sub;\nconst ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup;\n\nconst ContextMenuSubTrigger = React.forwardRef<\n React.ElementRef<typeof ContextMenuPrimitive.SubTrigger>,\n React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.SubTrigger> & {\n inset?: boolean;\n }\n>(({ className, inset, children, ...props }, ref) => (\n <ContextMenuPrimitive.SubTrigger\n ref={ref}\n className={cn(\n "flex cursor-default select-none items-center rounded-xs px-2 py-1.5 text-sm outline-hidden focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",\n inset && "pl-8",\n className\n )}\n {...props}\n >\n {children}\n <ChevronRight className="ml-auto h-4 w-4" />\n </ContextMenuPrimitive.SubTrigger>\n));\nContextMenuSubTrigger.displayName = ContextMenuPrimitive.SubTrigger.displayName;\n\nconst ContextMenuSubContent = React.forwardRef<\n React.ElementRef<typeof ContextMenuPrimitive.SubContent>,\n React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.SubContent>\n>(({ className, ...props }, ref) => (\n <ContextMenuPrimitive.SubContent\n ref={ref}\n className={cn(\n "z-50 min-w-[8rem] overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",\n className\n )}\n {...props}\n />\n));\nContextMenuSubContent.displayName =\n ContextMenuPrimitive.SubContent.displayName;\n\nconst ContextMenuContent = React.forwardRef<\n React.ElementRef<typeof ContextMenuPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Content>\n>(({ className, ...props }, ref) => (\n <ContextMenuPrimitive.Portal>\n <ContextMenuPrimitive.Content\n ref={ref}\n className={cn(\n "z-50 min-w-[8rem] overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md animate-in fade-in-80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",\n className\n )}\n {...props}\n />\n </ContextMenuPrimitive.Portal>\n));\nContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName;\n\nconst ContextMenuItem = React.forwardRef<\n React.ElementRef<typeof ContextMenuPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Item> & {\n inset?: boolean;\n }\n>(({ className, inset, ...props }, ref) => (\n <ContextMenuPrimitive.Item\n ref={ref}\n className={cn(\n "relative flex cursor-default select-none items-center rounded-xs px-2 py-1.5 text-sm outline-hidden focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",\n inset && "pl-8",\n className\n )}\n {...props}\n />\n));\nContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName;\n\nconst ContextMenuCheckboxItem = React.forwardRef<\n React.ElementRef<typeof ContextMenuPrimitive.CheckboxItem>,\n React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.CheckboxItem>\n>(({ className, children, checked, ...props }, ref) => (\n <ContextMenuPrimitive.CheckboxItem\n ref={ref}\n className={cn(\n "relative flex cursor-default select-none items-center rounded-xs py-1.5 pl-8 pr-2 text-sm outline-hidden focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",\n className\n )}\n checked={checked}\n {...props}\n >\n <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">\n <ContextMenuPrimitive.ItemIndicator>\n <Check className="h-4 w-4" />\n </ContextMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </ContextMenuPrimitive.CheckboxItem>\n));\nContextMenuCheckboxItem.displayName =\n ContextMenuPrimitive.CheckboxItem.displayName;\n\nconst ContextMenuRadioItem = React.forwardRef<\n React.ElementRef<typeof ContextMenuPrimitive.RadioItem>,\n React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.RadioItem>\n>(({ className, children, ...props }, ref) => (\n <ContextMenuPrimitive.RadioItem\n ref={ref}\n className={cn(\n "relative flex cursor-default select-none items-center rounded-xs py-1.5 pl-8 pr-2 text-sm outline-hidden focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",\n className\n )}\n {...props}\n >\n <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">\n <ContextMenuPrimitive.ItemIndicator>\n <Circle className="h-2 w-2 fill-current" />\n </ContextMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </ContextMenuPrimitive.RadioItem>\n));\nContextMenuRadioItem.displayName = ContextMenuPrimitive.RadioItem.displayName;\n\nconst ContextMenuLabel = React.forwardRef<\n React.ElementRef<typeof ContextMenuPrimitive.Label>,\n React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Label> & {\n inset?: boolean;\n }\n>(({ className, inset, ...props }, ref) => (\n <ContextMenuPrimitive.Label\n ref={ref}\n className={cn(\n "px-2 py-1.5 text-xs font-semibold text-muted-foreground",\n inset && "pl-8",\n className\n )}\n {...props}\n />\n));\nContextMenuLabel.displayName = ContextMenuPrimitive.Label.displayName;\n\nconst ContextMenuSeparator = React.forwardRef<\n React.ElementRef<typeof ContextMenuPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <ContextMenuPrimitive.Separator\n ref={ref}\n className={cn("-mx-1 my-1 h-px bg-border", className)}\n {...props}\n />\n));\nContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName;\n\nconst ContextMenuShortcut = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLSpanElement>) => {\n return (\n <span\n className={cn(\n "ml-auto text-xs tracking-widest text-muted-foreground",\n className\n )}\n {...props}\n />\n );\n};\nContextMenuShortcut.displayName = "ContextMenuShortcut";\n\nexport {\n ContextMenu,\n ContextMenuTrigger,\n ContextMenuContent,\n ContextMenuItem,\n ContextMenuCheckboxItem,\n ContextMenuRadioItem,\n ContextMenuLabel,\n ContextMenuSeparator,\n ContextMenuShortcut,\n ContextMenuGroup,\n ContextMenuPortal,\n ContextMenuSub,\n ContextMenuSubContent,\n ContextMenuSubTrigger,\n ContextMenuRadioGroup,\n};\n'
608
+ }
609
+ ]
610
+ },
611
+ "dialog": {
612
+ "name": "dialog",
613
+ "type": "components:ui",
614
+ "category": "overlay",
615
+ "description": "Eri\u015Filebilir modal diyalog penceresi",
616
+ "dependencies": [
617
+ "@radix-ui/react-dialog",
618
+ "lucide-react"
619
+ ],
620
+ "devDependencies": [],
621
+ "registryDependencies": [],
622
+ "files": [
623
+ {
624
+ "name": "dialog.tsx",
625
+ "content": '"use client";\n\nimport * as React from "react";\nimport * as DialogPrimitive from "@radix-ui/react-dialog";\nimport { X } from "lucide-react";\nimport { cn } from "@/lib/utils";\n\nconst Dialog = DialogPrimitive.Root;\nconst DialogTrigger = DialogPrimitive.Trigger;\nconst DialogPortal = DialogPrimitive.Portal;\nconst DialogClose = DialogPrimitive.Close;\n\nconst DialogOverlay = React.forwardRef<\n React.ElementRef<typeof DialogPrimitive.Overlay>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Overlay\n ref={ref}\n className={cn(\n "fixed inset-0 z-50 bg-black/50 backdrop-blur-sm",\n "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",\n className\n )}\n {...props}\n />\n));\nDialogOverlay.displayName = DialogPrimitive.Overlay.displayName;\n\nconst DialogContent = React.forwardRef<\n React.ElementRef<typeof DialogPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>\n>(({ className, children, ...props }, ref) => (\n <DialogPortal>\n <DialogOverlay />\n <DialogPrimitive.Content\n ref={ref}\n className={cn(\n "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4",\n "border border-border bg-background p-6 shadow-overlay duration-200 sm:rounded-lg",\n "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]",\n className\n )}\n {...props}\n >\n {children}\n <DialogPrimitive.Close\n className={cn(\n "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background",\n "transition-opacity hover:opacity-100",\n "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",\n "disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground"\n )}\n >\n <X className="h-4 w-4" />\n <span className="sr-only">Kapat</span>\n </DialogPrimitive.Close>\n </DialogPrimitive.Content>\n </DialogPortal>\n));\nDialogContent.displayName = DialogPrimitive.Content.displayName;\n\nconst DialogHeader = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn("flex flex-col space-y-1.5 text-center sm:text-left", className)}\n {...props}\n />\n);\nDialogHeader.displayName = "DialogHeader";\n\nconst DialogFooter = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className)}\n {...props}\n />\n);\nDialogFooter.displayName = "DialogFooter";\n\nconst DialogTitle = React.forwardRef<\n React.ElementRef<typeof DialogPrimitive.Title>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Title\n ref={ref}\n className={cn("text-lg font-semibold leading-none tracking-tight", className)}\n {...props}\n />\n));\nDialogTitle.displayName = DialogPrimitive.Title.displayName;\n\nconst DialogDescription = React.forwardRef<\n React.ElementRef<typeof DialogPrimitive.Description>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Description\n ref={ref}\n className={cn("text-sm text-muted-foreground", className)}\n {...props}\n />\n));\nDialogDescription.displayName = DialogPrimitive.Description.displayName;\n\nexport {\n Dialog,\n DialogPortal,\n DialogOverlay,\n DialogClose,\n DialogTrigger,\n DialogContent,\n DialogHeader,\n DialogFooter,\n DialogTitle,\n DialogDescription,\n};\n'
626
+ }
627
+ ]
628
+ },
629
+ "dropdown-menu": {
630
+ "name": "dropdown-menu",
631
+ "type": "components:ui",
632
+ "category": "overlay",
633
+ "description": "A\xE7\u0131l\u0131r eylem ve profil se\xE7enekleri men\xFCs\xFC",
634
+ "dependencies": [
635
+ "@radix-ui/react-dropdown-menu",
636
+ "lucide-react"
637
+ ],
638
+ "devDependencies": [],
639
+ "registryDependencies": [],
640
+ "files": [
641
+ {
642
+ "name": "dropdown-menu.tsx",
643
+ "content": '"use client";\n\nimport * as React from "react";\nimport * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";\nimport { Check, ChevronRight, Circle } from "lucide-react";\nimport { cn } from "@/lib/utils";\n\nconst DropdownMenu = DropdownMenuPrimitive.Root;\nconst DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;\nconst DropdownMenuGroup = DropdownMenuPrimitive.Group;\nconst DropdownMenuPortal = DropdownMenuPrimitive.Portal;\nconst DropdownMenuSub = DropdownMenuPrimitive.Sub;\nconst DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;\n\nconst DropdownMenuSubTrigger = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {\n inset?: boolean;\n }\n>(({ className, inset, children, ...props }, ref) => (\n <DropdownMenuPrimitive.SubTrigger\n ref={ref}\n className={cn(\n "flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none",\n "transition-colors duration-100",\n "focus:bg-accent data-[state=open]:bg-accent",\n inset && "pl-8",\n className\n )}\n {...props}\n >\n {children}\n <ChevronRight className="ml-auto h-4 w-4" />\n </DropdownMenuPrimitive.SubTrigger>\n));\nDropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;\n\nconst DropdownMenuSubContent = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>\n>(({ className, ...props }, ref) => (\n <DropdownMenuPrimitive.SubContent\n ref={ref}\n className={cn(\n "z-50 min-w-[8rem] overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-overlay",\n "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",\n "data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",\n className\n )}\n {...props}\n />\n));\nDropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;\n\nconst DropdownMenuContent = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>\n>(({ className, sideOffset = 4, ...props }, ref) => (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n className={cn(\n "z-50 min-w-[8rem] overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-overlay",\n "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",\n "data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2",\n "data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",\n className\n )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n));\nDropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;\n\nconst DropdownMenuItem = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean;\n }\n>(({ className, inset, ...props }, ref) => (\n <DropdownMenuPrimitive.Item\n ref={ref}\n className={cn(\n "relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none",\n "transition-colors duration-100",\n "focus:bg-accent focus:text-accent-foreground",\n "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",\n "[&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",\n inset && "pl-8",\n className\n )}\n {...props}\n />\n));\nDropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;\n\nconst DropdownMenuCheckboxItem = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>\n>(({ className, children, checked, ...props }, ref) => (\n <DropdownMenuPrimitive.CheckboxItem\n ref={ref}\n className={cn(\n "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none",\n "transition-colors duration-100",\n "focus:bg-accent focus:text-accent-foreground",\n "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",\n className\n )}\n checked={checked}\n {...props}\n >\n <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">\n <DropdownMenuPrimitive.ItemIndicator>\n <Check className="h-4 w-4" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n));\nDropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;\n\nconst DropdownMenuRadioItem = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>\n>(({ className, children, ...props }, ref) => (\n <DropdownMenuPrimitive.RadioItem\n ref={ref}\n className={cn(\n "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none",\n "transition-colors duration-100",\n "focus:bg-accent focus:text-accent-foreground",\n "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",\n className\n )}\n {...props}\n >\n <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">\n <DropdownMenuPrimitive.ItemIndicator>\n <Circle className="h-2 w-2 fill-current" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n));\nDropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;\n\nconst DropdownMenuLabel = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Label>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean;\n }\n>(({ className, inset, ...props }, ref) => (\n <DropdownMenuPrimitive.Label\n ref={ref}\n className={cn(\n "px-2 py-1.5 text-xs font-semibold text-muted-foreground",\n inset && "pl-8",\n className\n )}\n {...props}\n />\n));\nDropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;\n\nconst DropdownMenuSeparator = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <DropdownMenuPrimitive.Separator\n ref={ref}\n className={cn("-mx-1 my-1 h-px bg-border", className)}\n {...props}\n />\n));\nDropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;\n\nconst DropdownMenuShortcut = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLSpanElement>) => {\n return (\n <span\n className={cn("ml-auto text-xs tracking-widest opacity-60", className)}\n {...props}\n />\n );\n};\nDropdownMenuShortcut.displayName = "DropdownMenuShortcut";\n\nexport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuRadioItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuGroup,\n DropdownMenuPortal,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuRadioGroup,\n};\n'
644
+ }
645
+ ]
646
+ },
647
+ "empty-state": {
648
+ "name": "empty-state",
649
+ "type": "components:ui",
650
+ "category": "temel",
651
+ "description": "\u0130kon, ba\u015Fl\u0131k, a\xE7\u0131klama ve aksiyon butonlu bo\u015F durum g\xF6stergesi",
652
+ "dependencies": [],
653
+ "devDependencies": [],
654
+ "registryDependencies": [],
655
+ "files": [
656
+ {
657
+ "name": "empty-state.tsx",
658
+ "content": '"use client";\n\nimport * as React from "react";\nimport { cn } from "@/lib/utils";\n\nconst EmptyState = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n "flex min-h-[260px] w-full flex-col items-center justify-center rounded-2xl border border-dashed border-border/80 p-8 text-center bg-card/40",\n className\n )}\n {...props}\n />\n));\nEmptyState.displayName = "EmptyState";\n\nconst EmptyStateIcon = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n "flex h-12 w-12 items-center justify-center rounded-xl bg-muted text-muted-foreground mb-4 border border-border/60 [&_svg]:h-6 [&_svg]:w-6",\n className\n )}\n {...props}\n />\n));\nEmptyStateIcon.displayName = "EmptyStateIcon";\n\nconst EmptyStateTitle = React.forwardRef<\n HTMLHeadingElement,\n React.HTMLAttributes<HTMLHeadingElement>\n>(({ className, ...props }, ref) => (\n <h3\n ref={ref}\n className={cn("text-sm font-semibold tracking-tight text-foreground", className)}\n {...props}\n />\n));\nEmptyStateTitle.displayName = "EmptyStateTitle";\n\nconst EmptyStateDescription = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => (\n <p\n ref={ref}\n className={cn("text-xs text-muted-foreground mt-1.5 max-w-sm leading-relaxed", className)}\n {...props}\n />\n));\nEmptyStateDescription.displayName = "EmptyStateDescription";\n\nconst EmptyStateActions = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn("flex items-center justify-center gap-2.5 mt-6 flex-wrap", className)}\n {...props}\n />\n));\nEmptyStateActions.displayName = "EmptyStateActions";\n\nexport {\n EmptyState,\n EmptyStateIcon,\n EmptyStateTitle,\n EmptyStateDescription,\n EmptyStateActions,\n};\n'
659
+ }
660
+ ]
661
+ },
662
+ "hover-card": {
663
+ "name": "hover-card",
664
+ "type": "components:ui",
665
+ "category": "overlay",
666
+ "description": "\xDCzerine gelindi\u011Finde zengin \xF6nizleme kart\u0131",
667
+ "dependencies": [
668
+ "@radix-ui/react-hover-card"
669
+ ],
670
+ "devDependencies": [],
671
+ "registryDependencies": [],
672
+ "files": [
673
+ {
674
+ "name": "hover-card.tsx",
675
+ "content": '"use client";\n\nimport * as React from "react";\nimport * as HoverCardPrimitive from "@radix-ui/react-hover-card";\nimport { cn } from "@/lib/utils";\n\nconst HoverCard = HoverCardPrimitive.Root;\nconst HoverCardTrigger = HoverCardPrimitive.Trigger;\n\nconst HoverCardContent = React.forwardRef<\n React.ElementRef<typeof HoverCardPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof HoverCardPrimitive.Content>\n>(({ className, align = "center", sideOffset = 4, ...props }, ref) => (\n <HoverCardPrimitive.Content\n ref={ref}\n align={align}\n sideOffset={sideOffset}\n className={cn(\n "z-50 w-64 rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-md outline-hidden data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",\n className\n )}\n {...props}\n />\n));\nHoverCardContent.displayName = HoverCardPrimitive.Content.displayName;\n\nexport { HoverCard, HoverCardTrigger, HoverCardContent };\n'
676
+ }
677
+ ]
678
+ },
679
+ "input": {
680
+ "name": "input",
681
+ "type": "components:ui",
682
+ "category": "form",
683
+ "description": "Metin ve form veri giri\u015F alan\u0131",
684
+ "dependencies": [],
685
+ "devDependencies": [],
686
+ "registryDependencies": [],
687
+ "files": [
688
+ {
689
+ "name": "input.tsx",
690
+ "content": '"use client";\n\nimport * as React from "react";\nimport { cn } from "@/lib/utils";\n\nexport interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {\n /** Sol taraf ikon veya element */\n leftIcon?: React.ReactNode;\n /** Sa\u011F taraf ikon veya element */\n rightIcon?: React.ReactNode;\n /** Hata mesaj\u0131 */\n error?: string;\n /** Label metni */\n label?: string;\n /** Yard\u0131mc\u0131 metin */\n hint?: string;\n}\n\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(\n ({ className, type, leftIcon, rightIcon, error, label, hint, id, ...props }, ref) => {\n const generatedId = React.useId();\n const inputId = id ?? generatedId;\n\n return (\n <div className="w-full space-y-1.5">\n {label && (\n <label\n htmlFor={inputId}\n className="text-sm font-medium leading-none text-foreground"\n >\n {label}\n </label>\n )}\n <div className="relative flex items-center">\n {leftIcon && (\n <div className="absolute left-3 z-10 pointer-events-none flex items-center justify-center text-muted-foreground [&_svg]:h-4 [&_svg]:w-4 shrink-0">\n {leftIcon}\n </div>\n )}\n <input\n id={inputId}\n type={type}\n ref={ref}\n aria-invalid={!!error}\n aria-describedby={\n error ? `${inputId}-error` : hint ? `${inputId}-hint` : undefined\n }\n className={cn(\n "flex h-9 w-full rounded-md border border-input bg-background px-3 py-1 text-sm",\n "text-foreground placeholder:text-muted-foreground",\n "transition-colors duration-150",\n "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",\n "disabled:cursor-not-allowed disabled:opacity-50",\n leftIcon && "!pl-9",\n rightIcon && "!pr-9",\n error && "border-destructive focus-visible:ring-destructive",\n className\n )}\n {...props}\n />\n {rightIcon && (\n <div className="absolute right-3 z-10 flex items-center justify-center text-muted-foreground [&_svg]:h-4 [&_svg]:w-4 shrink-0">\n {rightIcon}\n </div>\n )}\n </div>\n {error && (\n <p id={`${inputId}-error`} className="text-xs text-destructive" role="alert">\n {error}\n </p>\n )}\n {hint && !error && (\n <p id={`${inputId}-hint`} className="text-xs text-muted-foreground">\n {hint}\n </p>\n )}\n </div>\n );\n }\n);\n\nInput.displayName = "Input";\n\nexport { Input };\n'
691
+ }
692
+ ]
693
+ },
694
+ "input-group": {
695
+ "name": "input-group",
696
+ "type": "components:ui",
697
+ "category": "form",
698
+ "description": "\u0130kon ve eklenti destekli form girdi grubu",
699
+ "dependencies": [],
700
+ "devDependencies": [],
701
+ "registryDependencies": [],
702
+ "files": [
703
+ {
704
+ "name": "input-group.tsx",
705
+ "content": '"use client";\n\nimport * as React from "react";\nimport { cn } from "@/lib/utils";\n\nconst InputGroup = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n "relative flex items-center w-full rounded-lg border border-input bg-background focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2 transition-all overflow-hidden",\n className\n )}\n {...props}\n />\n));\nInputGroup.displayName = "InputGroup";\n\ninterface InputAddonProps extends React.HTMLAttributes<HTMLDivElement> {\n position?: "left" | "right";\n}\n\nconst InputAddon = React.forwardRef<HTMLDivElement, InputAddonProps>(\n ({ className, position = "left", ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n "flex items-center justify-center bg-muted/60 px-3 text-xs text-muted-foreground select-none shrink-0 border-border font-medium h-9",\n position === "left" ? "border-r" : "border-l",\n className\n )}\n {...props}\n />\n )\n);\nInputAddon.displayName = "InputAddon";\n\nexport { InputGroup, InputAddon };\n'
706
+ }
707
+ ]
708
+ },
709
+ "input-otp": {
710
+ "name": "input-otp",
711
+ "type": "components:ui",
712
+ "category": "form",
713
+ "description": "2FA ve SMS do\u011Frulama i\xE7in b\xF6l\xFCmlenmi\u015F PIN/OTP giri\u015F bile\u015Feni",
714
+ "dependencies": [],
715
+ "devDependencies": [],
716
+ "registryDependencies": [],
717
+ "files": [
718
+ {
719
+ "name": "input-otp.tsx",
720
+ "content": '"use client";\n\nimport * as React from "react";\nimport { cn } from "@/lib/utils";\n\ninterface InputOTPContextValue {\n value: string;\n maxLength: number;\n focusedIndex: number | null;\n setFocusedIndex: (index: number | null) => void;\n disabled?: boolean;\n onSlotInput: (index: number, char: string) => void;\n onSlotKeyDown: (index: number, e: React.KeyboardEvent<HTMLInputElement>) => void;\n onSlotPaste: (e: React.ClipboardEvent<HTMLInputElement>) => void;\n inputRefs: React.MutableRefObject<(HTMLInputElement | null)[]>;\n}\n\nconst InputOTPContext = React.createContext<InputOTPContextValue | null>(null);\n\nfunction useInputOTP() {\n const context = React.useContext(InputOTPContext);\n if (!context) {\n throw new Error("useInputOTP must be used within an InputOTP provider");\n }\n return context;\n}\n\nexport interface InputOTPProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, "onChange"> {\n value?: string;\n defaultValue?: string;\n onChange?: (value: string) => void;\n onComplete?: (value: string) => void;\n maxLength?: number;\n disabled?: boolean;\n autoFocus?: boolean;\n}\n\nconst InputOTP = React.forwardRef<HTMLDivElement, InputOTPProps>(\n (\n {\n className,\n value: controlledValue,\n defaultValue = "",\n onChange,\n onComplete,\n maxLength = 6,\n disabled = false,\n autoFocus = false,\n children,\n ...props\n },\n ref\n ) => {\n const isControlled = controlledValue !== undefined;\n const [uncontrolledValue, setUncontrolledValue] = React.useState(defaultValue);\n const value = isControlled ? controlledValue : uncontrolledValue;\n\n const [focusedIndex, setFocusedIndex] = React.useState<number | null>(null);\n const inputRefs = React.useRef<(HTMLInputElement | null)[]>([]);\n\n const updateValue = React.useCallback(\n (nextValue: string) => {\n const sliced = nextValue.slice(0, maxLength);\n if (!isControlled) {\n setUncontrolledValue(sliced);\n }\n onChange?.(sliced);\n if (sliced.length === maxLength) {\n onComplete?.(sliced);\n }\n },\n [isControlled, maxLength, onChange, onComplete]\n );\n\n const onSlotInput = React.useCallback(\n (index: number, char: string) => {\n if (disabled) return;\n const chars = value.split("");\n chars[index] = char;\n const nextValue = chars.join("");\n updateValue(nextValue);\n\n // Move to next slot\n if (index < maxLength - 1) {\n inputRefs.current[index + 1]?.focus();\n }\n },\n [disabled, maxLength, updateValue, value]\n );\n\n const onSlotKeyDown = React.useCallback(\n (index: number, e: React.KeyboardEvent<HTMLInputElement>) => {\n if (disabled) return;\n\n if (e.key === "Backspace") {\n e.preventDefault();\n const chars = value.split("");\n if (chars[index]) {\n chars[index] = "";\n updateValue(chars.join(""));\n } else if (index > 0) {\n chars[index - 1] = "";\n updateValue(chars.join(""));\n inputRefs.current[index - 1]?.focus();\n }\n } else if (e.key === "ArrowLeft") {\n e.preventDefault();\n if (index > 0) {\n inputRefs.current[index - 1]?.focus();\n }\n } else if (e.key === "ArrowRight") {\n e.preventDefault();\n if (index < maxLength - 1) {\n inputRefs.current[index + 1]?.focus();\n }\n } else if (e.key === "Delete") {\n e.preventDefault();\n const chars = value.split("");\n chars[index] = "";\n updateValue(chars.join(""));\n }\n },\n [disabled, maxLength, updateValue, value]\n );\n\n const onSlotPaste = React.useCallback(\n (e: React.ClipboardEvent<HTMLInputElement>) => {\n e.preventDefault();\n if (disabled) return;\n const pastedData = e.clipboardData.getData("text/plain").trim();\n if (!pastedData) return;\n updateValue(pastedData);\n const nextFocusIndex = Math.min(pastedData.length, maxLength - 1);\n inputRefs.current[nextFocusIndex]?.focus();\n },\n [disabled, maxLength, updateValue]\n );\n\n React.useEffect(() => {\n if (autoFocus && inputRefs.current[0]) {\n inputRefs.current[0].focus();\n }\n }, [autoFocus]);\n\n return (\n <InputOTPContext.Provider\n value={{\n value,\n maxLength,\n focusedIndex,\n setFocusedIndex,\n disabled,\n onSlotInput,\n onSlotKeyDown,\n onSlotPaste,\n inputRefs,\n }}\n >\n <div\n ref={ref}\n className={cn("flex items-center gap-2 has-[:disabled]:opacity-50", className)}\n {...props}\n >\n {children}\n </div>\n </InputOTPContext.Provider>\n );\n }\n);\nInputOTP.displayName = "InputOTP";\n\nconst InputOTPGroup = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div ref={ref} className={cn("flex items-center", className)} {...props} />\n));\nInputOTPGroup.displayName = "InputOTPGroup";\n\nexport interface InputOTPSlotProps\n extends React.HTMLAttributes<HTMLDivElement> {\n index: number;\n}\n\nconst InputOTPSlot = React.forwardRef<HTMLDivElement, InputOTPSlotProps>(\n ({ index, className, ...props }, ref) => {\n const {\n value,\n focusedIndex,\n setFocusedIndex,\n disabled,\n onSlotInput,\n onSlotKeyDown,\n onSlotPaste,\n inputRefs,\n } = useInputOTP();\n\n const char = value[index] || "";\n const isFocused = focusedIndex === index;\n\n return (\n <div\n ref={ref}\n className={cn(\n "relative flex h-10 w-10 items-center justify-center border-y border-r border-border text-sm font-medium transition-all first:rounded-l-lg first:border-l last:rounded-r-lg bg-background",\n isFocused && "z-10 ring-2 ring-ring ring-offset-background border-ring",\n disabled && "cursor-not-allowed bg-muted/40",\n className\n )}\n {...props}\n >\n <input\n ref={(el) => {\n inputRefs.current[index] = el;\n }}\n type="text"\n inputMode="numeric"\n pattern="[0-9]*"\n maxLength={1}\n value={char}\n disabled={disabled}\n onFocus={() => setFocusedIndex(index)}\n onBlur={() => setFocusedIndex(null)}\n onChange={(e) => {\n const nextChar = e.target.value.slice(-1);\n onSlotInput(index, nextChar);\n }}\n onKeyDown={(e) => onSlotKeyDown(index, e)}\n onPaste={onSlotPaste}\n className="absolute inset-0 h-full w-full opacity-0 cursor-default disabled:cursor-not-allowed"\n aria-label={`Digit ${index + 1}`}\n />\n {char}\n {isFocused && !char && (\n <div className="pointer-events-none absolute inset-0 flex items-center justify-center">\n <div className="h-4 w-px animate-pulse bg-foreground" />\n </div>\n )}\n </div>\n );\n }\n);\nInputOTPSlot.displayName = "InputOTPSlot";\n\nconst InputOTPSeparator = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n role="separator"\n className={cn("flex items-center text-muted-foreground px-1 text-sm font-bold", className)}\n {...props}\n >\n -\n </div>\n));\nInputOTPSeparator.displayName = "InputOTPSeparator";\n\nexport { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator };\n'
721
+ }
722
+ ]
723
+ },
724
+ "kbd": {
725
+ "name": "kbd",
726
+ "type": "components:ui",
727
+ "category": "temel",
728
+ "description": "Klavye k\u0131sayol tu\u015Fu g\xF6stergesi",
729
+ "dependencies": [
730
+ "class-variance-authority"
731
+ ],
732
+ "devDependencies": [],
733
+ "registryDependencies": [],
734
+ "files": [
735
+ {
736
+ "name": "kbd.tsx",
737
+ "content": '"use client";\n\nimport * as React from "react";\nimport { cva, type VariantProps } from "class-variance-authority";\nimport { cn } from "@/lib/utils";\n\nconst kbdVariants = cva(\n "pointer-events-none inline-flex select-none items-center justify-center gap-1 rounded border border-border bg-muted font-mono font-medium text-muted-foreground transition-colors",\n {\n variants: {\n size: {\n sm: "h-4 min-w-[16px] px-1 text-[10px]",\n default: "h-5 min-w-[20px] px-1.5 text-[11px]",\n lg: "h-6 min-w-[24px] px-2 text-[12px]",\n },\n },\n defaultVariants: {\n size: "default",\n },\n }\n);\n\nexport interface KbdProps\n extends React.HTMLAttributes<HTMLElement>,\n VariantProps<typeof kbdVariants> {}\n\nconst Kbd = React.forwardRef<HTMLElement, KbdProps>(\n ({ className, size, children, ...props }, ref) => {\n return (\n <kbd\n ref={ref}\n className={cn(kbdVariants({ size }), className)}\n {...props}\n >\n {children}\n </kbd>\n );\n }\n);\n\nKbd.displayName = "Kbd";\n\nexport { Kbd, kbdVariants };\n'
738
+ }
739
+ ]
740
+ },
741
+ "label": {
742
+ "name": "label",
743
+ "type": "components:ui",
744
+ "category": "form",
745
+ "description": "Eri\u015Filebilir form etiket bile\u015Feni",
746
+ "dependencies": [
747
+ "@radix-ui/react-label",
748
+ "class-variance-authority"
749
+ ],
750
+ "devDependencies": [],
751
+ "registryDependencies": [],
752
+ "files": [
753
+ {
754
+ "name": "label.tsx",
755
+ "content": '"use client";\n\nimport * as React from "react";\nimport * as LabelPrimitive from "@radix-ui/react-label";\nimport { cva, type VariantProps } from "class-variance-authority";\nimport { cn } from "@/lib/utils";\n\nconst labelVariants = cva(\n "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"\n);\n\nconst Label = React.forwardRef<\n React.ElementRef<typeof LabelPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> &\n VariantProps<typeof labelVariants>\n>(({ className, ...props }, ref) => (\n <LabelPrimitive.Root\n ref={ref}\n className={cn(labelVariants(), className)}\n {...props}\n />\n));\nLabel.displayName = LabelPrimitive.Root.displayName;\n\nexport { Label };\n'
756
+ }
757
+ ]
758
+ },
759
+ "mermaid": {
760
+ "name": "mermaid",
761
+ "type": "components:ui",
762
+ "category": "navigation",
763
+ "description": "Canl\u0131 Markdown sequence, mimari ve ERD \u015Fema motoru",
764
+ "dependencies": [
765
+ "mermaid"
766
+ ],
767
+ "devDependencies": [],
768
+ "registryDependencies": [],
769
+ "files": [
770
+ {
771
+ "name": "mermaid.tsx",
772
+ "content": `"use client";
773
+
774
+ import * as React from "react";
775
+ import { cn } from "@/lib/utils";
776
+
777
+ export interface MermaidProps extends React.HTMLAttributes<HTMLDivElement> {
778
+ /** Mermaid diagram syntax string */
779
+ chart: string;
780
+ /** Custom theme: "dark" | "default" | "forest" | "neutral" | "base" */
781
+ theme?: "dark" | "default" | "forest" | "neutral" | "base";
782
+ /** Custom primary color override for nodes and accents */
783
+ primaryColor?: string;
784
+ /** Allow copying SVG or source code */
785
+ showControls?: boolean;
786
+ }
787
+
788
+ export function Mermaid({
789
+ chart,
790
+ theme,
791
+ primaryColor = "#e11d48",
792
+ showControls = true,
793
+ className,
794
+ ...props
795
+ }: MermaidProps) {
796
+ const containerRef = React.useRef<HTMLDivElement>(null);
797
+ const [svgContent, setSvgContent] = React.useState<string>("");
798
+ const [error, setError] = React.useState<string | null>(null);
799
+ const [copied, setCopied] = React.useState(false);
800
+ const [copiedSvg, setCopiedSvg] = React.useState(false);
801
+ const [isDarkMode, setIsDarkMode] = React.useState(false);
802
+
803
+ const uniqueId = React.useId().replace(/[:]/g, "_");
804
+
805
+ // Dark mode takibi
806
+ React.useEffect(() => {
807
+ const checkDark = () => {
808
+ const isDark =
809
+ document.documentElement.classList.contains("dark") ||
810
+ window.matchMedia("(prefers-color-scheme: dark)").matches;
811
+ setIsDarkMode(isDark);
812
+ };
813
+
814
+ checkDark();
815
+
816
+ const observer = new MutationObserver(() => {
817
+ checkDark();
818
+ });
819
+
820
+ observer.observe(document.documentElement, {
821
+ attributes: true,
822
+ attributeFilter: ["class"],
823
+ });
824
+
825
+ return () => observer.disconnect();
826
+ }, []);
827
+
828
+ React.useEffect(() => {
829
+ let isMounted = true;
830
+
831
+ async function renderChart() {
832
+ if (!chart.trim()) return;
833
+
834
+ try {
835
+ setError(null);
836
+ const mermaid = (await import("mermaid")).default;
837
+
838
+ const isDark = isDarkMode;
839
+ const brandColor = primaryColor || "#e11d48";
840
+
841
+ mermaid.initialize({
842
+ startOnLoad: false,
843
+ theme: theme || "base",
844
+ securityLevel: "loose",
845
+ fontFamily:
846
+ "ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif",
847
+ themeVariables: {
848
+ darkMode: isDark,
849
+ background: "transparent",
850
+ fontFamily:
851
+ "ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
852
+ fontSize: "13px",
853
+
854
+ // Ana Renkler
855
+ primaryColor: isDark ? "#1e1e24" : "#ffffff",
856
+ primaryTextColor: isDark ? "#f4f4f5" : "#0f172a",
857
+ primaryBorderColor: isDark ? "#3f3f46" : "#cbd5e1",
858
+ lineColor: isDark ? "#94a3b8" : "#475569",
859
+ textColor: isDark ? "#f4f4f5" : "#0f172a",
860
+
861
+ // Genel Node / Kutu Renkleri
862
+ mainBkg: isDark ? "#18181b" : "#ffffff",
863
+ nodeBorder: isDark ? "#3f3f46" : "#cbd5e1",
864
+ nodeTextColor: isDark ? "#f4f4f5" : "#0f172a",
865
+ clusterBkg: isDark ? "#18181b80" : "#f8fafc99",
866
+ clusterBorder: isDark ? "#27272a" : "#e2e8f0",
867
+ titleColor: isDark ? "#f4f4f5" : "#0f172a",
868
+ edgeLabelBackground: isDark ? "#18181b" : "#ffffff",
869
+
870
+ // Sequence Diagram \xD6zel Renkleri
871
+ actorBkg: isDark ? "#18181b" : "#ffffff",
872
+ actorBorder: isDark ? "#3f3f46" : "#cbd5e1",
873
+ actorTextColor: isDark ? "#f4f4f5" : "#0f172a",
874
+ actorLineColor: isDark ? "#52525b" : "#cbd5e1",
875
+ signalColor: isDark ? "#a1a1aa" : "#334155",
876
+ signalTextColor: isDark ? "#f4f4f5" : "#0f172a",
877
+ labelBoxBkgColor: isDark ? "#27272a" : "#f8fafc",
878
+ labelBoxBorderColor: isDark ? "#3f3f46" : "#cbd5e1",
879
+ labelTextColor: isDark ? "#f4f4f5" : "#0f172a",
880
+ loopTextColor: isDark ? "#f4f4f5" : "#0f172a",
881
+ sequenceNumberColor: "#ffffff",
882
+ activationBkgColor: isDark ? "#27272a" : "#f1f5f9",
883
+ activationBorderColor: isDark ? "#3f3f46" : "#94a3b8",
884
+
885
+ // Not Kutular\u0131
886
+ noteBkgColor: isDark ? "#27272a" : "#fefce8",
887
+ noteBorderColor: isDark ? "#3f3f46" : "#fef08a",
888
+ noteTextColor: isDark ? "#f4f4f5" : "#854d0e",
889
+
890
+ // Class & ER Diyagramlar\u0131
891
+ classText: isDark ? "#f4f4f5" : "#0f172a",
892
+ attributeBackgroundColorOdd: isDark ? "#18181b" : "#ffffff",
893
+ attributeBackgroundColorEven: isDark ? "#27272a" : "#f8fafc",
894
+
895
+ // Git Graph
896
+ git0: brandColor,
897
+ git1: "#6366f1",
898
+ git2: "#10b981",
899
+ git3: "#f59e0b",
900
+ git4: "#8b5cf6",
901
+ git5: "#06b6d4",
902
+ gitBranchLabel0: "#ffffff",
903
+ gitBranchLabel1: "#ffffff",
904
+ gitBranchLabel2: "#ffffff",
905
+ gitBranchLabel3: "#ffffff",
906
+
907
+ // Pie Chart
908
+ pie1: brandColor,
909
+ pie2: "#6366f1",
910
+ pie3: "#10b981",
911
+ pie4: "#f59e0b",
912
+ pie5: "#8b5cf6",
913
+ pie6: "#06b6d4",
914
+ pieTitleTextColor: isDark ? "#f4f4f5" : "#0f172a",
915
+ pieSectionTextColor: "#ffffff",
916
+ pieLegendTextColor: isDark ? "#cbd5e1" : "#334155",
917
+ },
918
+ });
919
+
920
+ const id = \`mermaid_\${uniqueId}_\${Date.now()}\`;
921
+ const { svg } = await mermaid.render(id, chart);
922
+
923
+ if (isMounted) {
924
+ setSvgContent(svg);
925
+ }
926
+ } catch (err: any) {
927
+ if (isMounted) {
928
+ console.error("Mermaid Render Error:", err);
929
+ setError(err?.message || "Diyagram \xE7izilirken s\xF6zdizimi hatas\u0131 olu\u015Ftu.");
930
+ }
931
+ }
932
+ }
933
+
934
+ renderChart();
935
+
936
+ return () => {
937
+ isMounted = false;
938
+ };
939
+ }, [chart, theme, primaryColor, uniqueId, isDarkMode]);
940
+
941
+ const handleCopySource = () => {
942
+ navigator.clipboard.writeText(chart);
943
+ setCopied(true);
944
+ setTimeout(() => setCopied(false), 2000);
945
+ };
946
+
947
+ const handleCopySvg = () => {
948
+ if (svgContent) {
949
+ navigator.clipboard.writeText(svgContent);
950
+ setCopiedSvg(true);
951
+ setTimeout(() => setCopiedSvg(false), 2000);
952
+ }
953
+ };
954
+
955
+ return (
956
+ <div
957
+ ref={containerRef}
958
+ className={cn(
959
+ "relative rounded-2xl border border-border bg-card overflow-hidden shadow-xs group",
960
+ className
961
+ )}
962
+ {...props}
963
+ >
964
+ {/* Controls Header */}
965
+ {showControls && (
966
+ <div className="flex items-center justify-between px-4 py-2.5 border-b border-border/60 bg-muted/20">
967
+ <div className="flex items-center gap-2">
968
+ <span className="h-2 w-2 rounded-full bg-primary animate-pulse" />
969
+ <span className="text-[11px] font-mono font-medium text-muted-foreground uppercase tracking-wider">
970
+ Mermaid Diagram
971
+ </span>
972
+ </div>
973
+
974
+ <div className="flex items-center gap-1.5">
975
+ <button
976
+ type="button"
977
+ onClick={handleCopySvg}
978
+ disabled={!svgContent}
979
+ className="text-[11px] font-medium px-2 py-1 rounded-md text-muted-foreground hover:text-foreground hover:bg-muted/60 transition-colors"
980
+ title="SVG format\u0131nda kopyala"
981
+ >
982
+ {copiedSvg ? "SVG Kopyaland\u0131" : "SVG Kopyala"}
983
+ </button>
984
+
985
+ <button
986
+ type="button"
987
+ onClick={handleCopySource}
988
+ className="text-[11px] font-medium px-2.5 py-1 rounded-md border border-border/60 bg-background text-muted-foreground hover:text-foreground hover:bg-muted transition-colors"
989
+ title="Kaynak Kodu Kopyala"
990
+ >
991
+ {copied ? "Kopyaland\u0131" : "Kodu Kopyala"}
992
+ </button>
993
+ </div>
994
+ </div>
995
+ )}
996
+
997
+ {/* Render Area with SVG Style Enhancements */}
998
+ <div className="p-6 md:p-10 flex items-center justify-center min-h-[260px] overflow-x-auto bg-background/50">
999
+ {error ? (
1000
+ <div className="p-4 rounded-xl border border-destructive/40 bg-destructive/10 text-destructive text-xs font-mono max-w-md text-center">
1001
+ <p className="font-bold mb-1">Mermaid \xC7izim Hatas\u0131</p>
1002
+ <p className="opacity-90">{error}</p>
1003
+ </div>
1004
+ ) : svgContent ? (
1005
+ <div
1006
+ className={cn(
1007
+ "w-full flex items-center justify-center transition-all duration-300",
1008
+ "[&_svg]:max-w-full [&_svg]:h-auto [&_svg]:drop-shadow-xs",
1009
+ // Metin netli\u011Fi ve kontrast g\xFC\xE7lendirmeleri
1010
+ "[&_text]:font-sans [&_text]:tracking-normal",
1011
+ "[&_.messageText]:fill-foreground [&_.messageText]:font-medium [&_.messageText]:text-[12.5px]",
1012
+ "[&_.actor_text]:fill-foreground [&_.actor_text]:font-semibold [&_text.actor]:fill-foreground",
1013
+ "[&_.nodeLabel]:fill-foreground [&_.nodeLabel]:font-medium",
1014
+ "[&_.labelText]:fill-foreground [&_.labelText]:font-medium",
1015
+ "[&_.sequenceNumber]:fill-white! [&_.sequenceNumber]:font-bold",
1016
+ "[&_.noteText]:fill-foreground [&_.noteText]:font-medium"
1017
+ )}
1018
+ dangerouslySetInnerHTML={{ __html: svgContent }}
1019
+ />
1020
+ ) : (
1021
+ <div className="flex items-center gap-2 text-xs text-muted-foreground font-mono">
1022
+ <span className="h-3 w-3 animate-spin rounded-full border-2 border-primary border-t-transparent" />
1023
+ <span>Diyagram y\xFCkleniyor...</span>
1024
+ </div>
1025
+ )}
1026
+ </div>
1027
+ </div>
1028
+ );
1029
+ }
1030
+
1031
+ `
1032
+ }
1033
+ ]
1034
+ },
1035
+ "pagination": {
1036
+ "name": "pagination",
1037
+ "type": "components:ui",
1038
+ "category": "navigation",
1039
+ "description": "\xC7oklu sayfa navigasyon bile\u015Feni",
1040
+ "dependencies": [
1041
+ "lucide-react"
1042
+ ],
1043
+ "devDependencies": [],
1044
+ "registryDependencies": [],
1045
+ "files": [
1046
+ {
1047
+ "name": "pagination.tsx",
1048
+ "content": '"use client";\n\nimport * as React from "react";\nimport { ChevronLeft, ChevronRight, MoreHorizontal } from "lucide-react";\nimport { cn } from "@/lib/utils";\nimport { ButtonProps, buttonVariants } from "@/components/ui/button";\n\nconst Pagination = ({ className, ...props }: React.ComponentProps<"nav">) => (\n <nav\n role="navigation"\n aria-label="pagination"\n className={cn("mx-auto flex w-full justify-center", className)}\n {...props}\n />\n);\nPagination.displayName = "Pagination";\n\nconst PaginationContent = React.forwardRef<\n HTMLUListElement,\n React.ComponentProps<"ul">\n>(({ className, ...props }, ref) => (\n <ul\n ref={ref}\n className={cn("flex flex-wrap items-center gap-1", className)}\n {...props}\n />\n));\nPaginationContent.displayName = "PaginationContent";\n\nconst PaginationItem = React.forwardRef<\n HTMLLIElement,\n React.ComponentProps<"li">\n>(({ className, ...props }, ref) => (\n <li ref={ref} className={cn("", className)} {...props} />\n));\nPaginationItem.displayName = "PaginationItem";\n\ntype PaginationLinkProps = {\n isActive?: boolean;\n} & Pick<ButtonProps, "size"> &\n React.ComponentProps<"a">;\n\nconst PaginationLink = ({\n className,\n isActive,\n size = "icon",\n ...props\n}: PaginationLinkProps) => (\n <a\n aria-current={isActive ? "page" : undefined}\n className={cn(\n buttonVariants({\n variant: isActive ? "outline" : "ghost",\n size,\n }),\n isActive && "bg-accent text-accent-foreground border-border font-medium",\n className\n )}\n {...props}\n />\n);\nPaginationLink.displayName = "PaginationLink";\n\nconst PaginationPrevious = ({\n className,\n ...props\n}: React.ComponentProps<typeof PaginationLink>) => (\n <PaginationLink\n aria-label="\xD6nceki sayfaya git"\n size="default"\n className={cn("gap-1 pl-2.5", className)}\n {...props}\n >\n <ChevronLeft className="h-4 w-4" />\n <span>\xD6nceki</span>\n </PaginationLink>\n);\nPaginationPrevious.displayName = "PaginationPrevious";\n\nconst PaginationNext = ({\n className,\n ...props\n}: React.ComponentProps<typeof PaginationLink>) => (\n <PaginationLink\n aria-label="Sonraki sayfaya git"\n size="default"\n className={cn("gap-1 pr-2.5", className)}\n {...props}\n >\n <span>Sonraki</span>\n <ChevronRight className="h-4 w-4" />\n </PaginationLink>\n);\nPaginationNext.displayName = "PaginationNext";\n\nconst PaginationEllipsis = ({\n className,\n ...props\n}: React.ComponentProps<"span">) => (\n <span\n aria-hidden\n className={cn("flex h-9 w-9 items-center justify-center text-muted-foreground", className)}\n {...props}\n >\n <MoreHorizontal className="h-4 w-4" />\n <span className="sr-only">Daha fazla sayfa</span>\n </span>\n);\nPaginationEllipsis.displayName = "PaginationEllipsis";\n\nexport {\n Pagination,\n PaginationContent,\n PaginationEllipsis,\n PaginationItem,\n PaginationLink,\n PaginationNext,\n PaginationPrevious,\n};\n'
1049
+ }
1050
+ ]
1051
+ },
1052
+ "popover": {
1053
+ "name": "popover",
1054
+ "type": "components:ui",
1055
+ "category": "overlay",
1056
+ "description": "Tetikleyiciye ba\u011Fl\u0131 a\xE7\u0131l\u0131r i\xE7erik balonu",
1057
+ "dependencies": [
1058
+ "@radix-ui/react-popover"
1059
+ ],
1060
+ "devDependencies": [],
1061
+ "registryDependencies": [],
1062
+ "files": [
1063
+ {
1064
+ "name": "popover.tsx",
1065
+ "content": '"use client";\n\nimport * as React from "react";\nimport * as PopoverPrimitive from "@radix-ui/react-popover";\nimport { cn } from "@/lib/utils";\n\nconst Popover = PopoverPrimitive.Root;\nconst PopoverTrigger = PopoverPrimitive.Trigger;\nconst PopoverAnchor = PopoverPrimitive.Anchor;\n\nconst PopoverContent = React.forwardRef<\n React.ElementRef<typeof PopoverPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>\n>(({ className, align = "center", sideOffset = 4, ...props }, ref) => (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n ref={ref}\n align={align}\n sideOffset={sideOffset}\n className={cn(\n "z-50 w-72 rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-md outline-hidden data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",\n className\n )}\n {...props}\n />\n </PopoverPrimitive.Portal>\n));\nPopoverContent.displayName = PopoverPrimitive.Content.displayName;\n\nexport { Popover, PopoverTrigger, PopoverContent, PopoverAnchor };\n'
1066
+ }
1067
+ ]
1068
+ },
1069
+ "progress": {
1070
+ "name": "progress",
1071
+ "type": "components:ui",
1072
+ "category": "feedback",
1073
+ "description": "\u0130\u015Flem ilerleme durum \xE7ubu\u011Fu",
1074
+ "dependencies": [
1075
+ "@radix-ui/react-progress"
1076
+ ],
1077
+ "devDependencies": [],
1078
+ "registryDependencies": [],
1079
+ "files": [
1080
+ {
1081
+ "name": "progress.tsx",
1082
+ "content": '"use client";\n\nimport * as React from "react";\nimport * as ProgressPrimitive from "@radix-ui/react-progress";\nimport { cn } from "@/lib/utils";\n\nexport interface ProgressProps\n extends React.ComponentPropsWithoutRef<typeof ProgressPrimitive.Root> {\n /** \u0130lerleme de\u011Feri (0-100) */\n value?: number;\n}\n\nconst Progress = React.forwardRef<\n React.ElementRef<typeof ProgressPrimitive.Root>,\n ProgressProps\n>(({ className, value = 0, ...props }, ref) => (\n <ProgressPrimitive.Root\n ref={ref}\n className={cn(\n "relative h-2 w-full overflow-hidden rounded-full bg-secondary",\n className\n )}\n {...props}\n >\n <ProgressPrimitive.Indicator\n className="h-full w-full flex-1 bg-primary transition-all duration-500 ease-in-out"\n style={{ transform: `translateX(-${100 - (value ?? 0)}%)` }}\n />\n </ProgressPrimitive.Root>\n));\nProgress.displayName = ProgressPrimitive.Root.displayName;\n\nexport { Progress };\n'
1083
+ }
1084
+ ]
1085
+ },
1086
+ "rating": {
1087
+ "name": "rating",
1088
+ "type": "components:ui",
1089
+ "category": "form",
1090
+ "description": "Hover, klavye ve salt okunur mod destekli y\u0131ld\u0131zl\u0131 puanlama bile\u015Feni",
1091
+ "dependencies": [
1092
+ "lucide-react",
1093
+ "class-variance-authority"
1094
+ ],
1095
+ "devDependencies": [],
1096
+ "registryDependencies": [],
1097
+ "files": [
1098
+ {
1099
+ "name": "rating.tsx",
1100
+ "content": '"use client";\n\nimport * as React from "react";\nimport { cva, type VariantProps } from "class-variance-authority";\nimport { Star } from "lucide-react";\nimport { cn } from "@/lib/utils";\n\nconst ratingVariants = cva("inline-flex items-center gap-1 select-none", {\n variants: {\n size: {\n sm: "[&_svg]:h-3.5 [&_svg]:w-3.5",\n md: "[&_svg]:h-4 [&_svg]:w-4",\n lg: "[&_svg]:h-6 [&_svg]:w-6",\n },\n },\n defaultVariants: {\n size: "md",\n },\n});\n\nexport interface RatingProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, "onChange">,\n VariantProps<typeof ratingVariants> {\n value?: number;\n defaultValue?: number;\n max?: number;\n readOnly?: boolean;\n disabled?: boolean;\n onChange?: (value: number) => void;\n}\n\nconst Rating = React.forwardRef<HTMLDivElement, RatingProps>(\n (\n {\n className,\n value: controlledValue,\n defaultValue = 0,\n max = 5,\n readOnly = false,\n disabled = false,\n size,\n onChange,\n ...props\n },\n ref\n ) => {\n const isControlled = controlledValue !== undefined;\n const [uncontrolledValue, setUncontrolledValue] = React.useState(defaultValue);\n const value = isControlled ? controlledValue : uncontrolledValue;\n\n const [hoverValue, setHoverValue] = React.useState<number | null>(null);\n\n const handleSelect = (nextValue: number) => {\n if (readOnly || disabled) return;\n if (!isControlled) {\n setUncontrolledValue(nextValue);\n }\n onChange?.(nextValue);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (readOnly || disabled) return;\n if (e.key === "ArrowRight" || e.key === "ArrowUp") {\n e.preventDefault();\n const next = Math.min(max, (value || 0) + 1);\n handleSelect(next);\n } else if (e.key === "ArrowLeft" || e.key === "ArrowDown") {\n e.preventDefault();\n const next = Math.max(0, (value || 0) - 1);\n handleSelect(next);\n } else if (e.key === "Home") {\n e.preventDefault();\n handleSelect(0);\n } else if (e.key === "End") {\n e.preventDefault();\n handleSelect(max);\n }\n };\n\n const displayValue = hoverValue !== null ? hoverValue : value;\n\n return (\n <div\n ref={ref}\n role={readOnly ? "img" : "slider"}\n aria-label={`De\u011Ferlendirme: ${value} / ${max}`}\n aria-valuenow={value}\n aria-valuemin={0}\n aria-valuemax={max}\n tabIndex={readOnly || disabled ? -1 : 0}\n onKeyDown={handleKeyDown}\n onMouseLeave={() => setHoverValue(null)}\n className={cn(\n ratingVariants({ size }),\n !readOnly && !disabled && "cursor-pointer focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 rounded-md p-0.5",\n disabled && "opacity-50 cursor-not-allowed",\n className\n )}\n {...props}\n >\n {Array.from({ length: max }).map((_, index) => {\n const starIndex = index + 1;\n const isFilled = starIndex <= displayValue;\n\n return (\n <span\n key={index}\n onMouseEnter={() => !readOnly && !disabled && setHoverValue(starIndex)}\n onClick={() => handleSelect(starIndex)}\n className={cn(\n "inline-flex p-0.5 transition-transform duration-100 rounded-sm",\n !readOnly && !disabled && "hover:scale-110 cursor-pointer",\n disabled && "cursor-not-allowed"\n )}\n aria-hidden="true"\n >\n <Star\n className={cn(\n "transition-colors duration-150",\n isFilled\n ? "fill-warning text-warning"\n : "fill-transparent text-muted-foreground/40"\n )}\n />\n </span>\n );\n })}\n </div>\n );\n }\n);\nRating.displayName = "Rating";\n\nexport { Rating, ratingVariants };\n'
1101
+ }
1102
+ ]
1103
+ },
1104
+ "resizable": {
1105
+ "name": "resizable",
1106
+ "type": "components:ui",
1107
+ "category": "navigation",
1108
+ "description": "S\xFCr\xFCklenebilir panel d\xFCzeni",
1109
+ "dependencies": [
1110
+ "lucide-react",
1111
+ "react-resizable-panels"
1112
+ ],
1113
+ "devDependencies": [],
1114
+ "registryDependencies": [],
1115
+ "files": [
1116
+ {
1117
+ "name": "resizable.tsx",
1118
+ "content": '"use client";\n\nimport * as React from "react";\nimport { GripVertical } from "lucide-react";\nimport { Group, Panel, Separator } from "react-resizable-panels";\nimport { cn } from "@/lib/utils";\n\nconst ResizablePanelGroup = ({\n className,\n orientation = "horizontal",\n ...props\n}: React.ComponentProps<typeof Group>) => (\n <Group\n orientation={orientation}\n className={cn(\n "flex h-full w-full data-[panel-group-direction=vertical]:flex-col",\n className\n )}\n {...props}\n />\n);\n\nconst ResizablePanel = Panel;\n\nconst ResizableHandle = ({\n withHandle,\n className,\n ...props\n}: React.ComponentProps<typeof Separator> & {\n withHandle?: boolean;\n}) => (\n <Separator\n className={cn(\n "relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:-translate-y-1/2 data-[panel-group-direction=vertical]:after:translate-x-0 [&[data-panel-group-direction=vertical]>div]:rotate-90",\n className\n )}\n {...props}\n >\n {withHandle && (\n <div className="z-10 flex h-4 w-3 items-center justify-center rounded-xs border border-border bg-background shadow-xs">\n <GripVertical className="h-2.5 w-2.5 text-muted-foreground" />\n </div>\n )}\n </Separator>\n);\n\nexport { ResizablePanelGroup, ResizablePanel, ResizableHandle };\n'
1119
+ }
1120
+ ]
1121
+ },
1122
+ "scroll-area": {
1123
+ "name": "scroll-area",
1124
+ "type": "components:ui",
1125
+ "category": "navigation",
1126
+ "description": "\xD6zel tasar\u0131m ve animasyonlu kayd\u0131rma alan\u0131",
1127
+ "dependencies": [
1128
+ "@radix-ui/react-scroll-area"
1129
+ ],
1130
+ "devDependencies": [],
1131
+ "registryDependencies": [],
1132
+ "files": [
1133
+ {
1134
+ "name": "scroll-area.tsx",
1135
+ "content": '"use client";\n\nimport * as React from "react";\nimport * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";\nimport { cn } from "@/lib/utils";\n\nconst ScrollArea = React.forwardRef<\n React.ElementRef<typeof ScrollAreaPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root>\n>(({ className, children, ...props }, ref) => (\n <ScrollAreaPrimitive.Root\n ref={ref}\n className={cn("relative overflow-hidden", className)}\n {...props}\n >\n <ScrollAreaPrimitive.Viewport className="h-full w-full rounded-[inherit]">\n {children}\n </ScrollAreaPrimitive.Viewport>\n <ScrollBar />\n <ScrollAreaPrimitive.Corner />\n </ScrollAreaPrimitive.Root>\n));\nScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;\n\nconst ScrollBar = React.forwardRef<\n React.ElementRef<typeof ScrollAreaPrimitive.Scrollbar>,\n React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Scrollbar>\n>(({ className, orientation = "vertical", ...props }, ref) => (\n <ScrollAreaPrimitive.Scrollbar\n ref={ref}\n orientation={orientation}\n className={cn(\n "flex touch-none select-none transition-colors",\n orientation === "vertical" &&\n "h-full w-2.5 border-l border-l-transparent p-px",\n orientation === "horizontal" &&\n "h-2.5 flex-col border-t border-t-transparent p-px",\n className\n )}\n {...props}\n >\n <ScrollAreaPrimitive.ScrollAreaThumb className="relative flex-1 rounded-full bg-border hover:bg-muted-foreground/30 transition-colors" />\n </ScrollAreaPrimitive.Scrollbar>\n));\nScrollBar.displayName = ScrollAreaPrimitive.Scrollbar.displayName;\n\nexport { ScrollArea, ScrollBar };\n'
1136
+ }
1137
+ ]
1138
+ },
1139
+ "select": {
1140
+ "name": "select",
1141
+ "type": "components:ui",
1142
+ "category": "form",
1143
+ "description": "A\xE7\u0131l\u0131r liste se\xE7im kutusu",
1144
+ "dependencies": [
1145
+ "@radix-ui/react-select",
1146
+ "lucide-react"
1147
+ ],
1148
+ "devDependencies": [],
1149
+ "registryDependencies": [],
1150
+ "files": [
1151
+ {
1152
+ "name": "select.tsx",
1153
+ "content": '"use client";\n\nimport * as React from "react";\nimport * as SelectPrimitive from "@radix-ui/react-select";\nimport { Check, ChevronDown, ChevronUp } from "lucide-react";\nimport { cn } from "@/lib/utils";\n\nconst Select = SelectPrimitive.Root;\nconst SelectGroup = SelectPrimitive.Group;\nconst SelectValue = SelectPrimitive.Value;\n\nconst SelectTrigger = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Trigger>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>\n>(({ className, children, ...props }, ref) => (\n <SelectPrimitive.Trigger\n ref={ref}\n className={cn(\n "flex h-9 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm",\n "text-foreground placeholder:text-muted-foreground",\n "transition-colors duration-150",\n "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",\n "disabled:cursor-not-allowed disabled:opacity-50",\n "[&>span]:line-clamp-1",\n className\n )}\n {...props}\n >\n {children}\n <SelectPrimitive.Icon asChild>\n <ChevronDown className="h-4 w-4 opacity-50" />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n));\nSelectTrigger.displayName = SelectPrimitive.Trigger.displayName;\n\nconst SelectScrollUpButton = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.ScrollUpButton\n ref={ref}\n className={cn("flex cursor-default items-center justify-center py-1", className)}\n {...props}\n >\n <ChevronUp className="h-4 w-4" />\n </SelectPrimitive.ScrollUpButton>\n));\nSelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;\n\nconst SelectScrollDownButton = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.ScrollDownButton\n ref={ref}\n className={cn("flex cursor-default items-center justify-center py-1", className)}\n {...props}\n >\n <ChevronDown className="h-4 w-4" />\n </SelectPrimitive.ScrollDownButton>\n));\nSelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;\n\nconst SelectContent = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>\n>(({ className, children, position = "popper", ...props }, ref) => (\n <SelectPrimitive.Portal>\n <SelectPrimitive.Content\n ref={ref}\n className={cn(\n "relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border border-border bg-popover text-popover-foreground shadow-overlay",\n "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",\n position === "popper" &&\n "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",\n className\n )}\n position={position}\n {...props}\n >\n <SelectScrollUpButton />\n <SelectPrimitive.Viewport\n className={cn(\n "p-1",\n position === "popper" &&\n "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"\n )}\n >\n {children}\n </SelectPrimitive.Viewport>\n <SelectScrollDownButton />\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n));\nSelectContent.displayName = SelectPrimitive.Content.displayName;\n\nconst SelectLabel = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Label>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.Label\n ref={ref}\n className={cn("py-1.5 pl-8 pr-2 text-xs font-semibold text-muted-foreground", className)}\n {...props}\n />\n));\nSelectLabel.displayName = SelectPrimitive.Label.displayName;\n\nconst SelectItem = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>\n>(({ className, children, ...props }, ref) => (\n <SelectPrimitive.Item\n ref={ref}\n className={cn(\n "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none",\n "transition-colors duration-100",\n "focus:bg-accent focus:text-accent-foreground",\n "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",\n className\n )}\n {...props}\n >\n <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">\n <SelectPrimitive.ItemIndicator>\n <Check className="h-4 w-4" />\n </SelectPrimitive.ItemIndicator>\n </span>\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n));\nSelectItem.displayName = SelectPrimitive.Item.displayName;\n\nconst SelectSeparator = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.Separator\n ref={ref}\n className={cn("-mx-1 my-1 h-px bg-border", className)}\n {...props}\n />\n));\nSelectSeparator.displayName = SelectPrimitive.Separator.displayName;\n\nexport {\n Select,\n SelectGroup,\n SelectValue,\n SelectTrigger,\n SelectContent,\n SelectLabel,\n SelectItem,\n SelectSeparator,\n SelectScrollUpButton,\n SelectScrollDownButton,\n};\n'
1154
+ }
1155
+ ]
1156
+ },
1157
+ "separator": {
1158
+ "name": "separator",
1159
+ "type": "components:ui",
1160
+ "category": "temel",
1161
+ "description": "Yatay veya dikey ayr\u0131c\u0131 \xE7izgi",
1162
+ "dependencies": [
1163
+ "@radix-ui/react-separator"
1164
+ ],
1165
+ "devDependencies": [],
1166
+ "registryDependencies": [],
1167
+ "files": [
1168
+ {
1169
+ "name": "separator.tsx",
1170
+ "content": '"use client";\n\nimport * as React from "react";\nimport * as SeparatorPrimitive from "@radix-ui/react-separator";\nimport { cn } from "@/lib/utils";\n\nexport interface SeparatorProps\n extends React.ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root> {\n /** Ay\u0131r\u0131c\u0131 \xFCzerinde g\xF6r\xFCnt\xFClenecek iste\u011Fe ba\u011Fl\u0131 metin veya rozet (\xF6rn: "VEYA") */\n label?: React.ReactNode;\n}\n\nconst Separator = React.forwardRef<\n React.ElementRef<typeof SeparatorPrimitive.Root>,\n SeparatorProps\n>(\n (\n { className, orientation = "horizontal", decorative = true, label, children, ...props },\n ref\n ) => {\n const textContent = label || children;\n\n if (orientation === "horizontal" && textContent) {\n return (\n <div\n ref={ref}\n role={decorative ? "none" : "separator"}\n aria-orientation="horizontal"\n className={cn("relative flex items-center w-full my-4", className)}\n >\n <div className="flex-grow border-t border-border" />\n <span className="flex-shrink mx-3 text-[11px] font-medium text-muted-foreground uppercase tracking-wider bg-background px-2">\n {textContent}\n </span>\n <div className="flex-grow border-t border-border" />\n </div>\n );\n }\n\n return (\n <SeparatorPrimitive.Root\n ref={ref}\n decorative={decorative}\n orientation={orientation}\n className={cn(\n "shrink-0 bg-border",\n orientation === "horizontal" ? "h-px w-full" : "h-full w-px min-h-[1rem]",\n className\n )}\n {...props}\n />\n );\n }\n);\n\nSeparator.displayName = SeparatorPrimitive.Root.displayName;\n\nexport { Separator };\n'
1171
+ }
1172
+ ]
1173
+ },
1174
+ "sheet": {
1175
+ "name": "sheet",
1176
+ "type": "components:ui",
1177
+ "category": "overlay",
1178
+ "description": "Yan \xE7ekmece (drawer) paneli",
1179
+ "dependencies": [
1180
+ "@radix-ui/react-dialog",
1181
+ "lucide-react",
1182
+ "class-variance-authority"
1183
+ ],
1184
+ "devDependencies": [],
1185
+ "registryDependencies": [],
1186
+ "files": [
1187
+ {
1188
+ "name": "sheet.tsx",
1189
+ "content": '"use client";\n\nimport * as React from "react";\nimport * as DialogPrimitive from "@radix-ui/react-dialog";\nimport { cva, type VariantProps } from "class-variance-authority";\nimport { X } from "lucide-react";\nimport { cn } from "@/lib/utils";\n\nconst Sheet = DialogPrimitive.Root;\nconst SheetTrigger = DialogPrimitive.Trigger;\nconst SheetClose = DialogPrimitive.Close;\nconst SheetPortal = DialogPrimitive.Portal;\n\nconst SheetOverlay = React.forwardRef<\n React.ElementRef<typeof DialogPrimitive.Overlay>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Overlay\n className={cn(\n "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 backdrop-blur-xs",\n className\n )}\n {...props}\n ref={ref}\n />\n));\nSheetOverlay.displayName = DialogPrimitive.Overlay.displayName;\n\nconst sheetVariants = cva(\n "fixed z-50 gap-4 bg-background p-6 shadow-xl transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500 border-border",\n {\n variants: {\n side: {\n top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",\n bottom:\n "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",\n left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",\n right:\n "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",\n },\n },\n defaultVariants: {\n side: "right",\n },\n }\n);\n\ninterface SheetContentProps\n extends React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>,\n VariantProps<typeof sheetVariants> {}\n\nconst SheetContent = React.forwardRef<\n React.ElementRef<typeof DialogPrimitive.Content>,\n SheetContentProps\n>(({ side = "right", className, children, ...props }, ref) => (\n <SheetPortal>\n <SheetOverlay />\n <DialogPrimitive.Content\n ref={ref}\n className={cn(sheetVariants({ side }), className)}\n {...props}\n >\n {children}\n <DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary">\n <X className="h-4 w-4" />\n <span className="sr-only">Kapat</span>\n </DialogPrimitive.Close>\n </DialogPrimitive.Content>\n </SheetPortal>\n));\nSheetContent.displayName = DialogPrimitive.Content.displayName;\n\nconst SheetHeader = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n "flex flex-col space-y-2 text-center sm:text-left",\n className\n )}\n {...props}\n />\n);\nSheetHeader.displayName = "SheetHeader";\n\nconst SheetFooter = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",\n className\n )}\n {...props}\n />\n);\nSheetFooter.displayName = "SheetFooter";\n\nconst SheetTitle = React.forwardRef<\n React.ElementRef<typeof DialogPrimitive.Title>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Title\n ref={ref}\n className={cn("text-lg font-semibold text-foreground", className)}\n {...props}\n />\n));\nSheetTitle.displayName = DialogPrimitive.Title.displayName;\n\nconst SheetDescription = React.forwardRef<\n React.ElementRef<typeof DialogPrimitive.Description>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Description\n ref={ref}\n className={cn("text-sm text-muted-foreground", className)}\n {...props}\n />\n));\nSheetDescription.displayName = DialogPrimitive.Description.displayName;\n\nexport {\n Sheet,\n SheetPortal,\n SheetOverlay,\n SheetTrigger,\n SheetClose,\n SheetContent,\n SheetHeader,\n SheetFooter,\n SheetTitle,\n SheetDescription,\n};\n'
1190
+ }
1191
+ ]
1192
+ },
1193
+ "skeleton": {
1194
+ "name": "skeleton",
1195
+ "type": "components:ui",
1196
+ "category": "feedback",
1197
+ "description": "\u0130\xE7erik y\xFCkleme yer tutucusu",
1198
+ "dependencies": [],
1199
+ "devDependencies": [],
1200
+ "registryDependencies": [],
1201
+ "files": [
1202
+ {
1203
+ "name": "skeleton.tsx",
1204
+ "content": '"use client";\n\nimport * as React from "react";\nimport { cn } from "@/lib/utils";\n\nexport interface SkeletonProps extends React.HTMLAttributes<HTMLDivElement> {}\n\nfunction Skeleton({ className, ...props }: SkeletonProps) {\n return (\n <div\n className={cn(\n "relative overflow-hidden rounded-md bg-muted",\n "before:absolute before:inset-0 before:-translate-x-full",\n "before:bg-gradient-to-r before:from-transparent before:via-white/10 before:to-transparent",\n "before:animate-shimmer",\n className\n )}\n aria-busy="true"\n aria-live="polite"\n {...props}\n />\n );\n}\n\nexport { Skeleton };\n'
1205
+ }
1206
+ ]
1207
+ },
1208
+ "slider": {
1209
+ "name": "slider",
1210
+ "type": "components:ui",
1211
+ "category": "form",
1212
+ "description": "Aral\u0131k ve say\u0131sal de\u011Fer kayd\u0131r\u0131c\u0131s\u0131",
1213
+ "dependencies": [
1214
+ "@radix-ui/react-slider"
1215
+ ],
1216
+ "devDependencies": [],
1217
+ "registryDependencies": [],
1218
+ "files": [
1219
+ {
1220
+ "name": "slider.tsx",
1221
+ "content": '"use client";\n\nimport * as React from "react";\nimport * as SliderPrimitive from "@radix-ui/react-slider";\nimport { cn } from "@/lib/utils";\n\nconst Slider = React.forwardRef<\n React.ElementRef<typeof SliderPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof SliderPrimitive.Root>\n>(({ className, ...props }, ref) => (\n <SliderPrimitive.Root\n ref={ref}\n className={cn(\n "relative flex w-full touch-none select-none items-center",\n className\n )}\n {...props}\n >\n <SliderPrimitive.Track className="relative h-1.5 w-full grow overflow-hidden rounded-full bg-muted">\n <SliderPrimitive.Range className="absolute h-full bg-primary" />\n </SliderPrimitive.Track>\n <SliderPrimitive.Thumb className="block h-4 w-4 rounded-full border-2 border-primary bg-background shadow-xs transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 cursor-pointer hover:scale-110" />\n </SliderPrimitive.Root>\n));\nSlider.displayName = SliderPrimitive.Root.displayName;\n\nexport { Slider };\n'
1222
+ }
1223
+ ]
1224
+ },
1225
+ "spinner": {
1226
+ "name": "spinner",
1227
+ "type": "components:ui",
1228
+ "category": "feedback",
1229
+ "description": "Animasyonlu y\xFCkleniyor g\xF6stergesi",
1230
+ "dependencies": [
1231
+ "class-variance-authority"
1232
+ ],
1233
+ "devDependencies": [],
1234
+ "registryDependencies": [],
1235
+ "files": [
1236
+ {
1237
+ "name": "spinner.tsx",
1238
+ "content": '"use client";\n\nimport * as React from "react";\nimport { cva, type VariantProps } from "class-variance-authority";\nimport { cn } from "@/lib/utils";\n\nconst spinnerVariants = cva(\n "animate-spin rounded-full border-2 border-current border-t-transparent",\n {\n variants: {\n size: {\n sm: "h-3 w-3",\n default: "h-4 w-4",\n lg: "h-6 w-6",\n xl: "h-8 w-8",\n },\n variant: {\n default: "text-primary",\n muted: "text-muted-foreground",\n white: "text-white",\n inherit: "text-current",\n },\n },\n defaultVariants: {\n size: "default",\n variant: "default",\n },\n }\n);\n\nexport interface SpinnerProps\n extends React.HTMLAttributes<HTMLSpanElement>,\n VariantProps<typeof spinnerVariants> {\n /** Ekran okuyucu i\xE7in etiket */\n label?: string;\n}\n\nfunction Spinner({ className, size, variant, label = "Y\xFCkleniyor...", ...props }: SpinnerProps) {\n return (\n <span role="status" aria-label={label} {...props}>\n <span\n className={cn(spinnerVariants({ size, variant }), "block", className)}\n aria-hidden="true"\n />\n <span className="sr-only">{label}</span>\n </span>\n );\n}\n\nexport { Spinner, spinnerVariants };\n'
1239
+ }
1240
+ ]
1241
+ },
1242
+ "stat-card": {
1243
+ "name": "stat-card",
1244
+ "type": "components:ui",
1245
+ "category": "temel",
1246
+ "description": "SaaS dashboard ve KPI panelleri i\xE7in trend ve ikonlu metrik kart\u0131",
1247
+ "dependencies": [
1248
+ "lucide-react",
1249
+ "class-variance-authority"
1250
+ ],
1251
+ "devDependencies": [],
1252
+ "registryDependencies": [],
1253
+ "files": [
1254
+ {
1255
+ "name": "stat-card.tsx",
1256
+ "content": '"use client";\n\nimport * as React from "react";\nimport { cva, type VariantProps } from "class-variance-authority";\nimport { ArrowUpRight, ArrowDownRight, Minus } from "lucide-react";\nimport { cn } from "@/lib/utils";\n\nconst statCardVariants = cva(\n "relative flex flex-col justify-between rounded-2xl border border-border/80 bg-card p-5 shadow-sm transition-all duration-200 hover:border-border hover:shadow-md",\n {\n variants: {\n variant: {\n default: "bg-card text-card-foreground",\n glass: "bg-card/40 backdrop-blur-xl border-border/60",\n muted: "bg-muted/40 text-foreground border-border/40",\n },\n },\n defaultVariants: {\n variant: "default",\n },\n }\n);\n\nexport interface StatCardProps\n extends React.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof statCardVariants> {}\n\nconst StatCard = React.forwardRef<HTMLDivElement, StatCardProps>(\n ({ className, variant, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(statCardVariants({ variant }), className)}\n {...props}\n />\n )\n);\nStatCard.displayName = "StatCard";\n\nconst StatCardHeader = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn("flex items-center justify-between gap-2 mb-3", className)}\n {...props}\n />\n));\nStatCardHeader.displayName = "StatCardHeader";\n\nconst StatCardTitle = React.forwardRef<\n HTMLHeadingElement,\n React.HTMLAttributes<HTMLHeadingElement>\n>(({ className, ...props }, ref) => (\n <h3\n ref={ref}\n className={cn("text-xs font-medium text-muted-foreground tracking-wide uppercase", className)}\n {...props}\n />\n));\nStatCardTitle.displayName = "StatCardTitle";\n\nconst StatCardIcon = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n "flex h-8 w-8 items-center justify-center rounded-xl bg-muted text-muted-foreground border border-border/60 [&_svg]:h-4 [&_svg]:w-4",\n className\n )}\n {...props}\n />\n));\nStatCardIcon.displayName = "StatCardIcon";\n\nconst StatCardValue = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn("text-2xl font-bold tracking-tight text-foreground", className)}\n {...props}\n />\n));\nStatCardValue.displayName = "StatCardValue";\n\nexport interface StatCardTrendProps extends React.HTMLAttributes<HTMLDivElement> {\n trend?: "up" | "down" | "neutral";\n value?: string | number;\n}\n\nconst StatCardTrend = React.forwardRef<HTMLDivElement, StatCardTrendProps>(\n ({ className, trend = "neutral", value, children, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\n "inline-flex items-center gap-1 text-xs font-medium rounded-md px-1.5 py-0.5",\n trend === "up" && "text-success bg-success/10",\n trend === "down" && "text-destructive bg-destructive/10",\n trend === "neutral" && "text-muted-foreground bg-muted",\n className\n )}\n {...props}\n >\n {trend === "up" && <ArrowUpRight className="h-3 w-3" />}\n {trend === "down" && <ArrowDownRight className="h-3 w-3" />}\n {trend === "neutral" && <Minus className="h-3 w-3" />}\n {value ? <span>{value}</span> : children}\n </div>\n );\n }\n);\nStatCardTrend.displayName = "StatCardTrend";\n\nconst StatCardDescription = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => (\n <p\n ref={ref}\n className={cn("text-xs text-muted-foreground mt-2 flex items-center gap-2", className)}\n {...props}\n />\n));\nStatCardDescription.displayName = "StatCardDescription";\n\nexport {\n StatCard,\n StatCardHeader,\n StatCardTitle,\n StatCardIcon,\n StatCardValue,\n StatCardTrend,\n StatCardDescription,\n statCardVariants,\n};\n'
1257
+ }
1258
+ ]
1259
+ },
1260
+ "status": {
1261
+ "name": "status",
1262
+ "type": "components:ui",
1263
+ "category": "temel",
1264
+ "description": "Online, busy, away, offline durumlar\u0131 i\xE7in radar ping animasyonlu rozet",
1265
+ "dependencies": [
1266
+ "class-variance-authority"
1267
+ ],
1268
+ "devDependencies": [],
1269
+ "registryDependencies": [],
1270
+ "files": [
1271
+ {
1272
+ "name": "status.tsx",
1273
+ "content": '"use client";\n\nimport * as React from "react";\nimport { cva, type VariantProps } from "class-variance-authority";\nimport { cn } from "@/lib/utils";\n\nconst statusDotVariants = cva("rounded-full shrink-0", {\n variants: {\n status: {\n online: "bg-emerald-500",\n offline: "bg-neutral-500",\n busy: "bg-rose-500",\n away: "bg-amber-500",\n info: "bg-sky-500",\n },\n },\n defaultVariants: {\n status: "online",\n },\n});\n\nconst statusContainerVariants = cva("relative inline-flex shrink-0 items-center justify-center", {\n variants: {\n size: {\n sm: "h-1.5 w-1.5",\n default: "h-2 w-2",\n lg: "h-2.5 w-2.5",\n },\n },\n defaultVariants: {\n size: "default",\n },\n});\n\nexport interface StatusProps\n extends React.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof statusDotVariants>,\n VariantProps<typeof statusContainerVariants> {\n /** Canl\u0131 darbe (pulse) efekti */\n pulse?: boolean;\n /** Yan\u0131nda g\xF6sterilecek metin etiketi */\n label?: React.ReactNode;\n}\n\nconst Status = React.forwardRef<HTMLDivElement, StatusProps>(\n ({ className, status, size, pulse = false, label, children, ...props }, ref) => {\n const colorClass = statusDotVariants({ status });\n\n return (\n <div\n ref={ref}\n className={cn("inline-flex items-center gap-2 text-xs font-medium text-foreground", className)}\n {...props}\n >\n <span className={cn(statusContainerVariants({ size }))}>\n {pulse && status !== "offline" && (\n <span\n className={cn(\n "absolute inset-0 rounded-full animate-ping opacity-75",\n colorClass\n )}\n />\n )}\n <span className={cn("relative inline-flex h-full w-full rounded-full", colorClass)} />\n </span>\n {(label || children) && (\n <span className="leading-none">{label || children}</span>\n )}\n </div>\n );\n }\n);\n\nStatus.displayName = "Status";\n\nexport { Status, statusDotVariants, statusContainerVariants };\n'
1274
+ }
1275
+ ]
1276
+ },
1277
+ "switch": {
1278
+ "name": "switch",
1279
+ "type": "components:ui",
1280
+ "category": "form",
1281
+ "description": "A\xE7\u0131k/Kapal\u0131 ge\xE7i\u015F anahtar\u0131",
1282
+ "dependencies": [
1283
+ "@radix-ui/react-switch"
1284
+ ],
1285
+ "devDependencies": [],
1286
+ "registryDependencies": [],
1287
+ "files": [
1288
+ {
1289
+ "name": "switch.tsx",
1290
+ "content": '"use client";\n\nimport * as React from "react";\nimport * as SwitchPrimitive from "@radix-ui/react-switch";\nimport { cn } from "@/lib/utils";\n\nconst Switch = React.forwardRef<\n React.ElementRef<typeof SwitchPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof SwitchPrimitive.Root>\n>(({ className, ...props }, ref) => (\n <SwitchPrimitive.Root\n className={cn(\n "peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent",\n "shadow-sm transition-colors duration-200",\n "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",\n "disabled:cursor-not-allowed disabled:opacity-50",\n "data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",\n className\n )}\n {...props}\n ref={ref}\n >\n <SwitchPrimitive.Thumb\n className={cn(\n "pointer-events-none block h-4 w-4 rounded-full bg-background shadow-lg",\n "transition-transform duration-200",\n "data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0"\n )}\n />\n </SwitchPrimitive.Root>\n));\nSwitch.displayName = SwitchPrimitive.Root.displayName;\n\nexport { Switch };\n'
1291
+ }
1292
+ ]
1293
+ },
1294
+ "table": {
1295
+ "name": "table",
1296
+ "type": "components:ui",
1297
+ "category": "navigation",
1298
+ "description": "Semantik HTML veri tablosu",
1299
+ "dependencies": [],
1300
+ "devDependencies": [],
1301
+ "registryDependencies": [],
1302
+ "files": [
1303
+ {
1304
+ "name": "table.tsx",
1305
+ "content": '"use client";\n\nimport * as React from "react";\nimport { cn } from "@/lib/utils";\n\nconst Table = React.forwardRef<\n HTMLTableElement,\n React.HTMLAttributes<HTMLTableElement>\n>(({ className, ...props }, ref) => (\n <div className="relative w-full overflow-auto rounded-lg border border-border">\n <table\n ref={ref}\n className={cn("w-full caption-bottom text-sm", className)}\n {...props}\n />\n </div>\n));\nTable.displayName = "Table";\n\nconst TableHeader = React.forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => (\n <thead ref={ref} className={cn("bg-muted/40 [&_tr]:border-b border-border", className)} {...props} />\n));\nTableHeader.displayName = "TableHeader";\n\nconst TableBody = React.forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => (\n <tbody\n ref={ref}\n className={cn("[&_tr:last-child]:border-0", className)}\n {...props}\n />\n));\nTableBody.displayName = "TableBody";\n\nconst TableFooter = React.forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => (\n <tfoot\n ref={ref}\n className={cn(\n "border-t border-border bg-muted/50 font-medium [&>tr]:last-child:border-b-0",\n className\n )}\n {...props}\n />\n));\nTableFooter.displayName = "TableFooter";\n\nconst TableRow = React.forwardRef<\n HTMLTableRowElement,\n React.HTMLAttributes<HTMLTableRowElement>\n>(({ className, ...props }, ref) => (\n <tr\n ref={ref}\n className={cn(\n "border-b border-border transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",\n className\n )}\n {...props}\n />\n));\nTableRow.displayName = "TableRow";\n\nconst TableHead = React.forwardRef<\n HTMLTableCellElement,\n React.ThHTMLAttributes<HTMLTableCellElement>\n>(({ className, ...props }, ref) => (\n <th\n ref={ref}\n className={cn(\n "h-11 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0",\n className\n )}\n {...props}\n />\n));\nTableHead.displayName = "TableHead";\n\nconst TableCell = React.forwardRef<\n HTMLTableCellElement,\n React.TdHTMLAttributes<HTMLTableCellElement>\n>(({ className, ...props }, ref) => (\n <td\n ref={ref}\n className={cn("p-4 align-middle [&:has([role=checkbox])]:pr-0", className)}\n {...props}\n />\n));\nTableCell.displayName = "TableCell";\n\nconst TableCaption = React.forwardRef<\n HTMLTableCaptionElement,\n React.HTMLAttributes<HTMLTableCaptionElement>\n>(({ className, ...props }, ref) => (\n <caption\n ref={ref}\n className={cn("mt-4 text-sm text-muted-foreground", className)}\n {...props}\n />\n));\nTableCaption.displayName = "TableCaption";\n\nexport {\n Table,\n TableHeader,\n TableBody,\n TableFooter,\n TableHead,\n TableRow,\n TableCell,\n TableCaption,\n};\n'
1306
+ }
1307
+ ]
1308
+ },
1309
+ "tabs": {
1310
+ "name": "tabs",
1311
+ "type": "components:ui",
1312
+ "category": "navigation",
1313
+ "description": "Sekmeli i\xE7erik konteyneri",
1314
+ "dependencies": [
1315
+ "@radix-ui/react-tabs"
1316
+ ],
1317
+ "devDependencies": [],
1318
+ "registryDependencies": [],
1319
+ "files": [
1320
+ {
1321
+ "name": "tabs.tsx",
1322
+ "content": '"use client";\n\nimport * as React from "react";\nimport * as TabsPrimitive from "@radix-ui/react-tabs";\nimport { cn } from "@/lib/utils";\n\nconst Tabs = TabsPrimitive.Root;\n\nconst TabsList = React.forwardRef<\n React.ElementRef<typeof TabsPrimitive.List>,\n React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>\n>(({ className, ...props }, ref) => (\n <TabsPrimitive.List\n ref={ref}\n className={cn(\n "inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",\n className\n )}\n {...props}\n />\n));\nTabsList.displayName = TabsPrimitive.List.displayName;\n\nconst TabsTrigger = React.forwardRef<\n React.ElementRef<typeof TabsPrimitive.Trigger>,\n React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>\n>(({ className, ...props }, ref) => (\n <TabsPrimitive.Trigger\n ref={ref}\n className={cn(\n "inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background",\n "transition-all duration-150",\n "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",\n "disabled:pointer-events-none disabled:opacity-50",\n "data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-subtle",\n className\n )}\n {...props}\n />\n));\nTabsTrigger.displayName = TabsPrimitive.Trigger.displayName;\n\nconst TabsContent = React.forwardRef<\n React.ElementRef<typeof TabsPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>\n>(({ className, ...props }, ref) => (\n <TabsPrimitive.Content\n ref={ref}\n className={cn(\n "mt-2 ring-offset-background",\n "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",\n "data-[state=active]:animate-fade-in",\n className\n )}\n {...props}\n />\n));\nTabsContent.displayName = TabsPrimitive.Content.displayName;\n\nexport { Tabs, TabsList, TabsTrigger, TabsContent };\n'
1323
+ }
1324
+ ]
1325
+ },
1326
+ "textarea": {
1327
+ "name": "textarea",
1328
+ "type": "components:ui",
1329
+ "category": "form",
1330
+ "description": "\xC7ok sat\u0131rl\u0131 metin ve a\xE7\u0131klama girdi alan\u0131",
1331
+ "dependencies": [],
1332
+ "devDependencies": [],
1333
+ "registryDependencies": [],
1334
+ "files": [
1335
+ {
1336
+ "name": "textarea.tsx",
1337
+ "content": '"use client";\n\nimport * as React from "react";\nimport { cn } from "@/lib/utils";\n\nexport interface TextareaProps\n extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {\n /** Label metni */\n label?: string;\n /** Hata mesaj\u0131 */\n error?: string;\n /** Yard\u0131mc\u0131 metin */\n hint?: string;\n /** Karakter sayac\u0131 g\xF6ster */\n showCount?: boolean;\n /** Maksimum karakter say\u0131s\u0131 (showCount ile birlikte kullan\u0131l\u0131r) */\n maxLength?: number;\n}\n\nconst Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(\n ({ className, label, error, hint, showCount, maxLength, id, value, onChange, ...props }, ref) => {\n const [charCount, setCharCount] = React.useState(\n typeof value === "string" ? value.length : 0\n );\n const generatedId = React.useId();\n const textareaId = id ?? generatedId;\n\n const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n setCharCount(e.target.value.length);\n onChange?.(e);\n };\n\n return (\n <div className="w-full space-y-1.5">\n {label && (\n <label\n htmlFor={textareaId}\n className="text-sm font-medium leading-none text-foreground"\n >\n {label}\n </label>\n )}\n <textarea\n id={textareaId}\n ref={ref}\n value={value}\n onChange={handleChange}\n maxLength={maxLength}\n aria-invalid={!!error}\n aria-describedby={\n error\n ? `${textareaId}-error`\n : hint\n ? `${textareaId}-hint`\n : undefined\n }\n className={cn(\n "flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm",\n "text-foreground placeholder:text-muted-foreground",\n "transition-colors duration-150 resize-y",\n "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",\n "disabled:cursor-not-allowed disabled:opacity-50",\n error && "border-destructive focus-visible:ring-destructive",\n className\n )}\n {...props}\n />\n <div className="flex items-center justify-between">\n <div>\n {error && (\n <p id={`${textareaId}-error`} className="text-xs text-destructive" role="alert">\n {error}\n </p>\n )}\n {hint && !error && (\n <p id={`${textareaId}-hint`} className="text-xs text-muted-foreground">\n {hint}\n </p>\n )}\n </div>\n {showCount && maxLength && (\n <p className="text-xs text-muted-foreground ml-auto">\n {charCount}/{maxLength}\n </p>\n )}\n </div>\n </div>\n );\n }\n);\n\nTextarea.displayName = "Textarea";\n\nexport { Textarea };\n'
1338
+ }
1339
+ ]
1340
+ },
1341
+ "timeline": {
1342
+ "name": "timeline",
1343
+ "type": "components:ui",
1344
+ "category": "temel",
1345
+ "description": "Dikey s\xFCre\xE7 ve aktivite zaman ak\u0131\u015F\u0131",
1346
+ "dependencies": [
1347
+ "lucide-react",
1348
+ "class-variance-authority"
1349
+ ],
1350
+ "devDependencies": [],
1351
+ "registryDependencies": [],
1352
+ "files": [
1353
+ {
1354
+ "name": "timeline.tsx",
1355
+ "content": '"use client";\n\nimport * as React from "react";\nimport { cva, type VariantProps } from "class-variance-authority";\nimport { Check, Circle } from "lucide-react";\nimport { cn } from "@/lib/utils";\n\nconst timelineItemVariants = cva(\n "relative flex gap-4 pb-8 last:pb-0 group",\n {\n variants: {\n status: {\n default: "[&_[data-timeline-connector]]:bg-border",\n completed: "[&_[data-timeline-connector]]:bg-primary [&_[data-timeline-icon]]:border-primary [&_[data-timeline-icon]]:bg-primary [&_[data-timeline-icon]]:text-primary-foreground",\n active: "[&_[data-timeline-connector]]:bg-border [&_[data-timeline-icon]]:border-primary [&_[data-timeline-icon]]:ring-4 [&_[data-timeline-icon]]:ring-primary/20",\n pending: "[&_[data-timeline-connector]]:bg-border/40 [&_[data-timeline-icon]]:border-border/60 [&_[data-timeline-icon]]:text-muted-foreground",\n error: "[&_[data-timeline-connector]]:bg-destructive/40 [&_[data-timeline-icon]]:border-destructive [&_[data-timeline-icon]]:text-destructive",\n },\n },\n defaultVariants: {\n status: "default",\n },\n }\n);\n\nexport interface TimelineProps extends React.HTMLAttributes<HTMLOListElement> {}\n\nconst Timeline = React.forwardRef<HTMLOListElement, TimelineProps>(\n ({ className, ...props }, ref) => (\n <ol\n ref={ref}\n className={cn("flex flex-col relative", className)}\n {...props}\n />\n )\n);\nTimeline.displayName = "Timeline";\n\nexport interface TimelineItemProps\n extends React.LiHTMLAttributes<HTMLLIElement>,\n VariantProps<typeof timelineItemVariants> {}\n\nconst TimelineItem = React.forwardRef<HTMLLIElement, TimelineItemProps>(\n ({ className, status, ...props }, ref) => (\n <li\n ref={ref}\n className={cn(timelineItemVariants({ status }), className)}\n {...props}\n />\n )\n);\nTimelineItem.displayName = "TimelineItem";\n\nconst TimelineConnector = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n data-timeline-connector=""\n className={cn(\n "absolute left-3.5 top-7 -bottom-1 w-px bg-border group-last:hidden transition-colors",\n className\n )}\n {...props}\n />\n));\nTimelineConnector.displayName = "TimelineConnector";\n\nexport interface TimelineIconProps extends React.HTMLAttributes<HTMLDivElement> {\n status?: "default" | "completed" | "active" | "pending" | "error";\n}\n\nconst TimelineIcon = React.forwardRef<HTMLDivElement, TimelineIconProps>(\n ({ className, status, children, ...props }, ref) => (\n <div\n ref={ref}\n data-timeline-icon=""\n className={cn(\n "relative z-10 flex h-7 w-7 shrink-0 items-center justify-center rounded-full border border-border bg-background text-xs font-semibold shadow-xs transition-all",\n status === "completed" && "border-primary bg-primary text-primary-foreground",\n status === "active" && "border-primary ring-4 ring-primary/20 bg-background text-primary",\n status === "error" && "border-destructive bg-destructive/10 text-destructive",\n className\n )}\n {...props}\n >\n {children ||\n (status === "completed" ? (\n <Check className="h-3.5 w-3.5" />\n ) : status === "active" ? (\n <span className="h-2 w-2 rounded-full bg-primary animate-pulse" />\n ) : (\n <Circle className="h-2.5 w-2.5 fill-current opacity-40" />\n ))}\n </div>\n )\n);\nTimelineIcon.displayName = "TimelineIcon";\n\nconst TimelineHeader = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn("flex items-center justify-between gap-2", className)}\n {...props}\n />\n));\nTimelineHeader.displayName = "TimelineHeader";\n\nconst TimelineTitle = React.forwardRef<\n HTMLHeadingElement,\n React.HTMLAttributes<HTMLHeadingElement>\n>(({ className, ...props }, ref) => (\n <h4\n ref={ref}\n className={cn("text-xs font-semibold text-foreground tracking-tight", className)}\n {...props}\n />\n));\nTimelineTitle.displayName = "TimelineTitle";\n\nconst TimelineTime = React.forwardRef<\n HTMLTimeElement,\n React.TimeHTMLAttributes<HTMLTimeElement>\n>(({ className, ...props }, ref) => (\n <time\n ref={ref}\n className={cn("text-[11px] text-muted-foreground", className)}\n {...props}\n />\n));\nTimelineTime.displayName = "TimelineTime";\n\nconst TimelineDescription = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => (\n <p\n ref={ref}\n className={cn("text-xs text-muted-foreground mt-1 leading-relaxed", className)}\n {...props}\n />\n));\nTimelineDescription.displayName = "TimelineDescription";\n\nconst TimelineContent = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div ref={ref} className={cn("flex-1 pt-0.5", className)} {...props} />\n));\nTimelineContent.displayName = "TimelineContent";\n\nexport {\n Timeline,\n TimelineItem,\n TimelineConnector,\n TimelineIcon,\n TimelineHeader,\n TimelineTitle,\n TimelineTime,\n TimelineDescription,\n TimelineContent,\n timelineItemVariants,\n};\n'
1356
+ }
1357
+ ]
1358
+ },
1359
+ "toast": {
1360
+ "name": "toast",
1361
+ "type": "components:ui",
1362
+ "category": "feedback",
1363
+ "description": "Sonner tabanl\u0131 modern bildirim ve toaster sistemi",
1364
+ "dependencies": [
1365
+ "sonner"
1366
+ ],
1367
+ "devDependencies": [],
1368
+ "registryDependencies": [],
1369
+ "files": [
1370
+ {
1371
+ "name": "toast.tsx",
1372
+ "content": '"use client";\n\nimport * as React from "react";\nimport { Toaster as SonnerToaster, toast } from "sonner";\n\ntype ToasterProps = React.ComponentProps<typeof SonnerToaster>;\n\nconst Toaster = ({ ...props }: ToasterProps) => {\n return (\n <SonnerToaster\n className="toaster group"\n toastOptions={{\n classNames: {\n toast:\n "group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-overlay group-[.toaster]:rounded-lg group-[.toaster]:p-4",\n description: "group-[.toast]:text-muted-foreground text-xs mt-1",\n actionButton:\n "group-[.toast]:bg-primary group-[.toast]:text-primary-foreground group-[.toast]:font-medium text-xs rounded-md px-3 py-1.5",\n cancelButton:\n "group-[.toast]:bg-muted group-[.toast]:text-muted-foreground group-[.toast]:font-medium text-xs rounded-md px-3 py-1.5",\n error: "group-[.toaster]:border-destructive/30 group-[.toaster]:bg-destructive/5 group-[.toaster]:text-destructive",\n success: "group-[.toaster]:border-success/30 group-[.toaster]:bg-success/5 group-[.toaster]:text-success",\n warning: "group-[.toaster]:border-warning/30 group-[.toaster]:bg-warning/5 group-[.toaster]:text-warning",\n info: "group-[.toaster]:border-info/30 group-[.toaster]:bg-info/5 group-[.toaster]:text-info",\n },\n }}\n {...props}\n />\n );\n};\n\nexport { Toaster, toast };\n'
1373
+ }
1374
+ ]
1375
+ },
1376
+ "toggle": {
1377
+ "name": "toggle",
1378
+ "type": "components:ui",
1379
+ "category": "navigation",
1380
+ "description": "\u0130ki durumlu bas-b\u0131rak buton",
1381
+ "dependencies": [
1382
+ "@radix-ui/react-toggle",
1383
+ "class-variance-authority"
1384
+ ],
1385
+ "devDependencies": [],
1386
+ "registryDependencies": [],
1387
+ "files": [
1388
+ {
1389
+ "name": "toggle.tsx",
1390
+ "content": '"use client";\n\nimport * as React from "react";\nimport * as TogglePrimitive from "@radix-ui/react-toggle";\nimport { cva, type VariantProps } from "class-variance-authority";\nimport { cn } from "@/lib/utils";\n\nconst toggleVariants = cva(\n "inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground border border-transparent",\n {\n variants: {\n variant: {\n default: "bg-transparent",\n outline:\n "border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground",\n },\n size: {\n default: "h-9 px-3 min-w-9",\n sm: "h-8 px-2 min-w-8 text-xs",\n lg: "h-10 px-3.5 min-w-10",\n },\n },\n defaultVariants: {\n variant: "default",\n size: "default",\n },\n }\n);\n\nconst Toggle = React.forwardRef<\n React.ElementRef<typeof TogglePrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof TogglePrimitive.Root> &\n VariantProps<typeof toggleVariants>\n>(({ className, variant, size, ...props }, ref) => (\n <TogglePrimitive.Root\n ref={ref}\n className={cn(toggleVariants({ variant, size, className }))}\n {...props}\n />\n));\n\nToggle.displayName = TogglePrimitive.Root.displayName;\n\nexport { Toggle, toggleVariants };\n'
1391
+ }
1392
+ ]
1393
+ },
1394
+ "toggle-group": {
1395
+ "name": "toggle-group",
1396
+ "type": "components:ui",
1397
+ "category": "navigation",
1398
+ "description": "\xC7oklu veya tekil se\xE7imli toggle grubu",
1399
+ "dependencies": [
1400
+ "@radix-ui/react-toggle-group",
1401
+ "class-variance-authority"
1402
+ ],
1403
+ "devDependencies": [],
1404
+ "registryDependencies": [],
1405
+ "files": [
1406
+ {
1407
+ "name": "toggle-group.tsx",
1408
+ "content": '"use client";\n\nimport * as React from "react";\nimport * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group";\nimport { type VariantProps } from "class-variance-authority";\nimport { cn } from "@/lib/utils";\nimport { toggleVariants } from "@/components/ui/toggle";\n\nconst ToggleGroupContext = React.createContext<\n VariantProps<typeof toggleVariants>\n>({\n size: "default",\n variant: "default",\n});\n\nconst ToggleGroup = React.forwardRef<\n React.ElementRef<typeof ToggleGroupPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Root> &\n VariantProps<typeof toggleVariants>\n>(({ className, variant, size, children, ...props }, ref) => (\n <ToggleGroupPrimitive.Root\n ref={ref}\n className={cn("flex items-center justify-center gap-1", className)}\n {...props}\n >\n <ToggleGroupContext.Provider value={{ variant, size }}>\n {children}\n </ToggleGroupContext.Provider>\n </ToggleGroupPrimitive.Root>\n));\n\nToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName;\n\nconst ToggleGroupItem = React.forwardRef<\n React.ElementRef<typeof ToggleGroupPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Item> &\n VariantProps<typeof toggleVariants>\n>(({ className, children, variant, size, ...props }, ref) => {\n const context = React.useContext(ToggleGroupContext);\n\n return (\n <ToggleGroupPrimitive.Item\n ref={ref}\n className={cn(\n toggleVariants({\n variant: context.variant || variant,\n size: context.size || size,\n }),\n className\n )}\n {...props}\n >\n {children}\n </ToggleGroupPrimitive.Item>\n );\n});\n\nToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName;\n\nexport { ToggleGroup, ToggleGroupItem };\n'
1409
+ }
1410
+ ]
1411
+ },
1412
+ "tooltip": {
1413
+ "name": "tooltip",
1414
+ "type": "components:ui",
1415
+ "category": "overlay",
1416
+ "description": "Hover ipucu metin balonu",
1417
+ "dependencies": [
1418
+ "@radix-ui/react-tooltip"
1419
+ ],
1420
+ "devDependencies": [],
1421
+ "registryDependencies": [],
1422
+ "files": [
1423
+ {
1424
+ "name": "tooltip.tsx",
1425
+ "content": '"use client";\n\nimport * as React from "react";\nimport * as TooltipPrimitive from "@radix-ui/react-tooltip";\nimport { cn } from "@/lib/utils";\n\nconst TooltipProvider = TooltipPrimitive.Provider;\nconst Tooltip = TooltipPrimitive.Root;\nconst TooltipTrigger = TooltipPrimitive.Trigger;\n\nconst TooltipContent = React.forwardRef<\n React.ElementRef<typeof TooltipPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>\n>(({ className, sideOffset = 4, ...props }, ref) => (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n className={cn(\n "z-50 overflow-hidden rounded-md border border-border bg-popover px-3 py-1.5 text-xs text-popover-foreground shadow-overlay",\n "animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",\n className\n )}\n {...props}\n />\n </TooltipPrimitive.Portal>\n));\nTooltipContent.displayName = TooltipPrimitive.Content.displayName;\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };\n'
1426
+ }
1427
+ ]
1428
+ },
1429
+ "auth-card": {
1430
+ "name": "auth-card",
1431
+ "type": "components:block",
1432
+ "category": "bloklar",
1433
+ "description": "Giri\u015F, Kay\u0131t, \u015Eifremi Unuttum ve Sosyal Giri\u015F destekli kimlik do\u011Frulama kart\u0131",
1434
+ "dependencies": [
1435
+ "lucide-react"
1436
+ ],
1437
+ "devDependencies": [],
1438
+ "registryDependencies": [],
1439
+ "files": [
1440
+ {
1441
+ "name": "auth-card.tsx",
1442
+ "content": '"use client";\n\nimport * as React from "react";\nimport { Mail, Lock, User, Eye, EyeOff, ArrowRight, Loader2, ArrowLeft } from "lucide-react";\nimport { cn } from "@/lib/utils";\nimport { Button } from "@/components/ui/../components/button";\nimport { Input } from "@/components/ui/../components/input";\nimport { Label } from "@/components/ui/../components/label";\nimport { Checkbox } from "@/components/ui/../components/checkbox";\nimport { Separator } from "@/components/ui/../components/separator";\n\nexport interface AuthCardProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "onError"> {\n defaultMode?: "login" | "register" | "forgot-password";\n logo?: React.ReactNode;\n title?: string;\n showSocial?: boolean;\n onLogin?: (data: { email: string; password?: string; rememberMe?: boolean }) => Promise<void> | void;\n onRegister?: (data: { name?: string; email: string; password?: string }) => Promise<void> | void;\n onForgotPassword?: (email: string) => Promise<void> | void;\n onSocialLogin?: (provider: "github" | "google") => void;\n}\n\nexport function AuthCard({\n defaultMode = "login",\n logo,\n showSocial = true,\n onLogin,\n onRegister,\n onForgotPassword,\n onSocialLogin,\n className,\n ...props\n}: AuthCardProps) {\n const [mode, setMode] = React.useState<"login" | "register" | "forgot-password">(defaultMode);\n const [showPassword, setShowPassword] = React.useState(false);\n const [loading, setLoading] = React.useState(false);\n\n const [name, setName] = React.useState("");\n const [email, setEmail] = React.useState("");\n const [password, setPassword] = React.useState("");\n const [rememberMe, setRememberMe] = React.useState(false);\n const [agreedTerms, setAgreedTerms] = React.useState(false);\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n setLoading(true);\n try {\n if (mode === "login") {\n await onLogin?.({ email, password, rememberMe });\n } else if (mode === "register") {\n await onRegister?.({ name, email, password });\n } else if (mode === "forgot-password") {\n await onForgotPassword?.(email);\n }\n } finally {\n setLoading(false);\n }\n };\n\n return (\n <div\n className={cn(\n "w-full max-w-md mx-auto rounded-2xl border border-border/80 bg-card p-6 sm:p-8 shadow-card",\n className\n )}\n {...props}\n >\n {/* Header */}\n <div className="flex flex-col items-center text-center space-y-2 mb-6">\n {logo && <div className="mb-2">{logo}</div>}\n <h2 className="text-xl font-bold tracking-tight text-foreground">\n {mode === "login" && "Hesab\u0131n\u0131za Giri\u015F Yap\u0131n"}\n {mode === "register" && "Yeni Hesap Olu\u015Fturun"}\n {mode === "forgot-password" && "\u015Eifrenizi S\u0131f\u0131rlay\u0131n"}\n </h2>\n <p className="text-xs text-muted-foreground max-w-xs">\n {mode === "login" && "Bilgilerinizi girerek y\xF6netim paneline eri\u015Fin."}\n {mode === "register" && "H\u0131zl\u0131ca kaydolun ve hemen kullanmaya ba\u015Flay\u0131n."}\n {mode === "forgot-password" && "E-posta adresinize s\u0131f\u0131rlama ba\u011Flant\u0131s\u0131 g\xF6nderece\u011Fiz."}\n </p>\n </div>\n\n {/* Social Login Buttons */}\n {showSocial && mode !== "forgot-password" && (\n <div className="space-y-3 mb-6">\n <div className="grid grid-cols-2 gap-2.5">\n <Button\n type="button"\n variant="outline"\n size="sm"\n className="text-xs font-medium rounded-xl h-9 gap-2 border-border/80 hover:bg-muted/50"\n onClick={() => onSocialLogin?.("github")}\n >\n <svg className="h-4 w-4 fill-current" viewBox="0 0 24 24">\n <path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z" />\n </svg>\n GitHub\n </Button>\n <Button\n type="button"\n variant="outline"\n size="sm"\n className="text-xs font-medium rounded-xl h-9 gap-2 border-border/80 hover:bg-muted/50"\n onClick={() => onSocialLogin?.("google")}\n >\n <svg className="h-4 w-4" viewBox="0 0 24 24">\n <path\n fill="#4285F4"\n d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"\n />\n <path\n fill="#34A853"\n d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"\n />\n <path\n fill="#FBBC05"\n d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.06H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.94l2.85-2.22.81-.63z"\n />\n <path\n fill="#EA4335"\n d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.06l3.66 2.84c.87-2.6 3.3-4.52 6.16-4.52z"\n />\n </svg>\n Google\n </Button>\n </div>\n\n <div className="relative flex items-center justify-center my-4">\n <Separator />\n <span className="absolute bg-card px-2 text-[11px] text-muted-foreground">\n veya e-posta ile\n </span>\n </div>\n </div>\n )}\n\n {/* Main Form */}\n <form onSubmit={handleSubmit} className="space-y-4">\n {/* Full Name Field (Register Mode) */}\n {mode === "register" && (\n <div className="space-y-1.5 animate-in fade-in-50 duration-200">\n <Label htmlFor="auth-name" className="text-xs">\n Ad Soyad\n </Label>\n <Input\n id="auth-name"\n placeholder="Alexourus"\n leftIcon={<User className="h-4 w-4" />}\n value={name}\n onChange={(e) => setName(e.target.value)}\n required\n className="h-9 text-xs rounded-xl"\n />\n </div>\n )}\n\n {/* Email Field */}\n <div className="space-y-1.5">\n <Label htmlFor="auth-email" className="text-xs">\n E-posta Adresi\n </Label>\n <Input\n id="auth-email"\n type="email"\n placeholder="ornek@alanadi.com"\n leftIcon={<Mail className="h-4 w-4" />}\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n required\n className="h-9 text-xs rounded-xl"\n />\n </div>\n\n {/* Password Field (Login & Register Modes) */}\n {mode !== "forgot-password" && (\n <div className="space-y-1.5">\n <div className="flex items-center justify-between">\n <Label htmlFor="auth-pass" className="text-xs">\n \u015Eifre\n </Label>\n {mode === "login" && (\n <button\n type="button"\n onClick={() => setMode("forgot-password")}\n className="text-[11px] text-primary hover:underline cursor-pointer"\n >\n \u015Eifremi unuttum\n </button>\n )}\n </div>\n <Input\n id="auth-pass"\n type={showPassword ? "text" : "password"}\n placeholder="\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022"\n leftIcon={<Lock className="h-4 w-4" />}\n rightIcon={\n <button\n type="button"\n onClick={() => setShowPassword((p) => !p)}\n className="text-muted-foreground hover:text-foreground pointer-events-auto cursor-pointer p-0.5"\n aria-label={showPassword ? "\u015Eifreyi gizle" : "\u015Eifreyi g\xF6ster"}\n >\n {showPassword ? <EyeOff className="h-4 w-4" /> : <Eye className="h-4 w-4" />}\n </button>\n }\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n required\n className="h-9 text-xs rounded-xl"\n />\n </div>\n )}\n\n {/* Remember Me / Terms Checkboxes */}\n {mode === "login" && (\n <div className="flex items-center gap-2 pt-1">\n <Checkbox\n id="remember-me"\n checked={rememberMe}\n onCheckedChange={(checked) => setRememberMe(!!checked)}\n />\n <Label htmlFor="remember-me" className="text-xs cursor-pointer text-muted-foreground">\n Beni hat\u0131rla\n </Label>\n </div>\n )}\n\n {mode === "register" && (\n <div className="flex items-center gap-2 pt-1">\n <Checkbox\n id="terms-agree"\n checked={agreedTerms}\n onCheckedChange={(checked) => setAgreedTerms(!!checked)}\n required\n />\n <Label htmlFor="terms-agree" className="text-xs cursor-pointer text-muted-foreground">\n Kullan\u0131m \u015Fartlar\u0131n\u0131 ve gizlilik politikas\u0131n\u0131 onayl\u0131yorum\n </Label>\n </div>\n )}\n\n {/* Submit Button */}\n <Button\n type="submit"\n disabled={loading}\n className="w-full text-xs font-semibold rounded-xl h-9 gap-1.5 mt-2"\n >\n {loading ? (\n <>\n <Loader2 className="h-3.5 w-3.5 animate-spin" />\n <span>\u0130\u015Fleniyor...</span>\n </>\n ) : (\n <>\n <span>\n {mode === "login" && "Giri\u015F Yap"}\n {mode === "register" && "Hesap Olu\u015Ftur"}\n {mode === "forgot-password" && "S\u0131f\u0131rlama Ba\u011Flant\u0131s\u0131 G\xF6nder"}\n </span>\n <ArrowRight className="h-3.5 w-3.5" />\n </>\n )}\n </Button>\n </form>\n\n {/* Footer Navigation */}\n <div className="mt-6 pt-4 border-t border-border/60 text-center text-xs text-muted-foreground">\n {mode === "login" && (\n <p>\n Hesab\u0131n\u0131z yok mu?{" "}\n <button\n type="button"\n onClick={() => setMode("register")}\n className="font-semibold text-foreground hover:underline"\n >\n Hemen Kaydolun\n </button>\n </p>\n )}\n {mode === "register" && (\n <p>\n Zaten hesab\u0131n\u0131z var m\u0131?{" "}\n <button\n type="button"\n onClick={() => setMode("login")}\n className="font-semibold text-foreground hover:underline"\n >\n Giri\u015F Yap\u0131n\n </button>\n </p>\n )}\n {mode === "forgot-password" && (\n <button\n type="button"\n onClick={() => setMode("login")}\n className="inline-flex items-center gap-1.5 font-medium text-foreground hover:underline"\n >\n <ArrowLeft className="h-3 w-3" />\n Giri\u015F sayfas\u0131na d\xF6n\n </button>\n )}\n </div>\n </div>\n );\n}\n'
1443
+ }
1444
+ ]
1445
+ },
1446
+ "data-table": {
1447
+ "name": "data-table",
1448
+ "type": "components:block",
1449
+ "category": "bloklar",
1450
+ "description": "Arama, s\xFCtun s\u0131ralama ve sayfalama destekli geli\u015Fmi\u015F SaaS tablosu",
1451
+ "dependencies": [
1452
+ "lucide-react",
1453
+ "@tanstack/react-table"
1454
+ ],
1455
+ "devDependencies": [],
1456
+ "registryDependencies": [],
1457
+ "files": [
1458
+ {
1459
+ "name": "data-table.tsx",
1460
+ "content": '"use client";\n\nimport * as React from "react";\nimport {\n type ColumnDef,\n type ColumnFiltersState,\n type SortingState,\n type VisibilityState,\n flexRender,\n getCoreRowModel,\n getFilteredRowModel,\n getPaginationRowModel,\n getSortedRowModel,\n useReactTable,\n} from "@tanstack/react-table";\nimport {\n ChevronDown,\n ChevronLeft,\n ChevronRight,\n ChevronsLeft,\n ChevronsRight,\n Search,\n SlidersHorizontal,\n} from "lucide-react";\n\nimport { cn } from "@/lib/utils";\nimport { Button } from "@/components/ui/../components/button";\nimport { Input } from "@/components/ui/../components/input";\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from "@/components/ui/../components/dropdown-menu";\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from "@/components/ui/../components/table";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from "@/components/ui/../components/select";\n\nexport interface DataTableProps<TData, TValue = any> {\n columns: ColumnDef<TData, TValue>[];\n data: TData[];\n searchKey?: string;\n searchPlaceholder?: string;\n className?: string;\n}\n\nexport function DataTable<TData, TValue>({\n columns,\n data,\n searchKey,\n searchPlaceholder = "Ara...",\n className,\n}: DataTableProps<TData, TValue>) {\n const [sorting, setSorting] = React.useState<SortingState>([]);\n const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>([]);\n const [columnVisibility, setColumnVisibility] = React.useState<VisibilityState>({});\n const [rowSelection, setRowSelection] = React.useState({});\n const [globalFilter, setGlobalFilter] = React.useState("");\n\n const table = useReactTable({\n data,\n columns,\n getCoreRowModel: getCoreRowModel(),\n getPaginationRowModel: getPaginationRowModel(),\n onSortingChange: setSorting,\n getSortedRowModel: getSortedRowModel(),\n onColumnFiltersChange: setColumnFilters,\n getFilteredRowModel: getFilteredRowModel(),\n onColumnVisibilityChange: setColumnVisibility,\n onRowSelectionChange: setRowSelection,\n onGlobalFilterChange: setGlobalFilter,\n state: {\n sorting,\n columnFilters,\n columnVisibility,\n rowSelection,\n globalFilter,\n },\n });\n\n return (\n <div className={cn("space-y-4 w-full", className)}>\n {/* \xDCst Ara\xE7 \xC7ubu\u011Fu */}\n <div className="flex flex-col sm:flex-row items-center justify-between gap-3">\n <div className="w-full sm:w-72">\n <Input\n placeholder={searchPlaceholder}\n leftIcon={<Search className="h-4 w-4" />}\n value={\n searchKey\n ? (table.getColumn(searchKey)?.getFilterValue() as string) ?? ""\n : globalFilter\n }\n onChange={(event) => {\n if (searchKey) {\n table.getColumn(searchKey)?.setFilterValue(event.target.value);\n } else {\n setGlobalFilter(event.target.value);\n }\n }}\n className="h-9 text-xs"\n />\n </div>\n\n <div className="flex items-center gap-2 w-full sm:w-auto justify-end">\n {/* Kolon G\xF6r\xFCn\xFCrl\xFC\u011F\xFC Dropdown */}\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant="outline" size="sm" className="h-9 gap-1.5">\n <SlidersHorizontal className="h-4 w-4" />\n <span>S\xFCtunlar</span>\n <ChevronDown className="h-3.5 w-3.5 opacity-60" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align="end" className="w-44">\n <DropdownMenuLabel>S\xFCtunlar\u0131 Y\xF6net</DropdownMenuLabel>\n <DropdownMenuSeparator />\n {table\n .getAllColumns()\n .filter((column: any) => column.getCanHide())\n .map((column: any) => {\n return (\n <DropdownMenuCheckboxItem\n key={column.id}\n className="capitalize text-xs"\n checked={column.getIsVisible()}\n onCheckedChange={(value) => column.toggleVisibility(!!value)}\n >\n {column.id}\n </DropdownMenuCheckboxItem>\n );\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </div>\n\n {/* Tablo Kapsay\u0131c\u0131s\u0131 */}\n <div className="rounded-lg border border-border bg-card overflow-hidden shadow-xs">\n <Table>\n <TableHeader className="bg-muted/40">\n {table.getHeaderGroups().map((headerGroup: any) => (\n <TableRow key={headerGroup.id}>\n {headerGroup.headers.map((header: any) => {\n return (\n <TableHead key={header.id} className="h-10 text-xs font-semibold">\n {header.isPlaceholder\n ? null\n : flexRender(\n header.column.columnDef.header,\n header.getContext()\n )}\n </TableHead>\n );\n })}\n </TableRow>\n ))}\n </TableHeader>\n <TableBody>\n {table.getRowModel().rows?.length ? (\n table.getRowModel().rows.map((row: any) => (\n <TableRow\n key={row.id}\n data-state={row.getIsSelected() && "selected"}\n className="transition-colors hover:bg-muted/30"\n >\n {row.getVisibleCells().map((cell: any) => (\n <TableCell key={cell.id} className="py-3 text-sm">\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </TableCell>\n ))}\n </TableRow>\n ))\n ) : (\n <TableRow>\n <TableCell\n colSpan={columns.length}\n className="h-32 text-center text-muted-foreground text-sm"\n >\n Sonu\xE7 bulunamad\u0131.\n </TableCell>\n </TableRow>\n )}\n </TableBody>\n </Table>\n </div>\n\n {/* Alt Altl\u0131k / Sayfalama (Pagination) Bar\u0131 */}\n <div className="flex flex-col sm:flex-row items-center justify-between gap-4 px-1 py-1">\n <div className="text-xs text-muted-foreground">\n {table.getFilteredSelectedRowModel().rows.length} /{" "}\n {table.getFilteredRowModel().rows.length} sat\u0131r se\xE7ildi.\n </div>\n\n <div className="flex flex-wrap items-center gap-4 sm:gap-6">\n <div className="flex items-center gap-2">\n <span className="text-xs text-muted-foreground">Sayfa Ba\u015F\u0131na:</span>\n <Select\n value={`${table.getState().pagination.pageSize}`}\n onValueChange={(value) => {\n table.setPageSize(Number(value));\n }}\n >\n <SelectTrigger className="h-8 w-[70px]">\n <SelectValue placeholder={table.getState().pagination.pageSize} />\n </SelectTrigger>\n <SelectContent side="top">\n {[5, 10, 20, 50].map((pageSize) => (\n <SelectItem key={pageSize} value={`${pageSize}`}>\n {pageSize}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n <div className="text-xs font-medium text-foreground">\n Sayfa {table.getState().pagination.pageIndex + 1} /{" "}\n {table.getPageCount() || 1}\n </div>\n\n <div className="flex items-center gap-1">\n <Button\n variant="outline"\n size="icon"\n className="h-8 w-8"\n onClick={() => table.setPageIndex(0)}\n disabled={!table.getCanPreviousPage()}\n >\n <ChevronsLeft className="h-4 w-4" />\n </Button>\n <Button\n variant="outline"\n size="icon"\n className="h-8 w-8"\n onClick={() => table.previousPage()}\n disabled={!table.getCanPreviousPage()}\n >\n <ChevronLeft className="h-4 w-4" />\n </Button>\n <Button\n variant="outline"\n size="icon"\n className="h-8 w-8"\n onClick={() => table.nextPage()}\n disabled={!table.getCanNextPage()}\n >\n <ChevronRight className="h-4 w-4" />\n </Button>\n <Button\n variant="outline"\n size="icon"\n className="h-8 w-8"\n onClick={() => table.setPageIndex(table.getPageCount() - 1)}\n disabled={!table.getCanNextPage()}\n >\n <ChevronsRight className="h-4 w-4" />\n </Button>\n </div>\n </div>\n </div>\n </div>\n );\n}\n'
1461
+ }
1462
+ ]
1463
+ },
1464
+ "file-uploader": {
1465
+ "name": "file-uploader",
1466
+ "type": "components:block",
1467
+ "category": "bloklar",
1468
+ "description": "S\xFCr\xFCkle-b\u0131rak destekli dosya y\xFCkleyici",
1469
+ "dependencies": [
1470
+ "lucide-react"
1471
+ ],
1472
+ "devDependencies": [],
1473
+ "registryDependencies": [],
1474
+ "files": [
1475
+ {
1476
+ "name": "file-uploader.tsx",
1477
+ "content": '"use client";\n\nimport * as React from "react";\nimport {\n UploadCloud,\n X,\n FileText,\n FileImage,\n FileArchive,\n File as FileIcon,\n CheckCircle2,\n AlertCircle,\n} from "lucide-react";\n\nimport { cn } from "@/lib/utils";\nimport { Button } from "@/components/ui/../components/button";\nimport { Progress } from "@/components/ui/../components/progress";\n\nexport interface FileItem {\n id: string;\n file: File;\n progress: number;\n status: "uploading" | "completed" | "error";\n error?: string;\n}\n\nexport interface FileUploaderProps {\n maxSizeMB?: number; // Varsay\u0131lan 5 MB\n maxFiles?: number; // Varsay\u0131lan 5 dosya\n accept?: string; // \xF6rn: "image/*,.pdf,.zip"\n onChange?: (files: File[]) => void;\n className?: string;\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes === 0) return "0 Bytes";\n const k = 1024;\n const sizes = ["Bytes", "KB", "MB", "GB"];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];\n}\n\nfunction getFileIcon(file: File) {\n if (file.type.startsWith("image/")) {\n return <FileImage className="h-5 w-5 text-sky-400" />;\n }\n if (file.type.includes("pdf") || file.type.includes("document") || file.type.includes("text")) {\n return <FileText className="h-5 w-5 text-indigo-400" />;\n }\n if (file.type.includes("zip") || file.type.includes("rar") || file.type.includes("tar")) {\n return <FileArchive className="h-5 w-5 text-amber-400" />;\n }\n return <FileIcon className="h-5 w-5 text-muted-foreground" />;\n}\n\nexport function FileUploader({\n maxSizeMB = 5,\n maxFiles = 5,\n accept = "image/*,.pdf,.docx,.zip",\n onChange,\n className,\n}: FileUploaderProps) {\n const [files, setFiles] = React.useState<FileItem[]>([]);\n const [isDragging, setIsDragging] = React.useState(false);\n const fileInputRef = React.useRef<HTMLInputElement>(null);\n\n const handleFiles = (incomingFiles: FileList | File[]) => {\n const validFiles: FileItem[] = [];\n const maxSizeBytes = maxSizeMB * 1024 * 1024;\n\n Array.from(incomingFiles).forEach((file) => {\n if (files.length + validFiles.length >= maxFiles) return;\n\n if (file.size > maxSizeBytes) {\n validFiles.push({\n id: Math.random().toString(36).substring(2, 9),\n file,\n progress: 0,\n status: "error",\n error: `Maksimum ${maxSizeMB}MB a\u015Famaz.`,\n });\n } else {\n validFiles.push({\n id: Math.random().toString(36).substring(2, 9),\n file,\n progress: 0,\n status: "uploading",\n });\n }\n });\n\n const updated = [...files, ...validFiles];\n setFiles(updated);\n if (onChange) {\n onChange(updated.map((f) => f.file));\n }\n\n // Y\xFCkleme sim\xFClasyonu\n validFiles.forEach((item) => {\n if (item.status === "uploading") {\n let progress = 0;\n const interval = setInterval(() => {\n progress += Math.floor(Math.random() * 30) + 20;\n if (progress >= 100) {\n progress = 100;\n clearInterval(interval);\n setFiles((prev) =>\n prev.map((f) =>\n f.id === item.id ? { ...f, progress: 100, status: "completed" } : f\n )\n );\n } else {\n setFiles((prev) =>\n prev.map((f) => (f.id === item.id ? { ...f, progress } : f))\n );\n }\n }, 300);\n }\n });\n };\n\n const handleDragOver = (e: React.DragEvent) => {\n e.preventDefault();\n setIsDragging(true);\n };\n\n const handleDragLeave = (e: React.DragEvent) => {\n e.preventDefault();\n setIsDragging(false);\n };\n\n const handleDrop = (e: React.DragEvent) => {\n e.preventDefault();\n setIsDragging(false);\n if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n handleFiles(e.dataTransfer.files);\n }\n };\n\n const removeFile = (id: string) => {\n const updated = files.filter((f) => f.id !== id);\n setFiles(updated);\n if (onChange) {\n onChange(updated.map((f) => f.file));\n }\n };\n\n return (\n <div className={cn("space-y-4 w-full", className)}>\n {/* S\xFCr\xFCkle B\u0131rak Alan\u0131 */}\n <div\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n onClick={() => fileInputRef.current?.click()}\n className={cn(\n "group relative flex flex-col items-center justify-center rounded-xl border-2 border-dashed border-border bg-card p-6 text-center transition-all cursor-pointer hover:border-primary/50 hover:bg-accent/40",\n isDragging && "border-primary bg-primary/5 ring-4 ring-primary/10"\n )}\n >\n <input\n ref={fileInputRef}\n type="file"\n multiple\n accept={accept}\n className="hidden"\n onChange={(e) => {\n if (e.target.files) handleFiles(e.target.files);\n }}\n />\n\n <div className="flex h-12 w-12 items-center justify-center rounded-full bg-muted transition-transform group-hover:scale-110">\n <UploadCloud className="h-6 w-6 text-primary" />\n </div>\n\n <div className="mt-3 space-y-1">\n <p className="text-sm font-semibold text-foreground">\n Dosya y\xFCklemek i\xE7in t\u0131klay\u0131n veya buraya s\xFCr\xFCkleyin\n </p>\n <p className="text-xs text-muted-foreground">\n Desteklenenler: PNG, JPG, PDF, DOCX (Maks {maxSizeMB}MB, en fazla {maxFiles} dosya)\n </p>\n </div>\n </div>\n\n {/* Y\xFCklenen Dosya Listesi */}\n {files.length > 0 && (\n <div className="space-y-2">\n <p className="text-xs font-medium text-muted-foreground px-1">\n Y\xFCklenen Dosyalar ({files.length}/{maxFiles})\n </p>\n <div className="space-y-2">\n {files.map((fileItem) => {\n const isImage = fileItem.file.type.startsWith("image/");\n const previewUrl = isImage ? URL.createObjectURL(fileItem.file) : null;\n\n return (\n <div\n key={fileItem.id}\n className="flex items-center gap-3 rounded-lg border border-border bg-card p-3 shadow-2xs transition-all"\n >\n {/* Dosya \u0130konu veya G\xF6rsel \xD6nizleme */}\n {previewUrl ? (\n <img\n src={previewUrl}\n alt={fileItem.file.name}\n className="h-10 w-10 rounded-md object-cover border border-border"\n />\n ) : (\n <div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-md bg-muted">\n {getFileIcon(fileItem.file)}\n </div>\n )}\n\n {/* Dosya Detaylar\u0131 & \u0130lerleme Bar\u0131 */}\n <div className="flex-1 min-w-0 space-y-1">\n <div className="flex items-center justify-between text-xs">\n <span className="font-medium truncate text-foreground">\n {fileItem.file.name}\n </span>\n <span className="text-muted-foreground shrink-0 ml-2">\n {formatBytes(fileItem.file.size)}\n </span>\n </div>\n\n {fileItem.status === "uploading" && (\n <div className="space-y-1">\n <Progress value={fileItem.progress} className="h-1.5" />\n <div className="text-[10px] text-muted-foreground text-right">\n %{fileItem.progress}\n </div>\n </div>\n )}\n\n {fileItem.status === "completed" && (\n <div className="flex items-center gap-1 text-[11px] text-emerald-500 font-medium">\n <CheckCircle2 className="h-3.5 w-3.5" />\n <span>Y\xFCklendi</span>\n </div>\n )}\n\n {fileItem.status === "error" && (\n <div className="flex items-center gap-1 text-[11px] text-destructive font-medium">\n <AlertCircle className="h-3.5 w-3.5" />\n <span>{fileItem.error || "Y\xFCkleme hatas\u0131"}</span>\n </div>\n )}\n </div>\n\n {/* Silme Butonu */}\n <Button\n variant="ghost"\n size="icon"\n className="h-8 w-8 text-muted-foreground hover:text-foreground shrink-0"\n onClick={(e) => {\n e.stopPropagation();\n removeFile(fileItem.id);\n }}\n >\n <X className="h-4 w-4" />\n </Button>\n </div>\n );\n })}\n </div>\n </div>\n )}\n </div>\n );\n}\n'
1478
+ }
1479
+ ]
1480
+ },
1481
+ "multi-step-form": {
1482
+ "name": "multi-step-form",
1483
+ "type": "components:block",
1484
+ "category": "bloklar",
1485
+ "description": "Ad\u0131m ad\u0131m sihirbaz form blo\u011Fu",
1486
+ "dependencies": [
1487
+ "lucide-react"
1488
+ ],
1489
+ "devDependencies": [],
1490
+ "registryDependencies": [],
1491
+ "files": [
1492
+ {
1493
+ "name": "multi-step-form.tsx",
1494
+ "content": '"use client";\n\nimport * as React from "react";\nimport { Check, ChevronLeft, ChevronRight, Loader2, Sparkles } from "lucide-react";\n\nimport { cn } from "@/lib/utils";\nimport { Button } from "@/components/ui/../components/button";\nimport { Card, CardContent, CardFooter, CardHeader } from "@/components/ui/../components/card";\n\nexport interface StepItem {\n id: string;\n title: string;\n description?: string;\n component: React.ReactNode;\n}\n\nexport interface MultiStepFormProps {\n steps: StepItem[];\n onComplete?: (formData: Record<string, any>) => Promise<void> | void;\n className?: string;\n}\n\nexport function MultiStepForm({ steps, onComplete, className }: MultiStepFormProps) {\n const [currentStepIndex, setCurrentStepIndex] = React.useState(0);\n const [isSubmitting, setIsSubmitting] = React.useState(false);\n const [isCompleted, setIsCompleted] = React.useState(false);\n\n const currentStep = steps[currentStepIndex];\n const isFirstStep = currentStepIndex === 0;\n const isLastStep = currentStepIndex === steps.length - 1;\n\n const handleNext = async () => {\n if (isLastStep) {\n setIsSubmitting(true);\n try {\n if (onComplete) {\n await onComplete({});\n }\n setIsCompleted(true);\n } finally {\n setIsSubmitting(false);\n }\n } else {\n setCurrentStepIndex((prev) => prev + 1);\n }\n };\n\n const handleBack = () => {\n if (!isFirstStep) {\n setCurrentStepIndex((prev) => prev - 1);\n }\n };\n\n const handleReset = () => {\n setCurrentStepIndex(0);\n setIsCompleted(false);\n };\n\n if (isCompleted) {\n return (\n <Card className={cn("w-full max-w-xl mx-auto border border-border shadow-card", className)}>\n <CardContent className="flex flex-col items-center justify-center p-8 text-center space-y-4">\n <div className="flex h-16 w-16 items-center justify-center rounded-full bg-emerald-500/10 text-emerald-500 animate-in zoom-in-50 duration-300">\n <Check className="h-8 w-8" />\n </div>\n <div className="space-y-1">\n <h3 className="text-xl font-bold text-foreground">\u0130\u015Flem Ba\u015Far\u0131yla Tamamland\u0131!</h3>\n <p className="text-sm text-muted-foreground">\n T\xFCm ad\u0131mlar ba\u015Far\u0131yla do\u011Fruland\u0131 ve kaydedildi.\n </p>\n </div>\n <Button onClick={handleReset} variant="outline" className="mt-4 gap-2">\n <Sparkles className="h-4 w-4 text-primary" />\n <span>Yeniden Ba\u015Flat</span>\n </Button>\n </CardContent>\n </Card>\n );\n }\n\n return (\n <Card className={cn("w-full max-w-2xl mx-auto border border-border shadow-card", className)}>\n {/* \xDCst Ad\u0131m Ba\u015Fl\u0131\u011F\u0131 ve \u0130lerleme G\xF6stergesi */}\n <CardHeader className="space-y-6 pb-4">\n {/* Ad\u0131mlar Bar\u0131 */}\n <div className="relative flex items-center justify-between w-full">\n {/* Ad\u0131mlar Aras\u0131 \xC7izgi */}\n <div className="absolute top-1/2 left-0 w-full -translate-y-1/2 h-0.5 bg-muted -z-0" />\n <div\n className="absolute top-1/2 left-0 -translate-y-1/2 h-0.5 bg-primary transition-all duration-300 -z-0"\n style={{\n width: `${(currentStepIndex / (steps.length - 1)) * 100}%`,\n }}\n />\n\n {steps.map((step, index) => {\n const isDone = index < currentStepIndex;\n const isCurrent = index === currentStepIndex;\n\n return (\n <div key={step.id} className="relative z-10 flex flex-col items-center">\n <button\n type="button"\n onClick={() => {\n if (index < currentStepIndex) setCurrentStepIndex(index);\n }}\n disabled={index > currentStepIndex}\n className={cn(\n "flex h-9 w-9 items-center justify-center rounded-full text-xs font-bold transition-all duration-200 ring-4 ring-background",\n isDone && "bg-primary text-primary-foreground",\n isCurrent && "bg-primary text-primary-foreground shadow-md scale-110 ring-primary/20",\n !isDone && !isCurrent && "bg-muted text-muted-foreground"\n )}\n >\n {isDone ? <Check className="h-4 w-4" /> : index + 1}\n </button>\n </div>\n );\n })}\n </div>\n\n {/* Ge\xE7erli Ad\u0131m Metin Bilgisi */}\n <div className="space-y-1 text-center sm:text-left">\n <div className="text-xs font-semibold text-primary uppercase tracking-wider">\n Ad\u0131m {currentStepIndex + 1} / {steps.length}\n </div>\n <h2 className="text-lg font-semibold text-foreground">{currentStep?.title}</h2>\n {currentStep?.description && (\n <p className="text-xs text-muted-foreground">{currentStep.description}</p>\n )}\n </div>\n </CardHeader>\n\n {/* Ad\u0131m \u0130\xE7eri\u011Fi */}\n <CardContent className="py-2">\n <div key={currentStep?.id} className="animate-in fade-in-50 duration-200">\n {currentStep?.component}\n </div>\n </CardContent>\n\n {/* Alt Gezinti Butonlar\u0131 */}\n <CardFooter className="flex items-center justify-between border-t border-border pt-4 mt-4">\n <Button\n type="button"\n variant="outline"\n onClick={handleBack}\n disabled={isFirstStep || isSubmitting}\n className="gap-1.5"\n >\n <ChevronLeft className="h-4 w-4" />\n <span>Geri</span>\n </Button>\n\n <Button\n type="button"\n onClick={handleNext}\n disabled={isSubmitting}\n className="gap-1.5"\n >\n {isSubmitting ? (\n <>\n <Loader2 className="h-4 w-4 animate-spin" />\n <span>Kaydediliyor...</span>\n </>\n ) : isLastStep ? (\n <>\n <span>Tamamla</span>\n <Check className="h-4 w-4" />\n </>\n ) : (\n <>\n <span>\u0130leri</span>\n <ChevronRight className="h-4 w-4" />\n </>\n )}\n </Button>\n </CardFooter>\n </Card>\n );\n}\n'
1495
+ }
1496
+ ]
1497
+ },
1498
+ "pricing-table": {
1499
+ "name": "pricing-table",
1500
+ "type": "components:block",
1501
+ "category": "bloklar",
1502
+ "description": "Ayl\u0131k/Y\u0131ll\u0131k indirim d\xF6ng\xFCl\xFC, pop\xFCler rozetli ve \xF6zellik listeli SaaS fiyat tablosu",
1503
+ "dependencies": [
1504
+ "lucide-react"
1505
+ ],
1506
+ "devDependencies": [],
1507
+ "registryDependencies": [],
1508
+ "files": [
1509
+ {
1510
+ "name": "pricing-table.tsx",
1511
+ "content": '"use client";\n\nimport * as React from "react";\nimport { Check, X, Sparkles } from "lucide-react";\nimport { cn } from "@/lib/utils";\nimport { Button } from "@/components/ui/../components/button";\nimport { Badge } from "@/components/ui/../components/badge";\n\nexport interface PricingFeature {\n text: string;\n included: boolean;\n}\n\nexport interface PricingPlan {\n id: string;\n name: string;\n description: string;\n priceMonthly: number | string;\n priceYearly: number | string;\n currency?: string;\n periodTextMonthly?: string;\n periodTextYearly?: string;\n isPopular?: boolean;\n popularBadge?: string;\n features: PricingFeature[];\n ctaText?: string;\n ctaVariant?: "default" | "outline" | "secondary";\n onSelect?: (cycle: "monthly" | "yearly") => void;\n}\n\nexport interface PricingTableProps extends React.HTMLAttributes<HTMLDivElement> {\n plans: PricingPlan[];\n defaultBillingCycle?: "monthly" | "yearly";\n discountBadge?: string;\n onPlanSelect?: (planId: string, cycle: "monthly" | "yearly") => void;\n}\n\nexport function PricingTable({\n plans,\n defaultBillingCycle = "monthly",\n discountBadge = "%20 \u0130ndirim",\n onPlanSelect,\n className,\n ...props\n}: PricingTableProps) {\n const [cycle, setCycle] = React.useState<"monthly" | "yearly">(defaultBillingCycle);\n\n return (\n <div className={cn("w-full space-y-8", className)} {...props}>\n {/* Billing Cycle Switcher */}\n <div className="flex items-center justify-center">\n <div className="inline-flex items-center gap-1 rounded-xl border border-border bg-muted/40 p-1">\n <button\n type="button"\n onClick={() => setCycle("monthly")}\n className={cn(\n "rounded-lg px-4 py-1.5 text-xs font-medium transition-all duration-150",\n cycle === "monthly"\n ? "bg-background text-foreground shadow-xs font-semibold"\n : "text-muted-foreground hover:text-foreground"\n )}\n >\n Ayl\u0131k Faturaland\u0131rma\n </button>\n <button\n type="button"\n onClick={() => setCycle("yearly")}\n className={cn(\n "inline-flex items-center gap-1.5 rounded-lg px-4 py-1.5 text-xs font-medium transition-all duration-150",\n cycle === "yearly"\n ? "bg-background text-foreground shadow-xs font-semibold"\n : "text-muted-foreground hover:text-foreground"\n )}\n >\n <span>Y\u0131ll\u0131k Faturaland\u0131rma</span>\n {discountBadge && (\n <Badge variant="success" className="text-[10px] px-1.5 py-0">\n {discountBadge}\n </Badge>\n )}\n </button>\n </div>\n </div>\n\n {/* Pricing Cards Grid */}\n <div className="grid grid-cols-1 md:grid-cols-3 gap-6">\n {plans.map((plan) => {\n const price = cycle === "monthly" ? plan.priceMonthly : plan.priceYearly;\n const currency = plan.currency || "\u20BA";\n const period =\n cycle === "monthly"\n ? plan.periodTextMonthly || "/ay"\n : plan.periodTextYearly || "/y\u0131l";\n\n return (\n <div\n key={plan.id}\n className={cn(\n "relative flex flex-col justify-between rounded-2xl border p-6 transition-all duration-200 bg-card",\n plan.isPopular\n ? "border-primary ring-1 ring-primary/30 shadow-lg shadow-primary/5"\n : "border-border/80 hover:border-border"\n )}\n >\n {plan.isPopular && (\n <div className="absolute -top-3 left-1/2 -translate-x-1/2">\n <Badge variant="default" className="gap-1 px-3 py-0.5 text-[11px] font-semibold uppercase tracking-wider">\n <Sparkles className="h-3 w-3" />\n {plan.popularBadge || "En Pop\xFCler"}\n </Badge>\n </div>\n )}\n\n <div>\n {/* Plan Title & Desc */}\n <div className="mb-4">\n <h3 className="text-base font-bold text-foreground">{plan.name}</h3>\n <p className="text-xs text-muted-foreground mt-1 leading-relaxed">\n {plan.description}\n </p>\n </div>\n\n {/* Price Display */}\n <div className="flex items-baseline gap-1 my-6">\n <span className="text-3xl font-extrabold tracking-tight text-foreground">\n {typeof price === "number" ? `${currency}${price}` : price}\n </span>\n {typeof price === "number" && (\n <span className="text-xs text-muted-foreground font-medium">{period}</span>\n )}\n </div>\n\n {/* Features List */}\n <div className="space-y-2.5 border-t border-border/60 pt-5">\n <p className="text-[11px] font-semibold text-muted-foreground uppercase tracking-wider">\n Dahil Olan \xD6zellikler\n </p>\n <ul className="space-y-2">\n {plan.features.map((feature, i) => (\n <li key={i} className="flex items-center gap-2 text-xs">\n {feature.included ? (\n <div className="flex h-4 w-4 shrink-0 items-center justify-center rounded-full bg-success/15 text-success">\n <Check className="h-2.5 w-2.5" />\n </div>\n ) : (\n <div className="flex h-4 w-4 shrink-0 items-center justify-center rounded-full bg-muted text-muted-foreground/50">\n <X className="h-2.5 w-2.5" />\n </div>\n )}\n <span\n className={cn(\n feature.included\n ? "text-foreground"\n : "text-muted-foreground/60 line-through"\n )}\n >\n {feature.text}\n </span>\n </li>\n ))}\n </ul>\n </div>\n </div>\n\n {/* CTA Button */}\n <div className="mt-8 pt-4 border-t border-border/40">\n <Button\n variant={plan.isPopular ? "default" : plan.ctaVariant || "outline"}\n className="w-full text-xs font-semibold rounded-xl h-9"\n onClick={() => {\n plan.onSelect?.(cycle);\n onPlanSelect?.(plan.id, cycle);\n }}\n >\n {plan.ctaText || "Plan\u0131 Se\xE7"}\n </Button>\n </div>\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n'
1512
+ }
1513
+ ]
1514
+ }
1515
+ };
1516
+
1517
+ // src/commands/add.ts
1518
+ async function runAdd(components, options) {
1519
+ const cwd = options.cwd || process.cwd();
1520
+ logger.banner();
1521
+ let config = {
1522
+ style: "default",
1523
+ tailwind: {
1524
+ config: "tailwind.config.js",
1525
+ css: "app/globals.css",
1526
+ baseColor: "zinc",
1527
+ cssVariables: true,
1528
+ prefix: ""
1529
+ },
1530
+ aliases: {
1531
+ components: "@/components",
1532
+ utils: "@/lib/utils",
1533
+ ui: "@/components/ui"
1534
+ }
1535
+ };
1536
+ const configPath = path3.join(cwd, "components.json");
1537
+ if (await fs3.pathExists(configPath)) {
1538
+ try {
1539
+ config = await fs3.readJSON(configPath);
1540
+ } catch {
1541
+ }
1542
+ }
1543
+ let selectedComponents = [];
1544
+ if (options.all) {
1545
+ selectedComponents = Object.keys(REGISTRY);
1546
+ } else if (components.length > 0) {
1547
+ selectedComponents = components;
1548
+ } else {
1549
+ const choices = Object.entries(REGISTRY).map(([key, item]) => ({
1550
+ title: `${item.name} (${item.category}) \u2014 ${item.description}`,
1551
+ value: key
1552
+ }));
1553
+ const response = await prompts2({
1554
+ type: "multiselect",
1555
+ name: "components",
1556
+ message: "Eklemek istedi\u011Finiz bile\u015Fenleri se\xE7in (Bo\u015Fluk tu\u015Fu ile se\xE7in):",
1557
+ choices,
1558
+ min: 1,
1559
+ hint: "- Bo\u015Fluk tu\u015Fu ile se\xE7in, Enter ile onaylay\u0131n"
1560
+ });
1561
+ if (!response.components || response.components.length === 0) {
1562
+ logger.warn("Hi\xE7bir bile\u015Fen se\xE7ilmedi.");
1563
+ process.exit(0);
1564
+ }
1565
+ selectedComponents = response.components;
1566
+ }
1567
+ const spinner = ora2("Bile\u015Fenler y\xFCkleniyor...").start();
1568
+ const dependenciesToInstall = /* @__PURE__ */ new Set();
1569
+ const uiDir = path3.join(cwd, config.aliases.ui.replace(/^@\//, ""));
1570
+ await fs3.ensureDir(uiDir);
1571
+ for (const compName of selectedComponents) {
1572
+ const registryItem = REGISTRY[compName];
1573
+ if (!registryItem) {
1574
+ logger.warn(`'${compName}' ad\u0131nda bir bile\u015Fen registry'de bulunamad\u0131.`);
1575
+ continue;
1576
+ }
1577
+ for (const dep of registryItem.dependencies) {
1578
+ dependenciesToInstall.add(dep);
1579
+ }
1580
+ for (const file of registryItem.files) {
1581
+ const targetFilePath = path3.join(uiDir, file.name);
1582
+ if (await fs3.pathExists(targetFilePath) && !options.overwrite) {
1583
+ logger.item(file.name, "Mevcut dosya atland\u0131 (\xFCzerine yazmak i\xE7in --overwrite kullan\u0131n)");
1584
+ continue;
1585
+ }
1586
+ await fs3.writeFile(targetFilePath, file.content, "utf-8");
1587
+ logger.item(file.name, `-> ${path3.relative(cwd, targetFilePath)}`);
1588
+ }
1589
+ }
1590
+ spinner.succeed("Bile\u015Fen dosyalar\u0131 projeye ba\u015Far\u0131yla eklendi.");
1591
+ if (dependenciesToInstall.size > 0) {
1592
+ const pm = await getPackageManager(cwd);
1593
+ const installSpinner = ora2(`Ba\u011F\u0131ml\u0131l\u0131klar y\xFCkleniyor: ${Array.from(dependenciesToInstall).join(", ")}...`).start();
1594
+ try {
1595
+ const isDev = false;
1596
+ const cmdParts = getInstallCommand(pm, isDev).split(" ");
1597
+ const [cmd, ...args] = cmdParts;
1598
+ if (cmd) {
1599
+ await execa2(cmd, [...args, ...Array.from(dependenciesToInstall)], { cwd });
1600
+ }
1601
+ installSpinner.succeed("T\xFCm ba\u011F\u0131ml\u0131l\u0131klar ba\u015Far\u0131yla y\xFCklendi.");
1602
+ } catch {
1603
+ installSpinner.warn("Ba\u011F\u0131ml\u0131l\u0131klar otomatik y\xFCklenemedi. L\xFCtfen elle y\xFCkleyin:");
1604
+ console.log(` ${getInstallCommand(pm)} ${Array.from(dependenciesToInstall).join(" ")}`);
1605
+ }
1606
+ }
1607
+ logger.break();
1608
+ logger.success("Bile\u015Fenler kullan\u0131ma haz\u0131r! \u{1F680}");
1609
+ logger.break();
1610
+ }
1611
+
1612
+ // src/commands/list.ts
1613
+ import { bold as bold2, cyan as cyan2, dim as dim2, green as green2, magenta as magenta2, yellow as yellow2 } from "kolorist";
1614
+ async function runList() {
1615
+ logger.banner();
1616
+ console.log(bold2(" \u{1F4E6} Kullan\u0131labilir Bile\u015Fenler ve Bloklar:\n"));
1617
+ const categories = {
1618
+ temel: [],
1619
+ form: [],
1620
+ feedback: [],
1621
+ overlay: [],
1622
+ navigation: [],
1623
+ bloklar: []
1624
+ };
1625
+ for (const [key, item] of Object.entries(REGISTRY)) {
1626
+ const list = categories[item.category];
1627
+ if (list) {
1628
+ list.push(key);
1629
+ } else {
1630
+ categories.temel?.push(key);
1631
+ }
1632
+ }
1633
+ const categoryTitles = {
1634
+ temel: "Temel Bile\u015Fenler (Core / Base)",
1635
+ form: "Form & Girdi Bile\u015Fenleri (Forms & Inputs)",
1636
+ feedback: "Geri Bildirim & Durum (Feedback & Status)",
1637
+ overlay: "A\xE7\u0131l\u0131r Pencereler & Katmanlar (Overlays & Dialogs)",
1638
+ navigation: "Navigasyon & D\xFCzen (Navigation & Layout)",
1639
+ bloklar: "Haz\u0131r SaaS Bloklar\u0131 (Composite Blocks)"
1640
+ };
1641
+ for (const [cat, compKeys] of Object.entries(categories)) {
1642
+ if (compKeys.length === 0) continue;
1643
+ console.log(` ${magenta2("\u25CF")} ${bold2(categoryTitles[cat] || cat)}`);
1644
+ for (const key of compKeys) {
1645
+ const item = REGISTRY[key];
1646
+ console.log(
1647
+ ` ${cyan2("\u2022")} ${bold2(item.name.padEnd(16))} ${dim2(item.description)}`
1648
+ );
1649
+ if (item.dependencies.length > 0) {
1650
+ console.log(
1651
+ ` ${dim2("deps:")} ${green2(item.dependencies.join(", "))}`
1652
+ );
1653
+ }
1654
+ }
1655
+ console.log();
1656
+ }
1657
+ console.log(
1658
+ dim2(" Bir bile\u015Feni eklemek i\xE7in:") + bold2(yellow2(" npx @alexourus/ui add <bile\u015Fen-ad\u0131>"))
1659
+ );
1660
+ console.log();
1661
+ }
1662
+
1663
+ // src/index.ts
1664
+ var program = new Command();
1665
+ program.name("alexourus-ui").description("alexourus-ui \u2014 Modern React ve Tailwind bile\u015Fen k\xFCt\xFCphanesi CLI arac\u0131").version("0.3.3");
1666
+ program.command("init").description("Projenizde alexourus-ui yap\u0131land\u0131rmas\u0131n\u0131 ba\u015Flat\u0131n ve temel dosyalar\u0131 olu\u015Fturun").option("-y, --yes", "T\xFCm sorulara varsay\u0131lan yan\u0131tlar\u0131 vererek otomatik kur").option("-c, --cwd <cwd>", "\xC7al\u0131\u015Fma dizini", process.cwd()).action(async (opts) => {
1667
+ await runInit(opts);
1668
+ });
1669
+ program.command("add [components...]").description("Projenize bir veya daha fazla alexourus-ui bile\u015Feni ekleyin").option("-a, --all", "T\xFCm bile\u015Fenleri ve bloklar\u0131 projeye ekle").option("-o, --overwrite", "Mevcut bile\u015Fen dosyalar\u0131n\u0131n \xFCzerine yaz").option("-c, --cwd <cwd>", "\xC7al\u0131\u015Fma dizini", process.cwd()).option("-y, --yes", "Onay istemeden do\u011Frudan kur").action(async (components, opts) => {
1670
+ await runAdd(components, opts);
1671
+ });
1672
+ program.command("list").description("Kullan\u0131labilir t\xFCm alexourus-ui bile\u015Fenlerini ve bloklar\u0131n\u0131 listeler").action(async () => {
1673
+ await runList();
1674
+ });
1675
+ program.parse(process.argv);