@docubook/create 2.4.0 → 2.5.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.
Files changed (43) hide show
  1. package/package.json +1 -1
  2. package/src/dist/app/docs/[[...slug]]/page.tsx +55 -59
  3. package/src/dist/app/docs/layout.tsx +11 -4
  4. package/src/dist/app/layout.tsx +10 -7
  5. package/src/dist/app/page.tsx +1 -1
  6. package/src/dist/components/{context-popover.tsx → ContextPopover.tsx} +3 -2
  7. package/src/dist/components/{docs-breadcrumb.tsx → DocsBreadcrumb.tsx} +1 -1
  8. package/src/dist/components/DocsNavbar.tsx +46 -0
  9. package/src/dist/components/DocsSidebar.tsx +196 -0
  10. package/src/dist/components/Github.tsx +26 -0
  11. package/src/dist/components/{scroll-to-top.tsx → ScrollToTop.tsx} +16 -9
  12. package/src/dist/components/SearchBox.tsx +37 -0
  13. package/src/dist/components/SearchContext.tsx +47 -0
  14. package/src/dist/components/SearchModal.tsx +1 -1
  15. package/src/dist/components/SearchTrigger.tsx +5 -5
  16. package/src/dist/components/Sponsor.tsx +2 -2
  17. package/src/dist/components/{theme-toggle.tsx → ThemeToggle.tsx} +10 -10
  18. package/src/dist/components/TocObserver.tsx +197 -0
  19. package/src/dist/components/footer.tsx +16 -12
  20. package/src/dist/components/leftbar.tsx +45 -73
  21. package/src/dist/components/markdown/AccordionGroupMdx.tsx +1 -1
  22. package/src/dist/components/markdown/AccordionMdx.tsx +1 -1
  23. package/src/dist/components/navbar.tsx +130 -53
  24. package/src/dist/components/toc.tsx +16 -14
  25. package/src/dist/components/typography.tsx +1 -1
  26. package/src/dist/components/ui/icon-cloud.tsx +353 -0
  27. package/src/dist/components/ui/scroll-area.tsx +2 -2
  28. package/src/dist/components/ui/sheet.tsx +4 -4
  29. package/src/dist/components/ui/toggle.tsx +3 -3
  30. package/src/dist/hooks/useActiveSection.ts +34 -32
  31. package/src/dist/hooks/useScrollPosition.ts +16 -14
  32. package/src/dist/package.json +1 -1
  33. package/src/dist/styles/algolia.css +11 -9
  34. package/src/dist/styles/{syntax.css → override.css} +82 -39
  35. package/src/dist/tailwind.config.ts +11 -110
  36. package/src/dist/components/GithubStart.tsx +0 -44
  37. package/src/dist/components/mob-toc.tsx +0 -134
  38. package/src/dist/components/search.tsx +0 -55
  39. package/src/dist/components/toc-observer.tsx +0 -254
  40. /package/src/dist/components/{docs-menu.tsx → DocsMenu.tsx} +0 -0
  41. /package/src/dist/components/{edit-on-github.tsx → EditWithGithub.tsx} +0 -0
  42. /package/src/dist/components/{theme-provider.tsx → ThemeProvider.tsx} +0 -0
  43. /package/src/dist/{components/AccordionContext.ts → lib/accordion-context.ts} +0 -0
@@ -7,7 +7,7 @@ import { cva, type VariantProps } from "class-variance-authority"
7
7
  import { cn } from "@/lib/utils"
8
8
 
