@vllnt/ui 0.1.4 → 0.1.7-canary.2c4792f

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.
Files changed (225) hide show
  1. package/dist/components/accordion/accordion.js +172 -0
  2. package/dist/components/accordion/index.js +12 -0
  3. package/dist/components/alert/alert.js +53 -0
  4. package/dist/components/alert/index.js +7 -0
  5. package/dist/components/alert-dialog/alert-dialog.js +117 -0
  6. package/dist/components/alert-dialog/index.js +26 -0
  7. package/dist/components/aspect-ratio/aspect-ratio.js +6 -0
  8. package/dist/components/aspect-ratio/index.js +4 -0
  9. package/dist/components/avatar/avatar.js +43 -0
  10. package/dist/components/avatar/index.js +6 -0
  11. package/dist/components/badge/badge.js +26 -0
  12. package/dist/components/badge/index.js +5 -0
  13. package/dist/components/blog-card/blog-card.js +50 -0
  14. package/dist/components/blog-card/index.js +5 -0
  15. package/dist/components/breadcrumb/breadcrumb.js +61 -0
  16. package/dist/components/breadcrumb/index.js +4 -0
  17. package/dist/components/button/button.js +48 -0
  18. package/dist/components/button/index.js +5 -0
  19. package/dist/components/calendar/calendar.js +71 -0
  20. package/dist/components/calendar/index.js +4 -0
  21. package/dist/components/callout/callout.js +59 -0
  22. package/dist/components/callout/index.js +4 -0
  23. package/dist/components/card/card.js +64 -0
  24. package/dist/components/card/index.js +16 -0
  25. package/dist/components/carousel/carousel.js +239 -0
  26. package/dist/components/carousel/index.js +14 -0
  27. package/dist/components/category-filter/category-filter.js +34 -0
  28. package/dist/components/category-filter/index.js +4 -0
  29. package/dist/components/chart/area-chart.js +99 -0
  30. package/dist/components/chart/bar-chart.js +80 -0
  31. package/dist/components/chart/index.js +3 -0
  32. package/dist/components/chart/line-chart.js +97 -0
  33. package/dist/components/checkbox/checkbox.js +28 -0
  34. package/dist/components/checkbox/index.js +4 -0
  35. package/dist/components/checklist/checklist.js +181 -0
  36. package/dist/components/checklist/index.js +6 -0
  37. package/dist/components/code-block/code-block.js +126 -0
  38. package/dist/components/code-block/index.js +4 -0
  39. package/dist/components/code-playground/code-playground.js +86 -0
  40. package/dist/components/code-playground/index.js +8 -0
  41. package/dist/components/collapsible/collapsible.js +10 -0
  42. package/dist/components/collapsible/index.js +10 -0
  43. package/dist/components/command/command.js +123 -0
  44. package/dist/components/command/index.js +22 -0
  45. package/dist/components/comparison/comparison.js +121 -0
  46. package/dist/components/comparison/index.js +8 -0
  47. package/dist/components/completion-dialog/completion-dialog.js +173 -0
  48. package/dist/components/completion-dialog/index.js +6 -0
  49. package/dist/components/content-intro/content-intro.js +144 -0
  50. package/dist/components/content-intro/index.js +6 -0
  51. package/dist/components/context-menu/context-menu.js +154 -0
  52. package/dist/components/context-menu/index.js +34 -0
  53. package/dist/components/cookie-consent/cookie-consent.js +175 -0
  54. package/dist/components/cookie-consent/index.js +8 -0
  55. package/dist/components/dialog/dialog.js +105 -0
  56. package/dist/components/dialog/index.js +24 -0
  57. package/dist/components/drawer/drawer.js +102 -0
  58. package/dist/components/drawer/index.js +24 -0
  59. package/dist/components/dropdown-menu/dropdown-menu.js +151 -0
  60. package/dist/components/dropdown-menu/index.js +34 -0
  61. package/dist/components/exercise/exercise.js +112 -0
  62. package/dist/components/exercise/index.js +4 -0
  63. package/dist/components/faq/faq.js +56 -0
  64. package/dist/components/faq/index.js +5 -0
  65. package/dist/components/filter-bar/filter-bar.js +244 -0
  66. package/dist/components/filter-bar/index.js +6 -0
  67. package/dist/components/floating-action-button/floating-action-button.js +35 -0
  68. package/dist/components/floating-action-button/index.js +6 -0
  69. package/dist/components/flow-diagram/flow-canvas.js +109 -0
  70. package/dist/components/flow-diagram/flow-controls.js +140 -0
  71. package/dist/components/flow-diagram/flow-diagram.js +114 -0
  72. package/dist/components/flow-diagram/flow-error-boundary.js +63 -0
  73. package/dist/components/flow-diagram/flow-fullscreen.js +58 -0
  74. package/dist/components/flow-diagram/index.js +12 -0
  75. package/dist/components/flow-diagram/types.js +0 -0
  76. package/dist/components/flow-diagram/use-flow-diagram.js +146 -0
  77. package/dist/components/horizontal-scroll-row/horizontal-scroll-row.js +66 -0
  78. package/dist/components/horizontal-scroll-row/index.js +6 -0
  79. package/dist/components/hover-card/hover-card.js +26 -0
  80. package/dist/components/hover-card/index.js +6 -0
  81. package/dist/components/index.js +641 -0
  82. package/dist/components/inline-input/index.js +4 -0
  83. package/dist/components/inline-input/inline-input.js +42 -0
  84. package/dist/components/input/index.js +4 -0
  85. package/dist/components/input/input.js +23 -0
  86. package/dist/components/input-otp/index.js +12 -0
  87. package/dist/components/input-otp/input-otp.js +54 -0
  88. package/dist/components/key-concept/index.js +8 -0
  89. package/dist/components/key-concept/key-concept.js +79 -0
  90. package/dist/components/keyboard-shortcuts-help/index.js +6 -0
  91. package/dist/components/keyboard-shortcuts-help/keyboard-shortcuts-help.js +121 -0
  92. package/dist/components/label/index.js +4 -0
  93. package/dist/components/label/label.js +21 -0
  94. package/dist/components/lang-provider/index.js +4 -0
  95. package/dist/components/lang-provider/lang-provider.js +18 -0
  96. package/dist/components/learning-objectives/index.js +10 -0
  97. package/dist/components/learning-objectives/learning-objectives.js +76 -0
  98. package/dist/components/mdx-content/index.js +4 -0
  99. package/dist/components/mdx-content/mdx-content.js +151 -0
  100. package/dist/components/menubar/index.js +36 -0
  101. package/dist/components/menubar/menubar.js +183 -0
  102. package/dist/components/model-selector/index.js +6 -0
  103. package/dist/components/model-selector/model-selector.js +374 -0
  104. package/dist/components/navbar-saas/index.js +6 -0
  105. package/dist/components/navbar-saas/navbar-saas.js +68 -0
  106. package/dist/components/navbar-saas/use-mobile.js +19 -0
  107. package/dist/components/navigation-menu/index.js +22 -0
  108. package/dist/components/navigation-menu/navigation-menu.js +108 -0
  109. package/dist/components/pagination/index.js +4 -0
  110. package/dist/components/pagination/pagination.js +44 -0
  111. package/dist/components/popover/index.js +12 -0
  112. package/dist/components/popover/popover.js +28 -0
  113. package/dist/components/pro-tip/index.js +8 -0
  114. package/dist/components/pro-tip/pro-tip.js +139 -0
  115. package/dist/components/profile-section/index.js +4 -0
  116. package/dist/components/profile-section/profile-section.js +45 -0
  117. package/dist/components/progress-bar/index.js +4 -0
  118. package/dist/components/progress-bar/progress-bar.js +56 -0
  119. package/dist/components/progress-card/index.js +6 -0
  120. package/dist/components/progress-card/progress-card.js +71 -0
  121. package/dist/components/quiz/index.js +4 -0
  122. package/dist/components/quiz/quiz.js +210 -0
  123. package/dist/components/radio-group/index.js +5 -0
  124. package/dist/components/radio-group/radio-group.js +36 -0
  125. package/dist/components/resizable/index.js +10 -0
  126. package/dist/components/resizable/resizable.js +39 -0
  127. package/dist/components/scroll-area/index.js +5 -0
  128. package/dist/components/scroll-area/scroll-area.js +39 -0
  129. package/dist/components/search-bar/index.js +4 -0
  130. package/dist/components/search-bar/search-bar.js +122 -0
  131. package/dist/components/search-dialog/index.js +4 -0
  132. package/dist/components/search-dialog/search-dialog.js +102 -0
  133. package/dist/components/select/index.js +24 -0
  134. package/dist/components/select/select.js +125 -0
  135. package/dist/components/separator/index.js +4 -0
  136. package/dist/components/separator/separator.js +25 -0
  137. package/dist/components/share-dialog/index.js +6 -0
  138. package/dist/components/share-dialog/share-dialog.js +121 -0
  139. package/dist/components/share-section/index.js +6 -0
  140. package/dist/components/share-section/share-section.js +57 -0
  141. package/dist/components/sheet/index.js +24 -0
  142. package/dist/components/sheet/sheet.js +116 -0
  143. package/dist/components/sidebar/index.js +4 -0
  144. package/dist/components/sidebar/sidebar.js +188 -0
  145. package/dist/components/sidebar-provider/index.js +5 -0
  146. package/dist/components/sidebar-provider/sidebar-provider.js +25 -0
  147. package/dist/components/sidebar-toggle/index.js +4 -0
  148. package/dist/components/sidebar-toggle/sidebar-toggle.js +36 -0
  149. package/dist/components/skeleton/index.js +4 -0
  150. package/dist/components/skeleton/skeleton.js +17 -0
  151. package/dist/components/slider/index.js +4 -0
  152. package/dist/components/slider/slider.js +24 -0
  153. package/dist/components/slideshow/index.js +6 -0
  154. package/dist/components/slideshow/slideshow.js +440 -0
  155. package/dist/components/social-fab/index.js +6 -0
  156. package/dist/components/social-fab/social-fab.js +211 -0
  157. package/dist/components/social-fab/use-social-fab.js +111 -0
  158. package/dist/components/spinner/index.js +4 -0
  159. package/dist/components/spinner/spinner.js +23 -0
  160. package/dist/components/step-by-step/index.js +8 -0
  161. package/dist/components/step-by-step/step-by-step.js +194 -0
  162. package/dist/components/step-navigation/index.js +4 -0
  163. package/dist/components/step-navigation/step-navigation.js +119 -0
  164. package/dist/components/switch/index.js +4 -0
  165. package/dist/components/switch/switch.js +28 -0
  166. package/dist/components/table/index.js +20 -0
  167. package/dist/components/table/table.js +87 -0
  168. package/dist/components/table-of-contents/index.js +4 -0
  169. package/dist/components/table-of-contents/table-of-contents.js +71 -0
  170. package/dist/components/table-of-contents-panel/index.js +6 -0
  171. package/dist/components/table-of-contents-panel/table-of-contents-panel.js +202 -0
  172. package/dist/components/tabs/index.js +12 -0
  173. package/dist/components/tabs/tabs.js +84 -0
  174. package/dist/components/terminal/index.js +8 -0
  175. package/dist/components/terminal/terminal.js +119 -0
  176. package/dist/components/textarea/index.js +4 -0
  177. package/dist/components/textarea/textarea.js +22 -0
  178. package/dist/components/theme-provider/index.js +4 -0
  179. package/dist/components/theme-provider/theme-provider.js +11 -0
  180. package/dist/components/theme-toggle/index.js +4 -0
  181. package/dist/components/theme-toggle/theme-toggle.js +170 -0
  182. package/dist/components/thinking-block/index.js +4 -0
  183. package/dist/components/thinking-block/thinking-block.js +56 -0
  184. package/dist/components/tldr-section/index.js +4 -0
  185. package/dist/components/tldr-section/tldr-section.js +101 -0
  186. package/dist/components/toast/index.js +18 -0
  187. package/dist/components/toast/toast.js +84 -0
  188. package/dist/components/toast/toaster.js +38 -0
  189. package/dist/components/toggle/index.js +5 -0
  190. package/dist/components/toggle/toggle.js +39 -0
  191. package/dist/components/toggle-group/index.js +5 -0
  192. package/dist/components/toggle-group/toggle-group.js +46 -0
  193. package/dist/components/tooltip/index.js +12 -0
  194. package/dist/components/tooltip/tooltip.js +27 -0
  195. package/dist/components/truncated-text/index.js +4 -0
  196. package/dist/components/truncated-text/truncated-text.js +25 -0
  197. package/dist/components/tutorial-card/index.js +6 -0
  198. package/dist/components/tutorial-card/tutorial-card.js +78 -0
  199. package/dist/components/tutorial-complete/index.js +6 -0
  200. package/dist/components/tutorial-complete/tutorial-complete.js +134 -0
  201. package/dist/components/tutorial-filters/index.js +6 -0
  202. package/dist/components/tutorial-filters/tutorial-filters.js +205 -0
  203. package/dist/components/tutorial-intro-content/index.js +6 -0
  204. package/dist/components/tutorial-intro-content/tutorial-intro-content.js +141 -0
  205. package/dist/components/tutorial-mdx/index.js +8 -0
  206. package/dist/components/tutorial-mdx/tutorial-mdx.js +219 -0
  207. package/dist/components/video-embed/index.js +4 -0
  208. package/dist/components/video-embed/video-embed.js +77 -0
  209. package/dist/components/view-switcher/index.js +6 -0
  210. package/dist/components/view-switcher/view-switcher.js +92 -0
  211. package/dist/index.d.ts +44 -2
  212. package/dist/index.js +14 -8556
  213. package/dist/lib/types.js +11 -0
  214. package/dist/lib/use-debounce.js +17 -0
  215. package/dist/lib/use-horizontal-scroll.js +60 -0
  216. package/dist/lib/use-mounted.js +17 -0
  217. package/dist/lib/utils.js +8 -0
  218. package/dist/tailwind-preset.d.ts +5 -0
  219. package/dist/tailwind-preset.js +9 -10
  220. package/dist/types/content.js +0 -0
  221. package/dist/types/index.js +0 -0
  222. package/package.json +42 -23
  223. package/LICENSE +0 -21
  224. package/dist/chunk-XRV5RSYH.js +0 -569
  225. package/dist/flow-diagram-N3EHM6VB.js +0 -2
