@docubook/create 1.16.0 → 2.0.0-beta.1

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.
@@ -2,27 +2,28 @@ import { useState, useCallback, useEffect } from 'react';
2
2
 
3
3
  export function useScrollPosition(threshold = 0.5) {
4
4
  const [isScrolled, setIsScrolled] = useState(false);
5
-
5
+
6
6
  const handleScroll = useCallback(() => {
7
7
  if (typeof window === 'undefined') return;
8
-
8
+
9
9
  const scrollPosition = window.scrollY;
10
10
  const viewportHeight = window.innerHeight;
11
11
  const shouldBeSticky = scrollPosition > viewportHeight * threshold;
12
-
12
+
13
13
  setIsScrolled(prev => shouldBeSticky !== prev ? shouldBeSticky : prev);
14
14
  }, [threshold]);
15
15
 
16
16
  // Add scroll event listener
17
17
  useEffect(() => {
18
18
  // Initial check
19
+ // eslint-disable-next-line react-hooks/set-state-in-effect
19
20
  handleScroll();
20
-
21
+
21
22
  window.addEventListener('scroll', handleScroll, { passive: true });
22
23
  return () => {
23
24
  window.removeEventListener('scroll', handleScroll);
24
25
  };
25
26
  }, [handleScroll]);
26
-
27
+
27
28
  return isScrolled;
28
29
  }
@@ -8,7 +8,7 @@ import rehypeSlug from "rehype-slug";
8
8
  import rehypeCodeTitles from "rehype-code-titles";
9
9
  import { page_routes, ROUTES } from "./routes-config";
10
10
  import { visit } from "unist-util-visit";
11
- import type { Node } from "unist";
11
+ import type { Node, Parent } from "unist";
12
12
  import matter from "gray-matter";
13
13
 
14
14
  // Type definitions for unist-util-visit
