@docubook/create 2.3.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.
- package/package.json +1 -1
- package/src/dist/app/docs/[[...slug]]/page.tsx +56 -63
- package/src/dist/app/docs/layout.tsx +11 -4
- package/src/dist/app/layout.tsx +10 -9
- package/src/dist/app/page.tsx +3 -22
- package/src/dist/components/{context-popover.tsx → ContextPopover.tsx} +4 -3
- package/src/dist/components/{docs-breadcrumb.tsx → DocsBreadcrumb.tsx} +1 -1
- package/src/dist/components/{docs-menu.tsx → DocsMenu.tsx} +2 -2
- package/src/dist/components/DocsNavbar.tsx +46 -0
- package/src/dist/components/DocsSidebar.tsx +196 -0
- package/src/dist/components/Github.tsx +26 -0
- package/src/dist/components/{scroll-to-top.tsx → ScrollToTop.tsx} +16 -9
- package/src/dist/components/SearchBox.tsx +37 -0
- package/src/dist/components/SearchContext.tsx +47 -0
- package/src/dist/components/SearchModal.tsx +2 -2
- package/src/dist/components/SearchTrigger.tsx +5 -5
- package/src/dist/components/Sponsor.tsx +2 -2
- package/src/dist/components/{theme-toggle.tsx → ThemeToggle.tsx} +10 -10
- package/src/dist/components/TocObserver.tsx +197 -0
- package/src/dist/components/footer.tsx +16 -12
- package/src/dist/components/leftbar.tsx +45 -73
- package/src/dist/components/markdown/AccordionGroupMdx.tsx +1 -1
- package/src/dist/components/markdown/AccordionMdx.tsx +4 -4
- package/src/dist/components/markdown/CardMdx.tsx +4 -4
- package/src/dist/components/markdown/FileTreeMdx.tsx +4 -4
- package/src/dist/components/markdown/ImageMdx.tsx +1 -1
- package/src/dist/components/markdown/ReleaseMdx.tsx +1 -1
- package/src/dist/components/markdown/TooltipsMdx.tsx +1 -1
- package/src/dist/components/navbar.tsx +130 -53
- package/src/dist/components/sublink.tsx +1 -1
- package/src/dist/components/toc.tsx +16 -14
- package/src/dist/components/typography.tsx +1 -1
- package/src/dist/components/ui/icon-cloud.tsx +353 -0
- package/src/dist/components/ui/scroll-area.tsx +2 -2
- package/src/dist/components/ui/sheet.tsx +4 -4
- package/src/dist/components/ui/toggle.tsx +3 -3
- package/src/dist/docs/components/accordion-group.mdx +68 -0
- package/src/dist/docs/components/accordion.mdx +59 -0
- package/src/dist/docs/components/button.mdx +40 -0
- package/src/dist/docs/components/card-group.mdx +47 -0
- package/src/dist/docs/components/card.mdx +68 -0
- package/src/dist/docs/components/code-block.mdx +67 -0
- package/src/dist/docs/components/custom.mdx +38 -0
- package/src/dist/docs/components/file-tree.mdx +109 -0
- package/src/dist/docs/components/image.mdx +37 -0
- package/src/dist/docs/components/index.mdx +9 -0
- package/src/dist/docs/components/keyboard.mdx +117 -0
- package/src/dist/docs/components/link.mdx +34 -0
- package/src/dist/docs/components/note.mdx +44 -0
- package/src/dist/docs/components/release-note.mdx +114 -0
- package/src/dist/docs/components/stepper.mdx +45 -0
- package/src/dist/docs/components/tables.mdx +35 -0
- package/src/dist/docs/components/tabs.mdx +72 -0
- package/src/dist/docs/components/tooltips.mdx +22 -0
- package/src/dist/docs/components/youtube.mdx +23 -0
- package/src/dist/docs/getting-started/introduction.mdx +18 -0
- package/src/dist/docs/getting-started/quick-start-guide.mdx +60 -0
- package/src/dist/docu.json +36 -33
- package/src/dist/eslint.config.mjs +17 -30
- package/src/dist/hooks/useActiveSection.ts +34 -32
- package/src/dist/hooks/useScrollPosition.ts +16 -14
- package/src/dist/lib/markdown.ts +32 -17
- package/src/dist/lib/utils.ts +1 -1
- package/src/dist/next.config.mjs +10 -11
- package/src/dist/package.json +1 -1
- package/src/dist/styles/algolia.css +11 -9
- package/src/dist/styles/{syntax.css → override.css} +82 -39
- package/src/dist/tailwind.config.ts +11 -110
- package/src/dist/components/GithubStart.tsx +0 -44
- package/src/dist/components/mob-toc.tsx +0 -134
- package/src/dist/components/search.tsx +0 -55
- package/src/dist/components/toc-observer.tsx +0 -254
- package/src/dist/docs/api-reference/delete/index.mdx +0 -63
- package/src/dist/docs/api-reference/fetch/index.mdx +0 -63
- package/src/dist/docs/api-reference/get/index.mdx +0 -63
- package/src/dist/docs/api-reference/post/index.mdx +0 -63
- package/src/dist/docs/changelog/index.mdx +0 -49
- package/src/dist/docs/getting-started/development/index.mdx +0 -92
- package/src/dist/docs/getting-started/introduction/index.mdx +0 -92
- package/src/dist/docs/getting-started/quick-start-guide/index.mdx +0 -92
- /package/src/dist/components/{edit-on-github.tsx → EditWithGithub.tsx} +0 -0
- /package/src/dist/components/{contexts/theme-provider.tsx → ThemeProvider.tsx} +0 -0
- /package/src/dist/{components/contexts/AccordionContext.ts → lib/accordion-context.ts} +0 -0
- /package/src/dist/lib/{routes-config.ts → routes.ts} +0 -0
|
@@ -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:
|
|
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:
|
|
75
|
-
height:
|
|
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);
|
|
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;
|
|
4
|
+
color: #1d4ed8;
|
|
5
|
+
/* Darker blue for better contrast */
|
|
5
6
|
}
|
|
6
7
|
|
|
7
8
|
.function {
|
|
8
|
-
color: #0369a1;
|
|
9
|
+
color: #0369a1;
|
|
10
|
+
/* Deep blue */
|
|
9
11
|
}
|
|
10
12
|
|
|
11
13
|
.punctuation {
|
|
12
|
-
color: #4b5563;
|
|
14
|
+
color: #4b5563;
|
|
15
|
+
/* Slate gray */
|
|
13
16
|
}
|
|
14
17
|
|
|
15
18
|
.comment {
|
|
16
|
-
color: #6b7280;
|
|
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;
|
|
29
|
+
color: #0d9488;
|
|
30
|
+
/* Teal for better distinction */
|
|
26
31
|
}
|
|
27
32
|
|
|
28
33
|
.tag {
|
|
29
|
-
color: #1d4ed8;
|
|
34
|
+
color: #1d4ed8;
|
|
35
|
+
/* Matching keyword color */
|
|
30
36
|
}
|
|
31
37
|
|
|
32
38
|
.attr-name {
|
|
33
|
-
color: #0284c7;
|
|
39
|
+
color: #0284c7;
|
|
40
|
+
/* Sky blue */
|
|
34
41
|
}
|
|
35
42
|
|
|
36
43
|
.attr-value {
|
|
37
|
-
color: #2563eb;
|
|
44
|
+
color: #2563eb;
|
|
45
|
+
/* Primary blue */
|
|
38
46
|
}
|
|
39
47
|
|
|
40
48
|
/* Dark Mode */
|
|
41
49
|
.dark .keyword {
|
|
42
|
-
color: #60a5fa;
|
|
50
|
+
color: #60a5fa;
|
|
51
|
+
/* Soft blue */
|
|
43
52
|
}
|
|
44
53
|
|
|
45
54
|
.dark .function {
|
|
46
|
-
color: #38bdf8;
|
|
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;
|
|
64
|
+
color: #2dd4bf;
|
|
65
|
+
/* Teal */
|
|
55
66
|
}
|
|
56
67
|
|
|
57
68
|
.dark .tag {
|
|
58
|
-
color: #60a5fa;
|
|
69
|
+
color: #60a5fa;
|
|
70
|
+
/* Matching keyword color */
|
|
59
71
|
}
|
|
60
72
|
|
|
61
73
|
.dark .attr-name {
|
|
62
|
-
color: #7dd3fc;
|
|
74
|
+
color: #7dd3fc;
|
|
75
|
+
/* Lighter blue */
|
|
63
76
|
}
|
|
64
77
|
|
|
65
78
|
.dark .attr-value {
|
|
66
|
-
color: #3b82f6;
|
|
79
|
+
color: #3b82f6;
|
|
80
|
+
/* Brighter blue */
|
|
67
81
|
}
|
|
68
82
|
|
|
69
83
|
.dark .comment {
|
|
70
|
-
color: #9ca3af;
|
|
84
|
+
color: #9ca3af;
|
|
85
|
+
/* Lighter gray for dark mode */
|
|
71
86
|
}
|
|
72
87
|
|
|
73
88
|
.dark .punctuation {
|
|
74
|
-
color: #9ca3af;
|
|
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
|
|
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
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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;
|
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { List, ChevronDown, ChevronUp } from "lucide-react";
|
|
4
|
-
import TocObserver from "./toc-observer";
|
|
5
|
-
import * as React from "react";
|
|
6
|
-
import { useRef, useMemo } from "react";
|
|
7
|
-
import { usePathname } from "next/navigation";
|
|
8
|
-
import { Button } from "./ui/button";
|
|
9
|
-
import { motion, AnimatePresence } from "framer-motion";
|
|
10
|
-
import { useActiveSection } from "@/hooks";
|
|
11
|
-
import { TocItem } from "@/lib/toc";
|
|
12
|
-
|
|
13
|
-
interface MobTocProps {
|
|
14
|
-
tocs: TocItem[];
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const useClickOutside = (ref: React.RefObject<HTMLElement | null>, callback: () => void) => {
|
|
18
|
-
const handleClick = React.useCallback((event: MouseEvent) => {
|
|
19
|
-
if (ref.current && !ref.current.contains(event.target as Node)) {
|
|
20
|
-
callback();
|
|
21
|
-
}
|
|
22
|
-
}, [ref, callback]);
|
|
23
|
-
|
|
24
|
-
React.useEffect(() => {
|
|
25
|
-
document.addEventListener('mousedown', handleClick);
|
|
26
|
-
return () => {
|
|
27
|
-
document.removeEventListener('mousedown', handleClick);
|
|
28
|
-
};
|
|
29
|
-
}, [handleClick]);
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
export default function MobToc({ tocs }: MobTocProps) {
|
|
33
|
-
const pathname = usePathname();
|
|
34
|
-
const [isExpanded, setIsExpanded] = React.useState(false);
|
|
35
|
-
const tocRef = useRef<HTMLDivElement>(null);
|
|
36
|
-
const contentRef = useRef<HTMLDivElement>(null);
|
|
37
|
-
|
|
38
|
-
// Use custom hooks
|
|
39
|
-
const { activeId, setActiveId } = useActiveSection(tocs);
|
|
40
|
-
|
|
41
|
-
// Only show on /docs pages
|
|
42
|
-
const isDocsPage = useMemo(() => pathname?.startsWith('/docs'), [pathname]);
|
|
43
|
-
|
|
44
|
-
const [mounted, setMounted] = React.useState(false);
|
|
45
|
-
|
|
46
|
-
React.useEffect(() => {
|
|
47
|
-
setMounted(true);
|
|
48
|
-
}, []);
|
|
49
|
-
|
|
50
|
-
// Toggle expanded state
|
|
51
|
-
const toggleExpanded = React.useCallback((e: React.MouseEvent) => {
|
|
52
|
-
e.stopPropagation();
|
|
53
|
-
setIsExpanded(prev => !prev);
|
|
54
|
-
}, []);
|
|
55
|
-
|
|
56
|
-
// Close TOC when clicking outside
|
|
57
|
-
useClickOutside(tocRef, () => {
|
|
58
|
-
if (isExpanded) {
|
|
59
|
-
setIsExpanded(false);
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
// Handle body overflow when TOC is expanded
|
|
64
|
-
React.useEffect(() => {
|
|
65
|
-
if (isExpanded) {
|
|
66
|
-
document.body.style.overflow = 'hidden';
|
|
67
|
-
} else {
|
|
68
|
-
document.body.style.overflow = '';
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return () => {
|
|
72
|
-
document.body.style.overflow = '';
|
|
73
|
-
};
|
|
74
|
-
}, [isExpanded]);
|
|
75
|
-
|
|
76
|
-
// Don't render anything if not on docs page or no TOC items
|
|
77
|
-
if (!isDocsPage || !tocs?.length || !mounted) return null;
|
|
78
|
-
|
|
79
|
-
const chevronIcon = isExpanded ? (
|
|
80
|
-
<ChevronUp className="w-4 h-4 text-muted-foreground flex-shrink-0" />
|
|
81
|
-
) : (
|
|
82
|
-
<ChevronDown className="w-4 h-4 text-muted-foreground flex-shrink-0" />
|
|
83
|
-
);
|
|
84
|
-
|
|
85
|
-
return (
|
|
86
|
-
<AnimatePresence>
|
|
87
|
-
<motion.div
|
|
88
|
-
ref={tocRef}
|
|
89
|
-
className="lg:hidden fixed top-16 left-0 right-0 z-50"
|
|
90
|
-
initial={{ y: -100, opacity: 0 }}
|
|
91
|
-
animate={{ y: 0, opacity: 1 }}
|
|
92
|
-
exit={{ y: -100, opacity: 0 }}
|
|
93
|
-
transition={{ duration: 0.2, ease: 'easeInOut' }}
|
|
94
|
-
>
|
|
95
|
-
<div className="w-full bg-background/95 backdrop-blur-sm border-b border-stone-200 dark:border-stone-800 shadow-sm">
|
|
96
|
-
<div className="sm:px-8 px-4 py-2">
|
|
97
|
-
<Button
|
|
98
|
-
variant="ghost"
|
|
99
|
-
size="sm"
|
|
100
|
-
className="w-full justify-between h-auto py-2 px-2 -mx-1 rounded-md hover:bg-transparent hover:text-inherit"
|
|
101
|
-
onClick={toggleExpanded}
|
|
102
|
-
aria-label={isExpanded ? 'Collapse table of contents' : 'Expand table of contents'}
|
|
103
|
-
>
|
|
104
|
-
<div className="flex items-center gap-2">
|
|
105
|
-
<List className="w-4 h-4 text-muted-foreground flex-shrink-0" />
|
|
106
|
-
<span className="font-medium text-sm">On this page</span>
|
|
107
|
-
</div>
|
|
108
|
-
{chevronIcon}
|
|
109
|
-
</Button>
|
|
110
|
-
|
|
111
|
-
<AnimatePresence>
|
|
112
|
-
{isExpanded && (
|
|
113
|
-
<motion.div
|
|
114
|
-
ref={contentRef}
|
|
115
|
-
className="mt-2 pb-2 max-h-[60vh] overflow-y-auto px-1 -mx-1"
|
|
116
|
-
initial={{ opacity: 0, height: 0 }}
|
|
117
|
-
animate={{ opacity: 1, height: 'auto' }}
|
|
118
|
-
exit={{ opacity: 0, height: 0 }}
|
|
119
|
-
transition={{ duration: 0.2, ease: 'easeInOut' }}
|
|
120
|
-
>
|
|
121
|
-
<TocObserver
|
|
122
|
-
data={tocs}
|
|
123
|
-
activeId={activeId}
|
|
124
|
-
onActiveIdChange={setActiveId}
|
|
125
|
-
/>
|
|
126
|
-
</motion.div>
|
|
127
|
-
)}
|
|
128
|
-
</AnimatePresence>
|
|
129
|
-
</div>
|
|
130
|
-
</div>
|
|
131
|
-
</motion.div>
|
|
132
|
-
</AnimatePresence>
|
|
133
|
-
);
|
|
134
|
-
}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { useState, useEffect } from "react";
|
|
4
|
-
import { Dialog } from "@/components/ui/dialog";
|
|
5
|
-
import { SearchTrigger } from "@/components/SearchTrigger";
|
|
6
|
-
import { SearchModal } from "@/components/SearchModal";
|
|
7
|
-
import DocSearchComponent from "@/components/DocSearch";
|
|
8
|
-
import { DialogTrigger } from "@radix-ui/react-dialog";
|
|
9
|
-
|
|
10
|
-
interface SearchProps {
|
|
11
|
-
/**
|
|
12
|
-
* Specify which search engine to use.
|
|
13
|
-
* @default 'default'
|
|
14
|
-
*/
|
|
15
|
-
type?: "default" | "algolia";
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export default function Search({ type = "default" }: SearchProps) {
|
|
19
|
-
const [isOpen, setIsOpen] = useState(false);
|
|
20
|
-
|
|
21
|
-
// The useEffect below is ONLY for the 'default' type, which is correct.
|
|
22
|
-
// DocSearch handles its own keyboard shortcut.
|
|
23
|
-
useEffect(() => {
|
|
24
|
-
if (type === 'default') {
|
|
25
|
-
const handleKeyDown = (event: KeyboardEvent) => {
|
|
26
|
-
if ((event.ctrlKey || event.metaKey) && event.key === "k") {
|
|
27
|
-
event.preventDefault();
|
|
28
|
-
setIsOpen((open) => !open);
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
window.addEventListener("keydown", handleKeyDown);
|
|
33
|
-
return () => {
|
|
34
|
-
window.removeEventListener("keydown", handleKeyDown);
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
}, [type]);
|
|
38
|
-
|
|
39
|
-
if (type === "algolia") {
|
|
40
|
-
// Just render the component without passing any state props
|
|
41
|
-
return <DocSearchComponent />;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// Logic for 'default' search
|
|
45
|
-
return (
|
|
46
|
-
<div>
|
|
47
|
-
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
|
48
|
-
<DialogTrigger asChild>
|
|
49
|
-
<SearchTrigger />
|
|
50
|
-
</DialogTrigger>
|
|
51
|
-
<SearchModal isOpen={isOpen} setIsOpen={setIsOpen} />
|
|
52
|
-
</Dialog>
|
|
53
|
-
</div>
|
|
54
|
-
);
|
|
55
|
-
}
|