9
9
  const toggleVariants = cva(
10
- "inline-flex items-center justify-center gap-1 rounded-md text-sm font-medium transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
10
+ "inline-flex items-center justify-center gap-1 rounded-md text-xs font-medium transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:size-3 [&_svg]:shrink-0",
11
11
  {
12
12
  variants: {
13
13
  variant: {
@@ -18,7 +18,7 @@ const toggleVariants = cva(
18
18
  size: {
19
19
  default: "h-9 px-2 min-w-9",
20
20
  sm: "h-8 px-1.5 min-w-8",
21
- xs: "h-7 px-1 min-w-7",
21
+ xs: "h-6 px-1.5 min-w-6",
22
22
  lg: "h-10 px-2.5 min-w-10",
23
23
  },
24
24
  },
@@ -32,7 +32,7 @@ const toggleVariants = cva(
32
32
  const Toggle = React.forwardRef<
33
33
  React.ElementRef<typeof TogglePrimitive.Root>,
34
34
  React.ComponentPropsWithoutRef<typeof TogglePrimitive.Root> &
35
- VariantProps<typeof toggleVariants>
35
+ VariantProps<typeof toggleVariants>
36
36
  >(({ className, variant, size, ...props }, ref) => (
37
37
  <TogglePrimitive.Root
38
38
  ref={ref}
@@ -1,68 +1,70 @@
1
- import { useState, useCallback, useEffect, useRef } from 'react';
2
- import { TocItem } from '@/lib/toc';
1
+ "use client"
2
+
3
+ import { useState, useCallback, useEffect, useRef } from "react"
4
+ import { TocItem } from "@/lib/toc"
3
5
 
4
6
  export function useActiveSection(tocs: TocItem[]) {
5
- const [activeId, setActiveId] = useState<string | null>(null);
6
- const observerRef = useRef<IntersectionObserver | null>(null);
7
- const clickedIdRef = useRef<string | null>(null);
7
+ const [activeId, setActiveId] = useState<string | null>(null)
8
+ const observerRef = useRef<IntersectionObserver | null>(null)
9
+ const clickedIdRef = useRef<string | null>(null)
8
10
 
9
11
  // Handle intersection observer for active section
10
12
  useEffect(() => {
11
- if (typeof document === 'undefined' || !tocs.length) return;
13
+ if (typeof document === "undefined" || !tocs.length) return
12
14
 
13
15
  const handleIntersect = (entries: IntersectionObserverEntry[]) => {
14
- if (clickedIdRef.current) return;
16
+ if (clickedIdRef.current) return
15
17
 
16
- const visibleEntries = entries.filter(entry => entry.isIntersecting);
17
- if (!visibleEntries.length) return;
18
+ const visibleEntries = entries.filter((entry) => entry.isIntersecting)
19
+ if (!visibleEntries.length) return
18
20
 
19
21
  // Find the most visible entry
20
22
  const mostVisibleEntry = visibleEntries.reduce((prev, current) => {
21
- return current.intersectionRatio > prev.intersectionRatio ? current : prev;
22
- }, visibleEntries[0]);
23
+ return current.intersectionRatio > prev.intersectionRatio ? current : prev
24
+ }, visibleEntries[0])
23
25
 
24
- const newActiveId = mostVisibleEntry.target.id;
26
+ const newActiveId = mostVisibleEntry.target.id
25
27
  if (newActiveId !== activeId) {
26
- setActiveId(newActiveId);
28
+ setActiveId(newActiveId)
27
29
  }
28
- };
30
+ }
29
31
 
30
32
  // Initialize intersection observer
31
33
  observerRef.current = new IntersectionObserver(handleIntersect, {
32
- root: null,
33
- rootMargin: '0px 0px -80% 0px',
34
- threshold: 0.1,
35
- });
34
+ root: document.getElementById("scroll-container"),
35
+ rootMargin: "0px 0px -60% 0px",
36
+ threshold: 0,
37
+ })
36
38
 
37
39
  // Observe all headings
38
- tocs.forEach(toc => {
39
- const element = document.getElementById(toc.href.slice(1));
40
+ tocs.forEach((toc) => {
41
+ const element = document.getElementById(toc.href.slice(1))
40
42
  if (element) {
41
- observerRef.current?.observe(element);
43
+ observerRef.current?.observe(element)
42
44
  }
43
- });
45
+ })
44
46
 
45
47
  // Cleanup
46
48
  return () => {
47
- observerRef.current?.disconnect();
48
- };
49
- }, [tocs, activeId]);
49
+ observerRef.current?.disconnect()
50
+ }
51
+ }, [tocs, activeId])
50
52
 
