@usecross/docs 0.2.6 → 0.2.7
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/dist/index.d.ts +6 -1
- package/dist/index.js +127 -60
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/EmojiConfetti.tsx +78 -0
- package/src/components/index.ts +1 -0
- package/src/index.ts +1 -0
- package/src/styles.css +22 -0
package/dist/index.d.ts
CHANGED
|
@@ -30,6 +30,11 @@ interface DocsPageProps extends Omit<DocsLayoutProps, 'children' | 'title'> {
|
|
|
30
30
|
*/
|
|
31
31
|
declare function DocsPage({ content, ...layoutProps }: DocsPageProps): react_jsx_runtime.JSX.Element;
|
|
32
32
|
|
|
33
|
+
declare function EmojiConfetti({ children, emoji }: {
|
|
34
|
+
children: React.ReactNode;
|
|
35
|
+
emoji: string;
|
|
36
|
+
}): react_jsx_runtime.JSX.Element;
|
|
37
|
+
|
|
33
38
|
interface HomeFeature {
|
|
34
39
|
title: string;
|
|
35
40
|
description: ReactNode;
|
|
@@ -175,4 +180,4 @@ declare function configureHighlighter(options: {
|
|
|
175
180
|
langs?: Promise<any>[];
|
|
176
181
|
}): void;
|
|
177
182
|
|
|
178
|
-
export { CodeBlock, CodeBlockProps, DocContent, DocsAppConfig, DocsLayout, DocsLayoutProps, DocsPage, HomeCTA, type HomeFeature, HomeFeatureItem, type HomeFeatureItemProps, HomeFeatures, type HomeFeaturesProps, HomeFooter, HomeHeader, type HomeHeaderProps, HomeHero, HomePage, type HomePageContextValue, type HomePageProps, InlineCode, Markdown, MarkdownProps, Sidebar, SidebarProps, cn, configureHighlighter, createDocsApp, getHighlighter };
|
|
183
|
+
export { CodeBlock, CodeBlockProps, DocContent, DocsAppConfig, DocsLayout, DocsLayoutProps, DocsPage, EmojiConfetti, HomeCTA, type HomeFeature, HomeFeatureItem, type HomeFeatureItemProps, HomeFeatures, type HomeFeaturesProps, HomeFooter, HomeHeader, type HomeHeaderProps, HomeHero, HomePage, type HomePageContextValue, type HomePageProps, InlineCode, Markdown, MarkdownProps, Sidebar, SidebarProps, cn, configureHighlighter, createDocsApp, getHighlighter };
|
package/dist/index.js
CHANGED
|
@@ -326,10 +326,76 @@ function DocsPage({ content, ...layoutProps }) {
|
|
|
326
326
|
return /* @__PURE__ */ jsx5(DocsLayout, { title: content?.title ?? "", description: content?.description, ...layoutProps, children: /* @__PURE__ */ jsx5(Markdown, { content: content?.body ?? "" }) });
|
|
327
327
|
}
|
|
328
328
|
|
|
329
|
+
// src/components/EmojiConfetti.tsx
|
|
330
|
+
import { useState as useState3, useCallback } from "react";
|
|
331
|
+
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
332
|
+
function EmojiConfetti({ children, emoji }) {
|
|
333
|
+
const [particles, setParticles] = useState3([]);
|
|
334
|
+
const [isActive, setIsActive] = useState3(false);
|
|
335
|
+
const triggerBurst = useCallback(() => {
|
|
336
|
+
if (isActive) return;
|
|
337
|
+
setIsActive(true);
|
|
338
|
+
const newParticles = [];
|
|
339
|
+
const count = 15;
|
|
340
|
+
for (let i = 0; i < count; i++) {
|
|
341
|
+
const angle = i / count * Math.PI * 2 + (Math.random() - 0.5) * 0.5;
|
|
342
|
+
newParticles.push({
|
|
343
|
+
id: Date.now() + i,
|
|
344
|
+
x: 50,
|
|
345
|
+
// Start from center
|
|
346
|
+
y: 50,
|
|
347
|
+
angle,
|
|
348
|
+
velocity: 80 + Math.random() * 60,
|
|
349
|
+
// Distance to travel
|
|
350
|
+
spin: (Math.random() - 0.5) * 720,
|
|
351
|
+
// Random rotation
|
|
352
|
+
scale: 0.7 + Math.random() * 0.6
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
setParticles(newParticles);
|
|
356
|
+
setTimeout(() => {
|
|
357
|
+
setParticles([]);
|
|
358
|
+
setIsActive(false);
|
|
359
|
+
}, 1e3);
|
|
360
|
+
}, [isActive]);
|
|
361
|
+
return /* @__PURE__ */ jsxs4(
|
|
362
|
+
"span",
|
|
363
|
+
{
|
|
364
|
+
className: "relative inline-block",
|
|
365
|
+
onMouseEnter: triggerBurst,
|
|
366
|
+
children: [
|
|
367
|
+
children,
|
|
368
|
+
/* @__PURE__ */ jsx6("span", { className: "absolute inset-0 pointer-events-none overflow-visible", children: particles.map((p) => {
|
|
369
|
+
const endX = p.x + Math.cos(p.angle) * p.velocity;
|
|
370
|
+
const endY = p.y + Math.sin(p.angle) * p.velocity;
|
|
371
|
+
return /* @__PURE__ */ jsx6(
|
|
372
|
+
"span",
|
|
373
|
+
{
|
|
374
|
+
className: "absolute",
|
|
375
|
+
style: {
|
|
376
|
+
left: "50%",
|
|
377
|
+
top: "50%",
|
|
378
|
+
fontSize: `${p.scale}rem`,
|
|
379
|
+
transform: "translate(-50%, -50%)",
|
|
380
|
+
animation: `emojiConfettiBurst 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards`,
|
|
381
|
+
"--end-x": `${endX - 50}px`,
|
|
382
|
+
"--end-y": `${endY - 50}px`,
|
|
383
|
+
"--spin": `${p.spin}deg`
|
|
384
|
+
},
|
|
385
|
+
children: emoji
|
|
386
|
+
},
|
|
387
|
+
p.id
|
|
388
|
+
);
|
|
389
|
+
}) })
|
|
390
|
+
]
|
|
391
|
+
}
|
|
392
|
+
);
|
|
393
|
+
}
|
|
394
|
+
|
|
329
395
|
// src/components/HomePage.tsx
|
|
330
396
|
import { Head as Head2, Link as Link3 } from "@inertiajs/react";
|
|
331
|
-
import { createContext, useContext, useState as
|
|
332
|
-
import { Fragment as Fragment2, jsx as
|
|
397
|
+
import { createContext, useContext, useState as useState4 } from "react";
|
|
398
|
+
import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
333
399
|
var HomePageContext = createContext(null);
|
|
334
400
|
function useHomePage() {
|
|
335
401
|
const context = useContext(HomePageContext);
|
|
@@ -339,28 +405,28 @@ function useHomePage() {
|
|
|
339
405
|
return context;
|
|
340
406
|
}
|
|
341
407
|
function InstallCommand({ command }) {
|
|
342
|
-
const [copied, setCopied] =
|
|
408
|
+
const [copied, setCopied] = useState4(false);
|
|
343
409
|
const copyToClipboard = async () => {
|
|
344
410
|
await navigator.clipboard.writeText(command);
|
|
345
411
|
setCopied(true);
|
|
346
412
|
setTimeout(() => setCopied(false), 2e3);
|
|
347
413
|
};
|
|
348
|
-
return /* @__PURE__ */
|
|
414
|
+
return /* @__PURE__ */ jsxs5(
|
|
349
415
|
"button",
|
|
350
416
|
{
|
|
351
417
|
onClick: copyToClipboard,
|
|
352
418
|
className: "group relative flex items-center bg-black border border-black px-4 h-14 font-mono text-sm text-white hover:bg-white hover:text-black transition-colors cursor-pointer",
|
|
353
419
|
children: [
|
|
354
|
-
/* @__PURE__ */
|
|
355
|
-
/* @__PURE__ */
|
|
356
|
-
/* @__PURE__ */
|
|
420
|
+
/* @__PURE__ */ jsx7("span", { className: "text-primary-500 mr-2", children: "$" }),
|
|
421
|
+
/* @__PURE__ */ jsx7("span", { children: command }),
|
|
422
|
+
/* @__PURE__ */ jsx7(
|
|
357
423
|
"svg",
|
|
358
424
|
{
|
|
359
425
|
className: `ml-4 w-4 h-4 transition ${copied ? "text-green-400" : "opacity-50 group-hover:opacity-100"}`,
|
|
360
426
|
fill: "none",
|
|
361
427
|
stroke: "currentColor",
|
|
362
428
|
viewBox: "0 0 24 24",
|
|
363
|
-
children: /* @__PURE__ */
|
|
429
|
+
children: /* @__PURE__ */ jsx7(
|
|
364
430
|
"path",
|
|
365
431
|
{
|
|
366
432
|
strokeLinecap: "round",
|
|
@@ -371,7 +437,7 @@ function InstallCommand({ command }) {
|
|
|
371
437
|
)
|
|
372
438
|
}
|
|
373
439
|
),
|
|
374
|
-
/* @__PURE__ */
|
|
440
|
+
/* @__PURE__ */ jsx7(
|
|
375
441
|
"span",
|
|
376
442
|
{
|
|
377
443
|
className: `absolute -top-8 left-1/2 -translate-x-1/2 bg-black text-white text-xs py-1 px-2 rounded transition-opacity duration-300 whitespace-nowrap ${copied ? "opacity-100" : "opacity-0"}`,
|
|
@@ -383,7 +449,7 @@ function InstallCommand({ command }) {
|
|
|
383
449
|
);
|
|
384
450
|
}
|
|
385
451
|
function GitHubIcon2() {
|
|
386
|
-
return /* @__PURE__ */
|
|
452
|
+
return /* @__PURE__ */ jsx7("svg", { className: "w-6 h-6", fill: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ jsx7(
|
|
387
453
|
"path",
|
|
388
454
|
{
|
|
389
455
|
fillRule: "evenodd",
|
|
@@ -395,16 +461,16 @@ function GitHubIcon2() {
|
|
|
395
461
|
function DefaultLogo() {
|
|
396
462
|
const { title, logoUrl } = useHomePage();
|
|
397
463
|
if (logoUrl) {
|
|
398
|
-
return /* @__PURE__ */
|
|
464
|
+
return /* @__PURE__ */ jsx7(Link3, { href: "/", className: "flex items-center", children: /* @__PURE__ */ jsx7("img", { src: logoUrl, alt: title, className: "h-8" }) });
|
|
399
465
|
}
|
|
400
|
-
return /* @__PURE__ */
|
|
466
|
+
return /* @__PURE__ */ jsx7(Link3, { href: "/", className: "font-bold text-lg", children: title });
|
|
401
467
|
}
|
|
402
468
|
function HomeHeader({ renderLogo } = {}) {
|
|
403
469
|
const { navLinks, githubUrl } = useHomePage();
|
|
404
|
-
return /* @__PURE__ */
|
|
405
|
-
renderLogo ? renderLogo() : /* @__PURE__ */
|
|
406
|
-
/* @__PURE__ */
|
|
407
|
-
navLinks.map((link) => /* @__PURE__ */
|
|
470
|
+
return /* @__PURE__ */ jsx7("nav", { className: "fixed w-full z-50 bg-white border-b border-gray-200", children: /* @__PURE__ */ jsx7("div", { className: "px-4 lg:px-10", children: /* @__PURE__ */ jsxs5("div", { className: "flex justify-between h-16 items-center", children: [
|
|
471
|
+
renderLogo ? renderLogo() : /* @__PURE__ */ jsx7(DefaultLogo, {}),
|
|
472
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex items-center space-x-8", children: [
|
|
473
|
+
navLinks.map((link) => /* @__PURE__ */ jsx7(
|
|
408
474
|
Link3,
|
|
409
475
|
{
|
|
410
476
|
href: link.href,
|
|
@@ -413,14 +479,14 @@ function HomeHeader({ renderLogo } = {}) {
|
|
|
413
479
|
},
|
|
414
480
|
link.href
|
|
415
481
|
)),
|
|
416
|
-
githubUrl && /* @__PURE__ */
|
|
482
|
+
githubUrl && /* @__PURE__ */ jsx7(
|
|
417
483
|
"a",
|
|
418
484
|
{
|
|
419
485
|
href: githubUrl,
|
|
420
486
|
target: "_blank",
|
|
421
487
|
rel: "noopener noreferrer",
|
|
422
488
|
className: "text-black hover:text-primary-500 transition-colors",
|
|
423
|
-
children: /* @__PURE__ */
|
|
489
|
+
children: /* @__PURE__ */ jsx7(GitHubIcon2, {})
|
|
424
490
|
}
|
|
425
491
|
)
|
|
426
492
|
] })
|
|
@@ -428,19 +494,19 @@ function HomeHeader({ renderLogo } = {}) {
|
|
|
428
494
|
}
|
|
429
495
|
function HomeHero() {
|
|
430
496
|
const { title, tagline, description, ctaText, ctaHref, installCommand, heroLogoUrl } = useHomePage();
|
|
431
|
-
return /* @__PURE__ */
|
|
432
|
-
/* @__PURE__ */
|
|
433
|
-
heroLogoUrl ? /* @__PURE__ */
|
|
497
|
+
return /* @__PURE__ */ jsx7("section", { className: "pt-16", children: /* @__PURE__ */ jsx7("div", { className: "px-4 lg:px-10 py-16 lg:py-24", children: /* @__PURE__ */ jsxs5("div", { className: "max-w-4xl", children: [
|
|
498
|
+
/* @__PURE__ */ jsx7("div", { className: "mb-4 text-sm font-mono uppercase tracking-widest text-gray-500", children: tagline }),
|
|
499
|
+
heroLogoUrl ? /* @__PURE__ */ jsx7("h1", { className: "mb-6 lg:mb-8", children: /* @__PURE__ */ jsx7(
|
|
434
500
|
"img",
|
|
435
501
|
{
|
|
436
502
|
src: heroLogoUrl,
|
|
437
503
|
alt: title,
|
|
438
504
|
className: "h-auto w-auto max-w-[580px]"
|
|
439
505
|
}
|
|
440
|
-
) }) : /* @__PURE__ */
|
|
441
|
-
/* @__PURE__ */
|
|
442
|
-
/* @__PURE__ */
|
|
443
|
-
/* @__PURE__ */
|
|
506
|
+
) }) : /* @__PURE__ */ jsx7("h1", { className: "text-5xl lg:text-7xl font-bold tracking-tight mb-6", children: title }),
|
|
507
|
+
/* @__PURE__ */ jsx7("p", { className: "text-xl lg:text-2xl text-gray-700 max-w-2xl leading-relaxed mb-8", children: description }),
|
|
508
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex flex-col sm:flex-row gap-3", children: [
|
|
509
|
+
/* @__PURE__ */ jsx7(
|
|
444
510
|
Link3,
|
|
445
511
|
{
|
|
446
512
|
href: ctaHref,
|
|
@@ -448,19 +514,19 @@ function HomeHero() {
|
|
|
448
514
|
children: ctaText
|
|
449
515
|
}
|
|
450
516
|
),
|
|
451
|
-
installCommand && /* @__PURE__ */
|
|
517
|
+
installCommand && /* @__PURE__ */ jsx7(InstallCommand, { command: installCommand })
|
|
452
518
|
] })
|
|
453
519
|
] }) }) });
|
|
454
520
|
}
|
|
455
521
|
function HomeFeatureItem({ feature, index, totalFeatures }) {
|
|
456
|
-
return /* @__PURE__ */
|
|
522
|
+
return /* @__PURE__ */ jsxs5(
|
|
457
523
|
"div",
|
|
458
524
|
{
|
|
459
525
|
className: `p-4 lg:p-10 border-b sm:border-b border-gray-200 ${index % 2 === 0 ? "sm:border-r" : ""} ${index >= totalFeatures - 2 ? "sm:border-b-0" : ""} ${index === totalFeatures - 1 && totalFeatures % 2 === 1 ? "border-b-0" : ""}`,
|
|
460
526
|
children: [
|
|
461
|
-
/* @__PURE__ */
|
|
462
|
-
/* @__PURE__ */
|
|
463
|
-
/* @__PURE__ */
|
|
527
|
+
/* @__PURE__ */ jsx7("div", { className: "text-5xl font-bold text-primary-500 mb-4", children: String(index + 1).padStart(2, "0") }),
|
|
528
|
+
/* @__PURE__ */ jsx7("h3", { className: "text-xl font-bold mb-2", children: feature.title }),
|
|
529
|
+
/* @__PURE__ */ jsx7("p", { className: "text-gray-600", children: feature.description })
|
|
464
530
|
]
|
|
465
531
|
}
|
|
466
532
|
);
|
|
@@ -470,17 +536,17 @@ function HomeFeatures({ renderFeature } = {}) {
|
|
|
470
536
|
if (features.length === 0) {
|
|
471
537
|
return null;
|
|
472
538
|
}
|
|
473
|
-
return /* @__PURE__ */
|
|
474
|
-
/* @__PURE__ */
|
|
475
|
-
/* @__PURE__ */
|
|
476
|
-
/* @__PURE__ */
|
|
539
|
+
return /* @__PURE__ */ jsx7("section", { className: "border-t border-gray-200", children: /* @__PURE__ */ jsxs5("div", { className: "grid grid-cols-12", children: [
|
|
540
|
+
/* @__PURE__ */ jsxs5("div", { className: "col-span-12 lg:col-span-4 p-4 lg:p-10 border-b lg:border-b-0 lg:border-r border-gray-200", children: [
|
|
541
|
+
/* @__PURE__ */ jsx7("div", { className: "text-sm font-mono uppercase tracking-widest text-gray-500 mb-4", children: "Features" }),
|
|
542
|
+
/* @__PURE__ */ jsxs5("h2", { className: "text-4xl lg:text-5xl font-bold tracking-tight", children: [
|
|
477
543
|
"Why ",
|
|
478
544
|
title,
|
|
479
545
|
"?"
|
|
480
546
|
] })
|
|
481
547
|
] }),
|
|
482
|
-
/* @__PURE__ */
|
|
483
|
-
(feature, index) => renderFeature ? /* @__PURE__ */
|
|
548
|
+
/* @__PURE__ */ jsx7("div", { className: "col-span-12 lg:col-span-8 grid grid-cols-1 sm:grid-cols-2", children: features.map(
|
|
549
|
+
(feature, index) => renderFeature ? /* @__PURE__ */ jsx7("div", { children: renderFeature(feature, index, HomeFeatureItem) }, index) : /* @__PURE__ */ jsx7(
|
|
484
550
|
HomeFeatureItem,
|
|
485
551
|
{
|
|
486
552
|
feature,
|
|
@@ -494,11 +560,11 @@ function HomeFeatures({ renderFeature } = {}) {
|
|
|
494
560
|
}
|
|
495
561
|
function HomeCTA() {
|
|
496
562
|
const { ctaHref } = useHomePage();
|
|
497
|
-
return /* @__PURE__ */
|
|
498
|
-
/* @__PURE__ */
|
|
499
|
-
/* @__PURE__ */
|
|
500
|
-
/* @__PURE__ */
|
|
501
|
-
/* @__PURE__ */
|
|
563
|
+
return /* @__PURE__ */ jsx7("section", { className: "border-t border-gray-200", children: /* @__PURE__ */ jsxs5("div", { className: "grid grid-cols-12 items-center", children: [
|
|
564
|
+
/* @__PURE__ */ jsxs5("div", { className: "col-span-12 lg:col-span-8 p-4 lg:p-10", children: [
|
|
565
|
+
/* @__PURE__ */ jsx7("h2", { className: "text-4xl lg:text-6xl font-bold tracking-tight mb-4", children: "Ready to start?" }),
|
|
566
|
+
/* @__PURE__ */ jsx7("p", { className: "text-xl text-gray-600 mb-8 max-w-2xl", children: "Get up and running in minutes. Check out our documentation to learn more." }),
|
|
567
|
+
/* @__PURE__ */ jsx7(
|
|
502
568
|
Link3,
|
|
503
569
|
{
|
|
504
570
|
href: ctaHref,
|
|
@@ -507,23 +573,23 @@ function HomeCTA() {
|
|
|
507
573
|
}
|
|
508
574
|
)
|
|
509
575
|
] }),
|
|
510
|
-
/* @__PURE__ */
|
|
576
|
+
/* @__PURE__ */ jsx7(
|
|
511
577
|
Link3,
|
|
512
578
|
{
|
|
513
579
|
href: ctaHref,
|
|
514
580
|
className: "col-span-12 lg:col-span-4 h-full bg-primary-500 hidden lg:flex items-center justify-center p-4 lg:p-10 hover:bg-black transition-colors min-h-[200px]",
|
|
515
|
-
children: /* @__PURE__ */
|
|
581
|
+
children: /* @__PURE__ */ jsx7("div", { className: "text-white text-8xl font-bold", children: "\u2192" })
|
|
516
582
|
}
|
|
517
583
|
)
|
|
518
584
|
] }) });
|
|
519
585
|
}
|
|
520
586
|
function HomeFooter() {
|
|
521
587
|
const { title, logoUrl, footerLogoUrl, navLinks, githubUrl } = useHomePage();
|
|
522
|
-
return /* @__PURE__ */
|
|
523
|
-
(footerLogoUrl || logoUrl) && /* @__PURE__ */
|
|
524
|
-
/* @__PURE__ */
|
|
525
|
-
navLinks.map((link) => /* @__PURE__ */
|
|
526
|
-
githubUrl && /* @__PURE__ */
|
|
588
|
+
return /* @__PURE__ */ jsx7("footer", { className: "border-t border-gray-200 py-8", children: /* @__PURE__ */ jsxs5("div", { className: "px-4 lg:px-10 flex flex-col md:flex-row justify-between items-center gap-6", children: [
|
|
589
|
+
(footerLogoUrl || logoUrl) && /* @__PURE__ */ jsx7(Link3, { href: "/", children: /* @__PURE__ */ jsx7("img", { src: footerLogoUrl || logoUrl, alt: title, className: "h-6" }) }),
|
|
590
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex gap-8 text-sm text-gray-600", children: [
|
|
591
|
+
navLinks.map((link) => /* @__PURE__ */ jsx7(Link3, { href: link.href, className: "hover:text-black transition-colors", children: link.label }, link.href)),
|
|
592
|
+
githubUrl && /* @__PURE__ */ jsx7(
|
|
527
593
|
"a",
|
|
528
594
|
{
|
|
529
595
|
href: githubUrl,
|
|
@@ -537,12 +603,12 @@ function HomeFooter() {
|
|
|
537
603
|
] }) });
|
|
538
604
|
}
|
|
539
605
|
function DefaultHomeLayout() {
|
|
540
|
-
return /* @__PURE__ */
|
|
541
|
-
/* @__PURE__ */
|
|
542
|
-
/* @__PURE__ */
|
|
543
|
-
/* @__PURE__ */
|
|
544
|
-
/* @__PURE__ */
|
|
545
|
-
/* @__PURE__ */
|
|
606
|
+
return /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
607
|
+
/* @__PURE__ */ jsx7(HomeHeader, {}),
|
|
608
|
+
/* @__PURE__ */ jsx7(HomeHero, {}),
|
|
609
|
+
/* @__PURE__ */ jsx7(HomeFeatures, {}),
|
|
610
|
+
/* @__PURE__ */ jsx7(HomeCTA, {}),
|
|
611
|
+
/* @__PURE__ */ jsx7(HomeFooter, {})
|
|
546
612
|
] });
|
|
547
613
|
}
|
|
548
614
|
function HomePage({
|
|
@@ -554,9 +620,9 @@ function HomePage({
|
|
|
554
620
|
...props,
|
|
555
621
|
navLinks
|
|
556
622
|
};
|
|
557
|
-
return /* @__PURE__ */
|
|
558
|
-
/* @__PURE__ */
|
|
559
|
-
children || /* @__PURE__ */
|
|
623
|
+
return /* @__PURE__ */ jsx7(HomePageContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs5("div", { className: "min-h-screen bg-white", children: [
|
|
624
|
+
/* @__PURE__ */ jsx7(Head2, { title: props.title }),
|
|
625
|
+
children || /* @__PURE__ */ jsx7(DefaultHomeLayout, {})
|
|
560
626
|
] }) });
|
|
561
627
|
}
|
|
562
628
|
HomePage.Header = HomeHeader;
|
|
@@ -569,7 +635,7 @@ HomePage.Footer = HomeFooter;
|
|
|
569
635
|
// src/app.tsx
|
|
570
636
|
import { createInertiaApp } from "@inertiajs/react";
|
|
571
637
|
import { createRoot, hydrateRoot } from "react-dom/client";
|
|
572
|
-
import { jsx as
|
|
638
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
573
639
|
function createDocsApp(config) {
|
|
574
640
|
const { pages, title } = config;
|
|
575
641
|
if (typeof window !== "undefined") {
|
|
@@ -587,9 +653,9 @@ function createDocsApp(config) {
|
|
|
587
653
|
},
|
|
588
654
|
setup({ el, App, props }) {
|
|
589
655
|
if (el.hasChildNodes()) {
|
|
590
|
-
hydrateRoot(el, /* @__PURE__ */
|
|
656
|
+
hydrateRoot(el, /* @__PURE__ */ jsx8(App, { ...props }));
|
|
591
657
|
} else {
|
|
592
|
-
createRoot(el).render(/* @__PURE__ */
|
|
658
|
+
createRoot(el).render(/* @__PURE__ */ jsx8(App, { ...props }));
|
|
593
659
|
}
|
|
594
660
|
}
|
|
595
661
|
});
|
|
@@ -598,6 +664,7 @@ export {
|
|
|
598
664
|
CodeBlock,
|
|
599
665
|
DocsLayout,
|
|
600
666
|
DocsPage,
|
|
667
|
+
EmojiConfetti,
|
|
601
668
|
HomeCTA,
|
|
602
669
|
HomeFeatureItem,
|
|
603
670
|
HomeFeatures,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/CodeBlock.tsx","../src/lib/utils.ts","../src/lib/shiki.ts","../src/components/DocsLayout.tsx","../src/components/Sidebar.tsx","../src/components/Markdown.tsx","../src/components/DocsPage.tsx","../src/components/HomePage.tsx","../src/app.tsx"],"sourcesContent":["import { useEffect, useState } from 'react'\nimport { cn } from '../lib/utils'\nimport { getHighlighter } from '../lib/shiki'\nimport type { CodeBlockProps } from '../types'\n\n/**\n * Syntax-highlighted code block component using Shiki.\n */\nexport function CodeBlock({\n code,\n language = 'python',\n filename,\n showLineNumbers = false,\n theme = 'github-dark-dimmed',\n className,\n}: CodeBlockProps) {\n const [html, setHtml] = useState<string>('')\n const [copied, setCopied] = useState(false)\n\n useEffect(() => {\n async function highlight() {\n const highlighter = await getHighlighter()\n const langs = highlighter.getLoadedLanguages()\n const lang = langs.includes(language) ? language : 'text'\n const highlighted = highlighter.codeToHtml(code.trim(), {\n lang,\n theme,\n })\n setHtml(highlighted)\n }\n highlight()\n }, [code, language, theme])\n\n const copyToClipboard = async () => {\n await navigator.clipboard.writeText(code.trim())\n setCopied(true)\n setTimeout(() => setCopied(false), 2000)\n }\n\n return (\n <div className={cn('group relative overflow-hidden rounded-lg bg-[#24292f] not-prose', className)}>\n {filename && (\n <div className=\"flex items-center gap-2 border-b border-slate-700 bg-slate-900 px-4 py-2 text-sm text-slate-400\">\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\"\n />\n </svg>\n {filename}\n </div>\n )}\n <button\n onClick={copyToClipboard}\n className=\"absolute right-2 top-2 z-10 rounded-md bg-slate-700/50 px-2 py-1 text-xs text-slate-400 opacity-0 transition-opacity hover:bg-slate-600 hover:text-white group-hover:opacity-100\"\n >\n {copied ? 'Copied!' : 'Copy'}\n </button>\n {html ? (\n <div\n className={cn(\n 'overflow-x-auto text-sm [&_pre]:!m-0 [&_pre]:!bg-transparent [&_code]:!p-4',\n showLineNumbers && '[&_code]:grid [&_code]:grid-cols-[auto_1fr]'\n )}\n dangerouslySetInnerHTML={{ __html: html }}\n />\n ) : (\n <pre className=\"shiki overflow-x-auto !m-0 !bg-transparent\">\n <code className=\"block p-4 text-sm leading-relaxed text-gray-300\">{code.trim()}</code>\n </pre>\n )}\n </div>\n )\n}\n\n/**\n * Simple inline code component.\n */\nexport function InlineCode({ children }: { children: React.ReactNode }) {\n return (\n <code className=\"rounded bg-slate-100 px-1.5 py-0.5 text-sm font-medium text-slate-800\">\n {children}\n </code>\n )\n}\n","import { clsx, type ClassValue } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\n/**\n * Merge Tailwind CSS classes with clsx\n */\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","import { createHighlighterCore, type HighlighterCore } from 'shiki/core'\nimport { createJavaScriptRegexEngine } from 'shiki/engine/javascript'\n\nlet highlighterPromise: Promise<HighlighterCore> | null = null\n\n// Default languages to load\nconst defaultLangs = [\n import('shiki/langs/python.mjs'),\n import('shiki/langs/javascript.mjs'),\n import('shiki/langs/typescript.mjs'),\n import('shiki/langs/tsx.mjs'),\n import('shiki/langs/jsx.mjs'),\n import('shiki/langs/bash.mjs'),\n import('shiki/langs/shellscript.mjs'),\n import('shiki/langs/json.mjs'),\n import('shiki/langs/html.mjs'),\n import('shiki/langs/css.mjs'),\n import('shiki/langs/yaml.mjs'),\n import('shiki/langs/toml.mjs'),\n import('shiki/langs/markdown.mjs'),\n]\n\n// Default theme\nconst defaultTheme = import('shiki/themes/github-dark-dimmed.mjs')\n\n/**\n * Get or create a Shiki highlighter instance.\n * Uses a singleton pattern to avoid creating multiple highlighters.\n */\nexport function getHighlighter(): Promise<HighlighterCore> {\n if (!highlighterPromise) {\n highlighterPromise = createHighlighterCore({\n themes: [defaultTheme],\n langs: defaultLangs,\n engine: createJavaScriptRegexEngine(),\n })\n }\n return highlighterPromise\n}\n\n/**\n * Configure the highlighter with custom themes and languages.\n * Must be called before getHighlighter() is first called.\n */\nexport function configureHighlighter(options: {\n theme?: Promise<any>\n langs?: Promise<any>[]\n}): void {\n if (highlighterPromise) {\n console.warn('configureHighlighter called after highlighter was created')\n return\n }\n\n highlighterPromise = createHighlighterCore({\n themes: [options.theme ?? defaultTheme],\n langs: options.langs ?? defaultLangs,\n engine: createJavaScriptRegexEngine(),\n })\n}\n","import { Head, Link, usePage } from '@inertiajs/react'\nimport { useState } from 'react'\nimport { Sidebar } from './Sidebar'\nimport type { DocsLayoutProps, SharedProps } from '../types'\n\nfunction MobileMenuButton({ onClick, isOpen }: { onClick: () => void; isOpen: boolean }) {\n return (\n <button\n onClick={onClick}\n className=\"inline-flex items-center justify-center p-2 -ml-2 text-black hover:text-primary-500 lg:hidden\"\n aria-expanded={isOpen}\n >\n <span className=\"sr-only\">{isOpen ? 'Close menu' : 'Open menu'}</span>\n {isOpen ? (\n <svg className=\"h-6 w-6\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n ) : (\n <svg className=\"h-6 w-6\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 6h16M4 12h16M4 18h16\" />\n </svg>\n )}\n </button>\n )\n}\n\nfunction GitHubIcon() {\n return (\n <svg className=\"w-6 h-6\" fill=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <path\n fillRule=\"evenodd\"\n d=\"M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z\"\n clipRule=\"evenodd\"\n />\n </svg>\n )\n}\n\n/**\n * Full-featured documentation layout with sidebar, mobile menu, and header.\n */\nexport function DocsLayout({\n children,\n title,\n description: _description,\n logo,\n logoInverted,\n logoUrl: propLogoUrl,\n logoInvertedUrl: propLogoInvertedUrl,\n githubUrl: propGithubUrl,\n navLinks: propNavLinks,\n footer,\n}: DocsLayoutProps) {\n const sharedProps = usePage<{ props: SharedProps }>().props as unknown as SharedProps\n const { nav, currentPath } = sharedProps\n const [mobileMenuOpen, setMobileMenuOpen] = useState(false)\n\n // Merge props - component props take precedence over shared props from Python\n const logoUrl = propLogoUrl ?? sharedProps.logoUrl\n const logoInvertedUrl = propLogoInvertedUrl ?? sharedProps.logoInvertedUrl\n const githubUrl = propGithubUrl ?? sharedProps.githubUrl\n const navLinks = propNavLinks ?? sharedProps.navLinks ?? []\n\n // Determine which logo to display in header (prefer inverted/dark version)\n const headerLogo = logoInverted || logo || (logoInvertedUrl ? (\n <img src={logoInvertedUrl} alt=\"Logo\" className=\"h-8\" />\n ) : logoUrl ? (\n <img src={logoUrl} alt=\"Logo\" className=\"h-8\" />\n ) : null)\n\n // Determine which logo to display in footer (prefer footer-specific logo)\n const footerLogoUrl = sharedProps.footerLogoUrl || logoUrl\n const footerLogo = logo || (footerLogoUrl ? (\n <img src={footerLogoUrl} alt=\"Logo\" className=\"h-6\" />\n ) : null)\n\n return (\n <div className=\"min-h-screen bg-white flex flex-col\">\n <Head title={title} />\n\n {/* Fixed navigation */}\n <nav className=\"fixed w-full z-50 bg-white border-b border-gray-200\">\n <div className=\"px-4 lg:px-10\">\n <div className=\"flex justify-between h-16 items-center\">\n <div className=\"flex items-center gap-2\">\n <MobileMenuButton onClick={() => setMobileMenuOpen(!mobileMenuOpen)} isOpen={mobileMenuOpen} />\n {headerLogo ? (\n <Link href=\"/\" className=\"flex items-center\">\n {headerLogo}\n </Link>\n ) : (\n <Link href=\"/\" className=\"font-bold text-lg\">\n Docs\n </Link>\n )}\n </div>\n <div className=\"flex items-center space-x-8\">\n {navLinks.map((link) => (\n <Link\n key={link.href}\n href={link.href}\n className=\"text-black font-medium hover:text-primary-500 transition-colors\"\n >\n {link.label}\n </Link>\n ))}\n {githubUrl && (\n <a\n href={githubUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-black hover:text-primary-500 transition-colors\"\n >\n <GitHubIcon />\n </a>\n )}\n </div>\n </div>\n </div>\n </nav>\n\n {/* Mobile sidebar */}\n {mobileMenuOpen && (\n <div className=\"fixed inset-0 z-40 lg:hidden\">\n <div className=\"fixed inset-0 bg-black/50\" onClick={() => setMobileMenuOpen(false)} />\n <div className=\"fixed inset-y-0 left-0 w-72 overflow-y-auto bg-white px-4 lg:px-10 py-6 pt-20 border-r border-gray-200\">\n <Sidebar nav={nav} currentPath={currentPath} />\n </div>\n </div>\n )}\n\n {/* Main content area */}\n <div className=\"bg-white pt-16 w-full flex-1\">\n <div className=\"grid grid-cols-12\">\n {/* Desktop sidebar */}\n <aside className=\"hidden lg:block lg:col-span-3 xl:col-span-2 border-r border-gray-200 min-h-[calc(100vh-4rem)]\">\n <nav className=\"sticky top-16 px-4 lg:px-10 py-6 max-h-[calc(100vh-4rem)] overflow-y-auto\">\n <Sidebar nav={nav} currentPath={currentPath} />\n </nav>\n </aside>\n\n {/* Main content */}\n <main className=\"col-span-12 lg:col-span-9 xl:col-span-10 p-4 lg:px-10 lg:py-6\">\n <article className=\"prose prose-lg max-w-3xl prose-headings:font-bold prose-headings:tracking-tight prose-h1:text-3xl prose-h1:mb-4 prose-h2:text-2xl prose-h2:mt-10 first:prose-h2:mt-0 prose-h3:text-xl prose-a:text-primary-600 prose-a:no-underline hover:prose-a:underline prose-code:bg-gray-100 prose-code:px-1.5 prose-code:py-0.5 prose-code:rounded prose-code:before:content-none prose-code:after:content-none\">\n {children}\n </article>\n </main>\n </div>\n </div>\n\n {/* Footer */}\n {footer || (\n <footer className=\"border-t border-gray-200 py-8\">\n <div className=\"px-4 lg:px-10 flex flex-col md:flex-row justify-between items-center gap-6\">\n {footerLogo && <Link href=\"/\">{footerLogo}</Link>}\n <div className=\"flex gap-8 text-sm text-gray-600\">\n {navLinks.map((link) => (\n <Link key={link.href} href={link.href} className=\"hover:text-black transition-colors\">\n {link.label}\n </Link>\n ))}\n {githubUrl && (\n <a\n href={githubUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"hover:text-black transition-colors\"\n >\n GitHub\n </a>\n )}\n </div>\n </div>\n </footer>\n )}\n </div>\n )\n}\n","import { Link } from '@inertiajs/react'\nimport { cn } from '../lib/utils'\nimport type { SidebarProps } from '../types'\n\n/**\n * Documentation sidebar with section-based navigation.\n */\nexport function Sidebar({ nav, currentPath, className }: SidebarProps) {\n return (\n <nav className={cn('space-y-8', className)}>\n {nav.map((section) => (\n <div key={section.title}>\n <h3 className=\"mb-3 text-xs font-mono uppercase tracking-widest text-gray-500\">\n {section.title}\n </h3>\n <ul className=\"space-y-1 border-l-2 border-gray-200\">\n {section.items.map((item) => (\n <li key={item.href}>\n <Link\n href={item.href}\n className={cn(\n 'block border-l-2 py-1.5 pl-4 text-sm transition-colors -ml-0.5',\n currentPath === item.href\n ? 'border-primary-500 text-black font-bold'\n : 'border-transparent text-gray-600 hover:border-black hover:text-black'\n )}\n >\n {item.title}\n </Link>\n </li>\n ))}\n </ul>\n </div>\n ))}\n </nav>\n )\n}\n","import ReactMarkdown from 'react-markdown'\nimport remarkGfm from 'remark-gfm'\nimport rehypeRaw from 'rehype-raw'\nimport { CodeBlock } from './CodeBlock'\nimport type { MarkdownProps } from '../types'\n\n/**\n * Markdown renderer with syntax highlighting and GFM support.\n */\nexport function Markdown({ content, components }: MarkdownProps) {\n return (\n <ReactMarkdown\n remarkPlugins={[remarkGfm]}\n rehypePlugins={[rehypeRaw]}\n components={{\n // Override pre to avoid double wrapping with CodeBlock\n pre({ children }) {\n return <>{children}</>\n },\n // Custom code block rendering with syntax highlighting\n code({ node, className, children, ...props }) {\n const match = /language-(\\w+)/.exec(className || '')\n const isInline = !match && !className\n\n if (isInline) {\n return (\n <code\n className=\"rounded bg-gray-100 px-1.5 py-0.5 text-sm font-medium text-gray-800 dark:bg-gray-800 dark:text-gray-200\"\n {...props}\n >\n {children}\n </code>\n )\n }\n\n // Parse meta string from the code fence (e.g., ```python title=\"app.py\" showLineNumbers)\n const meta = (node?.data?.meta as string) || ''\n const titleMatch = /title=\"([^\"]+)\"/.exec(meta)\n const filename = titleMatch ? titleMatch[1] : undefined\n const showLineNumbers = meta.includes('showLineNumbers')\n\n return (\n <CodeBlock\n code={String(children).replace(/\\n$/, '')}\n language={match ? match[1] : 'text'}\n filename={filename}\n showLineNumbers={showLineNumbers}\n />\n )\n },\n // Custom link styling\n a({ href, children }) {\n const isExternal = href?.startsWith('http')\n return (\n <a\n href={href}\n className=\"text-primary-600 hover:text-primary-700 dark:text-primary-400 dark:hover:text-primary-300\"\n {...(isExternal ? { target: '_blank', rel: 'noopener noreferrer' } : {})}\n >\n {children}\n </a>\n )\n },\n // Tables\n table({ children }) {\n return (\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-left text-sm\">{children}</table>\n </div>\n )\n },\n th({ children }) {\n return (\n <th className=\"border-b border-gray-200 bg-gray-50 px-4 py-2 font-semibold dark:border-gray-700 dark:bg-gray-800\">\n {children}\n </th>\n )\n },\n td({ children }) {\n return (\n <td className=\"border-b border-gray-200 px-4 py-2 dark:border-gray-700\">\n {children}\n </td>\n )\n },\n // Allow component overrides\n ...components,\n }}\n >\n {content}\n </ReactMarkdown>\n )\n}\n","import { DocsLayout } from './DocsLayout'\nimport { Markdown } from './Markdown'\nimport type { DocContent, DocsLayoutProps } from '../types'\n\ninterface DocsPageProps extends Omit<DocsLayoutProps, 'children' | 'title'> {\n content: DocContent\n}\n\n/**\n * Default documentation page component.\n * Renders markdown content within the DocsLayout.\n */\nexport function DocsPage({ content, ...layoutProps }: DocsPageProps) {\n return (\n <DocsLayout title={content?.title ?? ''} description={content?.description} {...layoutProps}>\n <Markdown content={content?.body ?? ''} />\n </DocsLayout>\n )\n}\n","import { Head, Link } from '@inertiajs/react'\nimport { createContext, useContext, useState, type ReactNode } from 'react'\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface HomeFeature {\n title: string\n description: ReactNode\n}\n\nexport interface HomePageContextValue {\n title: string\n tagline: string\n description: string\n installCommand: string\n ctaText: string\n ctaHref: string\n features: HomeFeature[]\n logoUrl?: string\n heroLogoUrl?: string\n footerLogoUrl?: string\n githubUrl?: string\n navLinks: Array<{ label: string; href: string }>\n}\n\nexport interface HomePageProps extends Omit<HomePageContextValue, 'navLinks'> {\n navLinks?: Array<{ label: string; href: string }>\n children?: ReactNode\n}\n\nexport interface HomeHeaderProps {\n renderLogo?: () => ReactNode\n}\n\nexport interface HomeFeaturesProps {\n renderFeature?: (\n feature: HomeFeature,\n index: number,\n DefaultFeature: typeof HomeFeatureItem\n ) => ReactNode\n}\n\nexport interface HomeFeatureItemProps {\n feature: HomeFeature\n index: number\n totalFeatures: number\n}\n\n// ============================================================================\n// Context\n// ============================================================================\n\nconst HomePageContext = createContext<HomePageContextValue | null>(null)\n\nfunction useHomePage(): HomePageContextValue {\n const context = useContext(HomePageContext)\n if (!context) {\n throw new Error('HomePage sub-components must be used within <HomePage>')\n }\n return context\n}\n\n// ============================================================================\n// Utility Components\n// ============================================================================\n\nfunction InstallCommand({ command }: { command: string }) {\n const [copied, setCopied] = useState(false)\n\n const copyToClipboard = async () => {\n await navigator.clipboard.writeText(command)\n setCopied(true)\n setTimeout(() => setCopied(false), 2000)\n }\n\n return (\n <button\n onClick={copyToClipboard}\n className=\"group relative flex items-center bg-black border border-black px-4 h-14 font-mono text-sm text-white hover:bg-white hover:text-black transition-colors cursor-pointer\"\n >\n <span className=\"text-primary-500 mr-2\">$</span>\n <span>{command}</span>\n <svg\n className={`ml-4 w-4 h-4 transition ${copied ? 'text-green-400' : 'opacity-50 group-hover:opacity-100'}`}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"\n />\n </svg>\n <span\n className={`absolute -top-8 left-1/2 -translate-x-1/2 bg-black text-white text-xs py-1 px-2 rounded transition-opacity duration-300 whitespace-nowrap ${\n copied ? 'opacity-100' : 'opacity-0'\n }`}\n >\n Copied!\n </span>\n </button>\n )\n}\n\nfunction GitHubIcon() {\n return (\n <svg className=\"w-6 h-6\" fill=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <path\n fillRule=\"evenodd\"\n d=\"M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z\"\n clipRule=\"evenodd\"\n />\n </svg>\n )\n}\n\n// ============================================================================\n// Sub-Components\n// ============================================================================\n\n/**\n * Default logo component that renders an image or text.\n */\nfunction DefaultLogo() {\n const { title, logoUrl } = useHomePage()\n\n if (logoUrl) {\n return (\n <Link href=\"/\" className=\"flex items-center\">\n <img src={logoUrl} alt={title} className=\"h-8\" />\n </Link>\n )\n }\n\n return (\n <Link href=\"/\" className=\"font-bold text-lg\">\n {title}\n </Link>\n )\n}\n\n/**\n * Navigation header for the homepage.\n * Accepts an optional renderLogo prop for custom logo rendering.\n */\nexport function HomeHeader({ renderLogo }: HomeHeaderProps = {}) {\n const { navLinks, githubUrl } = useHomePage()\n\n return (\n <nav className=\"fixed w-full z-50 bg-white border-b border-gray-200\">\n <div className=\"px-4 lg:px-10\">\n <div className=\"flex justify-between h-16 items-center\">\n {renderLogo ? renderLogo() : <DefaultLogo />}\n <div className=\"flex items-center space-x-8\">\n {navLinks.map((link) => (\n <Link\n key={link.href}\n href={link.href}\n className=\"text-black font-medium hover:text-primary-500 transition-colors\"\n >\n {link.label}\n </Link>\n ))}\n {githubUrl && (\n <a\n href={githubUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-black hover:text-primary-500 transition-colors\"\n >\n <GitHubIcon />\n </a>\n )}\n </div>\n </div>\n </div>\n </nav>\n )\n}\n\n/**\n * Hero section with title, tagline, description, and CTA.\n * If heroLogoUrl is provided, displays an image instead of text title.\n */\nexport function HomeHero() {\n const { title, tagline, description, ctaText, ctaHref, installCommand, heroLogoUrl } = useHomePage()\n\n return (\n <section className=\"pt-16\">\n <div className=\"px-4 lg:px-10 py-16 lg:py-24\">\n <div className=\"max-w-4xl\">\n <div className=\"mb-4 text-sm font-mono uppercase tracking-widest text-gray-500\">\n {tagline}\n </div>\n {heroLogoUrl ? (\n <h1 className=\"mb-6 lg:mb-8\">\n <img\n src={heroLogoUrl}\n alt={title}\n className=\"h-auto w-auto max-w-[580px]\"\n />\n </h1>\n ) : (\n <h1 className=\"text-5xl lg:text-7xl font-bold tracking-tight mb-6\">\n {title}\n </h1>\n )}\n <p className=\"text-xl lg:text-2xl text-gray-700 max-w-2xl leading-relaxed mb-8\">\n {description}\n </p>\n\n <div className=\"flex flex-col sm:flex-row gap-3\">\n <Link\n href={ctaHref}\n className=\"inline-flex items-center justify-center px-8 h-14 bg-black text-white font-bold text-lg hover:bg-primary-500 transition-colors border border-black\"\n >\n {ctaText}\n </Link>\n {installCommand && <InstallCommand command={installCommand} />}\n </div>\n </div>\n </div>\n </section>\n )\n}\n\n/**\n * Single feature item within the features grid.\n */\nexport function HomeFeatureItem({ feature, index, totalFeatures }: HomeFeatureItemProps) {\n return (\n <div\n className={`p-4 lg:p-10 border-b sm:border-b border-gray-200 ${\n index % 2 === 0 ? 'sm:border-r' : ''\n } ${index >= totalFeatures - 2 ? 'sm:border-b-0' : ''} ${\n index === totalFeatures - 1 && totalFeatures % 2 === 1 ? 'border-b-0' : ''\n }`}\n >\n <div className=\"text-5xl font-bold text-primary-500 mb-4\">\n {String(index + 1).padStart(2, '0')}\n </div>\n <h3 className=\"text-xl font-bold mb-2\">{feature.title}</h3>\n <p className=\"text-gray-600\">{feature.description}</p>\n </div>\n )\n}\n\n/**\n * Features section with customizable feature rendering.\n */\nexport function HomeFeatures({ renderFeature }: HomeFeaturesProps = {}) {\n const { title, features } = useHomePage()\n\n if (features.length === 0) {\n return null\n }\n\n return (\n <section className=\"border-t border-gray-200\">\n <div className=\"grid grid-cols-12\">\n <div className=\"col-span-12 lg:col-span-4 p-4 lg:p-10 border-b lg:border-b-0 lg:border-r border-gray-200\">\n <div className=\"text-sm font-mono uppercase tracking-widest text-gray-500 mb-4\">\n Features\n </div>\n <h2 className=\"text-4xl lg:text-5xl font-bold tracking-tight\">\n Why {title}?\n </h2>\n </div>\n\n <div className=\"col-span-12 lg:col-span-8 grid grid-cols-1 sm:grid-cols-2\">\n {features.map((feature, index) =>\n renderFeature ? (\n <div key={index}>\n {renderFeature(feature, index, HomeFeatureItem)}\n </div>\n ) : (\n <HomeFeatureItem\n key={index}\n feature={feature}\n index={index}\n totalFeatures={features.length}\n />\n )\n )}\n </div>\n </div>\n </section>\n )\n}\n\n/**\n * Call-to-action section.\n */\nexport function HomeCTA() {\n const { ctaHref } = useHomePage()\n\n return (\n <section className=\"border-t border-gray-200\">\n <div className=\"grid grid-cols-12 items-center\">\n <div className=\"col-span-12 lg:col-span-8 p-4 lg:p-10\">\n <h2 className=\"text-4xl lg:text-6xl font-bold tracking-tight mb-4\">\n Ready to start?\n </h2>\n <p className=\"text-xl text-gray-600 mb-8 max-w-2xl\">\n Get up and running in minutes. Check out our documentation to learn more.\n </p>\n <Link\n href={ctaHref}\n className=\"inline-flex items-center justify-center px-8 py-4 bg-primary-500 text-white font-bold text-lg hover:bg-black transition-colors border border-primary-500 hover:border-black\"\n >\n Read the Docs\n </Link>\n </div>\n <Link\n href={ctaHref}\n className=\"col-span-12 lg:col-span-4 h-full bg-primary-500 hidden lg:flex items-center justify-center p-4 lg:p-10 hover:bg-black transition-colors min-h-[200px]\"\n >\n <div className=\"text-white text-8xl font-bold\">→</div>\n </Link>\n </div>\n </section>\n )\n}\n\n/**\n * Footer section.\n */\nexport function HomeFooter() {\n const { title, logoUrl, footerLogoUrl, navLinks, githubUrl } = useHomePage()\n\n return (\n <footer className=\"border-t border-gray-200 py-8\">\n <div className=\"px-4 lg:px-10 flex flex-col md:flex-row justify-between items-center gap-6\">\n {(footerLogoUrl || logoUrl) && (\n <Link href=\"/\">\n <img src={footerLogoUrl || logoUrl} alt={title} className=\"h-6\" />\n </Link>\n )}\n <div className=\"flex gap-8 text-sm text-gray-600\">\n {navLinks.map((link) => (\n <Link key={link.href} href={link.href} className=\"hover:text-black transition-colors\">\n {link.label}\n </Link>\n ))}\n {githubUrl && (\n <a\n href={githubUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"hover:text-black transition-colors\"\n >\n GitHub\n </a>\n )}\n </div>\n </div>\n </footer>\n )\n}\n\n/**\n * Default layout when no children are provided.\n */\nfunction DefaultHomeLayout() {\n return (\n <>\n <HomeHeader />\n <HomeHero />\n <HomeFeatures />\n <HomeCTA />\n <HomeFooter />\n </>\n )\n}\n\n// ============================================================================\n// Main Component\n// ============================================================================\n\n/**\n * Homepage component for documentation sites.\n *\n * Can be used in two ways:\n *\n * 1. Simple - everything from config:\n * ```tsx\n * <HomePage {...props} />\n * ```\n *\n * 2. Composable - full control via children:\n * ```tsx\n * <HomePage {...props}>\n * <HomePage.Header />\n * <HomePage.Hero />\n * <MyCustomSection />\n * <HomePage.Features renderFeature={(feature, i, Default) => (\n * <Default feature={feature} index={i} totalFeatures={4} />\n * )} />\n * <HomePage.CTA />\n * <HomePage.Footer />\n * </HomePage>\n * ```\n */\nexport function HomePage({\n children,\n navLinks = [],\n ...props\n}: HomePageProps) {\n const contextValue: HomePageContextValue = {\n ...props,\n navLinks,\n }\n\n return (\n <HomePageContext.Provider value={contextValue}>\n <div className=\"min-h-screen bg-white\">\n <Head title={props.title} />\n {children || <DefaultHomeLayout />}\n </div>\n </HomePageContext.Provider>\n )\n}\n\n// Attach sub-components for compound component pattern\nHomePage.Header = HomeHeader\nHomePage.Hero = HomeHero\nHomePage.Features = HomeFeatures\nHomePage.Feature = HomeFeatureItem\nHomePage.CTA = HomeCTA\nHomePage.Footer = HomeFooter\n","import { createInertiaApp } from '@inertiajs/react'\nimport { createRoot, hydrateRoot } from 'react-dom/client'\nimport type { DocsAppConfig } from './types'\n\n/**\n * Create and mount an Inertia.js documentation app.\n *\n * @example\n * ```tsx\n * import { createDocsApp, DocsPage } from '@usecross/docs'\n *\n * createDocsApp({\n * pages: {\n * 'docs/DocsPage': DocsPage,\n * },\n * title: (title) => `${title} - My Docs`,\n * })\n * ```\n */\nexport function createDocsApp(config: DocsAppConfig): void {\n const { pages, title } = config\n\n // Disable scroll restoration on initial page load\n if (typeof window !== 'undefined') {\n window.history.scrollRestoration = 'manual'\n window.scrollTo(0, 0)\n }\n\n createInertiaApp({\n title: title ?? ((pageTitle) => (pageTitle ? `${pageTitle}` : 'Documentation')),\n resolve: (name) => {\n const page = pages[name]\n if (!page) {\n throw new Error(`Page component \"${name}\" not found`)\n }\n return page\n },\n setup({ el, App, props }) {\n if (el.hasChildNodes()) {\n hydrateRoot(el, <App {...props} />)\n } else {\n createRoot(el).render(<App {...props} />)\n }\n },\n })\n}\n"],"mappings":"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","names":["Link","useState","jsx","jsxs","jsx","jsxs","useState","Link","jsx","jsx","Head","Link","useState","Fragment","jsx","jsxs","GitHubIcon","jsx"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/CodeBlock.tsx","../src/lib/utils.ts","../src/lib/shiki.ts","../src/components/DocsLayout.tsx","../src/components/Sidebar.tsx","../src/components/Markdown.tsx","../src/components/DocsPage.tsx","../src/components/EmojiConfetti.tsx","../src/components/HomePage.tsx","../src/app.tsx"],"sourcesContent":["import { useEffect, useState } from 'react'\nimport { cn } from '../lib/utils'\nimport { getHighlighter } from '../lib/shiki'\nimport type { CodeBlockProps } from '../types'\n\n/**\n * Syntax-highlighted code block component using Shiki.\n */\nexport function CodeBlock({\n code,\n language = 'python',\n filename,\n showLineNumbers = false,\n theme = 'github-dark-dimmed',\n className,\n}: CodeBlockProps) {\n const [html, setHtml] = useState<string>('')\n const [copied, setCopied] = useState(false)\n\n useEffect(() => {\n async function highlight() {\n const highlighter = await getHighlighter()\n const langs = highlighter.getLoadedLanguages()\n const lang = langs.includes(language) ? language : 'text'\n const highlighted = highlighter.codeToHtml(code.trim(), {\n lang,\n theme,\n })\n setHtml(highlighted)\n }\n highlight()\n }, [code, language, theme])\n\n const copyToClipboard = async () => {\n await navigator.clipboard.writeText(code.trim())\n setCopied(true)\n setTimeout(() => setCopied(false), 2000)\n }\n\n return (\n <div className={cn('group relative overflow-hidden rounded-lg bg-[#24292f] not-prose', className)}>\n {filename && (\n <div className=\"flex items-center gap-2 border-b border-slate-700 bg-slate-900 px-4 py-2 text-sm text-slate-400\">\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\"\n />\n </svg>\n {filename}\n </div>\n )}\n <button\n onClick={copyToClipboard}\n className=\"absolute right-2 top-2 z-10 rounded-md bg-slate-700/50 px-2 py-1 text-xs text-slate-400 opacity-0 transition-opacity hover:bg-slate-600 hover:text-white group-hover:opacity-100\"\n >\n {copied ? 'Copied!' : 'Copy'}\n </button>\n {html ? (\n <div\n className={cn(\n 'overflow-x-auto text-sm [&_pre]:!m-0 [&_pre]:!bg-transparent [&_code]:!p-4',\n showLineNumbers && '[&_code]:grid [&_code]:grid-cols-[auto_1fr]'\n )}\n dangerouslySetInnerHTML={{ __html: html }}\n />\n ) : (\n <pre className=\"shiki overflow-x-auto !m-0 !bg-transparent\">\n <code className=\"block p-4 text-sm leading-relaxed text-gray-300\">{code.trim()}</code>\n </pre>\n )}\n </div>\n )\n}\n\n/**\n * Simple inline code component.\n */\nexport function InlineCode({ children }: { children: React.ReactNode }) {\n return (\n <code className=\"rounded bg-slate-100 px-1.5 py-0.5 text-sm font-medium text-slate-800\">\n {children}\n </code>\n )\n}\n","import { clsx, type ClassValue } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\n/**\n * Merge Tailwind CSS classes with clsx\n */\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","import { createHighlighterCore, type HighlighterCore } from 'shiki/core'\nimport { createJavaScriptRegexEngine } from 'shiki/engine/javascript'\n\nlet highlighterPromise: Promise<HighlighterCore> | null = null\n\n// Default languages to load\nconst defaultLangs = [\n import('shiki/langs/python.mjs'),\n import('shiki/langs/javascript.mjs'),\n import('shiki/langs/typescript.mjs'),\n import('shiki/langs/tsx.mjs'),\n import('shiki/langs/jsx.mjs'),\n import('shiki/langs/bash.mjs'),\n import('shiki/langs/shellscript.mjs'),\n import('shiki/langs/json.mjs'),\n import('shiki/langs/html.mjs'),\n import('shiki/langs/css.mjs'),\n import('shiki/langs/yaml.mjs'),\n import('shiki/langs/toml.mjs'),\n import('shiki/langs/markdown.mjs'),\n]\n\n// Default theme\nconst defaultTheme = import('shiki/themes/github-dark-dimmed.mjs')\n\n/**\n * Get or create a Shiki highlighter instance.\n * Uses a singleton pattern to avoid creating multiple highlighters.\n */\nexport function getHighlighter(): Promise<HighlighterCore> {\n if (!highlighterPromise) {\n highlighterPromise = createHighlighterCore({\n themes: [defaultTheme],\n langs: defaultLangs,\n engine: createJavaScriptRegexEngine(),\n })\n }\n return highlighterPromise\n}\n\n/**\n * Configure the highlighter with custom themes and languages.\n * Must be called before getHighlighter() is first called.\n */\nexport function configureHighlighter(options: {\n theme?: Promise<any>\n langs?: Promise<any>[]\n}): void {\n if (highlighterPromise) {\n console.warn('configureHighlighter called after highlighter was created')\n return\n }\n\n highlighterPromise = createHighlighterCore({\n themes: [options.theme ?? defaultTheme],\n langs: options.langs ?? defaultLangs,\n engine: createJavaScriptRegexEngine(),\n })\n}\n","import { Head, Link, usePage } from '@inertiajs/react'\nimport { useState } from 'react'\nimport { Sidebar } from './Sidebar'\nimport type { DocsLayoutProps, SharedProps } from '../types'\n\nfunction MobileMenuButton({ onClick, isOpen }: { onClick: () => void; isOpen: boolean }) {\n return (\n <button\n onClick={onClick}\n className=\"inline-flex items-center justify-center p-2 -ml-2 text-black hover:text-primary-500 lg:hidden\"\n aria-expanded={isOpen}\n >\n <span className=\"sr-only\">{isOpen ? 'Close menu' : 'Open menu'}</span>\n {isOpen ? (\n <svg className=\"h-6 w-6\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n ) : (\n <svg className=\"h-6 w-6\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 6h16M4 12h16M4 18h16\" />\n </svg>\n )}\n </button>\n )\n}\n\nfunction GitHubIcon() {\n return (\n <svg className=\"w-6 h-6\" fill=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <path\n fillRule=\"evenodd\"\n d=\"M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z\"\n clipRule=\"evenodd\"\n />\n </svg>\n )\n}\n\n/**\n * Full-featured documentation layout with sidebar, mobile menu, and header.\n */\nexport function DocsLayout({\n children,\n title,\n description: _description,\n logo,\n logoInverted,\n logoUrl: propLogoUrl,\n logoInvertedUrl: propLogoInvertedUrl,\n githubUrl: propGithubUrl,\n navLinks: propNavLinks,\n footer,\n}: DocsLayoutProps) {\n const sharedProps = usePage<{ props: SharedProps }>().props as unknown as SharedProps\n const { nav, currentPath } = sharedProps\n const [mobileMenuOpen, setMobileMenuOpen] = useState(false)\n\n // Merge props - component props take precedence over shared props from Python\n const logoUrl = propLogoUrl ?? sharedProps.logoUrl\n const logoInvertedUrl = propLogoInvertedUrl ?? sharedProps.logoInvertedUrl\n const githubUrl = propGithubUrl ?? sharedProps.githubUrl\n const navLinks = propNavLinks ?? sharedProps.navLinks ?? []\n\n // Determine which logo to display in header (prefer inverted/dark version)\n const headerLogo = logoInverted || logo || (logoInvertedUrl ? (\n <img src={logoInvertedUrl} alt=\"Logo\" className=\"h-8\" />\n ) : logoUrl ? (\n <img src={logoUrl} alt=\"Logo\" className=\"h-8\" />\n ) : null)\n\n // Determine which logo to display in footer (prefer footer-specific logo)\n const footerLogoUrl = sharedProps.footerLogoUrl || logoUrl\n const footerLogo = logo || (footerLogoUrl ? (\n <img src={footerLogoUrl} alt=\"Logo\" className=\"h-6\" />\n ) : null)\n\n return (\n <div className=\"min-h-screen bg-white flex flex-col\">\n <Head title={title} />\n\n {/* Fixed navigation */}\n <nav className=\"fixed w-full z-50 bg-white border-b border-gray-200\">\n <div className=\"px-4 lg:px-10\">\n <div className=\"flex justify-between h-16 items-center\">\n <div className=\"flex items-center gap-2\">\n <MobileMenuButton onClick={() => setMobileMenuOpen(!mobileMenuOpen)} isOpen={mobileMenuOpen} />\n {headerLogo ? (\n <Link href=\"/\" className=\"flex items-center\">\n {headerLogo}\n </Link>\n ) : (\n <Link href=\"/\" className=\"font-bold text-lg\">\n Docs\n </Link>\n )}\n </div>\n <div className=\"flex items-center space-x-8\">\n {navLinks.map((link) => (\n <Link\n key={link.href}\n href={link.href}\n className=\"text-black font-medium hover:text-primary-500 transition-colors\"\n >\n {link.label}\n </Link>\n ))}\n {githubUrl && (\n <a\n href={githubUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-black hover:text-primary-500 transition-colors\"\n >\n <GitHubIcon />\n </a>\n )}\n </div>\n </div>\n </div>\n </nav>\n\n {/* Mobile sidebar */}\n {mobileMenuOpen && (\n <div className=\"fixed inset-0 z-40 lg:hidden\">\n <div className=\"fixed inset-0 bg-black/50\" onClick={() => setMobileMenuOpen(false)} />\n <div className=\"fixed inset-y-0 left-0 w-72 overflow-y-auto bg-white px-4 lg:px-10 py-6 pt-20 border-r border-gray-200\">\n <Sidebar nav={nav} currentPath={currentPath} />\n </div>\n </div>\n )}\n\n {/* Main content area */}\n <div className=\"bg-white pt-16 w-full flex-1\">\n <div className=\"grid grid-cols-12\">\n {/* Desktop sidebar */}\n <aside className=\"hidden lg:block lg:col-span-3 xl:col-span-2 border-r border-gray-200 min-h-[calc(100vh-4rem)]\">\n <nav className=\"sticky top-16 px-4 lg:px-10 py-6 max-h-[calc(100vh-4rem)] overflow-y-auto\">\n <Sidebar nav={nav} currentPath={currentPath} />\n </nav>\n </aside>\n\n {/* Main content */}\n <main className=\"col-span-12 lg:col-span-9 xl:col-span-10 p-4 lg:px-10 lg:py-6\">\n <article className=\"prose prose-lg max-w-3xl prose-headings:font-bold prose-headings:tracking-tight prose-h1:text-3xl prose-h1:mb-4 prose-h2:text-2xl prose-h2:mt-10 first:prose-h2:mt-0 prose-h3:text-xl prose-a:text-primary-600 prose-a:no-underline hover:prose-a:underline prose-code:bg-gray-100 prose-code:px-1.5 prose-code:py-0.5 prose-code:rounded prose-code:before:content-none prose-code:after:content-none\">\n {children}\n </article>\n </main>\n </div>\n </div>\n\n {/* Footer */}\n {footer || (\n <footer className=\"border-t border-gray-200 py-8\">\n <div className=\"px-4 lg:px-10 flex flex-col md:flex-row justify-between items-center gap-6\">\n {footerLogo && <Link href=\"/\">{footerLogo}</Link>}\n <div className=\"flex gap-8 text-sm text-gray-600\">\n {navLinks.map((link) => (\n <Link key={link.href} href={link.href} className=\"hover:text-black transition-colors\">\n {link.label}\n </Link>\n ))}\n {githubUrl && (\n <a\n href={githubUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"hover:text-black transition-colors\"\n >\n GitHub\n </a>\n )}\n </div>\n </div>\n </footer>\n )}\n </div>\n )\n}\n","import { Link } from '@inertiajs/react'\nimport { cn } from '../lib/utils'\nimport type { SidebarProps } from '../types'\n\n/**\n * Documentation sidebar with section-based navigation.\n */\nexport function Sidebar({ nav, currentPath, className }: SidebarProps) {\n return (\n <nav className={cn('space-y-8', className)}>\n {nav.map((section) => (\n <div key={section.title}>\n <h3 className=\"mb-3 text-xs font-mono uppercase tracking-widest text-gray-500\">\n {section.title}\n </h3>\n <ul className=\"space-y-1 border-l-2 border-gray-200\">\n {section.items.map((item) => (\n <li key={item.href}>\n <Link\n href={item.href}\n className={cn(\n 'block border-l-2 py-1.5 pl-4 text-sm transition-colors -ml-0.5',\n currentPath === item.href\n ? 'border-primary-500 text-black font-bold'\n : 'border-transparent text-gray-600 hover:border-black hover:text-black'\n )}\n >\n {item.title}\n </Link>\n </li>\n ))}\n </ul>\n </div>\n ))}\n </nav>\n )\n}\n","import ReactMarkdown from 'react-markdown'\nimport remarkGfm from 'remark-gfm'\nimport rehypeRaw from 'rehype-raw'\nimport { CodeBlock } from './CodeBlock'\nimport type { MarkdownProps } from '../types'\n\n/**\n * Markdown renderer with syntax highlighting and GFM support.\n */\nexport function Markdown({ content, components }: MarkdownProps) {\n return (\n <ReactMarkdown\n remarkPlugins={[remarkGfm]}\n rehypePlugins={[rehypeRaw]}\n components={{\n // Override pre to avoid double wrapping with CodeBlock\n pre({ children }) {\n return <>{children}</>\n },\n // Custom code block rendering with syntax highlighting\n code({ node, className, children, ...props }) {\n const match = /language-(\\w+)/.exec(className || '')\n const isInline = !match && !className\n\n if (isInline) {\n return (\n <code\n className=\"rounded bg-gray-100 px-1.5 py-0.5 text-sm font-medium text-gray-800 dark:bg-gray-800 dark:text-gray-200\"\n {...props}\n >\n {children}\n </code>\n )\n }\n\n // Parse meta string from the code fence (e.g., ```python title=\"app.py\" showLineNumbers)\n const meta = (node?.data?.meta as string) || ''\n const titleMatch = /title=\"([^\"]+)\"/.exec(meta)\n const filename = titleMatch ? titleMatch[1] : undefined\n const showLineNumbers = meta.includes('showLineNumbers')\n\n return (\n <CodeBlock\n code={String(children).replace(/\\n$/, '')}\n language={match ? match[1] : 'text'}\n filename={filename}\n showLineNumbers={showLineNumbers}\n />\n )\n },\n // Custom link styling\n a({ href, children }) {\n const isExternal = href?.startsWith('http')\n return (\n <a\n href={href}\n className=\"text-primary-600 hover:text-primary-700 dark:text-primary-400 dark:hover:text-primary-300\"\n {...(isExternal ? { target: '_blank', rel: 'noopener noreferrer' } : {})}\n >\n {children}\n </a>\n )\n },\n // Tables\n table({ children }) {\n return (\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-left text-sm\">{children}</table>\n </div>\n )\n },\n th({ children }) {\n return (\n <th className=\"border-b border-gray-200 bg-gray-50 px-4 py-2 font-semibold dark:border-gray-700 dark:bg-gray-800\">\n {children}\n </th>\n )\n },\n td({ children }) {\n return (\n <td className=\"border-b border-gray-200 px-4 py-2 dark:border-gray-700\">\n {children}\n </td>\n )\n },\n // Allow component overrides\n ...components,\n }}\n >\n {content}\n </ReactMarkdown>\n )\n}\n","import { DocsLayout } from './DocsLayout'\nimport { Markdown } from './Markdown'\nimport type { DocContent, DocsLayoutProps } from '../types'\n\ninterface DocsPageProps extends Omit<DocsLayoutProps, 'children' | 'title'> {\n content: DocContent\n}\n\n/**\n * Default documentation page component.\n * Renders markdown content within the DocsLayout.\n */\nexport function DocsPage({ content, ...layoutProps }: DocsPageProps) {\n return (\n <DocsLayout title={content?.title ?? ''} description={content?.description} {...layoutProps}>\n <Markdown content={content?.body ?? ''} />\n </DocsLayout>\n )\n}\n","import { useState, useCallback } from 'react'\n\ninterface ConfettiParticle {\n id: number\n x: number\n y: number\n angle: number\n velocity: number\n spin: number\n scale: number\n}\n\nexport function EmojiConfetti({ children, emoji }: { children: React.ReactNode; emoji: string }) {\n const [particles, setParticles] = useState<ConfettiParticle[]>([])\n const [isActive, setIsActive] = useState(false)\n\n const triggerBurst = useCallback(() => {\n if (isActive) return\n setIsActive(true)\n\n const newParticles: ConfettiParticle[] = []\n const count = 15\n\n for (let i = 0; i < count; i++) {\n // Burst in all directions from center\n const angle = (i / count) * Math.PI * 2 + (Math.random() - 0.5) * 0.5\n newParticles.push({\n id: Date.now() + i,\n x: 50, // Start from center\n y: 50,\n angle,\n velocity: 80 + Math.random() * 60, // Distance to travel\n spin: (Math.random() - 0.5) * 720, // Random rotation\n scale: 0.7 + Math.random() * 0.6,\n })\n }\n setParticles(newParticles)\n\n setTimeout(() => {\n setParticles([])\n setIsActive(false)\n }, 1000)\n }, [isActive])\n\n return (\n <span\n className=\"relative inline-block\"\n onMouseEnter={triggerBurst}\n >\n {children}\n <span className=\"absolute inset-0 pointer-events-none overflow-visible\">\n {particles.map((p) => {\n const endX = p.x + Math.cos(p.angle) * p.velocity\n const endY = p.y + Math.sin(p.angle) * p.velocity\n\n return (\n <span\n key={p.id}\n className=\"absolute\"\n style={{\n left: '50%',\n top: '50%',\n fontSize: `${p.scale}rem`,\n transform: 'translate(-50%, -50%)',\n animation: `emojiConfettiBurst 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards`,\n '--end-x': `${(endX - 50)}px`,\n '--end-y': `${(endY - 50)}px`,\n '--spin': `${p.spin}deg`,\n } as React.CSSProperties}\n >\n {emoji}\n </span>\n )\n })}\n </span>\n </span>\n )\n}\n","import { Head, Link } from '@inertiajs/react'\nimport { createContext, useContext, useState, type ReactNode } from 'react'\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface HomeFeature {\n title: string\n description: ReactNode\n}\n\nexport interface HomePageContextValue {\n title: string\n tagline: string\n description: string\n installCommand: string\n ctaText: string\n ctaHref: string\n features: HomeFeature[]\n logoUrl?: string\n heroLogoUrl?: string\n footerLogoUrl?: string\n githubUrl?: string\n navLinks: Array<{ label: string; href: string }>\n}\n\nexport interface HomePageProps extends Omit<HomePageContextValue, 'navLinks'> {\n navLinks?: Array<{ label: string; href: string }>\n children?: ReactNode\n}\n\nexport interface HomeHeaderProps {\n renderLogo?: () => ReactNode\n}\n\nexport interface HomeFeaturesProps {\n renderFeature?: (\n feature: HomeFeature,\n index: number,\n DefaultFeature: typeof HomeFeatureItem\n ) => ReactNode\n}\n\nexport interface HomeFeatureItemProps {\n feature: HomeFeature\n index: number\n totalFeatures: number\n}\n\n// ============================================================================\n// Context\n// ============================================================================\n\nconst HomePageContext = createContext<HomePageContextValue | null>(null)\n\nfunction useHomePage(): HomePageContextValue {\n const context = useContext(HomePageContext)\n if (!context) {\n throw new Error('HomePage sub-components must be used within <HomePage>')\n }\n return context\n}\n\n// ============================================================================\n// Utility Components\n// ============================================================================\n\nfunction InstallCommand({ command }: { command: string }) {\n const [copied, setCopied] = useState(false)\n\n const copyToClipboard = async () => {\n await navigator.clipboard.writeText(command)\n setCopied(true)\n setTimeout(() => setCopied(false), 2000)\n }\n\n return (\n <button\n onClick={copyToClipboard}\n className=\"group relative flex items-center bg-black border border-black px-4 h-14 font-mono text-sm text-white hover:bg-white hover:text-black transition-colors cursor-pointer\"\n >\n <span className=\"text-primary-500 mr-2\">$</span>\n <span>{command}</span>\n <svg\n className={`ml-4 w-4 h-4 transition ${copied ? 'text-green-400' : 'opacity-50 group-hover:opacity-100'}`}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"\n />\n </svg>\n <span\n className={`absolute -top-8 left-1/2 -translate-x-1/2 bg-black text-white text-xs py-1 px-2 rounded transition-opacity duration-300 whitespace-nowrap ${\n copied ? 'opacity-100' : 'opacity-0'\n }`}\n >\n Copied!\n </span>\n </button>\n )\n}\n\nfunction GitHubIcon() {\n return (\n <svg className=\"w-6 h-6\" fill=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <path\n fillRule=\"evenodd\"\n d=\"M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z\"\n clipRule=\"evenodd\"\n />\n </svg>\n )\n}\n\n// ============================================================================\n// Sub-Components\n// ============================================================================\n\n/**\n * Default logo component that renders an image or text.\n */\nfunction DefaultLogo() {\n const { title, logoUrl } = useHomePage()\n\n if (logoUrl) {\n return (\n <Link href=\"/\" className=\"flex items-center\">\n <img src={logoUrl} alt={title} className=\"h-8\" />\n </Link>\n )\n }\n\n return (\n <Link href=\"/\" className=\"font-bold text-lg\">\n {title}\n </Link>\n )\n}\n\n/**\n * Navigation header for the homepage.\n * Accepts an optional renderLogo prop for custom logo rendering.\n */\nexport function HomeHeader({ renderLogo }: HomeHeaderProps = {}) {\n const { navLinks, githubUrl } = useHomePage()\n\n return (\n <nav className=\"fixed w-full z-50 bg-white border-b border-gray-200\">\n <div className=\"px-4 lg:px-10\">\n <div className=\"flex justify-between h-16 items-center\">\n {renderLogo ? renderLogo() : <DefaultLogo />}\n <div className=\"flex items-center space-x-8\">\n {navLinks.map((link) => (\n <Link\n key={link.href}\n href={link.href}\n className=\"text-black font-medium hover:text-primary-500 transition-colors\"\n >\n {link.label}\n </Link>\n ))}\n {githubUrl && (\n <a\n href={githubUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-black hover:text-primary-500 transition-colors\"\n >\n <GitHubIcon />\n </a>\n )}\n </div>\n </div>\n </div>\n </nav>\n )\n}\n\n/**\n * Hero section with title, tagline, description, and CTA.\n * If heroLogoUrl is provided, displays an image instead of text title.\n */\nexport function HomeHero() {\n const { title, tagline, description, ctaText, ctaHref, installCommand, heroLogoUrl } = useHomePage()\n\n return (\n <section className=\"pt-16\">\n <div className=\"px-4 lg:px-10 py-16 lg:py-24\">\n <div className=\"max-w-4xl\">\n <div className=\"mb-4 text-sm font-mono uppercase tracking-widest text-gray-500\">\n {tagline}\n </div>\n {heroLogoUrl ? (\n <h1 className=\"mb-6 lg:mb-8\">\n <img\n src={heroLogoUrl}\n alt={title}\n className=\"h-auto w-auto max-w-[580px]\"\n />\n </h1>\n ) : (\n <h1 className=\"text-5xl lg:text-7xl font-bold tracking-tight mb-6\">\n {title}\n </h1>\n )}\n <p className=\"text-xl lg:text-2xl text-gray-700 max-w-2xl leading-relaxed mb-8\">\n {description}\n </p>\n\n <div className=\"flex flex-col sm:flex-row gap-3\">\n <Link\n href={ctaHref}\n className=\"inline-flex items-center justify-center px-8 h-14 bg-black text-white font-bold text-lg hover:bg-primary-500 transition-colors border border-black\"\n >\n {ctaText}\n </Link>\n {installCommand && <InstallCommand command={installCommand} />}\n </div>\n </div>\n </div>\n </section>\n )\n}\n\n/**\n * Single feature item within the features grid.\n */\nexport function HomeFeatureItem({ feature, index, totalFeatures }: HomeFeatureItemProps) {\n return (\n <div\n className={`p-4 lg:p-10 border-b sm:border-b border-gray-200 ${\n index % 2 === 0 ? 'sm:border-r' : ''\n } ${index >= totalFeatures - 2 ? 'sm:border-b-0' : ''} ${\n index === totalFeatures - 1 && totalFeatures % 2 === 1 ? 'border-b-0' : ''\n }`}\n >\n <div className=\"text-5xl font-bold text-primary-500 mb-4\">\n {String(index + 1).padStart(2, '0')}\n </div>\n <h3 className=\"text-xl font-bold mb-2\">{feature.title}</h3>\n <p className=\"text-gray-600\">{feature.description}</p>\n </div>\n )\n}\n\n/**\n * Features section with customizable feature rendering.\n */\nexport function HomeFeatures({ renderFeature }: HomeFeaturesProps = {}) {\n const { title, features } = useHomePage()\n\n if (features.length === 0) {\n return null\n }\n\n return (\n <section className=\"border-t border-gray-200\">\n <div className=\"grid grid-cols-12\">\n <div className=\"col-span-12 lg:col-span-4 p-4 lg:p-10 border-b lg:border-b-0 lg:border-r border-gray-200\">\n <div className=\"text-sm font-mono uppercase tracking-widest text-gray-500 mb-4\">\n Features\n </div>\n <h2 className=\"text-4xl lg:text-5xl font-bold tracking-tight\">\n Why {title}?\n </h2>\n </div>\n\n <div className=\"col-span-12 lg:col-span-8 grid grid-cols-1 sm:grid-cols-2\">\n {features.map((feature, index) =>\n renderFeature ? (\n <div key={index}>\n {renderFeature(feature, index, HomeFeatureItem)}\n </div>\n ) : (\n <HomeFeatureItem\n key={index}\n feature={feature}\n index={index}\n totalFeatures={features.length}\n />\n )\n )}\n </div>\n </div>\n </section>\n )\n}\n\n/**\n * Call-to-action section.\n */\nexport function HomeCTA() {\n const { ctaHref } = useHomePage()\n\n return (\n <section className=\"border-t border-gray-200\">\n <div className=\"grid grid-cols-12 items-center\">\n <div className=\"col-span-12 lg:col-span-8 p-4 lg:p-10\">\n <h2 className=\"text-4xl lg:text-6xl font-bold tracking-tight mb-4\">\n Ready to start?\n </h2>\n <p className=\"text-xl text-gray-600 mb-8 max-w-2xl\">\n Get up and running in minutes. Check out our documentation to learn more.\n </p>\n <Link\n href={ctaHref}\n className=\"inline-flex items-center justify-center px-8 py-4 bg-primary-500 text-white font-bold text-lg hover:bg-black transition-colors border border-primary-500 hover:border-black\"\n >\n Read the Docs\n </Link>\n </div>\n <Link\n href={ctaHref}\n className=\"col-span-12 lg:col-span-4 h-full bg-primary-500 hidden lg:flex items-center justify-center p-4 lg:p-10 hover:bg-black transition-colors min-h-[200px]\"\n >\n <div className=\"text-white text-8xl font-bold\">→</div>\n </Link>\n </div>\n </section>\n )\n}\n\n/**\n * Footer section.\n */\nexport function HomeFooter() {\n const { title, logoUrl, footerLogoUrl, navLinks, githubUrl } = useHomePage()\n\n return (\n <footer className=\"border-t border-gray-200 py-8\">\n <div className=\"px-4 lg:px-10 flex flex-col md:flex-row justify-between items-center gap-6\">\n {(footerLogoUrl || logoUrl) && (\n <Link href=\"/\">\n <img src={footerLogoUrl || logoUrl} alt={title} className=\"h-6\" />\n </Link>\n )}\n <div className=\"flex gap-8 text-sm text-gray-600\">\n {navLinks.map((link) => (\n <Link key={link.href} href={link.href} className=\"hover:text-black transition-colors\">\n {link.label}\n </Link>\n ))}\n {githubUrl && (\n <a\n href={githubUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"hover:text-black transition-colors\"\n >\n GitHub\n </a>\n )}\n </div>\n </div>\n </footer>\n )\n}\n\n/**\n * Default layout when no children are provided.\n */\nfunction DefaultHomeLayout() {\n return (\n <>\n <HomeHeader />\n <HomeHero />\n <HomeFeatures />\n <HomeCTA />\n <HomeFooter />\n </>\n )\n}\n\n// ============================================================================\n// Main Component\n// ============================================================================\n\n/**\n * Homepage component for documentation sites.\n *\n * Can be used in two ways:\n *\n * 1. Simple - everything from config:\n * ```tsx\n * <HomePage {...props} />\n * ```\n *\n * 2. Composable - full control via children:\n * ```tsx\n * <HomePage {...props}>\n * <HomePage.Header />\n * <HomePage.Hero />\n * <MyCustomSection />\n * <HomePage.Features renderFeature={(feature, i, Default) => (\n * <Default feature={feature} index={i} totalFeatures={4} />\n * )} />\n * <HomePage.CTA />\n * <HomePage.Footer />\n * </HomePage>\n * ```\n */\nexport function HomePage({\n children,\n navLinks = [],\n ...props\n}: HomePageProps) {\n const contextValue: HomePageContextValue = {\n ...props,\n navLinks,\n }\n\n return (\n <HomePageContext.Provider value={contextValue}>\n <div className=\"min-h-screen bg-white\">\n <Head title={props.title} />\n {children || <DefaultHomeLayout />}\n </div>\n </HomePageContext.Provider>\n )\n}\n\n// Attach sub-components for compound component pattern\nHomePage.Header = HomeHeader\nHomePage.Hero = HomeHero\nHomePage.Features = HomeFeatures\nHomePage.Feature = HomeFeatureItem\nHomePage.CTA = HomeCTA\nHomePage.Footer = HomeFooter\n","import { createInertiaApp } from '@inertiajs/react'\nimport { createRoot, hydrateRoot } from 'react-dom/client'\nimport type { DocsAppConfig } from './types'\n\n/**\n * Create and mount an Inertia.js documentation app.\n *\n * @example\n * ```tsx\n * import { createDocsApp, DocsPage } from '@usecross/docs'\n *\n * createDocsApp({\n * pages: {\n * 'docs/DocsPage': DocsPage,\n * },\n * title: (title) => `${title} - My Docs`,\n * })\n * ```\n */\nexport function createDocsApp(config: DocsAppConfig): void {\n const { pages, title } = config\n\n // Disable scroll restoration on initial page load\n if (typeof window !== 'undefined') {\n window.history.scrollRestoration = 'manual'\n window.scrollTo(0, 0)\n }\n\n createInertiaApp({\n title: title ?? ((pageTitle) => (pageTitle ? `${pageTitle}` : 'Documentation')),\n resolve: (name) => {\n const page = pages[name]\n if (!page) {\n throw new Error(`Page component \"${name}\" not found`)\n }\n return page\n },\n setup({ el, App, props }) {\n if (el.hasChildNodes()) {\n hydrateRoot(el, <App {...props} />)\n } else {\n createRoot(el).render(<App {...props} />)\n }\n },\n })\n}\n"],"mappings":"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","names":["Link","useState","jsx","jsxs","jsx","jsxs","useState","Link","jsx","jsx","useState","jsx","jsxs","Head","Link","useState","Fragment","jsx","jsxs","GitHubIcon","jsx"]}
|
package/package.json
CHANGED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { useState, useCallback } from 'react'
|
|
2
|
+
|
|
3
|
+
interface ConfettiParticle {
|
|
4
|
+
id: number
|
|
5
|
+
x: number
|
|
6
|
+
y: number
|
|
7
|
+
angle: number
|
|
8
|
+
velocity: number
|
|
9
|
+
spin: number
|
|
10
|
+
scale: number
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function EmojiConfetti({ children, emoji }: { children: React.ReactNode; emoji: string }) {
|
|
14
|
+
const [particles, setParticles] = useState<ConfettiParticle[]>([])
|
|
15
|
+
const [isActive, setIsActive] = useState(false)
|
|
16
|
+
|
|
17
|
+
const triggerBurst = useCallback(() => {
|
|
18
|
+
if (isActive) return
|
|
19
|
+
setIsActive(true)
|
|
20
|
+
|
|
21
|
+
const newParticles: ConfettiParticle[] = []
|
|
22
|
+
const count = 15
|
|
23
|
+
|
|
24
|
+
for (let i = 0; i < count; i++) {
|
|
25
|
+
// Burst in all directions from center
|
|
26
|
+
const angle = (i / count) * Math.PI * 2 + (Math.random() - 0.5) * 0.5
|
|
27
|
+
newParticles.push({
|
|
28
|
+
id: Date.now() + i,
|
|
29
|
+
x: 50, // Start from center
|
|
30
|
+
y: 50,
|
|
31
|
+
angle,
|
|
32
|
+
velocity: 80 + Math.random() * 60, // Distance to travel
|
|
33
|
+
spin: (Math.random() - 0.5) * 720, // Random rotation
|
|
34
|
+
scale: 0.7 + Math.random() * 0.6,
|
|
35
|
+
})
|
|
36
|
+
}
|
|
37
|
+
setParticles(newParticles)
|
|
38
|
+
|
|
39
|
+
setTimeout(() => {
|
|
40
|
+
setParticles([])
|
|
41
|
+
setIsActive(false)
|
|
42
|
+
}, 1000)
|
|
43
|
+
}, [isActive])
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<span
|
|
47
|
+
className="relative inline-block"
|
|
48
|
+
onMouseEnter={triggerBurst}
|
|
49
|
+
>
|
|
50
|
+
{children}
|
|
51
|
+
<span className="absolute inset-0 pointer-events-none overflow-visible">
|
|
52
|
+
{particles.map((p) => {
|
|
53
|
+
const endX = p.x + Math.cos(p.angle) * p.velocity
|
|
54
|
+
const endY = p.y + Math.sin(p.angle) * p.velocity
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<span
|
|
58
|
+
key={p.id}
|
|
59
|
+
className="absolute"
|
|
60
|
+
style={{
|
|
61
|
+
left: '50%',
|
|
62
|
+
top: '50%',
|
|
63
|
+
fontSize: `${p.scale}rem`,
|
|
64
|
+
transform: 'translate(-50%, -50%)',
|
|
65
|
+
animation: `emojiConfettiBurst 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards`,
|
|
66
|
+
'--end-x': `${(endX - 50)}px`,
|
|
67
|
+
'--end-y': `${(endY - 50)}px`,
|
|
68
|
+
'--spin': `${p.spin}deg`,
|
|
69
|
+
} as React.CSSProperties}
|
|
70
|
+
>
|
|
71
|
+
{emoji}
|
|
72
|
+
</span>
|
|
73
|
+
)
|
|
74
|
+
})}
|
|
75
|
+
</span>
|
|
76
|
+
</span>
|
|
77
|
+
)
|
|
78
|
+
}
|
package/src/components/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { CodeBlock, InlineCode } from './CodeBlock'
|
|
2
2
|
export { DocsLayout } from './DocsLayout'
|
|
3
3
|
export { DocsPage } from './DocsPage'
|
|
4
|
+
export { EmojiConfetti } from './EmojiConfetti'
|
|
4
5
|
export { HomePage } from './HomePage'
|
|
5
6
|
export { Markdown } from './Markdown'
|
|
6
7
|
export { Sidebar } from './Sidebar'
|
package/src/index.ts
CHANGED
package/src/styles.css
CHANGED
|
@@ -126,3 +126,25 @@
|
|
|
126
126
|
::-webkit-scrollbar-thumb:hover {
|
|
127
127
|
@apply bg-gray-400;
|
|
128
128
|
}
|
|
129
|
+
|
|
130
|
+
/* Emoji confetti animation */
|
|
131
|
+
@keyframes emojiConfettiBurst {
|
|
132
|
+
0% {
|
|
133
|
+
transform: translate(-50%, -50%) scale(0.3) rotate(0deg);
|
|
134
|
+
opacity: 1;
|
|
135
|
+
}
|
|
136
|
+
20% {
|
|
137
|
+
opacity: 1;
|
|
138
|
+
transform: translate(
|
|
139
|
+
calc(-50% + var(--end-x) * 0.3),
|
|
140
|
+
calc(-50% + var(--end-y) * 0.3)
|
|
141
|
+
) scale(1) rotate(calc(var(--spin) * 0.3));
|
|
142
|
+
}
|
|
143
|
+
100% {
|
|
144
|
+
transform: translate(
|
|
145
|
+
calc(-50% + var(--end-x)),
|
|
146
|
+
calc(-50% + var(--end-y) + 30px)
|
|
147
|
+
) scale(0.6) rotate(var(--spin));
|
|
148
|
+
opacity: 0;
|
|
149
|
+
}
|
|
150
|
+
}
|