@@ -16,6 +16,7 @@ interface Element extends Node {
16
16
  type: string;
17
17
  tagName?: string;
18
18
  properties?: Record<string, unknown> & {
19
+ className?: string[];
19
20
  raw?: string;
20
21
  };
21
22
  children?: Node[];
@@ -77,6 +78,49 @@ const components = {
77
78
  AccordionGroup
78
79
  };
79
80
 
81
+ // helper function to handle rehype code titles, since by default we can't inject into the className of rehype-code-titles
82
+ const handleCodeTitles = () => (tree: Node) => {
83
+ visit(tree, "element", (node: Element, index: number | null, parent: Parent | null) => {
84
+ // Ensure the visited node is valid
85
+ if (!parent || index === null || node.tagName !== 'div') {
86
+ return;
87
+ }
88
+
89
+ // Check if this is the title div from rehype-code-titles
90
+ const isTitleDiv = node.properties?.className?.includes('rehype-code-title');
91
+ if (!isTitleDiv) {
92
+ return;
93
+ }
94
+
95
+ // Find the next <pre> element, skipping over other nodes like whitespace text
96
+ let nextElement = null;
97
+ for (let i = index + 1; i < parent.children.length; i++) {
98
+ const sibling = parent.children[i];
99
+ if (sibling.type === 'element') {
100
+ nextElement = sibling as Element;
101
+ break;
102
+ }
103
+ }
104
+
105
+ // If the next element is a <pre>, move the title to it
106
+ if (nextElement && nextElement.tagName === 'pre') {
107
+ const titleNode = node.children?.[0] as TextNode;
108
+ if (titleNode && titleNode.type === 'text') {
109
+ if (!nextElement.properties) {
110
+ nextElement.properties = {};
111
+ }
112
+ nextElement.properties['data-title'] = titleNode.value;
113
+
114
+ // Remove the original title div
115
+ parent.children.splice(index, 1);
116
+
117
+ // Return the same index to continue visiting from the correct position
118
+ return index;
119
+ }
120
+ }
121
+ });
122
+ };
123
+
80
124
  // can be used for other pages like blogs, Guides etc
81
125
  async function parseMdx<Frontmatter>(rawMdx: string) {
82
126
  return await compileMDX<Frontmatter>({
@@ -87,6 +131,7 @@ async function parseMdx<Frontmatter>(rawMdx: string) {
87
131
  rehypePlugins: [
88
132
  preProcess,
89
133
  rehypeCodeTitles,
134
+ handleCodeTitles,
90
135
  rehypePrism,
91
136
  rehypeSlug,
92
137
  rehypeAutolinkHeadings,
@@ -1,62 +1,67 @@
1
1
  {
2
2
  "name": "docubook",
3
- "version": "1.16.0",
3
+ "version": "2.0.0-beta.1",
4
4
  "private": true,
5
5
  "scripts": {
6
6
  "dev": "next dev",
7
7
  "build": "next build",
8
8
  "start": "next start",
9
- "lint": "next lint"
9
+ "lint": "eslint ."
10
10
  },
11
11
  "dependencies": {
12
- "@docsearch/css": "3",
12
+ "@docsearch/css": "^3.9.0",
13
13
  "@docsearch/react": "^3.9.0",
14
- "@radix-ui/react-accordion": "^1.2.0",
15
- "@radix-ui/react-avatar": "^1.1.0",
16
- "@radix-ui/react-collapsible": "^1.1.0",
17
- "@radix-ui/react-dialog": "^1.1.6",
18
- "@radix-ui/react-dropdown-menu": "^2.1.1",
19
- "@radix-ui/react-popover": "^1.1.6",
20
- "@radix-ui/react-scroll-area": "^1.2.0",
21
- "@radix-ui/react-separator": "^1.0.3",
22
- "@radix-ui/react-slot": "^1.1.0",
23
- "@radix-ui/react-tabs": "^1.1.0",
24
- "@radix-ui/react-toggle": "^1.1.2",
25
- "@radix-ui/react-toggle-group": "^1.1.2",
26
- "algoliasearch": "^5.35.0",
27
- "class-variance-authority": "^0.7.0",
14
+ "@radix-ui/react-accordion": "^1.2.12",
15
+ "@radix-ui/react-avatar": "^1.1.11",
16
+ "@radix-ui/react-collapsible": "^1.1.12",
17
+ "@radix-ui/react-dialog": "^1.1.15",
18
+ "@radix-ui/react-dropdown-menu": "^2.1.16",
19
+ "@radix-ui/react-popover": "^1.1.15",
20
+ "@radix-ui/react-scroll-area": "^1.2.10",
21
+ "@radix-ui/react-separator": "^1.1.8",
22
+ "@radix-ui/react-slot": "^1.2.4",
23
+ "@radix-ui/react-tabs": "^1.1.13",
24
+ "@radix-ui/react-toggle": "^1.1.10",
25
+ "@radix-ui/react-toggle-group": "^1.1.11",
26
+ "algoliasearch": "^5.46.3",
27
+ "class-variance-authority": "^0.7.1",
28
28
  "clsx": "^2.1.1",
29
- "cmdk": "1.0.0",
30
- "framer-motion": "^12.4.1",
31
- "geist": "^1.3.1",
29
+ "cmdk": "^1.1.1",
30
+ "framer-motion": "^12.26.2",
31
+ "geist": "^1.5.1",
32
32
  "gray-matter": "^4.0.3",
33
- "install": "^0.13.0",
34
33
  "lucide-react": "^0.511.0",
35
- "next": "^14.2.6",
34
+ "next": "16.1.3",
36
35
  "next-mdx-remote": "^5.0.0",
37
- "next-themes": "^0.3.0",
38
- "react": "^18.3.1",
39
- "react-dom": "^18.3.1",
36
+ "next-themes": "^0.4.4",
37
+ "react": "19.2.3",
38
+ "react-dom": "19.2.3",
39
+ "react-icons": "^5.5.0",
40
40
  "rehype-autolink-headings": "^7.1.0",
41
- "rehype-code-titles": "^1.2.0",
42
- "rehype-prism-plus": "^2.0.0",
41
+ "rehype-code-titles": "^1.2.1",
42
+ "rehype-prism-plus": "^2.0.1",
43
43
  "rehype-slug": "^6.0.0",
44
- "remark-gfm": "^4.0.0",
45
- "sonner": "^1.4.3",
46
- "tailwind-merge": "^2.5.2",
44
+ "remark-gfm": "^4.0.1",
45
+ "sonner": "^1.7.4",
46
+ "tailwind-merge": "^2.6.0",
47
47
  "tailwindcss-animate": "^1.0.7",
48
48
  "unist-util-visit": "^5.0.0"
49
49
  },
50
50
  "devDependencies": {
51
- "@tailwindcss/typography": "^0.5.14",
52
- "@types/node": "^20",
53
- "@types/react": "^18",
54
- "@types/react-dom": "^18",
55
- "autoprefixer": "^10.4.20",
56
- "eslint": "^8",
57
- "eslint-config-next": "^14.2.6",
58
- "postcss": "^8",
59
- "tailwindcss": "^3.4.10",
60
- "typescript": "^5"
51
+ "@tailwindcss/postcss": "^4.1.18",
52
+ "@tailwindcss/typography": "^0.5.19",
53
+ "@types/node": "^20.19.30",
54
+ "@types/react": "19.2.8",
55
+ "@types/react-dom": "19.2.3",
56
+ "autoprefixer": "^10.4.23",
57
+ "eslint": "^9.39.2",
58
+ "eslint-config-next": "16.1.3",
59
+ "postcss": "^8.5.6",
60
+ "tailwindcss": "^4.1.18",
61
+ "typescript": "^5.9.3"
62
+ },
63
+ "overrides": {
64
+ "@types/react": "19.2.8",
65
+ "@types/react-dom": "19.2.3"
61
66
  }
62
67
  }
@@ -1,6 +1,6 @@
1
1
  module.exports = {
2
2
  plugins: {
3
- tailwindcss: {},
3
+ '@tailwindcss/postcss': {},
4
4
  autoprefixer: {},
5
5
  },
6
6
  };
@@ -1,69 +1,189 @@
1
- @import "@docsearch/css";
2
- @import "./algolia.css";
1
+ @import 'tailwindcss';
2
+ @plugin '@tailwindcss/typography';
3
3
 
4
- @tailwind base;
5
- @tailwind components;
6
- @tailwind utilities;
7
4
 
8
- @import url("./syntax.css");
9
- /* Modern Blue Theme */
10
- @layer base {
11
- :root {
12
- --background: 210 40% 98%;
13
- --foreground: 220 30% 15%;
14
- --card: 0 0% 100%;
15
- --card-foreground: 220 30% 15%;
16
- --popover: 0 0% 100%;
17
- --popover-foreground: 220 30% 15%;
18
- --primary: 210 81% 56%; /* #2281E3 */
19
- --primary-foreground: 0 0% 100%;
20
- --secondary: 210 30% 90%;
21
- --secondary-foreground: 220 30% 15%;
22
- --muted: 210 20% 92%;
23
- --muted-foreground: 220 15% 50%;
24
- --accent: 200 100% 40%;
25
- --accent-foreground: 0 0% 100%;
26
- --destructive: 0 85% 60%;
27
- --destructive-foreground: 0 0% 100%;
28
- --border: 210 20% 85%;
29
- --input: 210 20% 85%;
30
- --ring: 210 81% 56%;
31
- --radius: 0.5rem;
32
- --chart-1: 210 81% 56%;
33
- --chart-2: 200 100% 40%;
34
- --chart-3: 220 76% 60%;
35
- --chart-4: 190 90% 50%;
36
- --chart-5: 230 86% 45%;
37
- --line-number-color: rgba(0, 0, 0, 0.05);
5
+ @custom-variant dark (&:is(.dark *));
6
+
7
+ @utility container {
8
+ margin-inline: auto;
9
+ padding-inline: 2rem;
10
+
11
+ @media (width >=--theme(--breakpoint-sm)) {
12
+ max-width: none;
13
+ }
14
+
15
+ @media (width >=1440px) {
16
+ max-width: 1440px;
17
+ }
18
+ }
19
+
20
+ @theme {
21
+ --color-border: hsl(var(--border));
22
+ --color-input: hsl(var(--input));
23
+ --color-ring: hsl(var(--ring));
24
+ --color-background: hsl(var(--background));
25
+ --color-foreground: hsl(var(--foreground));
26
+
27
+ --color-primary: hsl(var(--primary));
28
+ --color-primary-foreground: hsl(var(--primary-foreground));
29
+
30
+ --color-secondary: hsl(var(--secondary));
31
+ --color-secondary-foreground: hsl(var(--secondary-foreground));
32
+
33
+ --color-destructive: hsl(var(--destructive));
34
+ --color-destructive-foreground: hsl(var(--destructive-foreground));
35
+
36
+ --color-muted: hsl(var(--muted));
37
+ --color-muted-foreground: hsl(var(--muted-foreground));
38
+
39
+ --color-accent: hsl(var(--accent));
40
+ --color-accent-foreground: hsl(var(--accent-foreground));
41
+
42
+ --color-popover: hsl(var(--popover));
43
+ --color-popover-foreground: hsl(var(--popover-foreground));
44
+
45
+ --color-card: hsl(var(--card));
46
+ --color-card-foreground: hsl(var(--card-foreground));
47
+
48
+ --color-sidebar: hsl(var(--sidebar-background));
49
+ --color-sidebar-foreground: hsl(var(--sidebar-foreground));
50
+ --color-sidebar-primary: hsl(var(--sidebar-primary));
51
+ --color-sidebar-primary-foreground: hsl(var(--sidebar-primary-foreground));
52
+ --color-sidebar-accent: hsl(var(--sidebar-accent));
53
+ --color-sidebar-accent-foreground: hsl(var(--sidebar-accent-foreground));
54
+ --color-sidebar-border: hsl(var(--sidebar-border));
55
+ --color-sidebar-ring: hsl(var(--sidebar-ring));
56
+
57
+ --radius-lg: var(--radius);
58
+ --radius-md: calc(var(--radius) - 2px);
59
+ --radius-sm: calc(var(--radius) - 4px);
60
+
61
+ --font-code: var(--font-geist-mono);
62
+ --font-regular: var(--font-geist-sans);
63
+
64
+ --animate-accordion-down: accordion-down 0.2s ease-out;
65
+ --animate-accordion-up: accordion-up 0.2s ease-out;
66
+ --animate-shiny-text: shiny-text 8s infinite;
67
+
68
+ @keyframes accordion-down {
69
+ from {
70
+ height: 0;
71
+ }
72
+
73
+ to {
74
+ height: var(--radix-accordion-content-height);
75
+ }
76
+ }
77
+
78
+ @keyframes accordion-up {
79
+ from {
80
+ height: var(--radix-accordion-content-height);
38
81
  }
39
82
 
40
- .dark {
41
- --background: 220 25% 10%;
42
- --foreground: 210 30% 96%;
43
- --card: 220 25% 15%;
44
- --card-foreground: 210 30% 96%;
45
- --popover: 220 25% 15%;
46
- --popover-foreground: 210 30% 96%;
47
- --primary: 210 100% 65%;
48
- --primary-foreground: 220 25% 10%;
49
- --secondary: 215 25% 20%;
50
- --secondary-foreground: 210 30% 96%;
51
- --muted: 215 20% 25%;
52
- --muted-foreground: 215 20% 65%;
53
- --accent: 200 100% 60%;
54
- --accent-foreground: 0 0% 100%;
55
- --destructive: 0 85% 70%;
56
- --destructive-foreground: 0 0% 100%;
57
- --border: 215 20% 25%;
58
- --input: 215 20% 25%;
59
- --ring: 210 100% 65%;
60
- --chart-1: 210 100% 65%;
61
- --chart-2: 200 100% 60%;
62
- --chart-3: 220 90% 70%;
63
- --chart-4: 190 100% 65%;
64
- --chart-5: 230 90% 60%;
65
- --line-number-color: rgba(255, 255, 255, 0.1);
83
+ to {
84
+ height: 0;
66
85
  }
86
+ }
87
+
88
+ @keyframes shiny-text {
89
+
90
+ 0%,
91
+ 90%,
92
+ 100% {
93
+ background-position: calc(-100% - var(--shiny-width)) 0;
94
+ }
95
+
96
+ 30%,
97
+ 60% {
98
+ background-position: calc(100% + var(--shiny-width)) 0;
99
+ }
100
+ }
101
+ }
102
+
103
+ /*
104
+ The default border color has changed to `currentcolor` in Tailwind CSS v4,
105
+ so we've added these compatibility styles to make sure everything still
106
+ looks the same as it did with Tailwind CSS v3.
107
+
108
+ If we ever want to remove these styles, we need to add an explicit border
109
+ color utility to any element that depends on these defaults.
110
+ */
111
+ @layer base {
112
+
113
+ *,
114
+ ::after,
115
+ ::before,
116
+ ::backdrop,
117
+ ::file-selector-button {
118
+ border-color: var(--color-gray-200, currentcolor);
119
+ }
120
+ }
121
+
122
+ @utility animate-shine {
123
+ --animate-shine: shine var(--duration) infinite linear;
124
+ animation: var(--animate-shine);
125
+ background-size: 200% 200%;
126
+ }
127
+
128
+ /* Modern Blue Theme */
129
+ @layer base {
130
+ :root {
131
+ --background: 210 40% 98%;
132
+ --foreground: 220 30% 15%;
133
+ --card: 0 0% 100%;
134
+ --card-foreground: 220 30% 15%;
135
+ --popover: 0 0% 100%;
136
+ --popover-foreground: 220 30% 15%;
137
+ --primary: 210 81% 56%;
138
+ /* #2281E3 */
139
+ --primary-foreground: 0 0% 100%;
140
+ --secondary: 210 30% 90%;
141
+ --secondary-foreground: 220 30% 15%;
142
+ --muted: 210 20% 92%;
143
+ --muted-foreground: 220 15% 50%;
144
+ --accent: 200 100% 40%;
145
+ --accent-foreground: 0 0% 100%;
146
+ --destructive: 0 85% 60%;
147
+ --destructive-foreground: 0 0% 100%;
148
+ --border: 210 20% 85%;
149
+ --input: 210 20% 85%;
150
+ --ring: 210 81% 56%;
151
+ --radius: 0.5rem;
152
+ --chart-1: 210 81% 56%;
153
+ --chart-2: 200 100% 40%;
154
+ --chart-3: 220 76% 60%;
155
+ --chart-4: 190 90% 50%;
156
+ --chart-5: 230 86% 45%;
157
+ --line-number-color: rgba(0, 0, 0, 0.05);
158
+ }
159
+
160
+ .dark {
161
+ --background: 220 25% 10%;
162
+ --foreground: 210 30% 96%;
163
+ --card: 220 25% 15%;
164
+ --card-foreground: 210 30% 96%;
165
+ --popover: 220 25% 15%;
166
+ --popover-foreground: 210 30% 96%;
167
+ --primary: 210 100% 65%;
168
+ --primary-foreground: 220 25% 10%;
169
+ --secondary: 215 25% 20%;
170
+ --secondary-foreground: 210 30% 96%;
171
+ --muted: 215 20% 25%;
172
+ --muted-foreground: 215 20% 65%;
173
+ --accent: 200 100% 60%;
174
+ --accent-foreground: 0 0% 100%;
175
+ --destructive: 0 85% 70%;
176
+ --destructive-foreground: 0 0% 100%;
177
+ --border: 215 20% 25%;
178
+ --input: 215 20% 25%;
179
+ --ring: 210 100% 65%;
180
+ --chart-1: 210 100% 65%;
181
+ --chart-2: 200 100% 60%;
182
+ --chart-3: 220 90% 70%;
183
+ --chart-4: 190 100% 65%;
184
+ --chart-5: 230 90% 60%;
185
+ --line-number-color: rgba(255, 255, 255, 0.1);
186
+ }
67
187
  }
68
188
 
69
189
  @layer base {
@@ -76,66 +196,66 @@
76
196
  }
77
197
  }
78
198
 
79
- .prose {
80
- margin: 0 !important;
81
- }
199
+ @layer utilities {
200
+ .prose {
201
+ margin: 0 !important;
202
+ }
82
203
 
83
- pre {
84
- padding: 2px 0 !important;
85
- width: inherit !important;
86
- overflow-x: auto;
87
- }
204
+ pre {
205
+ padding: 2px 0 !important;
206
+ width: inherit !important;
207
+ overflow-x: auto;
208
+ }
88
209
 
89
- pre>code {
90
- display: grid;
91
- max-width: inherit !important;
92
- padding: 14px 0 !important;
93
- }
210
+ pre>code {
211
+ display: grid;
212
+ max-width: inherit !important;
213
+ padding: 14px 0 !important;
214
+ border: 0 !important;
215
+ }
94
216
 
95
- .code-line {
96
- padding: 0.75px 16px;
97
- @apply border-l-2 border-transparent
98
- }
217
+ .code-line {
218
+ padding: 0.75px 16px;
219
+ @apply border-l-2 border-transparent;
220
+ }
99
221
 
100
- .line-number::before {
101
- display: inline-block;
102
- width: 1rem;
103
- margin-right: 22px;
104
- margin-left: -2px;
105
- color: rgb(110, 110, 110);
106
- content: attr(line);
107
- font-size: 13.5px;
108
- text-align: right;
109
- }
222
+ .line-number::before {
223
+ display: inline-block;
224
+ width: 1rem;
225
+ margin-right: 22px;
226
+ margin-left: -2px;
227
+ color: rgb(110, 110, 110);
228
+ content: attr(line);
229
+ font-size: 13.5px;
230
+ text-align: right;
231
+ }
110
232
 
111
- .highlight-line {
112
- @apply bg-primary/5 border-l-2 border-primary/30;
113
- }
233
+ .highlight-line {
234
+ @apply bg-primary/5 border-l-2 border-primary/30;
235
+ }
114
236
 
115
- .rehype-code-title {
116
- @apply px-2 -mb-8 w-full text-sm pb-5 font-medium mt-5 font-code;
117
- }
237
+ .rehype-code-title {
238
+ @apply px-2 -mb-8 w-full text-sm pb-5 font-medium mt-5 font-code;
239
+ }
118
240
 
119
- .highlight-comp>code {
120
- background-color: transparent !important;
241
+ .highlight-comp>code {
242
+ background-color: transparent !important;
243
+ }
121
244
  }
122
245
 
123
246
  @layer utilities {
124
- .animate-shine {
125
- --animate-shine: shine var(--duration) infinite linear;
126
- animation: var(--animate-shine);
127
- background-size: 200% 200%;
247
+
248
+ @keyframes shine {
249
+ 0% {
250
+ background-position: 0% 0%;
251
+ }
252
+
253
+ 50% {
254
+ background-position: 100% 100%;
128
255
  }
129
256
 
130
- @keyframes shine {
131
- 0% {
132
- background-position: 0% 0%;
133
- }
134
- 50% {
135
- background-position: 100% 100%;
136
- }
137
- 100% {
138
- background-position: 0% 0%;
139
- }
257
+ 100% {
258
+ background-position: 0% 0%;
140
259
  }
141
- }
260
+ }
261
+ }
@@ -93,3 +93,87 @@
93
93
  border: none;
94
94
  border-radius: 8px; /* Sudut melengkung pada iframe */
95
95
  }
96
+
97
+ /* ======================================================================== */
98
+ /* Custom styling for code blocks */
99
+ /* ======================================================================== */
100
+
101
+ .code-block-container {
102
+ position: relative;
103
+ margin: 1.5rem 0;
104
+ border: 1px solid hsl(var(--border));
105
+ overflow: hidden;
106
+ font-size: 0.875rem;
107
+ border-radius: 0.75rem;
108
+ }
109
+
110
+ .code-block-header {
111
+ display: flex;
112
+ align-items: center;
113
+ gap: 0.5rem;
114
+ background-color: hsl(var(--muted));
115
+ padding: 0.5rem 1rem;
116
+ border-bottom: 1px solid hsl(var(--border));
117
+ color: hsl(var(--muted-foreground));
118
+ font-family: monospace;
119
+ font-size: 0.8rem;
120
+ }
121
+
122
+ .code-block-actions {
123
+ position: absolute;
124
+ top: 0.5rem;
125
+ right: 0.75rem;
126
+ z-index: 10;
127
+ }
128
+ .code-block-actions button {
129
+ color: hsl(var(--muted-foreground));
130
+ transition: color 0.2s ease-in-out;
131
+ }
132
+ .code-block-actions button:hover {
133
+ color: hsl(var(--foreground));
134
+ }
135
+
136
+
137
+ .code-block-body pre[class*="language-"] {
138
+ margin: 0 !important;
139
+ padding: 0 !important;
140
+ background: transparent !important;
141
+ }
142
+
143
+ .line-numbers-wrapper {
144
+ position: absolute;
145
+ top: 0;
146
+ left: 0;
147
+ width: 3rem;
148
+ padding-top: 1rem;
149
+ text-align: right;
150
+ color: var(--line-number-color);
151
+ user-select: none;
152
+ }
153
+
154
+ .line-highlight {
155
+ position: absolute;
156
+ left: 0;
157
+ right: 0;
158
+ background: hsl(var(--primary) / 0.1);
159
+ border-left: 2px solid hsl(var(--primary));
160
+ pointer-events: none;
161
+ }
162
+
163
+ .code-block-body pre[data-line-numbers="true"] .line-highlight {
164
+ padding-left: 3.5rem;
165
+ }
166
+
167
+ .code-block-body::-webkit-scrollbar {
168
+ height: 8px;
169
+ }
170
+ .code-block-body::-webkit-scrollbar-track {
171
+ background: transparent;
172
+ }
173
+ .code-block-body::-webkit-scrollbar-thumb {
174
+ background: hsl(var(--border));
175
+ border-radius: 4px;
176
+ }
177
+ .code-block-body::-webkit-scrollbar-thumb:hover {
178
+ background: hsl(var(--muted));
179
+ }