51
53
  const handleLinkClick = useCallback((id: string) => {
52
- clickedIdRef.current = id;
53
- setActiveId(id);
54
+ clickedIdRef.current = id
55
+ setActiveId(id)
54
56
 
55
57
  // Reset clicked state after scroll completes
56
58
  const timer = setTimeout(() => {
57
- clickedIdRef.current = null;
58
- }, 1000);
59
+ clickedIdRef.current = null
60
+ }, 1000)
59
61
 
60
- return () => clearTimeout(timer);
61
- }, []);
62
+ return () => clearTimeout(timer)
63
+ }, [])
62
64
 
63
65
  return {
64
66
  activeId,
65
67
  setActiveId,
66
68
  handleLinkClick,
67
- };
69
+ }
68
70
  }
@@ -1,29 +1,31 @@
1
- import { useState, useCallback, useEffect } from 'react';
1
+ "use client"
2
+
3
+ import { useState, useCallback, useEffect } from "react"
2
4
 
3
5
  export function useScrollPosition(threshold = 0.5) {
4
- const [isScrolled, setIsScrolled] = useState(false);
6
+ const [isScrolled, setIsScrolled] = useState(false)
5
7
 
6
8
  const handleScroll = useCallback(() => {
7
- if (typeof window === 'undefined') return;
9
+ if (typeof window === "undefined") return
8
10
 
9
- const scrollPosition = window.scrollY;
10
- const viewportHeight = window.innerHeight;
11
- const shouldBeSticky = scrollPosition > viewportHeight * threshold;
11
+ const scrollPosition = window.scrollY
12
+ const viewportHeight = window.innerHeight
13
+ const shouldBeSticky = scrollPosition > viewportHeight * threshold
12
14
 
13
- setIsScrolled(prev => shouldBeSticky !== prev ? shouldBeSticky : prev);
14
- }, [threshold]);
15
+ setIsScrolled((prev) => (shouldBeSticky !== prev ? shouldBeSticky : prev))
16
+ }, [threshold])
15
17
 
16
18
  // Add scroll event listener
17
19
  useEffect(() => {
18
20
  // Initial check
19
21
  // eslint-disable-next-line react-hooks/set-state-in-effect
20
- handleScroll();
22
+ handleScroll()
21
23
 
22
- window.addEventListener('scroll', handleScroll, { passive: true });
24
+ window.addEventListener("scroll", handleScroll, { passive: true })
23
25
  return () => {
24
- window.removeEventListener('scroll', handleScroll);
25
- };
26
- }, [handleScroll]);
26
+ window.removeEventListener("scroll", handleScroll)
27
+ }
28
+ }, [handleScroll])
27
29
 
28
- return isScrolled;
30
+ return isScrolled
29
31
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "docubook",
3
- "version": "2.4.0",
3
+ "version": "2.5.0",
4
4
  "private": true,
