@docubook/mdx 1.0.0

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.
@@ -0,0 +1,896 @@
1
+ "use client";
2
+
3
+ // src/core/components/Accordion.tsx
4
+ import { useContext, useState as useState2 } from "react";
5
+ import { ChevronRight } from "lucide-react";
6
+ import * as Icons from "lucide-react";
7
+
8
+ // src/core/utils/cn.ts
9
+ import { clsx } from "clsx";
10
+ import { twMerge } from "tailwind-merge";
11
+ function cn(...inputs) {
12
+ return twMerge(clsx(inputs));
13
+ }
14
+
15
+ // src/core/components/AccordionContext.tsx
16
+ import { createContext, useId, useState } from "react";
17
+ import { jsx } from "react/jsx-runtime";
18
+ var AccordionGroupContext = createContext(null);
19
+ function AccordionGroupProvider({ children }) {
20
+ const [openTitle, setOpenTitle] = useState(null);
21
+ const groupId = useId();
22
+ return /* @__PURE__ */ jsx(
23
+ AccordionGroupContext.Provider,
24
+ {
25
+ value: { inGroup: true, groupId, openTitle, setOpenTitle },
26
+ children
27
+ }
28
+ );
29
+ }
30
+
31
+ // src/core/components/Accordion.tsx
32
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
33
+ function Accordion({ title, children, icon }) {
34
+ const groupContext = useContext(AccordionGroupContext);
35
+ const isInGroup = groupContext?.inGroup === true;
36
+ const groupOpen = groupContext?.openTitle === title;
37
+ const setGroupOpen = groupContext?.setOpenTitle;
38
+ const [localOpen, setLocalOpen] = useState2(false);
39
+ const isOpen = isInGroup ? groupOpen : localOpen;
40
+ const handleToggle = () => {
41
+ if (isInGroup && setGroupOpen) {
42
+ setGroupOpen(groupOpen ? null : title);
43
+ } else {
44
+ setLocalOpen(!localOpen);
45
+ }
46
+ };
47
+ const Icon = icon ? Icons[icon] : null;
48
+ return /* @__PURE__ */ jsxs(
49
+ "div",
50
+ {
51
+ className: cn(
52
+ !isInGroup && "rounded-lg border shadow-sm",
53
+ isInGroup && "border-border border-b last:border-b-0"
54
+ ),
55
+ children: [
56
+ /* @__PURE__ */ jsxs(
57
+ "button",
58
+ {
59
+ type: "button",
60
+ onClick: handleToggle,
61
+ className: "bg-muted/40 dark:bg-muted/20 hover:bg-muted/70 dark:hover:bg-muted/70 flex w-full cursor-pointer items-center gap-2 px-4 py-3 text-start transition-colors",
62
+ children: [
63
+ /* @__PURE__ */ jsx2(
64
+ ChevronRight,
65
+ {
66
+ className: cn(
67
+ "text-muted-foreground h-4 w-4 shrink-0 transition-transform duration-200",
68
+ isOpen && "rotate-90"
69
+ )
70
+ }
71
+ ),
72
+ Icon && /* @__PURE__ */ jsx2(Icon, { className: "text-foreground h-4 w-4 shrink-0" }),
73
+ /* @__PURE__ */ jsx2("h3", { className: "text-foreground m-0! text-base font-medium", children: title })
74
+ ]
75
+ }
76
+ ),
77
+ /* @__PURE__ */ jsx2(
78
+ "div",
79
+ {
80
+ className: cn(
81
+ "grid transition-[grid-template-rows] duration-200 ease-out",
82
+ isOpen ? "grid-rows-[1fr]" : "grid-rows-[0fr]"
83
+ ),
84
+ children: /* @__PURE__ */ jsx2("div", { className: "overflow-hidden", children: /* @__PURE__ */ jsx2("div", { className: "dark:bg-muted/10 bg-muted/15 px-4 py-3", children }) })
85
+ }
86
+ )
87
+ ]
88
+ }
89
+ );
90
+ }
91
+
92
+ // src/core/components/AccordionGroup.tsx
93
+ import clsx2 from "clsx";
94
+ import { jsx as jsx3 } from "react/jsx-runtime";
95
+ function AccordionGroup({ children, className }) {
96
+ return /* @__PURE__ */ jsx3(AccordionGroupProvider, { children: /* @__PURE__ */ jsx3("div", { className: clsx2("overflow-hidden rounded-lg border", className), children }) });
97
+ }
98
+
99
+ // src/core/components/Button.tsx
100
+ import * as Icons2 from "lucide-react";
101
+ import { Fragment, jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
102
+ function Button({
103
+ icon,
104
+ text,
105
+ href,
106
+ target,
107
+ size = "md",
108
+ variation = "primary",
109
+ LinkComponent
110
+ }) {
111
+ const baseStyles = "inline-flex items-center justify-center rounded font-medium focus:outline-none transition no-underline";
112
+ const sizeStyles = {
113
+ sm: "px-3 py-1 my-6 text-sm",
114
+ md: "px-4 py-2 my-6 text-base",
115
+ lg: "px-5 py-3 my-6 text-lg"
116
+ };
117
+ const variationStyles = {
118
+ primary: "bg-primary text-white hover:bg-primary/90",
119
+ accent: "bg-accent text-white hover:bg-accent/90",
120
+ outline: "border border-accent text-accent hover:bg-accent/10"
121
+ };
122
+ const Icon = icon ? Icons2[icon] : null;
123
+ const className = `${baseStyles} ${sizeStyles[size]} ${variationStyles[variation]}`;
124
+ const inner = /* @__PURE__ */ jsxs2(Fragment, { children: [
125
+ text && /* @__PURE__ */ jsx4("span", { children: text }),
126
+ Icon && /* @__PURE__ */ jsx4(Icon, { className: "mr-2 h-5 w-5" })
127
+ ] });
128
+ if (LinkComponent) {
129
+ return /* @__PURE__ */ jsx4(
130
+ LinkComponent,
131
+ {
132
+ href,
133
+ target,
134
+ rel: target === "_blank" ? "noopener noreferrer" : void 0,
135
+ className,
136
+ children: inner
137
+ }
138
+ );
139
+ }
140
+ return /* @__PURE__ */ jsx4(
141
+ "a",
142
+ {
143
+ href,
144
+ target,
145
+ rel: target === "_blank" ? "noopener noreferrer" : void 0,
146
+ className,
147
+ children: inner
148
+ }
149
+ );
150
+ }
151
+
152
+ // src/core/components/Card.tsx
153
+ import * as Icons3 from "lucide-react";
154
+ import clsx3 from "clsx";
155
+ import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
156
+ function Card({
157
+ title,
158
+ icon,
159
+ href,
160
+ horizontal,
161
+ children,
162
+ className,
163
+ LinkComponent
164
+ }) {
165
+ const Icon = icon ? Icons3[icon] : null;
166
+ const content = /* @__PURE__ */ jsxs3(
167
+ "div",
168
+ {
169
+ className: clsx3(
170
+ "border rounded-lg shadow-sm p-4 transition-all duration-200",
171
+ "bg-card text-card-foreground border-border",
172
+ "hover:bg-accent/5 hover:border-accent/30",
173
+ "flex gap-2",
174
+ horizontal ? "flex-row items-start gap-1" : "flex-col space-y-1",
175
+ className
176
+ ),
177
+ children: [
178
+ Icon && /* @__PURE__ */ jsx5(Icon, { className: clsx3("w-5 h-5 text-primary shrink-0", horizontal && "mt-0.5") }),
179
+ /* @__PURE__ */ jsxs3("div", { className: "flex-1 min-w-0", children: [
180
+ /* @__PURE__ */ jsx5("div", { className: "text-base font-semibold text-foreground leading-6", children: title }),
181
+ /* @__PURE__ */ jsx5("div", { className: "text-sm text-muted-foreground -mt-3", children })
182
+ ] })
183
+ ]
184
+ }
185
+ );
186
+ if (!href) return content;
187
+ if (LinkComponent) {
188
+ return /* @__PURE__ */ jsx5(LinkComponent, { href, className: "no-underline block", children: content });
189
+ }
190
+ return /* @__PURE__ */ jsx5("a", { className: "no-underline block", href, children: content });
191
+ }
192
+
193
+ // src/core/components/CardGroup.tsx
194
+ import React from "react";
195
+ import clsx4 from "clsx";
196
+ import { jsx as jsx6 } from "react/jsx-runtime";
197
+ function CardGroup({ children, cols = 2, className }) {
198
+ const cardsArray = React.Children.toArray(children);
199
+ const gridColsClass = {
200
+ 1: "grid-cols-1",
201
+ 2: "grid-cols-1 sm:grid-cols-2",
202
+ 3: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3",
203
+ 4: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-4"
204
+ }[cols] || "grid-cols-1 sm:grid-cols-2";
205
+ return /* @__PURE__ */ jsx6("div", { className: clsx4("grid gap-4 text-foreground", gridColsClass, className), children: cardsArray.map((card, index) => /* @__PURE__ */ jsx6("div", { children: card }, index)) });
206
+ }
207
+
208
+ // src/core/components/FileTree.tsx
209
+ import {
210
+ Children,
211
+ cloneElement,
212
+ isValidElement,
213
+ useState as useState3
214
+ } from "react";
215
+ import {
216
+ ChevronRight as ChevronRight2,
217
+ File as FileIcon,
218
+ Folder as FolderIcon,
219
+ FolderOpen
220
+ } from "lucide-react";
221
+ import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
222
+ function FileComponent({ name }) {
223
+ const [isHovered, setIsHovered] = useState3(false);
224
+ const fileExtension = name.split(".").pop()?.toUpperCase();
225
+ return /* @__PURE__ */ jsxs4(
226
+ "div",
227
+ {
228
+ className: `
229
+ flex items-center gap-2 py-1.5 pl-7 pr-3 text-sm rounded-md
230
+ transition-colors duration-150 cursor-default select-none
231
+ ${isHovered ? "bg-accent/10" : "hover:bg-muted/50"}
232
+ `,
233
+ onMouseEnter: () => setIsHovered(true),
234
+ onMouseLeave: () => setIsHovered(false),
235
+ tabIndex: -1,
236
+ children: [
237
+ /* @__PURE__ */ jsx7(
238
+ FileIcon,
239
+ {
240
+ className: `
241
+ h-3.5 w-3.5 shrink-0 transition-colors
242
+ ${isHovered ? "text-accent" : "text-muted-foreground"}
243
+ `
244
+ }
245
+ ),
246
+ /* @__PURE__ */ jsx7("span", { className: "font-mono text-sm text-foreground truncate", children: name }),
247
+ isHovered && fileExtension && /* @__PURE__ */ jsx7("span", { className: "ml-auto text-xs text-muted-foreground/80", children: fileExtension })
248
+ ]
249
+ }
250
+ );
251
+ }
252
+ function FolderComponent({ name, children }) {
253
+ const [isOpen, setIsOpen] = useState3(true);
254
+ const [isHovered, setIsHovered] = useState3(false);
255
+ const hasChildren = Children.count(children) > 0;
256
+ return /* @__PURE__ */ jsxs4("div", { className: "relative", children: [
257
+ /* @__PURE__ */ jsxs4(
258
+ "div",
259
+ {
260
+ className: `
261
+ flex items-center gap-2 py-1.5 pl-4 pr-3 rounded-md
262
+ transition-colors duration-150 select-none
263
+ ${isHovered ? "bg-muted/60" : ""}
264
+ ${isOpen ? "text-foreground" : "text-foreground/80"}
265
+ ${hasChildren ? "cursor-pointer" : "cursor-default"}
266
+ `,
267
+ onClick: () => hasChildren && setIsOpen(!isOpen),
268
+ onMouseEnter: () => setIsHovered(true),
269
+ onMouseLeave: () => setIsHovered(false),
270
+ tabIndex: -1,
271
+ children: [
272
+ hasChildren ? /* @__PURE__ */ jsx7(
273
+ ChevronRight2,
274
+ {
275
+ className: `
276
+ h-3.5 w-3.5 shrink-0 transition-transform duration-200
277
+ ${isOpen ? "rotate-90" : ""}
278
+ ${isHovered ? "text-foreground/70" : "text-muted-foreground"}
279
+ `
280
+ }
281
+ ) : /* @__PURE__ */ jsx7("div", { className: "w-3.5" }),
282
+ isOpen ? /* @__PURE__ */ jsx7(
283
+ FolderOpen,
284
+ {
285
+ className: `
286
+ h-4 w-4 shrink-0 transition-colors
287
+ ${isHovered ? "text-accent" : "text-muted-foreground"}
288
+ `
289
+ }
290
+ ) : /* @__PURE__ */ jsx7(
291
+ FolderIcon,
292
+ {
293
+ className: `
294
+ h-4 w-4 shrink-0 transition-colors
295
+ ${isHovered ? "text-accent/80" : "text-muted-foreground/80"}
296
+ `
297
+ }
298
+ ),
299
+ /* @__PURE__ */ jsx7("span", { className: `font-medium transition-colors duration-150 ${isHovered ? "text-accent" : ""}`, children: name })
300
+ ]
301
+ }
302
+ ),
303
+ isOpen && hasChildren && /* @__PURE__ */ jsx7("div", { className: "ml-5 border-l-2 border-muted/50 pl-2", children })
304
+ ] });
305
+ }
306
+ function Files({ children }) {
307
+ return /* @__PURE__ */ jsx7(
308
+ "div",
309
+ {
310
+ className: "\n rounded-xl border border-muted/20\n bg-card/20 backdrop-blur-sm\n shadow-sm overflow-hidden\n transition-all duration-200\n hover:shadow-md hover:border-muted/60\n ",
311
+ children: /* @__PURE__ */ jsx7("div", { className: "p-2", children: Children.map(children, (child, index) => {
312
+ if (isValidElement(child)) {
313
+ return cloneElement(child, { key: index });
314
+ }
315
+ return null;
316
+ }) })
317
+ }
318
+ );
319
+ }
320
+ function Folder({ name, children }) {
321
+ return /* @__PURE__ */ jsx7(FolderComponent, { name, children });
322
+ }
323
+ function File({ name }) {
324
+ return /* @__PURE__ */ jsx7(FileComponent, { name });
325
+ }
326
+
327
+ // src/core/components/Image.tsx
328
+ import { createPortal } from "react-dom";
329
+ import { X, ZoomIn } from "lucide-react";
330
+ import { useEffect, useRef, useState as useState4 } from "react";
331
+ import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
332
+ function Image({
333
+ src,
334
+ alt = "alt",
335
+ width = 800,
336
+ height = 350,
337
+ ...props
338
+ }) {
339
+ const [isOpen, setIsOpen] = useState4(false);
340
+ const scrollYRef = useRef(0);
341
+ useEffect(() => {
342
+ if (!isOpen) return;
343
+ scrollYRef.current = window.scrollY;
344
+ document.body.style.position = "fixed";
345
+ document.body.style.top = `-${scrollYRef.current}px`;
346
+ document.body.style.width = "100%";
347
+ const handleEsc = (e) => {
348
+ if (e.key === "Escape") setIsOpen(false);
349
+ };
350
+ window.addEventListener("keydown", handleEsc);
351
+ return () => {
352
+ document.body.style.position = "";
353
+ document.body.style.top = "";
354
+ document.body.style.width = "";
355
+ window.scrollTo(0, scrollYRef.current);
356
+ window.removeEventListener("keydown", handleEsc);
357
+ };
358
+ }, [isOpen]);
359
+ if (!src) return null;
360
+ return /* @__PURE__ */ jsxs5(Fragment2, { children: [
361
+ /* @__PURE__ */ jsxs5(
362
+ "button",
363
+ {
364
+ type: "button",
365
+ className: "relative group cursor-zoom-in my-6 w-full flex justify-center rounded-lg",
366
+ onClick: () => setIsOpen(true),
367
+ "aria-label": "Zoom image",
368
+ children: [
369
+ /* @__PURE__ */ jsx8("span", { className: "absolute inset-0 bg-black/0 group-hover:bg-black/5 transition-colors z-10 flex items-center justify-center opacity-0 group-hover:opacity-100 rounded-lg", children: /* @__PURE__ */ jsx8(ZoomIn, { className: "w-8 h-8 text-white drop-shadow-md" }) }),
370
+ /* @__PURE__ */ jsx8(
371
+ "img",
372
+ {
373
+ src: typeof src === "string" ? src : "",
374
+ alt,
375
+ width,
376
+ height,
377
+ className: "w-full h-auto rounded-lg transition-transform duration-300 group-hover:scale-[1.01]",
378
+ ...props
379
+ }
380
+ )
381
+ ]
382
+ }
383
+ ),
384
+ isOpen && /* @__PURE__ */ jsx8(Portal, { children: /* @__PURE__ */ jsxs5(
385
+ "div",
386
+ {
387
+ className: "fixed inset-0 z-99999 flex items-center justify-center bg-black/90 backdrop-blur-md p-4 md:p-10 cursor-zoom-out",
388
+ onClick: () => setIsOpen(false),
389
+ children: [
390
+ /* @__PURE__ */ jsx8(
391
+ "button",
392
+ {
393
+ className: "absolute top-4 right-4 z-50 p-2 text-white/70 hover:text-white bg-black/20 hover:bg-white/10 rounded-full transition-colors",
394
+ onClick: (e) => {
395
+ e.stopPropagation();
396
+ setIsOpen(false);
397
+ },
398
+ children: /* @__PURE__ */ jsx8(X, { className: "w-6 h-6" })
399
+ }
400
+ ),
401
+ /* @__PURE__ */ jsx8(
402
+ "div",
403
+ {
404
+ className: "relative max-w-7xl w-full h-full flex items-center justify-center",
405
+ onClick: (e) => e.stopPropagation(),
406
+ children: /* @__PURE__ */ jsx8(
407
+ "div",
408
+ {
409
+ className: "relative w-full h-full flex items-center justify-center",
410
+ onClick: () => setIsOpen(false),
411
+ children: /* @__PURE__ */ jsx8(
412
+ "img",
413
+ {
414
+ src: typeof src === "string" ? src : "",
415
+ alt,
416
+ width: 1920,
417
+ height: 1080,
418
+ className: "object-contain max-h-[90vh] w-auto h-auto rounded-md shadow-2xl"
419
+ }
420
+ )
421
+ }
422
+ )
423
+ }
424
+ ),
425
+ alt && alt !== "alt" && /* @__PURE__ */ jsx8("div", { className: "absolute bottom-6 left-1/2 -translate-x-1/2 bg-black/60 text-white px-4 py-2 rounded-full text-sm font-medium backdrop-blur-md border border-white/10", children: alt })
426
+ ]
427
+ }
428
+ ) })
429
+ ] });
430
+ }
431
+ function Portal({ children }) {
432
+ if (typeof window === "undefined") return null;
433
+ return createPortal(children, document.body);
434
+ }
435
+
436
+ // src/core/components/Keyboard.tsx
437
+ import { jsx as jsx9 } from "react/jsx-runtime";
438
+ var macKeyMap = {
439
+ command: "\u2318",
440
+ cmd: "\u2318",
441
+ option: "\u2325",
442
+ alt: "\u2325",
443
+ shift: "\u21E7",
444
+ ctrl: "\u2303",
445
+ control: "\u2303",
446
+ tab: "\u21E5",
447
+ caps: "\u21EA",
448
+ enter: "\u23CE",
449
+ return: "\u23CE",
450
+ delete: "\u232B",
451
+ escape: "\u238B",
452
+ esc: "\u238B",
453
+ up: "\u2191",
454
+ down: "\u2193",
455
+ left: "\u2190",
456
+ right: "\u2192",
457
+ space: "\u2423"
458
+ };
459
+ var windowsKeyMap = {
460
+ command: "Win",
461
+ cmd: "Win",
462
+ option: "Alt",
463
+ alt: "Alt",
464
+ ctrl: "Ctrl",
465
+ control: "Ctrl",
466
+ delete: "Del",
467
+ escape: "Esc",
468
+ esc: "Esc",
469
+ enter: "Enter",
470
+ return: "Enter",
471
+ tab: "Tab",
472
+ caps: "Caps",
473
+ shift: "Shift",
474
+ space: "Space",
475
+ up: "\u2191",
476
+ down: "\u2193",
477
+ left: "\u2190",
478
+ right: "\u2192"
479
+ };
480
+ function Kbd({
481
+ show: keyProp,
482
+ type = "window",
483
+ children,
484
+ ...props
485
+ }) {
486
+ const getKeyDisplay = () => {
487
+ if (!keyProp || typeof keyProp !== "string") return null;
488
+ const lowerKey = keyProp.toLowerCase();
489
+ if (type === "mac") {
490
+ return macKeyMap[lowerKey] || keyProp;
491
+ }
492
+ return windowsKeyMap[lowerKey] || keyProp.charAt(0).toUpperCase() + keyProp.slice(1);
493
+ };
494
+ const renderContent = () => {
495
+ if (children !== void 0 && children !== null && children !== "") {
496
+ return children;
497
+ }
498
+ return getKeyDisplay() || keyProp || "";
499
+ };
500
+ return /* @__PURE__ */ jsx9(
501
+ "kbd",
502
+ {
503
+ className: "inline-flex items-center justify-center px-2 py-1 mx-0.5 text-xs font-mono font-medium text-foreground bg-secondary/70 border rounded-md",
504
+ ...props,
505
+ children: renderContent()
506
+ }
507
+ );
508
+ }
509
+
510
+ // src/core/components/Link.tsx
511
+ import { jsx as jsx10 } from "react/jsx-runtime";
512
+ function isUnsafeHref(href) {
513
+ const normalized = href.trim().toLowerCase();
514
+ return normalized.startsWith("javascript:") || normalized.startsWith("data:") || normalized.startsWith("vbscript:");
515
+ }
516
+ function Link({ href, target, rel, ...props }) {
517
+ if (!href) return null;
518
+ if (isUnsafeHref(href)) return null;
519
+ const isExternal = /^https?:\/\//.test(href);
520
+ return /* @__PURE__ */ jsx10(
521
+ "a",
522
+ {
523
+ href,
524
+ ...props,
525
+ target: target ?? (isExternal ? "_blank" : void 0),
526
+ rel: rel ?? (isExternal ? "noopener noreferrer" : void 0)
527
+ }
528
+ );
529
+ }
530
+
531
+ // src/core/components/Note.tsx
532
+ import { cva } from "class-variance-authority";
533
+ import {
534
+ AlertTriangle,
535
+ CheckCircle2,
536
+ Info,
537
+ ShieldAlert
538
+ } from "lucide-react";
539
+ import { jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
540
+ var noteVariants = cva(
541
+ "relative w-full rounded-lg border border-l-4 p-4 mb-4 [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground",
542
+ {
543
+ variants: {
544
+ variant: {
545
+ note: "bg-muted/30 border-border border-l-primary/50 text-foreground [&>svg]:text-primary",
546
+ danger: "border-destructive/20 border-l-destructive/60 bg-destructive/5 text-destructive [&>svg]:text-destructive dark:border-destructive/30",
547
+ warning: "border-orange-500/20 border-l-orange-500/60 bg-orange-500/5 text-orange-600 dark:text-orange-400 [&>svg]:text-orange-600 dark:[&>svg]:text-orange-400",
548
+ success: "border-emerald-500/20 border-l-emerald-500/60 bg-emerald-500/5 text-emerald-600 dark:text-emerald-400 [&>svg]:text-emerald-600 dark:[&>svg]:text-emerald-400"
549
+ }
550
+ },
551
+ defaultVariants: {
552
+ variant: "note"
553
+ }
554
+ }
555
+ );
556
+ var iconMap = {
557
+ note: Info,
558
+ danger: ShieldAlert,
559
+ warning: AlertTriangle,
560
+ success: CheckCircle2
561
+ };
562
+ function Note({
563
+ className,
564
+ title = "Note",
565
+ type = "note",
566
+ children,
567
+ ...props
568
+ }) {
569
+ const Icon = iconMap[type] || Info;
570
+ return /* @__PURE__ */ jsxs6("div", { className: cn(noteVariants({ variant: type }), className), ...props, children: [
571
+ /* @__PURE__ */ jsx11(Icon, { className: "h-5 w-5" }),
572
+ /* @__PURE__ */ jsxs6("div", { className: "pl-8", children: [
573
+ /* @__PURE__ */ jsx11("h5", { className: "mb-1 font-medium leading-none tracking-tight", children: title }),
574
+ /* @__PURE__ */ jsx11("div", { className: "text-sm [&_p]:leading-relaxed opacity-90", children })
575
+ ] })
576
+ ] });
577
+ }
578
+
579
+ // src/core/components/Copy.tsx
580
+ import { ClipboardCheckIcon, ClipboardIcon } from "lucide-react";
581
+ import { useState as useState5 } from "react";
582
+ import { jsx as jsx12 } from "react/jsx-runtime";
583
+ function Copy({ content }) {
584
+ const [isCopied, setIsCopied] = useState5(false);
585
+ async function handleCopy() {
586
+ await navigator.clipboard.writeText(content);
587
+ setIsCopied(true);
588
+ setTimeout(() => {
589
+ setIsCopied(false);
590
+ }, 2e3);
591
+ }
592
+ return /* @__PURE__ */ jsx12(
593
+ "button",
594
+ {
595
+ type: "button",
596
+ className: "border cursor-copy inline-flex h-6 w-6 items-center justify-center rounded-md",
597
+ onClick: handleCopy,
598
+ "aria-label": isCopied ? "Copied" : "Copy code",
599
+ children: isCopied ? /* @__PURE__ */ jsx12(ClipboardCheckIcon, { className: "w-3 h-3" }) : /* @__PURE__ */ jsx12(ClipboardIcon, { className: "w-3 h-3" })
600
+ }
601
+ );
602
+ }
603
+
604
+ // src/core/components/Pre.tsx
605
+ import {
606
+ SiJavascript,
607
+ SiTypescript,
608
+ SiReact,
609
+ SiPython,
610
+ SiGo,
611
+ SiPhp,
612
+ SiRuby,
613
+ SiSwift,
614
+ SiKotlin,
615
+ SiHtml5,
616
+ SiCss,
617
+ SiSass,
618
+ SiPostgresql,
619
+ SiGraphql,
620
+ SiYaml,
621
+ SiToml,
622
+ SiDocker,
623
+ SiNginx,
624
+ SiGit,
625
+ SiGnubash,
626
+ SiMarkdown
627
+ } from "react-icons/si";
628
+ import { FaJava, FaCode } from "react-icons/fa";
629
+ import { TbJson } from "react-icons/tb";
630
+ import { jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
631
+ function LanguageIcon({ lang }) {
632
+ const iconProps = { size: 16, className: "w-4 h-4" };
633
+ const languageToIconMap = {
634
+ gitignore: /* @__PURE__ */ jsx13(SiGit, { ...iconProps }),
635
+ docker: /* @__PURE__ */ jsx13(SiDocker, { ...iconProps }),
636
+ dockerfile: /* @__PURE__ */ jsx13(SiDocker, { ...iconProps }),
637
+ nginx: /* @__PURE__ */ jsx13(SiNginx, { ...iconProps }),
638
+ sql: /* @__PURE__ */ jsx13(SiPostgresql, { ...iconProps }),
639
+ graphql: /* @__PURE__ */ jsx13(SiGraphql, { ...iconProps }),
640
+ yaml: /* @__PURE__ */ jsx13(SiYaml, { ...iconProps }),
641
+ yml: /* @__PURE__ */ jsx13(SiYaml, { ...iconProps }),
642
+ toml: /* @__PURE__ */ jsx13(SiToml, { ...iconProps }),
643
+ json: /* @__PURE__ */ jsx13(TbJson, { ...iconProps }),
644
+ md: /* @__PURE__ */ jsx13(SiMarkdown, { ...iconProps }),
645
+ markdown: /* @__PURE__ */ jsx13(SiMarkdown, { ...iconProps }),
646
+ bash: /* @__PURE__ */ jsx13(SiGnubash, { ...iconProps }),
647
+ sh: /* @__PURE__ */ jsx13(SiGnubash, { ...iconProps }),
648
+ shell: /* @__PURE__ */ jsx13(SiGnubash, { ...iconProps }),
649
+ swift: /* @__PURE__ */ jsx13(SiSwift, { ...iconProps }),
650
+ kotlin: /* @__PURE__ */ jsx13(SiKotlin, { ...iconProps }),
651
+ kt: /* @__PURE__ */ jsx13(SiKotlin, { ...iconProps }),
652
+ kts: /* @__PURE__ */ jsx13(SiKotlin, { ...iconProps }),
653
+ rb: /* @__PURE__ */ jsx13(SiRuby, { ...iconProps }),
654
+ ruby: /* @__PURE__ */ jsx13(SiRuby, { ...iconProps }),
655
+ php: /* @__PURE__ */ jsx13(SiPhp, { ...iconProps }),
656
+ go: /* @__PURE__ */ jsx13(SiGo, { ...iconProps }),
657
+ py: /* @__PURE__ */ jsx13(SiPython, { ...iconProps }),
658
+ python: /* @__PURE__ */ jsx13(SiPython, { ...iconProps }),
659
+ java: /* @__PURE__ */ jsx13(FaJava, { ...iconProps }),
660
+ tsx: /* @__PURE__ */ jsx13(SiReact, { ...iconProps }),
661
+ typescript: /* @__PURE__ */ jsx13(SiTypescript, { ...iconProps }),
662
+ ts: /* @__PURE__ */ jsx13(SiTypescript, { ...iconProps }),
663
+ jsx: /* @__PURE__ */ jsx13(SiReact, { ...iconProps }),
664
+ js: /* @__PURE__ */ jsx13(SiJavascript, { ...iconProps }),
665
+ javascript: /* @__PURE__ */ jsx13(SiJavascript, { ...iconProps }),
666
+ html: /* @__PURE__ */ jsx13(SiHtml5, { ...iconProps }),
667
+ css: /* @__PURE__ */ jsx13(SiCss, { ...iconProps }),
668
+ scss: /* @__PURE__ */ jsx13(SiSass, { ...iconProps }),
669
+ sass: /* @__PURE__ */ jsx13(SiSass, { ...iconProps })
670
+ };
671
+ return languageToIconMap[lang] || /* @__PURE__ */ jsx13(FaCode, { ...iconProps });
672
+ }
673
+ function getLanguage(className = "") {
674
+ const match = className.match(/language-(\w+)/);
675
+ return match ? match[1] : "default";
676
+ }
677
+ function Pre({ children, raw, ...rest }) {
678
+ const { "data-title": title, className, ...restProps } = rest;
679
+ const language = getLanguage(className);
680
+ const hasTitle = !!title;
681
+ return /* @__PURE__ */ jsxs7("div", { className: "code-block-container", children: [
682
+ /* @__PURE__ */ jsx13("div", { className: "code-block-actions", children: raw && /* @__PURE__ */ jsx13(Copy, { content: raw }) }),
683
+ hasTitle && /* @__PURE__ */ jsx13("div", { className: "code-block-header", children: /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2", children: [
684
+ /* @__PURE__ */ jsx13(LanguageIcon, { lang: language }),
685
+ /* @__PURE__ */ jsx13("span", { children: title })
686
+ ] }) }),
687
+ /* @__PURE__ */ jsx13("div", { className: "code-block-body", children: /* @__PURE__ */ jsx13("pre", { className, ...restProps, children }) })
688
+ ] });
689
+ }
690
+
691
+ // src/core/components/Release.tsx
692
+ import { Children as Children2 } from "react";
693
+ import {
694
+ AlertTriangle as AlertTriangle2,
695
+ PlusCircle,
696
+ Wrench,
697
+ XCircle,
698
+ Zap
699
+ } from "lucide-react";
700
+ import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
701
+ function Release({ version, title, date, children }) {
702
+ return /* @__PURE__ */ jsxs8("div", { className: "mb-16 group", children: [
703
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-3 mt-6 mb-2", children: [
704
+ /* @__PURE__ */ jsxs8(
705
+ "div",
706
+ {
707
+ id: version,
708
+ className: "inline-flex items-center rounded-full border border-primary/20 bg-primary/10 px-3 py-1 text-sm font-semibold text-primary transition-colors hover:bg-primary/15 scroll-m-20 backdrop-blur-sm",
709
+ children: [
710
+ "v",
711
+ version
712
+ ]
713
+ }
714
+ ),
715
+ date && /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-3 text-sm font-medium text-muted-foreground", children: [
716
+ /* @__PURE__ */ jsx14("span", { className: "h-1 w-1 rounded-full bg-muted-foreground/30" }),
717
+ /* @__PURE__ */ jsx14("time", { dateTime: date, children: new Date(date).toLocaleDateString("en-US", {
718
+ year: "numeric",
719
+ month: "long",
720
+ day: "numeric"
721
+ }) })
722
+ ] })
723
+ ] }),
724
+ /* @__PURE__ */ jsx14("h3", { className: "text-2xl font-bold text-foreground/90 mb-6 mt-0!", children: title }),
725
+ /* @__PURE__ */ jsx14("div", { className: "space-y-8", children })
726
+ ] });
727
+ }
728
+ var typeConfig = {
729
+ added: {
730
+ label: "Added",
731
+ className: "bg-green-100 dark:bg-green-900/50 text-green-700 dark:text-green-300",
732
+ icon: PlusCircle
733
+ },
734
+ fixed: {
735
+ label: "Fixed",
736
+ className: "bg-yellow-100 dark:bg-yellow-900/50 text-yellow-700 dark:text-yellow-300",
737
+ icon: Wrench
738
+ },
739
+ improved: {
740
+ label: "Improved",
741
+ className: "bg-cyan-100 dark:bg-cyan-900/50 text-cyan-700 dark:text-cyan-300",
742
+ icon: Zap
743
+ },
744
+ deprecated: {
745
+ label: "Deprecated",
746
+ className: "bg-orange-100 dark:bg-orange-900/50 text-orange-700 dark:text-orange-300",
747
+ icon: AlertTriangle2
748
+ },
749
+ removed: {
750
+ label: "Removed",
751
+ className: "bg-pink-100 dark:bg-pink-900/50 text-pink-700 dark:text-pink-300",
752
+ icon: XCircle
753
+ }
754
+ };
755
+ function Changes({ type, children }) {
756
+ const config = typeConfig[type] || typeConfig.added;
757
+ return /* @__PURE__ */ jsxs8("div", { className: "space-y-3 mb-8", children: [
758
+ /* @__PURE__ */ jsx14("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxs8(
759
+ "div",
760
+ {
761
+ className: cn(
762
+ "px-3 py-1 rounded-full text-sm font-medium flex items-center gap-1.5",
763
+ config.className
764
+ ),
765
+ children: [
766
+ /* @__PURE__ */ jsx14(config.icon, { className: "h-3.5 w-3.5" }),
767
+ /* @__PURE__ */ jsx14("span", { children: config.label })
768
+ ]
769
+ }
770
+ ) }),
771
+ /* @__PURE__ */ jsx14("ul", { className: "list-none pl-0 space-y-2 text-foreground/80", children: Children2.map(children, (child, index) => {
772
+ const processedChild = typeof child === "string" ? child.trim().replace(/^[-*]\s+/, "") : child;
773
+ return /* @__PURE__ */ jsx14("li", { className: "leading-relaxed", children: processedChild }, index);
774
+ }) })
775
+ ] });
776
+ }
777
+
778
+ // src/core/components/Stepper.tsx
779
+ import clsx5 from "clsx";
780
+ import { Children as Children3 } from "react";
781
+ import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
782
+ function Stepper({ children }) {
783
+ const length = Children3.count(children);
784
+ return /* @__PURE__ */ jsx15("div", { className: "flex flex-col", children: Children3.map(children, (child, index) => {
785
+ return /* @__PURE__ */ jsxs9(
786
+ "div",
787
+ {
788
+ className: cn(
789
+ "border-l border-muted pl-9 ml-3 relative",
790
+ clsx5({
791
+ "pb-5 ": index < length - 1
792
+ })
793
+ ),
794
+ children: [
795
+ /* @__PURE__ */ jsx15("div", { className: "bg-muted text-muted-foreground w-8 h-8 text-xs font-medium rounded-md border border-border/50 flex items-center justify-center absolute -left-4 font-code", children: index + 1 }),
796
+ child
797
+ ]
798
+ }
799
+ );
800
+ }) });
801
+ }
802
+ function StepperItem({
803
+ children,
804
+ title
805
+ }) {
806
+ return /* @__PURE__ */ jsxs9("div", { className: "pt-0.5", children: [
807
+ /* @__PURE__ */ jsx15("h4", { className: "mt-0", children: title }),
808
+ /* @__PURE__ */ jsx15("div", { children })
809
+ ] });
810
+ }
811
+
812
+ // src/core/components/Tooltip.tsx
813
+ import { useState as useState6 } from "react";
814
+ import { jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
815
+ var Tooltip = ({ text, tip }) => {
816
+ const [visible, setVisible] = useState6(false);
817
+ return /* @__PURE__ */ jsxs10(
818
+ "span",
819
+ {
820
+ className: "relative inline-flex items-center cursor-help text-primary hover:text-primary/80 transition-colors",
821
+ onMouseEnter: () => setVisible(true),
822
+ onMouseLeave: () => setVisible(false),
823
+ children: [
824
+ /* @__PURE__ */ jsx16("span", { className: "border-b border-dashed border-primary/60 pb-0.5", children: text }),
825
+ visible && /* @__PURE__ */ jsxs10("span", { className: "absolute bottom-full left-1/2 -translate-x-1/2 mb-3 w-64 bg-popover text-popover-foreground text-sm p-3 rounded-md shadow-lg border border-border/50 wrap-break-word text-left z-50", children: [
826
+ tip,
827
+ /* @__PURE__ */ jsx16("span", { className: "absolute -bottom-1.5 left-1/2 -translate-x-1/2 w-3 h-3 bg-popover rotate-45 border-b border-r border-border/50 -z-10" })
828
+ ] })
829
+ ]
830
+ }
831
+ );
832
+ };
833
+
834
+ // src/core/components/Youtube.tsx
835
+ import { jsx as jsx17 } from "react/jsx-runtime";
836
+ var Youtube = ({ videoId, className }) => {
837
+ return /* @__PURE__ */ jsx17("div", { className: `youtube ${className || ""}`, children: /* @__PURE__ */ jsx17(
838
+ "iframe",
839
+ {
840
+ src: `https://www.youtube.com/embed/${videoId}?rel=0&modestbranding=1&showinfo=0&autohide=1&controls=1`,
841
+ title: "YouTube video player",
842
+ frameBorder: "0",
843
+ allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",
844
+ allowFullScreen: true
845
+ }
846
+ ) });
847
+ };
848
+
849
+ // src/core/index.ts
850
+ function createCoreMdxComponents() {
851
+ return {
852
+ Accordion,
853
+ AccordionGroup,
854
+ Button,
855
+ Card,
856
+ CardGroup,
857
+ Kbd,
858
+ kbd: Kbd,
859
+ pre: Pre,
860
+ Note,
861
+ Stepper,
862
+ StepperItem,
863
+ Youtube,
864
+ Tooltip,
865
+ Release,
866
+ Changes,
867
+ File,
868
+ Files,
869
+ Folder,
870
+ img: Image,
871
+ a: Link
872
+ };
873
+ }
874
+ export {
875
+ Accordion,
876
+ AccordionGroup,
877
+ Button,
878
+ Card,
879
+ CardGroup,
880
+ Changes,
881
+ Copy,
882
+ File,
883
+ Files,
884
+ Folder,
885
+ Image,
886
+ Kbd,
887
+ Link,
888
+ Note,
889
+ Pre,
890
+ Release,
891
+ Stepper,
892
+ StepperItem,
893
+ Tooltip,
894
+ Youtube,
895
+ createCoreMdxComponents
896
+ };