@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
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import React, { useEffect, useRef, useState, useMemo } from "react";
|
|
4
|
+
import { renderToString } from "react-dom/server";
|
|
5
|
+
|
|
6
|
+
interface Icon {
|
|
7
|
+
x: number;
|
|
8
|
+
y: number;
|
|
9
|
+
z: number;
|
|
10
|
+
scale: number;
|
|
11
|
+
opacity: number;
|
|
12
|
+
id: number;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface IconCloudProps {
|
|
16
|
+
icons?: React.ReactNode[];
|
|
17
|
+
images?: string[];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function easeOutCubic(t: number): number {
|
|
21
|
+
return 1 - Math.pow(1 - t, 3);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function IconCloud({ icons, images }: IconCloudProps) {
|
|
25
|
+
const canvasRef = useRef<HTMLCanvasElement>(null);
|
|
26
|
+
// const [iconPositions, setIconPositions] = useState<Icon[]>([]);
|
|
27
|
+
const iconPositions = useMemo<Icon[]>(() => {
|
|
28
|
+
const items = icons || images || [];
|
|
29
|
+
const newIcons: Icon[] = [];
|
|
30
|
+
const numIcons = items.length || 20;
|
|
31
|
+
|
|
32
|
+
// Fibonacci sphere parameters
|
|
33
|
+
const offset = 2 / numIcons;
|
|
34
|
+
const increment = Math.PI * (3 - Math.sqrt(5));
|
|
35
|
+
|
|
36
|
+
for (let i = 0; i < numIcons; i++) {
|
|
37
|
+
const y = i * offset - 1 + offset / 2;
|
|
38
|
+
const r = Math.sqrt(1 - y * y);
|
|
39
|
+
const phi = i * increment;
|
|
40
|
+
|
|
41
|
+
const x = Math.cos(phi) * r;
|
|
42
|
+
const z = Math.sin(phi) * r;
|
|
43
|
+
|
|
44
|
+
newIcons.push({
|
|
45
|
+
x: x * 100,
|
|
46
|
+
y: y * 100,
|
|
47
|
+
z: z * 100,
|
|
48
|
+
scale: 1,
|
|
49
|
+
opacity: 1,
|
|
50
|
+
id: i,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
return newIcons;
|
|
54
|
+
}, [icons, images]);
|
|
55
|
+
const [rotation] = useState({ x: 0, y: 0 });
|
|
56
|
+
const [isDragging, setIsDragging] = useState(false);
|
|
57
|
+
const [lastMousePos, setLastMousePos] = useState({ x: 0, y: 0 });
|
|
58
|
+
const [mousePos, setMousePos] = useState({ x: 0, y: 0 });
|
|
59
|
+
const [targetRotation, setTargetRotation] = useState<{
|
|
60
|
+
x: number;
|
|
61
|
+
y: number;
|
|
62
|
+
startX: number;
|
|
63
|
+
startY: number;
|
|
64
|
+
distance: number;
|
|
65
|
+
startTime: number;
|
|
66
|
+
duration: number;
|
|
67
|
+
} | null>(null);
|
|
68
|
+
const animationFrameRef = useRef<number>(undefined);
|
|
69
|
+
const rotationRef = useRef(rotation);
|
|
70
|
+
const iconCanvasesRef = useRef<HTMLCanvasElement[]>([]);
|
|
71
|
+
const imagesLoadedRef = useRef<boolean[]>([]);
|
|
72
|
+
|
|
73
|
+
// Create icon canvases once when icons/images change
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
if (!icons && !images) return;
|
|
76
|
+
|
|
77
|
+
const items = icons || images || [];
|
|
78
|
+
imagesLoadedRef.current = new Array(items.length).fill(false);
|
|
79
|
+
|
|
80
|
+
const newIconCanvases = items.map((item, index) => {
|
|
81
|
+
const offscreen = document.createElement("canvas");
|
|
82
|
+
offscreen.width = 40;
|
|
83
|
+
offscreen.height = 40;
|
|
84
|
+
const offCtx = offscreen.getContext("2d");
|
|
85
|
+
|
|
86
|
+
if (offCtx) {
|
|
87
|
+
if (images) {
|
|
88
|
+
// Handle image URLs directly
|
|
89
|
+
const img = new Image();
|
|
90
|
+
img.crossOrigin = "anonymous";
|
|
91
|
+
img.src = items[index] as string;
|
|
92
|
+
img.onload = () => {
|
|
93
|
+
offCtx.clearRect(0, 0, offscreen.width, offscreen.height);
|
|
94
|
+
|
|
95
|
+
// Create circular clipping path
|
|
96
|
+
offCtx.beginPath();
|
|
97
|
+
offCtx.arc(20, 20, 20, 0, Math.PI * 2);
|
|
98
|
+
offCtx.closePath();
|
|
99
|
+
offCtx.clip();
|
|
100
|
+
|
|
101
|
+
// Draw the image
|
|
102
|
+
offCtx.drawImage(img, 0, 0, 40, 40);
|
|
103
|
+
|
|
104
|
+
imagesLoadedRef.current[index] = true;
|
|
105
|
+
};
|
|
106
|
+
} else {
|
|
107
|
+
// Handle SVG icons
|
|
108
|
+
offCtx.scale(0.4, 0.4);
|
|
109
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
110
|
+
const svgString = renderToString(item as React.ReactElement<any>);
|
|
111
|
+
const img = new Image();
|
|
112
|
+
img.src = "data:image/svg+xml;base64," + btoa(svgString);
|
|
113
|
+
img.onload = () => {
|
|
114
|
+
offCtx.clearRect(0, 0, offscreen.width, offscreen.height);
|
|
115
|
+
offCtx.drawImage(img, 0, 0);
|
|
116
|
+
imagesLoadedRef.current[index] = true;
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return offscreen;
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
iconCanvasesRef.current = newIconCanvases;
|
|
124
|
+
}, [icons, images]);
|
|
125
|
+
|
|
126
|
+
// Generate initial icon positions on a sphere
|
|
127
|
+
// useEffect(() => {
|
|
128
|
+
// const items = icons || images || [];
|
|
129
|
+
// const newIcons: Icon[] = [];
|
|
130
|
+
// const numIcons = items.length || 20;
|
|
131
|
+
|
|
132
|
+
// // Fibonacci sphere parameters
|
|
133
|
+
// const offset = 2 / numIcons;
|
|
134
|
+
// const increment = Math.PI * (3 - Math.sqrt(5));
|
|
135
|
+
|
|
136
|
+
// for (let i = 0; i < numIcons; i++) {
|
|
137
|
+
// const y = i * offset - 1 + offset / 2;
|
|
138
|
+
// const r = Math.sqrt(1 - y * y);
|
|
139
|
+
// const phi = i * increment;
|
|
140
|
+
|
|
141
|
+
// const x = Math.cos(phi) * r;
|
|
142
|
+
// const z = Math.sin(phi) * r;
|
|
143
|
+
|
|
144
|
+
// newIcons.push({
|
|
145
|
+
// x: x * 100,
|
|
146
|
+
// y: y * 100,
|
|
147
|
+
// z: z * 100,
|
|
148
|
+
// scale: 1,
|
|
149
|
+
// opacity: 1,
|
|
150
|
+
// id: i,
|
|
151
|
+
// });
|
|
152
|
+
// }
|
|
153
|
+
// setIconPositions(newIcons);
|
|
154
|
+
// }, [icons, images]);
|
|
155
|
+
|
|
156
|
+
// Handle mouse events
|
|
157
|
+
const handleMouseDown = (e: React.MouseEvent<HTMLCanvasElement>) => {
|
|
158
|
+
const rect = canvasRef.current?.getBoundingClientRect();
|
|
159
|
+
if (!rect || !canvasRef.current) return;
|
|
160
|
+
|
|
161
|
+
const x = e.clientX - rect.left;
|
|
162
|
+
const y = e.clientY - rect.top;
|
|
163
|
+
|
|
164
|
+
const ctx = canvasRef.current.getContext("2d");
|
|
165
|
+
if (!ctx) return;
|
|
166
|
+
|
|
167
|
+
iconPositions.forEach((icon) => {
|
|
168
|
+
const cosX = Math.cos(rotationRef.current.x);
|
|
169
|
+
const sinX = Math.sin(rotationRef.current.x);
|
|
170
|
+
const cosY = Math.cos(rotationRef.current.y);
|
|
171
|
+
const sinY = Math.sin(rotationRef.current.y);
|
|
172
|
+
|
|
173
|
+
const rotatedX = icon.x * cosY - icon.z * sinY;
|
|
174
|
+
const rotatedZ = icon.x * sinY + icon.z * cosY;
|
|
175
|
+
const rotatedY = icon.y * cosX + rotatedZ * sinX;
|
|
176
|
+
|
|
177
|
+
const screenX = canvasRef.current!.width / 2 + rotatedX;
|
|
178
|
+
const screenY = canvasRef.current!.height / 2 + rotatedY;
|
|
179
|
+
|
|
180
|
+
const scale = (rotatedZ + 200) / 300;
|
|
181
|
+
const radius = 20 * scale;
|
|
182
|
+
const dx = x - screenX;
|
|
183
|
+
const dy = y - screenY;
|
|
184
|
+
|
|
185
|
+
if (dx * dx + dy * dy < radius * radius) {
|
|
186
|
+
const targetX = -Math.atan2(
|
|
187
|
+
icon.y,
|
|
188
|
+
Math.sqrt(icon.x * icon.x + icon.z * icon.z),
|
|
189
|
+
);
|
|
190
|
+
const targetY = Math.atan2(icon.x, icon.z);
|
|
191
|
+
|
|
192
|
+
const currentX = rotationRef.current.x;
|
|
193
|
+
const currentY = rotationRef.current.y;
|
|
194
|
+
const distance = Math.sqrt(
|
|
195
|
+
Math.pow(targetX - currentX, 2) + Math.pow(targetY - currentY, 2),
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
const duration = Math.min(2000, Math.max(800, distance * 1000));
|
|
199
|
+
|
|
200
|
+
setTargetRotation({
|
|
201
|
+
x: targetX,
|
|
202
|
+
y: targetY,
|
|
203
|
+
startX: currentX,
|
|
204
|
+
startY: currentY,
|
|
205
|
+
distance,
|
|
206
|
+
startTime: performance.now(),
|
|
207
|
+
duration,
|
|
208
|
+
});
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
setIsDragging(true);
|
|
214
|
+
setLastMousePos({ x: e.clientX, y: e.clientY });
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
const handleMouseMove = (e: React.MouseEvent<HTMLCanvasElement>) => {
|
|
218
|
+
const rect = canvasRef.current?.getBoundingClientRect();
|
|
219
|
+
if (rect) {
|
|
220
|
+
const x = e.clientX - rect.left;
|
|
221
|
+
const y = e.clientY - rect.top;
|
|
222
|
+
setMousePos({ x, y });
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (isDragging) {
|
|
226
|
+
const deltaX = e.clientX - lastMousePos.x;
|
|
227
|
+
const deltaY = e.clientY - lastMousePos.y;
|
|
228
|
+
|
|
229
|
+
rotationRef.current = {
|
|
230
|
+
x: rotationRef.current.x + deltaY * 0.002,
|
|
231
|
+
y: rotationRef.current.y + deltaX * 0.002,
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
setLastMousePos({ x: e.clientX, y: e.clientY });
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
const handleMouseUp = () => {
|
|
239
|
+
setIsDragging(false);
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
// Animation and rendering
|
|
243
|
+
useEffect(() => {
|
|
244
|
+
const canvas = canvasRef.current;
|
|
245
|
+
const ctx = canvas?.getContext("2d");
|
|
246
|
+
if (!canvas || !ctx) return;
|
|
247
|
+
|
|
248
|
+
const animate = () => {
|
|
249
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
250
|
+
|
|
251
|
+
const centerX = canvas.width / 2;
|
|
252
|
+
const centerY = canvas.height / 2;
|
|
253
|
+
const maxDistance = Math.sqrt(centerX * centerX + centerY * centerY);
|
|
254
|
+
const dx = mousePos.x - centerX;
|
|
255
|
+
const dy = mousePos.y - centerY;
|
|
256
|
+
const distance = Math.sqrt(dx * dx + dy * dy);
|
|
257
|
+
const speed = 0.003 + (distance / maxDistance) * 0.01;
|
|
258
|
+
|
|
259
|
+
if (targetRotation) {
|
|
260
|
+
const elapsed = performance.now() - targetRotation.startTime;
|
|
261
|
+
const progress = Math.min(1, elapsed / targetRotation.duration);
|
|
262
|
+
const easedProgress = easeOutCubic(progress);
|
|
263
|
+
|
|
264
|
+
rotationRef.current = {
|
|
265
|
+
x:
|
|
266
|
+
targetRotation.startX +
|
|
267
|
+
(targetRotation.x - targetRotation.startX) * easedProgress,
|
|
268
|
+
y:
|
|
269
|
+
targetRotation.startY +
|
|
270
|
+
(targetRotation.y - targetRotation.startY) * easedProgress,
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
if (progress >= 1) {
|
|
274
|
+
setTargetRotation(null);
|
|
275
|
+
}
|
|
276
|
+
} else if (!isDragging) {
|
|
277
|
+
rotationRef.current = {
|
|
278
|
+
x: rotationRef.current.x + (dy / canvas.height) * speed,
|
|
279
|
+
y: rotationRef.current.y + (dx / canvas.width) * speed,
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
iconPositions.forEach((icon, index) => {
|
|
284
|
+
const cosX = Math.cos(rotationRef.current.x);
|
|
285
|
+
const sinX = Math.sin(rotationRef.current.x);
|
|
286
|
+
const cosY = Math.cos(rotationRef.current.y);
|
|
287
|
+
const sinY = Math.sin(rotationRef.current.y);
|
|
288
|
+
|
|
289
|
+
const rotatedX = icon.x * cosY - icon.z * sinY;
|
|
290
|
+
const rotatedZ = icon.x * sinY + icon.z * cosY;
|
|
291
|
+
const rotatedY = icon.y * cosX + rotatedZ * sinX;
|
|
292
|
+
|
|
293
|
+
const scale = (rotatedZ + 200) / 300;
|
|
294
|
+
const opacity = Math.max(0.2, Math.min(1, (rotatedZ + 150) / 200));
|
|
295
|
+
|
|
296
|
+
ctx.save();
|
|
297
|
+
ctx.translate(
|
|
298
|
+
canvas.width / 2 + rotatedX,
|
|
299
|
+
canvas.height / 2 + rotatedY,
|
|
300
|
+
);
|
|
301
|
+
ctx.scale(scale, scale);
|
|
302
|
+
ctx.globalAlpha = opacity;
|
|
303
|
+
|
|
304
|
+
if (icons || images) {
|
|
305
|
+
// Only try to render icons/images if they exist
|
|
306
|
+
if (
|
|
307
|
+
iconCanvasesRef.current[index] &&
|
|
308
|
+
imagesLoadedRef.current[index]
|
|
309
|
+
) {
|
|
310
|
+
ctx.drawImage(iconCanvasesRef.current[index], -20, -20, 40, 40);
|
|
311
|
+
}
|
|
312
|
+
} else {
|
|
313
|
+
// Show numbered circles if no icons/images are provided
|
|
314
|
+
ctx.beginPath();
|
|
315
|
+
ctx.arc(0, 0, 20, 0, Math.PI * 2);
|
|
316
|
+
ctx.fillStyle = "#4444ff";
|
|
317
|
+
ctx.fill();
|
|
318
|
+
ctx.fillStyle = "white";
|
|
319
|
+
ctx.textAlign = "center";
|
|
320
|
+
ctx.textBaseline = "middle";
|
|
321
|
+
ctx.font = "16px Arial";
|
|
322
|
+
ctx.fillText(`${icon.id + 1}`, 0, 0);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
ctx.restore();
|
|
326
|
+
});
|
|
327
|
+
animationFrameRef.current = requestAnimationFrame(animate);
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
animate();
|
|
331
|
+
|
|
332
|
+
return () => {
|
|
333
|
+
if (animationFrameRef.current) {
|
|
334
|
+
cancelAnimationFrame(animationFrameRef.current);
|
|
335
|
+
}
|
|
336
|
+
};
|
|
337
|
+
}, [icons, images, iconPositions, isDragging, mousePos, targetRotation]);
|
|
338
|
+
|
|
339
|
+
return (
|
|
340
|
+
<canvas
|
|
341
|
+
ref={canvasRef}
|
|
342
|
+
width={400}
|
|
343
|
+
height={400}
|
|
344
|
+
onMouseDown={handleMouseDown}
|
|
345
|
+
onMouseMove={handleMouseMove}
|
|
346
|
+
onMouseUp={handleMouseUp}
|
|
347
|
+
onMouseLeave={handleMouseUp}
|
|
348
|
+
className="rounded-full"
|
|
349
|
+
aria-label="Interactive 3D Icon Cloud"
|
|
350
|
+
role="img"
|
|
351
|
+
/>
|
|
352
|
+
);
|
|
353
|
+
}
|
|
@@ -33,9 +33,9 @@ const ScrollBar = React.forwardRef<
|
|
|
33
33
|
className={cn(
|
|
34
34
|
"flex touch-none select-none transition-colors",
|
|
35
35
|
orientation === "vertical" &&
|
|
36
|
-
|
|
36
|
+
"h-full w-2.5 border-l border-l-transparent p-px",
|
|
37
37
|
orientation === "horizontal" &&
|
|
38
|
-
|
|
38
|
+
"h-2.5 flex-col border-t border-t-transparent p-px",
|
|
39
39
|
className
|
|
40
40
|
)}
|
|
41
41
|
{...props}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
import * as SheetPrimitive from "@radix-ui/react-dialog";
|
|
5
5
|
import { cva, type VariantProps } from "class-variance-authority";
|
|
6
|
-
import {
|
|
6
|
+
import { PanelRightClose } from "lucide-react";
|
|
7
7
|
|
|
8
8
|
import { cn } from "@/lib/utils";
|
|
9
9
|
|
|
@@ -51,7 +51,7 @@ const sheetVariants = cva(
|
|
|
51
51
|
|
|
52
52
|
interface SheetContentProps
|
|
53
53
|
extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,
|
|
54
|
-
|
|
54
|
+
VariantProps<typeof sheetVariants> { }
|
|
55
55
|
|
|
56
56
|
const SheetContent = React.forwardRef<
|
|
57
57
|
React.ElementRef<typeof SheetPrimitive.Content>,
|
|
@@ -65,8 +65,8 @@ const SheetContent = React.forwardRef<
|
|
|
65
65
|
{...props}
|
|
66
66
|
>
|
|
67
67
|
{children}
|
|
68
|
-
<SheetPrimitive.Close className="absolute right-4
|
|
69
|
-
<
|
|
68
|
+
<SheetPrimitive.Close className="absolute top-7 right-4 z-50 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary">
|
|
69
|
+
<PanelRightClose className="w-6 h-6 shrink-0 text-muted-foreground" />
|
|
70
70
|
<span className="sr-only">Close</span>
|
|
71
71
|
</SheetPrimitive.Close>
|
|
72
72
|
</SheetPrimitive.Content>
|
|
@@ -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-
|
|
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-
|
|
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
|
-
|
|
35
|
+
VariantProps<typeof toggleVariants>
|
|
36
36
|
>(({ className, variant, size, ...props }, ref) => (
|
|
37
37
|
<TogglePrimitive.Root
|
|
38
38
|
ref={ref}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
title : Accordion Group
|
|
3
|
+
description: for writing multiple accordions and grouping them together
|
|
4
|
+
date : 10-08-2025
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
An accordion is like a button that opens and closes information. To avoid clutter, long information can be hidden first and then revealed when clicked.
|
|
8
|
+
|
|
9
|
+
<Note type="note" title="Note">
|
|
10
|
+
Group related accordions together using `<AccordionGroup>`. This creates a cohesive section of accordions that can be individually expanded or collapsed.
|
|
11
|
+
</Note>
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
<AccordionGroup>
|
|
16
|
+
<Accordion title="Basic Usage">
|
|
17
|
+
example of using regular paragraph content inside the accordion component
|
|
18
|
+
</Accordion>
|
|
19
|
+
|
|
20
|
+
<Accordion title="With icon props" icon="MousePointerClick">
|
|
21
|
+
This accordion includes a [Lucide Icon](https://lucide.dev/icons/) because the `icon` prop is provided.
|
|
22
|
+
</Accordion>
|
|
23
|
+
|
|
24
|
+
<Accordion title="Expanded by Default" defaultOpen>
|
|
25
|
+
You can put other components inside Accordions.
|
|
26
|
+
```jsx:helloword.jsx
|
|
27
|
+
class HelloWorld {
|
|
28
|
+
public static void main(String[] args) {
|
|
29
|
+
System.out.println("Hello, World!");
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
</Accordion>
|
|
34
|
+
</AccordionGroup>
|
|
35
|
+
|
|
36
|
+
## Writing Markdown
|
|
37
|
+
|
|
38
|
+
````plaintext
|
|
39
|
+
<AccordionGroup>
|
|
40
|
+
<Accordion title="Basic Usage">
|
|
41
|
+
This accordion includes a [Lucide Icon](https://lucide.dev/icons/) because the `icon` prop is provided.
|
|
42
|
+
</Accordion>
|
|
43
|
+
|
|
44
|
+
<Accordion title="With icon props" icon="MousePointerClick">
|
|
45
|
+
This accordion includes a Lucide icon because the `icon` prop is provided.
|
|
46
|
+
</Accordion>
|
|
47
|
+
|
|
48
|
+
<Accordion title="Expanded by Default" defaultOpen>
|
|
49
|
+
You can put other components inside Accordions.
|
|
50
|
+
```jsx:helloword.jsx
|
|
51
|
+
class HelloWorld {
|
|
52
|
+
public static void main(String[] args) {
|
|
53
|
+
System.out.println("Hello, World!");
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
</Accordion>
|
|
58
|
+
</AccordionGroup>
|
|
59
|
+
````
|
|
60
|
+
|
|
61
|
+
## Props
|
|
62
|
+
|
|
63
|
+
| Prop | Type | Default | Description |
|
|
64
|
+
|------|------|---------|-------------|
|
|
65
|
+
| `title` | string | - | **Required**. The text displayed in the accordion header. |
|
|
66
|
+
| `children` | ReactNode | null | The content to be displayed when the accordion is expanded. Can be plain text, markdown, or React components. |
|
|
67
|
+
| `defaultOpen` | boolean | false | When true, the accordion will be expanded by default. |
|
|
68
|
+
| `icon` | string | undefined | Optional. Adds a Lucide icon before the title in the accordion header. |
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Accordion
|
|
3
|
+
description: A component used to create collapsible content that can be hidden and shown again.
|
|
4
|
+
date: 22-12-2024
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Preview
|
|
8
|
+
|
|
9
|
+
### Basic Usage
|
|
10
|
+
|
|
11
|
+
```plaintext
|
|
12
|
+
<Accordion title="Click to expand">
|
|
13
|
+
This is a simple accordion component that can be toggled by clicking the header. The content can include any valid React nodes, including text, components, and markdown.
|
|
14
|
+
</Accordion>
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Render as :
|
|
18
|
+
|
|
19
|
+
<Accordion title="Click to expand">
|
|
20
|
+
This is a simple accordion component that can be toggled by clicking the header. The content can include any valid React nodes, including text, components, and markdown.
|
|
21
|
+
</Accordion>
|
|
22
|
+
|
|
23
|
+
### With Code Block
|
|
24
|
+
|
|
25
|
+
````plaintext
|
|
26
|
+
<Accordion title="Code Block" defaultOpen={true} icon="Code">
|
|
27
|
+
```javascript:main.js showLineNumbers {3-4}
|
|
28
|
+
function isRocketAboutToCrash() {
|
|
29
|
+
// Check if the rocket is stable
|
|
30
|
+
if (!isStable()) {
|
|
31
|
+
NoCrash(); // Prevent the crash
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
</Accordion>
|
|
36
|
+
````
|
|
37
|
+
|
|
38
|
+
Render as :
|
|
39
|
+
|
|
40
|
+
<Accordion title="Code Block" defaultOpen={true} icon="Code">
|
|
41
|
+
```javascript:main.js showLineNumbers {3-4}
|
|
42
|
+
function isRocketAboutToCrash() {
|
|
43
|
+
// Check if the rocket is stable
|
|
44
|
+
if (!isStable()) {
|
|
45
|
+
NoCrash(); // Prevent the crash
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
</Accordion>
|
|
50
|
+
|
|
51
|
+
## Props
|
|
52
|
+
|
|
53
|
+
| Prop | Type | Default | Description |
|
|
54
|
+
|------|------|---------|-------------|
|
|
55
|
+
| `title` | string | - | **Required**. The text displayed in the accordion header. |
|
|
56
|
+
| `children` | ReactNode | null | The content to be displayed when the accordion is expanded. Can be plain text, markdown, or React components. |
|
|
57
|
+
| `defaultOpen` | boolean | false | When true, the accordion will be expanded by default. |
|
|
58
|
+
| `icon` | string | undefined | Optional. Adds a Lucide icon before the title in the accordion header. |
|
|
59
|
+
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Button
|
|
3
|
+
description: A component used to create buttons that can be used to trigger actions or navigate to other pages.
|
|
4
|
+
date: 14-12-2024
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Preview
|
|
8
|
+
|
|
9
|
+
<Button
|
|
10
|
+
text="Learn More"
|
|
11
|
+
href="https://learn.example.com"
|
|
12
|
+
icon="MoveUpRight"
|
|
13
|
+
size="md"
|
|
14
|
+
target="_blank"
|
|
15
|
+
variation="primary"
|
|
16
|
+
/>
|
|
17
|
+
|
|
18
|
+
## Props
|
|
19
|
+
|
|
20
|
+
| Prop | Type | Default | Description |
|
|
21
|
+
| ----------- | -------- | ----------- | -------------------------------------------- |
|
|
22
|
+
| `text` | string | undefined | The button text |
|
|
23
|
+
| `href` | string | **required**| The URL to navigate to |
|
|
24
|
+
| `icon` | string | undefined | Lucide icon name (e.g. "MoveUpRight") |
|
|
25
|
+
| `size` | string | "md" | Button size: `"sm"`, `"md"`, or `"lg"` |
|
|
26
|
+
| `target` | string | undefined | Link target (e.g. "_blank") |
|
|
27
|
+
| `variation` | string | "primary" | Button style: `"primary"`, `"accent"`, or `"outline"` |
|
|
28
|
+
|
|
29
|
+
## Output Markdown
|
|
30
|
+
|
|
31
|
+
```markdown
|
|
32
|
+
<Button
|
|
33
|
+
text="Learn More"
|
|
34
|
+
href="https://learn.example.com"
|
|
35
|
+
icon="MoveUpRight"
|
|
36
|
+
size="md"
|
|
37
|
+
target="_blank"
|
|
38
|
+
variation="primary"
|
|
39
|
+
/>
|
|
40
|
+
```
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Card Group
|
|
3
|
+
description: A component used to create card groups that can be used to display multiple cards in a compact and organized way.
|
|
4
|
+
date: 20-02-2025
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Preview
|
|
8
|
+
|
|
9
|
+
<CardGroup cols={2}>
|
|
10
|
+
<Card title="Heading 1" icon="Heading1">
|
|
11
|
+
This is an example of card content with columns.
|
|
12
|
+
</Card>
|
|
13
|
+
<Card title="Heading 2" icon="Heading2">
|
|
14
|
+
This is an example of card content with columns.
|
|
15
|
+
</Card>
|
|
16
|
+
<Card title="Grid Card" icon="Grid" horizontal>
|
|
17
|
+
This is a horizontal card layout.
|
|
18
|
+
</Card>
|
|
19
|
+
<Card title="Horizontal Card" icon="Layout" horizontal>
|
|
20
|
+
This is a horizontal card layout.
|
|
21
|
+
</Card>
|
|
22
|
+
</CardGroup>
|
|
23
|
+
|
|
24
|
+
## Props
|
|
25
|
+
|
|
26
|
+
| Prop | Type | Default | Description |
|
|
27
|
+
| ------------- | -------- | ------- | ------------------------------------------------------- |
|
|
28
|
+
| `cols` | number | `{2}` | By default 2 The number of columns per row |
|
|
29
|
+
|
|
30
|
+
## Output Markdown
|
|
31
|
+
|
|
32
|
+
```markdown
|
|
33
|
+
<CardGroup cols={2}>
|
|
34
|
+
<Card title="Heading 1" icon="Heading1">
|
|
35
|
+
This is an example of card content with columns.
|
|
36
|
+
</Card>
|
|
37
|
+
<Card title="Heading 2" icon="Heading2">
|
|
38
|
+
This is an example of card content with columns.
|
|
39
|
+
</Card>
|
|
40
|
+
<Card title="Grid Card" icon="Grid" horizontal>
|
|
41
|
+
This is a horizontal card layout.
|
|
42
|
+
</Card>
|
|
43
|
+
<Card title="Horizontal Card" icon="Layout" horizontal>
|
|
44
|
+
This is a horizontal card layout.
|
|
45
|
+
</Card>
|
|
46
|
+
</CardGroup>
|
|
47
|
+
```
|