5
5
  "scripts": {
6
6
  "dev": "next dev",
@@ -18,31 +18,31 @@
18
18
  --docsearch-muted-color: hsl(var(--muted-foreground));
19
19
  --docsearch-container-background: rgba(0, 0, 0, 0.7);
20
20
  --docsearch-logo-color: hsl(var(--primary-foreground));
21
-
21
+
22
22
  /* Modal */
23
23
  --docsearch-modal-width: 560px;
24
24
  --docsearch-modal-height: 600px;
25
25
  --docsearch-modal-background: hsl(var(--background));
26
26
  --docsearch-modal-shadow: 0 0 0 1px hsl(var(--border)), 0 8px 20px rgba(0, 0, 0, 0.2);
27
-
27
+
28
28
  /* SearchBox */
29
29
  --docsearch-searchbox-height: 56px;
30
30
  --docsearch-searchbox-background: hsl(var(--input));
31
31
  --docsearch-searchbox-focus-background: hsl(var(--card));
32
32
  --docsearch-searchbox-shadow: none;
33
-
33
+
34
34
  /* Hit (Hasil Pencarian) */
35
35
  --docsearch-hit-height: 56px;
36
36
  --docsearch-hit-color: hsl(var(--foreground));
37
37
  --docsearch-hit-active-color: hsl(var(--primary-foreground));
38
38
  --docsearch-hit-background: hsl(var(--card));
39
39
  --docsearch-hit-shadow: none;
40
-
40
+
41
41
  /* Keys */
42
42
  --docsearch-key-gradient: none;
43
43
  --docsearch-key-shadow: none;
44
44
  --docsearch-key-pressed-shadow: none;
45
-
45
+
46
46
  /* Footer */
47
47
  --docsearch-footer-height: 44px;
48
48
  --docsearch-footer-background: hsl(var(--background));
@@ -57,7 +57,7 @@
57
57
  background-color: hsl(var(--secondary));
58
58
  border: 1px solid hsl(var(--border));
59
59
  border-radius: 9999px;
60
- width: 160px;
60
+ width: 260px;
61
61
  height: 40px;
62
62
  color: hsl(var(--muted-foreground));
63
63
  transition: width 0.3s ease;
@@ -71,8 +71,8 @@
71
71
 
72
72
  .docsearch .DocSearch-Search-Icon {
73
73
  color: var(--docsearch-muted-color);
74
- width: 1rem;
75
- height: 1rem;
74
+ width: 1.2rem;
75
+ height: 1.2rem;
76
76
  }
77
77
 
78
78
  .docsearch .DocSearch-Button-Placeholder {
@@ -85,7 +85,8 @@
85
85
 
86
86
  .docsearch .DocSearch-Button-Key {
87
87
  background: var(--docsearch-primary-color);
88
- color: var(--docsearch-logo-color); /* Menggunakan variabel yg relevan */
88
+ color: var(--docsearch-logo-color);
89
+ /* Menggunakan variabel yg relevan */
89
90
  border-radius: 6px;
90
91
  font-size: 14px;
91
92
  font-weight: 500;
@@ -155,6 +156,7 @@
155
156
  background: none;
156
157
  border: none;
157
158
  }
159
+
158
160
  .docsearch .DocSearch-Button-Placeholder,
159
161
  .docsearch .DocSearch-Button-Key {
160
162
  display: none;
@@ -1,19 +1,23 @@
1
1
  /* Modern Blue Theme */
2
2
  /* Light Mode */
3
3
  .keyword {
4
- color: #1d4ed8; /* Darker blue for better contrast */
4
+ color: #1d4ed8;
5
+ /* Darker blue for better contrast */
5
6
  }
6
7
 
7
8
  .function {
8
- color: #0369a1; /* Deep blue */
9
+ color: #0369a1;
10
+ /* Deep blue */
9
11
  }
10
12
 
11
13
  .punctuation {
12
- color: #4b5563; /* Slate gray */
14
+ color: #4b5563;
15
+ /* Slate gray */
13
16
  }
14
17
 
15
18
  .comment {
16
- color: #6b7280; /* Muted gray */
19
+ color: #6b7280;
20
+ /* Muted gray */
17
21
  font-style: italic;
18
22
  }
19
23
 
@@ -22,28 +26,34 @@
22
26
  .annotation,
23
27
  .boolean,
24
28
  .number {
25
- color: #0d9488; /* Teal for better distinction */
29
+ color: #0d9488;
30
+ /* Teal for better distinction */
26
31
  }
27
32
 
28
33
  .tag {
29
- color: #1d4ed8; /* Matching keyword color */
34
+ color: #1d4ed8;
35
+ /* Matching keyword color */
30
36
  }
31
37
 
32
38
  .attr-name {
33
- color: #0284c7; /* Sky blue */
39
+ color: #0284c7;
40
+ /* Sky blue */
34
41
  }
35
42
 
36
43
  .attr-value {
37
- color: #2563eb; /* Primary blue */
44
+ color: #2563eb;
45
+ /* Primary blue */
38
46
  }
39
47
 
40
48
  /* Dark Mode */
41
49
  .dark .keyword {
42
- color: #60a5fa; /* Soft blue */
50
+ color: #60a5fa;
51
+ /* Soft blue */
43
52
  }
44
53
 
45
54
  .dark .function {
46
- color: #38bdf8; /* Sky blue */
55
+ color: #38bdf8;
56
+ /* Sky blue */
47
57
  }
48
58
 
49
59
  .dark .string,
@@ -51,47 +61,33 @@
51
61
  .dark .annotation,
52
62
  .dark .boolean,
53
63
  .dark .number {
54
- color: #2dd4bf; /* Teal */
64
+ color: #2dd4bf;
65
+ /* Teal */
55
66
  }
56
67
 
57
68
  .dark .tag {
58
- color: #60a5fa; /* Matching keyword color */
69
+ color: #60a5fa;
70
+ /* Matching keyword color */
59
71
  }
60
72
 
61
73
  .dark .attr-name {
62
- color: #7dd3fc; /* Lighter blue */
74
+ color: #7dd3fc;
75
+ /* Lighter blue */
63
76
  }
64
77
 
65
78
  .dark .attr-value {
66
- color: #3b82f6; /* Brighter blue */
79
+ color: #3b82f6;
80
+ /* Brighter blue */
67
81
  }
68
82
 
69
83
  .dark .comment {
70
- color: #9ca3af; /* Lighter gray for dark mode */
84
+ color: #9ca3af;
85
+ /* Lighter gray for dark mode */
71
86
  }
72
87
 
73
88
  .dark .punctuation {
74
- color: #9ca3af; /* Lighter gray for dark mode */
75
- }
76
-
77
- .youtube {
78
- position: relative;
79
- padding-bottom: 56.25%; /* Rasio aspek 16:9 */
80
- height: 0;
81
- overflow: hidden;
82
- background: #000; /* Latar belakang hitam untuk memadukan player */
83
- border-radius: 8px; /* Sudut melengkung */
84
- box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2); /* Bayangan lembut */
85
- }
86
-
87
- .youtube iframe {
88
- position: absolute;
89
- top: 0;
90
- left: 0;
91
- width: 100%;
92
- height: 100%;
93
- border: none;
94
- border-radius: 8px; /* Sudut melengkung pada iframe */
89
+ color: #9ca3af;
90
+ /* Lighter gray for dark mode */
95
91
  }
96
92
 
97
93
  /* ======================================================================== */
@@ -111,7 +107,7 @@
111
107
  display: flex;
112
108
  align-items: center;
113
109
  gap: 0.5rem;
114
- background-color: hsl(var(--muted));
110
+ background-color: hsl(var(--muted));
115
111
  padding: 0.5rem 1rem;
116
112
  border-bottom: 1px solid hsl(var(--border));
117
113
  color: hsl(var(--muted-foreground));
@@ -125,10 +121,12 @@
125
121
  right: 0.75rem;
126
122
  z-index: 10;
127
123
  }
124
+
128
125
  .code-block-actions button {
129
126
  color: hsl(var(--muted-foreground));
130
127
  transition: color 0.2s ease-in-out;
131
128
  }
129
+
132
130
  .code-block-actions button:hover {
133
131
  color: hsl(var(--foreground));
134
132
  }
@@ -147,7 +145,7 @@
147
145
  width: 3rem;
148
146
  padding-top: 1rem;
149
147
  text-align: right;
150
- color: var(--line-number-color);
148
+ color: var(--line-number-color);
151
149
  user-select: none;
152
150
  }
