gardesk/tarmac-web / b87ee90

Browse files

add mdx-components.tsx

Authored by espadonne
SHA
b87ee90af26f7d36845041572dbd008be69418df
Parents
4c05b3a
Tree
9bc85eb

1 changed file

StatusFile+-
A mdx-components.tsx 126 0
mdx-components.tsxadded
@@ -0,0 +1,126 @@
1
+import type { MDXComponents } from "mdx/types";
2
+import ShellHighlighter from "@/components/ShellHighlighter";
3
+import LuaHighlighter from "@/components/LuaHighlighter";
4
+
5
+function slugify(text: string): string {
6
+  return text
7
+    .toLowerCase()
8
+    .replace(/[^a-z0-9]+/g, "-")
9
+    .replace(/(^-|-$)/g, "");
10
+}
11
+
12
+export function useMDXComponents(components: MDXComponents): MDXComponents {
13
+  return {
14
+    h1: ({ children }) => (
15
+      <h1 className="text-3xl font-bold text-surface-900 dark:text-surface-100 mb-6 mt-8 first:mt-0">
16
+        {children}
17
+      </h1>
18
+    ),
19
+    h2: ({ children }) => {
20
+      const id = typeof children === "string" ? slugify(children) : "";
21
+      return (
22
+        <h2
23
+          id={id}
24
+          className="text-2xl font-semibold text-surface-900 dark:text-surface-100 mb-4 mt-8 border-b border-surface-200 dark:border-surface-700 pb-2"
25
+        >
26
+          {children}
27
+        </h2>
28
+      );
29
+    },
30
+    h3: ({ children }) => {
31
+      const id = typeof children === "string" ? slugify(children) : "";
32
+      return (
33
+        <h3
34
+          id={id}
35
+          className="text-xl font-semibold text-surface-900 dark:text-surface-100 mb-3 mt-6"
36
+        >
37
+          {children}
38
+        </h3>
39
+      );
40
+    },
41
+    h4: ({ children }) => (
42
+      <h4 className="text-lg font-medium text-surface-900 dark:text-surface-100 mb-2 mt-4">
43
+        {children}
44
+      </h4>
45
+    ),
46
+    p: ({ children }) => (
47
+      <p className="text-surface-700 dark:text-surface-300 mb-4 leading-relaxed">
48
+        {children}
49
+      </p>
50
+    ),
51
+    ul: ({ children }) => (
52
+      <ul className="list-disc list-inside mb-4 text-surface-700 dark:text-surface-300 space-y-1">
53
+        {children}
54
+      </ul>
55
+    ),
56
+    ol: ({ children }) => (
57
+      <ol className="list-decimal list-inside mb-4 text-surface-700 dark:text-surface-300 space-y-1">
58
+        {children}
59
+      </ol>
60
+    ),
61
+    li: ({ children }) => <li className="ml-4">{children}</li>,
62
+    code: ({ children, className }) => {
63
+      const isBlock = className?.includes("language-");
64
+      const isShell =
65
+        className?.includes("language-bash") ||
66
+        className?.includes("language-sh") ||
67
+        className?.includes("language-shell");
68
+      const isLua = className?.includes("language-lua");
69
+
70
+      if (isBlock) {
71
+        if (isShell && typeof children === "string") {
72
+          return <ShellHighlighter code={children} className="block text-sm font-mono" />;
73
+        }
74
+        if (isLua && typeof children === "string") {
75
+          return <LuaHighlighter code={children} className="block text-sm font-mono" />;
76
+        }
77
+        return (
78
+          <code className={`block text-surface-100 text-sm font-mono ${className || ""}`}>
79
+            {children}
80
+          </code>
81
+        );
82
+      }
83
+      return (
84
+        <code className="bg-surface-200 dark:bg-surface-700 text-surface-800 dark:text-surface-200 px-1.5 py-0.5 rounded text-sm font-mono">
85
+          {children}
86
+        </code>
87
+      );
88
+    },
89
+    pre: ({ children }) => (
90
+      <pre className="bg-surface-900 dark:bg-surface-950 rounded-lg mb-4 overflow-x-auto p-4">
91
+        {children}
92
+      </pre>
93
+    ),
94
+    blockquote: ({ children }) => (
95
+      <blockquote className="border-l-4 border-surface-300 dark:border-surface-600 pl-4 italic text-surface-600 dark:text-surface-400 mb-4">
96
+        {children}
97
+      </blockquote>
98
+    ),
99
+    a: ({ href, children }) => (
100
+      <a href={href} className="text-accent hover:underline">
101
+        {children}
102
+      </a>
103
+    ),
104
+    table: ({ children }) => (
105
+      <div className="overflow-x-auto mb-4">
106
+        <table className="min-w-full border border-surface-200 dark:border-surface-700">
107
+          {children}
108
+        </table>
109
+      </div>
110
+    ),
111
+    th: ({ children }) => (
112
+      <th className="border border-surface-200 dark:border-surface-700 px-4 py-2 bg-surface-100 dark:bg-surface-800 font-semibold text-left">
113
+        {children}
114
+      </th>
115
+    ),
116
+    td: ({ children }) => (
117
+      <td className="border border-surface-200 dark:border-surface-700 px-4 py-2">
118
+        {children}
119
+      </td>
120
+    ),
121
+    hr: () => (
122
+      <hr className="border-surface-200 dark:border-surface-700 my-8" />
123
+    ),
124
+    ...components,
125
+  };
126
+}