@@ -0,0 +1,54 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { forwardRef, useContext } from "react";
4
+ import { OTPInput, OTPInputContext } from "input-otp";
5
+ import { Dot } from "lucide-react";
6
+ import { cn } from "../../lib/utils";
7
+ const InputOTP = forwardRef(({ className, containerClassName, ...props }, ref) => /* @__PURE__ */ jsx(
8
+ OTPInput,
9
+ {
10
+ className: cn("disabled:cursor-not-allowed", className),
11
+ containerClassName: cn(
12
+ "flex items-center gap-2 has-[:disabled]:opacity-50",
13
+ containerClassName
14
+ ),
15
+ ref,
16
+ ...props
17
+ }
18
+ ));
19
+ InputOTP.displayName = "InputOTP";
20
+ const InputOTPGroup = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { className: cn("flex items-center", className), ref, ...props }));
21
+ InputOTPGroup.displayName = "InputOTPGroup";
22
+ const InputOTPSlot = forwardRef(({ className, index, ...props }, ref) => {
23
+ const inputOTPContext = useContext(OTPInputContext);
24
+ const slot = inputOTPContext.slots[index];
25
+ if (!slot) {
26
+ return null;
27
+ }
28
+ const { char, hasFakeCaret, isActive } = slot;
29
+ return /* @__PURE__ */ jsxs(
30
+ "div",
31
+ {
32
+ className: cn(
33
+ "relative flex h-10 w-10 items-center justify-center border-y border-r border-input text-sm transition-all first:rounded-l-md first:border-l last:rounded-r-md",
34
+ isActive && "z-10 ring-2 ring-ring ring-offset-background",
35
+ className
36
+ ),
37
+ ref,
38
+ ...props,
39
+ children: [
40
+ char,
41
+ hasFakeCaret ? /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsx("div", { className: "h-4 w-px animate-caret-blink bg-foreground duration-1000" }) }) : null
42
+ ]
43
+ }
44
+ );
45
+ });
46
+ InputOTPSlot.displayName = "InputOTPSlot";
47
+ const InputOTPSeparator = forwardRef(({ ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, role: "separator", ...props, children: /* @__PURE__ */ jsx(Dot, {}) }));
48
+ InputOTPSeparator.displayName = "InputOTPSeparator";
49
+ export {
50
+ InputOTP,
51
+ InputOTPGroup,
52
+ InputOTPSeparator,
53
+ InputOTPSlot
54
+ };
@@ -0,0 +1,8 @@
1
+ import {
2
+ Glossary,
3
+ KeyConcept
4
+ } from "./key-concept";
5
+ export {
6
+ Glossary,
7
+ KeyConcept
8
+ };
@@ -0,0 +1,79 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { cn } from "../../lib/utils";
3
+ function KeyConcept({
4
+ children,
5
+ className,
6
+ highlight = false,
7
+ icon,
8
+ term
9
+ }) {
10
+ return /* @__PURE__ */ jsx(
11
+ "div",
12
+ {
13
+ className: cn(
14
+ "my-4 rounded-lg border p-4",
15
+ highlight ? "border-primary/50 bg-primary/5" : "border-border bg-muted/30",
16
+ className
17
+ ),
18
+ children: /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3", children: [
19
+ icon ? /* @__PURE__ */ jsx("span", { className: "h-5 w-5 text-primary flex-shrink-0 mt-0.5", children: icon }) : /* @__PURE__ */ jsx(
20
+ "svg",
21
+ {
22
+ className: "h-5 w-5 text-primary flex-shrink-0 mt-0.5",
23
+ fill: "none",
24
+ stroke: "currentColor",
25
+ viewBox: "0 0 24 24",
26
+ children: /* @__PURE__ */ jsx(
27
+ "path",
28
+ {
29
+ d: "M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253",
30
+ strokeLinecap: "round",
31
+ strokeLinejoin: "round",
32
+ strokeWidth: 2
33
+ }
34
+ )
35
+ }
36
+ ),
37
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
38
+ /* @__PURE__ */ jsx("dt", { className: "font-bold text-foreground mb-1", children: term }),
39
+ /* @__PURE__ */ jsx("dd", { className: "text-sm text-muted-foreground [&>p]:mb-0", children })
40
+ ] })
41
+ ] })
42
+ }
43
+ );
44
+ }
45
+ function Glossary({
46
+ children,
47
+ className,
48
+ icon,
49
+ title = "Key Terms"
50
+ }) {
51
+ return /* @__PURE__ */ jsxs("div", { className: cn("my-6", className), children: [
52
+ /* @__PURE__ */ jsxs("h4", { className: "font-semibold mb-3 flex items-center gap-2", children: [
53
+ icon ? /* @__PURE__ */ jsx("span", { className: "h-4 w-4", children: icon }) : /* @__PURE__ */ jsx(
54
+ "svg",
55
+ {
56
+ className: "h-4 w-4",
57
+ fill: "none",
58
+ stroke: "currentColor",
59
+ viewBox: "0 0 24 24",
60
+ children: /* @__PURE__ */ jsx(
61
+ "path",
62
+ {
63
+ d: "M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253",
64
+ strokeLinecap: "round",
65
+ strokeLinejoin: "round",
66
+ strokeWidth: 2
67
+ }
68
+ )
69
+ }
70
+ ),
71
+ title
72
+ ] }),
73
+ /* @__PURE__ */ jsx("dl", { className: "space-y-2", children })
74
+ ] });
75
+ }
76
+ export {
77
+ Glossary,
78
+ KeyConcept
79
+ };
@@ -0,0 +1,6 @@
1
+ import {
2
+ KeyboardShortcutsHelp
3
+ } from "./keyboard-shortcuts-help";
4
+ export {
5
+ KeyboardShortcutsHelp
6
+ };
@@ -0,0 +1,121 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { memo, useEffect, useRef } from "react";
4
+ import { cn } from "../../lib/utils";
5
+ function KeyboardShortcutsHelpImpl({
6
+ className,
7
+ closeIcon,
8
+ footer,
9
+ isOpen,
10
+ onClose,
11
+ shortcuts,
12
+ title = "Keyboard Shortcuts"
13
+ }) {
14
+ const closeButtonRef = useRef(null);
15
+ useEffect(() => {
16
+ if (!isOpen) return;
17
+ closeButtonRef.current?.focus();
18
+ const handleKeyDown = (event) => {
19
+ if (event.key === "Escape") {
20
+ event.preventDefault();
21
+ onClose();
22
+ }
23
+ };
24
+ window.addEventListener("keydown", handleKeyDown);
25
+ return () => {
26
+ window.removeEventListener("keydown", handleKeyDown);
27
+ };
28
+ }, [isOpen, onClose]);
29
+ useEffect(() => {
30
+ document.body.style.overflow = isOpen ? "hidden" : "";
31
+ return () => {
32
+ document.body.style.overflow = "";
33
+ };
34
+ }, [isOpen]);
35
+ if (!isOpen) return null;
36
+ return /* @__PURE__ */ jsxs(
37
+ "div",
38
+ {
39
+ "aria-labelledby": "shortcuts-title",
40
+ "aria-modal": "true",
41
+ className: "fixed inset-0 z-50 flex items-center justify-center",
42
+ role: "dialog",
43
+ children: [
44
+ /* @__PURE__ */ jsx(
45
+ "div",
46
+ {
47
+ "aria-hidden": "true",
48
+ className: "absolute inset-0 bg-black/50 backdrop-blur-sm",
49
+ onClick: onClose
50
+ }
51
+ ),
52
+ /* @__PURE__ */ jsxs(
53
+ "div",
54
+ {
55
+ className: cn(
56
+ "relative z-10 w-full max-w-sm rounded-lg bg-background p-6 shadow-xl mx-4",
57
+ className
58
+ ),
59
+ children: [
60
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-4", children: [
61
+ /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold", id: "shortcuts-title", children: title }),
62
+ /* @__PURE__ */ jsx(
63
+ "button",
64
+ {
65
+ "aria-label": "Close shortcuts help",
66
+ className: "flex h-8 w-8 items-center justify-center rounded-md hover:bg-muted",
67
+ onClick: onClose,
68
+ ref: closeButtonRef,
69
+ type: "button",
70
+ children: closeIcon ?? /* @__PURE__ */ jsx(
71
+ "svg",
72
+ {
73
+ className: "h-5 w-5",
74
+ fill: "none",
75
+ stroke: "currentColor",
76
+ viewBox: "0 0 24 24",
77
+ children: /* @__PURE__ */ jsx(
78
+ "path",
79
+ {
80
+ d: "M6 18L18 6M6 6l12 12",
81
+ strokeLinecap: "round",
82
+ strokeLinejoin: "round",
83
+ strokeWidth: 2
84
+ }
85
+ )
86
+ }
87
+ )
88
+ }
89
+ )
90
+ ] }),
91
+ /* @__PURE__ */ jsx("div", { className: "space-y-3", children: shortcuts.map((shortcut) => /* @__PURE__ */ jsxs(
92
+ "div",
93
+ {
94
+ className: "flex items-center justify-between text-sm",
95
+ children: [
96
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: shortcut.description }),
97
+ /* @__PURE__ */ jsx("div", { className: "flex gap-1", children: shortcut.keys.map((key) => /* @__PURE__ */ jsx(
98
+ "kbd",
99
+ {
100
+ className: "inline-flex h-6 min-w-[24px] items-center justify-center rounded border border-border bg-muted px-1.5 font-mono text-xs",
101
+ children: key
102
+ },
103
+ key
104
+ )) })
105
+ ]
106
+ },
107
+ shortcut.description
108
+ )) }),
109
+ footer ? /* @__PURE__ */ jsx("div", { className: "mt-4 text-xs text-muted-foreground text-center", children: footer }) : null
110
+ ]
111
+ }
112
+ )
113
+ ]
114
+ }
115
+ );
116
+ }
117
+ const KeyboardShortcutsHelp = memo(KeyboardShortcutsHelpImpl);
118
+ KeyboardShortcutsHelp.displayName = "KeyboardShortcutsHelp";
119
+ export {
120
+ KeyboardShortcutsHelp
121
+ };
@@ -0,0 +1,4 @@
1
+ import { Label } from "./label";
2
+ export {
3
+ Label
4
+ };
@@ -0,0 +1,21 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import * as LabelPrimitive from "@radix-ui/react-label";
5
+ import { cva } from "class-variance-authority";
6
+ import { cn } from "../../lib/utils";
7
+ const labelVariants = cva(
8
+ "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
9
+ );
10
+ const Label = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
11
+ LabelPrimitive.Root,
12
+ {
13
+ className: cn(labelVariants(), className),
14
+ ref,
15
+ ...props
16
+ }
17
+ ));
18
+ Label.displayName = LabelPrimitive.Root.displayName;
19
+ export {
20
+ Label
21
+ };
@@ -0,0 +1,4 @@
1
+ import { LangProvider } from "./lang-provider";
2
+ export {
3
+ LangProvider
4
+ };
@@ -0,0 +1,18 @@
1
+ "use client";
2
+ import { useEffect } from "react";
3
+ import { usePathname } from "next/navigation";
4
+ function LangProvider({
5
+ defaultLanguage = "en",
6
+ supportedLanguages = ["en", "fr"]
7
+ }) {
8
+ const pathname = usePathname();
9
+ useEffect(() => {
10
+ const langMatch = /^\/([a-z]{2})(?:\/|$)/.exec(pathname);
11
+ const lang = langMatch && supportedLanguages.includes(langMatch[1]) ? langMatch[1] : defaultLanguage;
12
+ document.documentElement.setAttribute("lang", lang);
13
+ }, [pathname, defaultLanguage, supportedLanguages]);
14
+ return null;
15
+ }
16
+ export {
17
+ LangProvider
18
+ };
@@ -0,0 +1,10 @@
1
+ import {
2
+ LearningObjectives,
3
+ Prerequisites,
4
+ Summary
5
+ } from "./learning-objectives";
6
+ export {
7
+ LearningObjectives,
8
+ Prerequisites,
9
+ Summary
10
+ };
@@ -0,0 +1,76 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { CheckCircle2, Clock, GraduationCap, Target } from "lucide-react";
4
+ function LearningObjectives({
5
+ estimatedTime,
6
+ objectives,
7
+ title = "What you'll learn"
8
+ }) {
9
+ return /* @__PURE__ */ jsxs("div", { className: "my-6 rounded-lg border bg-gradient-to-br from-primary/5 to-primary/10 p-6", children: [
10
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-4", children: [
11
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
12
+ /* @__PURE__ */ jsx(Target, { className: "h-5 w-5 text-primary" }),
13
+ /* @__PURE__ */ jsx("h4", { className: "font-semibold text-foreground", children: title })
14
+ ] }),
15
+ estimatedTime ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
16
+ /* @__PURE__ */ jsx(Clock, { className: "h-4 w-4" }),
17
+ /* @__PURE__ */ jsx("span", { children: estimatedTime })
18
+ ] }) : null
19
+ ] }),
20
+ /* @__PURE__ */ jsx("ul", { className: "space-y-2", children: objectives.map((objective, index) => /* @__PURE__ */ jsxs("li", { className: "flex items-start gap-2", children: [
21
+ /* @__PURE__ */ jsx(CheckCircle2, { className: "h-4 w-4 text-primary flex-shrink-0 mt-0.5" }),
22
+ /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: objective })
23
+ ] }, index)) })
24
+ ] });
25
+ }
26
+ function Prerequisites({
27
+ items,
28
+ level,
29
+ title = "Prerequisites"
30
+ }) {
31
+ return /* @__PURE__ */ jsxs("div", { className: "my-6 rounded-lg border bg-muted/30 p-6", children: [
32
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-4", children: [
33
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
34
+ /* @__PURE__ */ jsx(GraduationCap, { className: "h-5 w-5 text-muted-foreground" }),
35
+ /* @__PURE__ */ jsx("h4", { className: "font-semibold text-foreground", children: title })
36
+ ] }),
37
+ level ? /* @__PURE__ */ jsx("span", { className: "text-xs font-medium px-2 py-1 rounded-full bg-primary/10 text-primary capitalize", children: level }) : null
38
+ ] }),
39
+ /* @__PURE__ */ jsx("ul", { className: "space-y-2", children: items.map((item, index) => /* @__PURE__ */ jsxs(
40
+ "li",
41
+ {
42
+ className: "flex items-start gap-2 text-sm text-muted-foreground",
43
+ children: [
44
+ /* @__PURE__ */ jsx("span", { className: "text-primary", children: "\u2022" }),
45
+ item
46
+ ]
47
+ },
48
+ index
49
+ )) })
50
+ ] });
51
+ }
52
+ function Summary({
53
+ children,
54
+ keyTakeaways,
55
+ title = "Summary"
56
+ }) {
57
+ return /* @__PURE__ */ jsxs("div", { className: "my-6 rounded-lg border bg-muted/30 p-6", children: [
58
+ /* @__PURE__ */ jsxs("h4", { className: "font-semibold text-foreground mb-3 flex items-center gap-2", children: [
59
+ /* @__PURE__ */ jsx(GraduationCap, { className: "h-5 w-5" }),
60
+ title
61
+ ] }),
62
+ /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground [&>p]:mb-2", children }),
63
+ keyTakeaways && keyTakeaways.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "mt-4 pt-4 border-t border-border", children: [
64
+ /* @__PURE__ */ jsx("p", { className: "text-xs font-medium uppercase tracking-wider text-muted-foreground mb-2", children: "Key Takeaways" }),
65
+ /* @__PURE__ */ jsx("ul", { className: "space-y-1", children: keyTakeaways.map((takeaway, index) => /* @__PURE__ */ jsxs("li", { className: "flex items-start gap-2 text-sm", children: [
66
+ /* @__PURE__ */ jsx(CheckCircle2, { className: "h-4 w-4 text-green-500 flex-shrink-0 mt-0.5" }),
67
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: takeaway })
68
+ ] }, index)) })
69
+ ] }) : null
70
+ ] });
71
+ }
72
+ export {
73
+ LearningObjectives,
74
+ Prerequisites,
75
+ Summary
76
+ };
@@ -0,0 +1,4 @@
1
+ import { MDXContent } from "./mdx-content";
2
+ export {
3
+ MDXContent
4
+ };
@@ -0,0 +1,151 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { evaluate } from "@mdx-js/mdx";
3
+ import * as runtime from "react/jsx-runtime";
4
+ import ReactMarkdown from "react-markdown";
5
+ import { CodeBlock } from "../code-block/code-block";
6
+ const MDXComponents = {
7
+ a: ({ children, href, ...props }) => /* @__PURE__ */ jsx(
8
+ "a",
9
+ {
10
+ className: "text-primary underline underline-offset-4 hover:text-primary/80 font-medium",
11
+ href,
12
+ ...props,
13
+ children
14
+ }
15
+ ),
16
+ blockquote: ({ children, ...props }) => /* @__PURE__ */ jsx(
17
+ "blockquote",
18
+ {
19
+ className: "border-l-4 border-primary pl-4 italic text-muted-foreground my-6 py-2 text-sm",
20
+ ...props,
21
+ children
22
+ }
23
+ ),
24
+ code: ({ children, className, ...props }) => {
25
+ if (typeof className === "string" && className.startsWith("language-")) {
26
+ const language = className.replace(/^language-/, "");
27
+ const text = typeof children === "string" ? children.replace(/\n$/, "") : String(children ?? "");
28
+ return /* @__PURE__ */ jsx(CodeBlock, { language, children: text });
29
+ }
30
+ return /* @__PURE__ */ jsx(
31
+ "code",
32
+ {
33
+ className: "bg-muted px-1 py-0.5 rounded text-sm font-mono",
34
+ ...props,
35
+ children
36
+ }
37
+ );
38
+ },
39
+ em: ({ children, ...props }) => /* @__PURE__ */ jsx("em", { className: "italic", ...props, children }),
40
+ h1: ({ children, ...props }) => /* @__PURE__ */ jsx("h1", { className: "text-2xl font-bold mt-8 mb-4", ...props, children }),
41
+ h2: ({ children, ...props }) => /* @__PURE__ */ jsx("h2", { className: "text-xl font-bold mt-6 mb-3", ...props, children }),
42
+ h3: ({ children, ...props }) => /* @__PURE__ */ jsx("h3", { className: "text-lg font-bold mt-4 mb-2", ...props, children }),
43
+ hr: ({ ...props }) => /* @__PURE__ */ jsx("hr", { className: "my-8 border-border", ...props }),
44
+ li: ({ children, ...props }) => /* @__PURE__ */ jsx(
45
+ "li",
46
+ {
47
+ className: "mb-2 leading-relaxed text-muted-foreground text-sm pl-2",
48
+ ...props,
49
+ children
50
+ }
51
+ ),
52
+ ol: ({ children, ...props }) => /* @__PURE__ */ jsx(
53
+ "ol",
54
+ {
55
+ className: "list-decimal list-outside mb-6 space-y-2 ml-6 text-muted-foreground text-sm",
56
+ ...props,
57
+ children
58
+ }
59
+ ),
60
+ p: ({ children, ...props }) => /* @__PURE__ */ jsx(
61
+ "p",
62
+ {
63
+ className: "mb-6 leading-relaxed text-muted-foreground text-sm max-w-none",
64
+ ...props,
65
+ children
66
+ }
67
+ ),
68
+ pre: ({ children }) => /* @__PURE__ */ jsx("div", { className: "contents", children }),
69
+ strong: ({ children, ...props }) => /* @__PURE__ */ jsx("strong", { className: "font-semibold", ...props, children }),
70
+ ul: ({ children, ...props }) => /* @__PURE__ */ jsx(
71
+ "ul",
72
+ {
73
+ className: "list-disc list-outside mb-6 space-y-2 ml-6 text-muted-foreground text-sm",
74
+ ...props,
75
+ children
76
+ }
77
+ )
78
+ };
79
+ const proseClasses = [
80
+ "prose prose-lg dark:prose-invert max-w-none",
81
+ "prose-headings:font-bold prose-headings:tracking-tight",
82
+ "prose-h1:text-2xl prose-h1:mt-8 prose-h1:mb-4",
83
+ "prose-h2:text-xl prose-h2:mt-6 prose-h2:mb-3",
84
+ "prose-h3:text-lg prose-h3:mt-4 prose-h3:mb-2",
85
+ "prose-p:leading-relaxed prose-p:mb-6 prose-p:text-muted-foreground prose-p:text-sm prose-p:max-w-none",
86
+ "prose-ul:my-6 prose-ul:ml-6 prose-ul:list-disc prose-ul:list-outside",
87
+ "prose-ol:my-6 prose-ol:ml-6 prose-ol:list-decimal prose-ol:list-outside",
88
+ "prose-li:mb-2 prose-li:leading-relaxed prose-li:pl-2",
89
+ "prose-strong:font-semibold prose-em:italic",
90
+ "prose-a:text-primary prose-a:underline prose-a:underline-offset-4 hover:prose-a:text-primary/80",
91
+ "prose-code:bg-muted prose-code:px-1 prose-code:py-0.5 prose-code:rounded prose-code:text-sm prose-code:font-mono",
92
+ "prose-pre:my-6 prose-pre:overflow-x-auto prose-pre:rounded-lg prose-pre:border prose-pre:bg-black prose-pre:py-4 prose-pre:font-mono prose-pre:text-sm prose-pre:text-white prose-pre:shadow-lg dark:prose-pre:bg-zinc-900",
93
+ "prose-blockquote:border-l-4 prose-blockquote:border-primary prose-blockquote:pl-4 prose-blockquote:italic prose-blockquote:text-muted-foreground prose-blockquote:my-6 prose-blockquote:py-2",
94
+ "prose-hr:my-8 prose-hr:border-border",
95
+ "prose-table:w-full prose-table:border-collapse prose-table:border prose-table:border-border",
96
+ "prose-th:border prose-th:border-border prose-th:bg-muted prose-th:p-2 prose-th:text-left prose-th:font-medium",
97
+ "prose-td:border prose-td:border-border prose-td:p-2",
98
+ "prose-img:rounded-lg prose-img:border prose-img:border-border prose-img:shadow-lg"
99
+ ].join(" ");
100
+ function removeImportStatements(content, componentNames) {
101
+ let processed = content.replaceAll(/^import\s+.*CodeBlock.*from.*$/gm, "");
102
+ componentNames.forEach((name) => {
103
+ processed = processed.replaceAll(
104
+ new RegExp(`^import\\s+.*${name}.*from.*$`, "gm"),
105
+ ""
106
+ );
107
+ });
108
+ return processed;
109
+ }
110
+ function buildCustomComponents(injectedComponents) {
111
+ return {
112
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
113
+ CodeBlock,
114
+ ...injectedComponents
115
+ };
116
+ }
117
+ async function MDXContent({
118
+ components = {},
119
+ content,
120
+ enableMDX = true
121
+ }) {
122
+ const componentNames = Object.keys(components);
123
+ const processedContent = removeImportStatements(content, componentNames);
124
+ const contentWithoutCodeBlocks = processedContent.replaceAll(
125
+ /```[\S\s]*?```/g,
126
+ ""
127
+ );
128
+ const hasJSX = /<[A-Z][A-Za-z]*/.test(contentWithoutCodeBlocks);
129
+ const customComponents = buildCustomComponents(components);
130
+ const allComponents = { ...MDXComponents, ...customComponents };
131
+ if (enableMDX && hasJSX) {
132
+ let Component;
133
+ try {
134
+ const result = await evaluate(processedContent, {
135
+ ...runtime,
136
+ baseUrl: import.meta.url
137
+ });
138
+ Component = result.default;
139
+ } catch (error) {
140
+ console.error("Error rendering MDX:", error);
141
+ }
142
+ if (Component) {
143
+ return /* @__PURE__ */ jsx("div", { className: proseClasses, children: /* @__PURE__ */ jsx(Component, { components: allComponents }) });
144
+ }
145
+ return /* @__PURE__ */ jsx("div", { className: proseClasses, children: /* @__PURE__ */ jsx(ReactMarkdown, { components: allComponents, children: content }) });
146
+ }
147
+ return /* @__PURE__ */ jsx("div", { className: proseClasses, children: /* @__PURE__ */ jsx(ReactMarkdown, { components: allComponents, children: content }) });
148
+ }
149
+ export {
150
+ MDXContent
151
+ };
@@ -0,0 +1,36 @@
1
+ import {
2
+ Menubar,
3
+ MenubarCheckboxItem,
4
+ MenubarContent,
5
+ MenubarGroup,
6
+ MenubarItem,
7
+ MenubarLabel,
8
+ MenubarMenu,
9
+ MenubarPortal,
10
+ MenubarRadioGroup,
11
+ MenubarRadioItem,
12
+ MenubarSeparator,
13
+ MenubarShortcut,
14
+ MenubarSub,
15
+ MenubarSubContent,
16
+ MenubarSubTrigger,
17
+ MenubarTrigger
18
+ } from "./menubar";
19
+ export {
20
+ Menubar,
21
+ MenubarCheckboxItem,
22
+ MenubarContent,
23
+ MenubarGroup,
24
+ MenubarItem,
25
+ MenubarLabel,
26
+ MenubarMenu,
27
+ MenubarPortal,
28
+ MenubarRadioGroup,
29
+ MenubarRadioItem,
30
+ MenubarSeparator,
31
+ MenubarShortcut,
32
+ MenubarSub,
33
+ MenubarSubContent,
34
+ MenubarSubTrigger,
35
+ MenubarTrigger
36
+ };