153
151
 
@@ -155,7 +153,7 @@
155
153
  position: absolute;
156
154
  left: 0;
157
155
  right: 0;
158
- background: hsl(var(--primary) / 0.1);
156
+ background: hsl(var(--primary) / 0.1);
159
157
  border-left: 2px solid hsl(var(--primary));
160
158
  pointer-events: none;
161
159
  }
@@ -167,13 +165,58 @@
167
165
  .code-block-body::-webkit-scrollbar {
168
166
  height: 8px;
169
167
  }
168
+
170
169
  .code-block-body::-webkit-scrollbar-track {
171
170
  background: transparent;
172
171
  }
172
+
173
173
  .code-block-body::-webkit-scrollbar-thumb {
174
174
  background: hsl(var(--border));
175
175
  border-radius: 4px;
176
176
  }
177
+
177
178
  .code-block-body::-webkit-scrollbar-thumb:hover {
178
179
  background: hsl(var(--muted));
180
+ }
181
+
182
+ /* ======================================================================== */
183
+ /* Custom styling for youtube blocks */
184
+ /* ======================================================================== */
185
+ .youtube {
186
+ position: relative;
187
+ padding-bottom: 56.25%;
188
+ /* Aspect Ratio 16:9 */
189
+ height: 0;
190
+ overflow: hidden;
191
+ background: #000;
192
+ /* Black background to blend the player */
193
+ border-radius: 8px;
194
+ /* Rounded corners */
195
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
196
+ /* Soft shadow */
197
+ }
198
+
199
+ .youtube iframe {
200
+ position: absolute;
201
+ top: 0;
202
+ left: 0;
203
+ width: 100%;
204
+ height: 100%;
205
+ border: none;
206
+ border-radius: 8px;
207
+ /* Rounded corners on iframe */
208
+ }
209
+
210
+ /* Hide main navbar and footer when docs layout is active */
211
+ body:has(.docs-layout) #main-navbar,
212
+ body:has(.docs-layout) #main-footer {
213
+ display: none;
214
+ }
215
+
216
+ /* Remove container constraints for docs pages */
217
+ body:has(.docs-layout) #main-content {
218
+ max-width: none;
219
+ width: 100%;
220
+ padding: 0;
221
+ margin: 0;
179
222
  }
@@ -1,113 +1,14 @@
1
- import type { Config } from "tailwindcss";
2
- import tailwindAnimate from "tailwindcss-animate";
3
- import typography from "@tailwindcss/typography";
1
+ import typography from "@tailwindcss/typography"
4
2
 
5
3
  const config = {
6
- darkMode: "class",
7
- content: [
8
- "./pages/**/*.{ts,tsx}",
9
- "./components/**/*.{ts,tsx}",
10
- "./app/**/*.{ts,tsx}",
11
- "./src/**/*.{ts,tsx}",
12
- ],
13
- prefix: "",
14
- theme: {
15
- container: {
16
- center: true,
17
- padding: '2rem',
18
- screens: {
19
- '2xl': '1440px'
20
- }
21
- },
22
- extend: {
23
- colors: {
24
- border: 'hsl(var(--border))',
25
- input: 'hsl(var(--input))',
26
- ring: 'hsl(var(--ring))',
27
- background: 'hsl(var(--background))',
28
- foreground: 'hsl(var(--foreground))',
29
- primary: {
30
- DEFAULT: 'hsl(var(--primary))',
31
- foreground: 'hsl(var(--primary-foreground))'
32
- },
33
- secondary: {
34
- DEFAULT: 'hsl(var(--secondary))',
35
- foreground: 'hsl(var(--secondary-foreground))'
36
- },
37
- destructive: {
38
- DEFAULT: 'hsl(var(--destructive))',
39
- foreground: 'hsl(var(--destructive-foreground))'
40
- },
41
- muted: {
42
- DEFAULT: 'hsl(var(--muted))',
43
- foreground: 'hsl(var(--muted-foreground))'
44
- },
45
- accent: {
46
- DEFAULT: 'hsl(var(--accent))',
47
- foreground: 'hsl(var(--accent-foreground))'
48
- },
49
- popover: {
50
- DEFAULT: 'hsl(var(--popover))',
51
- foreground: 'hsl(var(--popover-foreground))'
52
- },
53
- card: {
54
- DEFAULT: 'hsl(var(--card))',
55
- foreground: 'hsl(var(--card-foreground))'
56
- },
57
- sidebar: {
58
- DEFAULT: 'hsl(var(--sidebar-background))',
59
- foreground: 'hsl(var(--sidebar-foreground))',
60
- primary: 'hsl(var(--sidebar-primary))',
61
- 'primary-foreground': 'hsl(var(--sidebar-primary-foreground))',
62
- accent: 'hsl(var(--sidebar-accent))',
63
- 'accent-foreground': 'hsl(var(--sidebar-accent-foreground))',
64
- border: 'hsl(var(--sidebar-border))',
65
- ring: 'hsl(var(--sidebar-ring))'
66
- }
67
- },
68
- borderRadius: {
69
- lg: 'var(--radius)',
70
- md: 'calc(var(--radius) - 2px)',
71
- sm: 'calc(var(--radius) - 4px)'
72
- },
73
- fontFamily: {
74
- code: ["var(--font-geist-mono)"],
75
- regular: ["var(--font-geist-sans)"]
76
- },
77
- keyframes: {
78
- 'accordion-down': {
79
- from: {
80
- height: '0'
81
- },
82
- to: {
83
- height: 'var(--radix-accordion-content-height)'
84
- }
85
- },
86
- 'accordion-up': {
87
- from: {
88
- height: 'var(--radix-accordion-content-height)'
89
- },
90
- to: {
91
- height: '0'
92
- }
93
- },
94
- 'shiny-text': {
95
- '0%, 90%, 100%': {
96
- 'background-position': 'calc(-100% - var(--shiny-width)) 0'
97
- },
98
- '30%, 60%': {
99
- 'background-position': 'calc(100% + var(--shiny-width)) 0'
100
- }
101
- }
102
- },
103
- animation: {
104
- 'accordion-down': 'accordion-down 0.2s ease-out',
105
- 'accordion-up': 'accordion-up 0.2s ease-out',
106
- 'shiny-text': 'shiny-text 8s infinite'
107
- }
108
- }
109
- },
110
- plugins: [tailwindAnimate, typography],
111
- } satisfies Config;
4
+ darkMode: ["class"],
5
+ content: [
6
+ "./app/**/*.{ts,tsx}",
7
+ "./components/**/*.{ts,tsx}",
8
+ "./contents/**/*.{md,mdx}",
9
+ "../../packages/ui/src/**/*.{ts,tsx}",
10
+ ],
11
+ plugins: [typography],
12
+ }
112
13
 
113
- export default config;
14
+ export default config
@@ -1,44 +0,0 @@
1
- 'use client';
2
-
3
- import React, { useEffect, useState } from 'react';
4
- import Link from 'next/link';
5
-
6
- const GitHubStarButton: React.FC = () => {
7
- const [stars, setStars] = useState<number | null>(null);
8
-
9
- useEffect(() => {
10
- fetch('https://api.github.com/repos/gitfromwildan/docubook')
11
- .then((res) => res.json())
12
- .then((data) => {
13
- if (data.stargazers_count !== undefined) {
14
- setStars(data.stargazers_count);
15
- }
16
- })
17
- .catch((error) => console.error('Failed to fetch stars:', error));
18
- }, []);
19
-
20
- const formatStars = (count: number) =>
21
- count >= 1000 ? `${(count / 1000).toFixed(1)}K` : `${count}`;
22
-
23
- return (
24
- <Link
25
- href="https://github.com/gitfromwildan/docubook"
26
- target="_blank"
27
- rel="noopener noreferrer"
28
- className="inline-flex items-center rounded-full px-3 py-1.5 text-sm font-medium text-muted-foreground border no-underline"
29
- >
30
- <svg
31
- height="16"
32
- width="16"
33
- viewBox="0 0 16 16"
34
- aria-hidden="true"
35
- className="fill-current mr-1.5"
36
- >
37
- <path d="M8 0C3.58 0 0 3.58 0 8a8 8 0 005.47 7.59c.4.07.55-.17.55-.38v-1.32c-2.22.48-2.69-1.07-2.69-1.07-.36-.92-.89-1.17-.89-1.17-.73-.5.06-.49.06-.49.81.06 1.23.83 1.23.83.72 1.23 1.89.88 2.35.67.07-.52.28-.88.5-1.08-1.77-.2-3.64-.88-3.64-3.93 0-.87.31-1.58.82-2.14-.08-.2-.36-1.01.08-2.12 0 0 .67-.21 2.2.82a7.7 7.7 0 012.01-.27 7.7 7.7 0 012.01.27c1.53-1.03 2.2-.82 2.2-.82.44 1.11.16 1.92.08 2.12.51.56.82 1.27.82 2.14 0 3.06-1.87 3.73-3.65 3.93.29.25.54.73.54 1.48v2.2c0 .21.15.46.55.38A8 8 0 0016 8c0-4.42-3.58-8-8-8z" />
38
- </svg>
39
- {stars !== null ? formatStars(stars) : '...'}
40
- </Link>
41
- );
42
- };
43
-
44
- export default GitHubStarButton;