@usecross/docs 0.3.0 → 0.4.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/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { C as CodeBlockProps, D as DocsLayoutProps, a as DocContent, M as MarkdownProps, S as SidebarProps, b as DocsAppConfig } from './types-Vodb50Bj.js';
3
- export { N as NavItem, c as NavSection, d as SharedProps } from './types-Vodb50Bj.js';
2
+ import { C as CodeBlockProps, D as DocsLayoutProps, a as DocContent, M as MarkdownProps, S as SidebarProps, b as DocsAppConfig } from './types-CCdOzu28.js';
3
+ export { N as NavItem, c as NavSection, d as SharedProps } from './types-CCdOzu28.js';
4
4
  import { ReactNode } from 'react';
5
5
  import { ClassValue } from 'clsx';
6
6
  import { HighlighterCore } from 'shiki/core';
package/dist/index.js CHANGED
@@ -251,12 +251,20 @@ import remarkGfm from "remark-gfm";
251
251
  import rehypeRaw from "rehype-raw";
252
252
  import { Fragment, jsx as jsx4 } from "react/jsx-runtime";
253
253
  function Markdown({ content, components }) {
254
+ const lowercaseComponents = components ? Object.entries(components).reduce(
255
+ (acc, [name, Component]) => {
256
+ acc[name.toLowerCase()] = Component;
257
+ return acc;
258
+ },
259
+ {}
260
+ ) : {};
254
261
  return /* @__PURE__ */ jsx4(
255
262
  ReactMarkdown,
256
263
  {
257
264
  remarkPlugins: [remarkGfm],
258
265
  rehypePlugins: [rehypeRaw],
259
266
  components: {
267
+ ...lowercaseComponents,
260
268
  // Override pre to avoid double wrapping with CodeBlock
261
269
  pre({ children }) {
262
270
  return /* @__PURE__ */ jsx4(Fragment, { children });
@@ -311,24 +319,37 @@ function Markdown({ content, components }) {
311
319
  },
312
320
  td({ children }) {
313
321
  return /* @__PURE__ */ jsx4("td", { className: "border-b border-gray-200 px-4 py-2 dark:border-gray-700", children });
314
- },
315
- // Allow component overrides
316
- ...components
322
+ }
317
323
  },
318
324
  children: content
319
325
  }
320
326
  );
321
327
  }
322
328
 
323
- // src/components/DocsPage.tsx
329
+ // src/context/ComponentsContext.tsx
330
+ import { createContext, useContext } from "react";
324
331
  import { jsx as jsx5 } from "react/jsx-runtime";
332
+ var ComponentsContext = createContext({});
333
+ function ComponentsProvider({
334
+ children,
335
+ components
336
+ }) {
337
+ return /* @__PURE__ */ jsx5(ComponentsContext.Provider, { value: { components }, children });
338
+ }
339
+ function useComponents() {
340
+ return useContext(ComponentsContext);
341
+ }
342
+
343
+ // src/components/DocsPage.tsx
344
+ import { jsx as jsx6 } from "react/jsx-runtime";
325
345
  function DocsPage({ content, ...layoutProps }) {
326
- return /* @__PURE__ */ jsx5(DocsLayout, { title: content?.title ?? "", description: content?.description, ...layoutProps, children: /* @__PURE__ */ jsx5(Markdown, { content: content?.body ?? "" }) });
346
+ const { components } = useComponents();
347
+ return /* @__PURE__ */ jsx6(DocsLayout, { title: content?.title ?? "", description: content?.description, ...layoutProps, children: /* @__PURE__ */ jsx6(Markdown, { content: content?.body ?? "", components }) });
327
348
  }
328
349
 
329
350
  // src/components/EmojiConfetti.tsx
330
351
  import { useState as useState3, useCallback } from "react";
331
- import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
352
+ import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
332
353
  function EmojiConfetti({ children, emoji }) {
333
354
  const [particles, setParticles] = useState3([]);
334
355
  const [isActive, setIsActive] = useState3(false);
@@ -365,10 +386,10 @@ function EmojiConfetti({ children, emoji }) {
365
386
  onMouseEnter: triggerBurst,
366
387
  children: [
367
388
  children,
368
- /* @__PURE__ */ jsx6("span", { className: "absolute inset-0 pointer-events-none overflow-visible", children: particles.map((p) => {
389
+ /* @__PURE__ */ jsx7("span", { className: "absolute inset-0 pointer-events-none overflow-visible", children: particles.map((p) => {
369
390
  const endX = p.x + Math.cos(p.angle) * p.velocity;
370
391
  const endY = p.y + Math.sin(p.angle) * p.velocity;
371
- return /* @__PURE__ */ jsx6(
392
+ return /* @__PURE__ */ jsx7(
372
393
  "span",
373
394
  {
374
395
  className: "absolute",
@@ -394,11 +415,11 @@ function EmojiConfetti({ children, emoji }) {
394
415
 
395
416
  // src/components/HomePage.tsx
396
417
  import { Head as Head2, Link as Link3 } from "@inertiajs/react";
397
- import { createContext, useContext, useState as useState4 } from "react";
398
- import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
399
- var HomePageContext = createContext(null);
418
+ import { createContext as createContext2, useContext as useContext2, useState as useState4 } from "react";
419
+ import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
420
+ var HomePageContext = createContext2(null);
400
421
  function useHomePage() {
401
- const context = useContext(HomePageContext);
422
+ const context = useContext2(HomePageContext);
402
423
  if (!context) {
403
424
  throw new Error("HomePage sub-components must be used within <HomePage>");
404
425
  }
@@ -417,16 +438,16 @@ function InstallCommand({ command }) {
417
438
  onClick: copyToClipboard,
418
439
  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",
419
440
  children: [
420
- /* @__PURE__ */ jsx7("span", { className: "text-primary-500 mr-2", children: "$" }),
421
- /* @__PURE__ */ jsx7("span", { children: command }),
422
- /* @__PURE__ */ jsx7(
441
+ /* @__PURE__ */ jsx8("span", { className: "text-primary-500 mr-2", children: "$" }),
442
+ /* @__PURE__ */ jsx8("span", { children: command }),
443
+ /* @__PURE__ */ jsx8(
423
444
  "svg",
424
445
  {
425
446
  className: `ml-4 w-4 h-4 transition ${copied ? "text-green-400" : "opacity-50 group-hover:opacity-100"}`,
426
447
  fill: "none",
427
448
  stroke: "currentColor",
428
449
  viewBox: "0 0 24 24",
429
- children: /* @__PURE__ */ jsx7(
450
+ children: /* @__PURE__ */ jsx8(
430
451
  "path",
431
452
  {
432
453
  strokeLinecap: "round",
@@ -437,7 +458,7 @@ function InstallCommand({ command }) {
437
458
  )
438
459
  }
439
460
  ),
440
- /* @__PURE__ */ jsx7(
461
+ /* @__PURE__ */ jsx8(
441
462
  "span",
442
463
  {
443
464
  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"}`,
@@ -449,7 +470,7 @@ function InstallCommand({ command }) {
449
470
  );
450
471
  }
451
472
  function GitHubIcon2() {
452
- return /* @__PURE__ */ jsx7("svg", { className: "w-6 h-6", fill: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ jsx7(
473
+ return /* @__PURE__ */ jsx8("svg", { className: "w-6 h-6", fill: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ jsx8(
453
474
  "path",
454
475
  {
455
476
  fillRule: "evenodd",
@@ -461,16 +482,16 @@ function GitHubIcon2() {
461
482
  function DefaultLogo() {
462
483
  const { title, logoUrl } = useHomePage();
463
484
  if (logoUrl) {
464
- return /* @__PURE__ */ jsx7(Link3, { href: "/", className: "flex items-center", children: /* @__PURE__ */ jsx7("img", { src: logoUrl, alt: title, className: "h-8" }) });
485
+ return /* @__PURE__ */ jsx8(Link3, { href: "/", className: "flex items-center", children: /* @__PURE__ */ jsx8("img", { src: logoUrl, alt: title, className: "h-8" }) });
465
486
  }
466
- return /* @__PURE__ */ jsx7(Link3, { href: "/", className: "font-bold text-lg", children: title });
487
+ return /* @__PURE__ */ jsx8(Link3, { href: "/", className: "font-bold text-lg", children: title });
467
488
  }
468
489
  function HomeHeader({ renderLogo } = {}) {
469
490
  const { navLinks, githubUrl } = useHomePage();
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, {}),
491
+ return /* @__PURE__ */ jsx8("nav", { className: "fixed w-full z-50 bg-white border-b border-gray-200", children: /* @__PURE__ */ jsx8("div", { className: "px-4 lg:px-10", children: /* @__PURE__ */ jsxs5("div", { className: "flex justify-between h-16 items-center", children: [
492
+ renderLogo ? renderLogo() : /* @__PURE__ */ jsx8(DefaultLogo, {}),
472
493
  /* @__PURE__ */ jsxs5("div", { className: "flex items-center space-x-8", children: [
473
- navLinks.map((link) => /* @__PURE__ */ jsx7(
494
+ navLinks.map((link) => /* @__PURE__ */ jsx8(
474
495
  Link3,
475
496
  {
476
497
  href: link.href,
@@ -479,14 +500,14 @@ function HomeHeader({ renderLogo } = {}) {
479
500
  },
480
501
  link.href
481
502
  )),
482
- githubUrl && /* @__PURE__ */ jsx7(
503
+ githubUrl && /* @__PURE__ */ jsx8(
483
504
  "a",
484
505
  {
485
506
  href: githubUrl,
486
507
  target: "_blank",
487
508
  rel: "noopener noreferrer",
488
509
  className: "text-black hover:text-primary-500 transition-colors",
489
- children: /* @__PURE__ */ jsx7(GitHubIcon2, {})
510
+ children: /* @__PURE__ */ jsx8(GitHubIcon2, {})
490
511
  }
491
512
  )
492
513
  ] })
@@ -494,19 +515,19 @@ function HomeHeader({ renderLogo } = {}) {
494
515
  }
495
516
  function HomeHero() {
496
517
  const { title, tagline, description, ctaText, ctaHref, installCommand, heroLogoUrl } = useHomePage();
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(
518
+ return /* @__PURE__ */ jsx8("section", { className: "pt-16", children: /* @__PURE__ */ jsx8("div", { className: "px-4 lg:px-10 py-16 lg:py-24", children: /* @__PURE__ */ jsxs5("div", { className: "max-w-4xl", children: [
519
+ /* @__PURE__ */ jsx8("div", { className: "mb-4 text-sm font-mono uppercase tracking-widest text-gray-500", children: tagline }),
520
+ heroLogoUrl ? /* @__PURE__ */ jsx8("h1", { className: "mb-6 lg:mb-8", children: /* @__PURE__ */ jsx8(
500
521
  "img",
501
522
  {
502
523
  src: heroLogoUrl,
503
524
  alt: title,
504
525
  className: "h-auto w-auto max-w-[580px]"
505
526
  }
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 }),
527
+ ) }) : /* @__PURE__ */ jsx8("h1", { className: "text-5xl lg:text-7xl font-bold tracking-tight mb-6", children: title }),
528
+ /* @__PURE__ */ jsx8("p", { className: "text-xl lg:text-2xl text-gray-700 max-w-2xl leading-relaxed mb-8", children: description }),
508
529
  /* @__PURE__ */ jsxs5("div", { className: "flex flex-col sm:flex-row gap-3", children: [
509
- /* @__PURE__ */ jsx7(
530
+ /* @__PURE__ */ jsx8(
510
531
  Link3,
511
532
  {
512
533
  href: ctaHref,
@@ -514,7 +535,7 @@ function HomeHero() {
514
535
  children: ctaText
515
536
  }
516
537
  ),
517
- installCommand && /* @__PURE__ */ jsx7(InstallCommand, { command: installCommand })
538
+ installCommand && /* @__PURE__ */ jsx8(InstallCommand, { command: installCommand })
518
539
  ] })
519
540
  ] }) }) });
520
541
  }
@@ -524,9 +545,9 @@ function HomeFeatureItem({ feature, index, totalFeatures }) {
524
545
  {
525
546
  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" : ""}`,
526
547
  children: [
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 })
548
+ /* @__PURE__ */ jsx8("div", { className: "text-5xl font-bold text-primary-500 mb-4", children: String(index + 1).padStart(2, "0") }),
549
+ /* @__PURE__ */ jsx8("h3", { className: "text-xl font-bold mb-2", children: feature.title }),
550
+ /* @__PURE__ */ jsx8("p", { className: "text-gray-600", children: feature.description })
530
551
  ]
531
552
  }
532
553
  );
@@ -536,17 +557,17 @@ function HomeFeatures({ renderFeature } = {}) {
536
557
  if (features.length === 0) {
537
558
  return null;
538
559
  }
539
- return /* @__PURE__ */ jsx7("section", { className: "border-t border-gray-200", children: /* @__PURE__ */ jsxs5("div", { className: "grid grid-cols-12", children: [
560
+ return /* @__PURE__ */ jsx8("section", { className: "border-t border-gray-200", children: /* @__PURE__ */ jsxs5("div", { className: "grid grid-cols-12", children: [
540
561
  /* @__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" }),
562
+ /* @__PURE__ */ jsx8("div", { className: "text-sm font-mono uppercase tracking-widest text-gray-500 mb-4", children: "Features" }),
542
563
  /* @__PURE__ */ jsxs5("h2", { className: "text-4xl lg:text-5xl font-bold tracking-tight", children: [
543
564
  "Why ",
544
565
  title,
545
566
  "?"
546
567
  ] })
547
568
  ] }),
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(
569
+ /* @__PURE__ */ jsx8("div", { className: "col-span-12 lg:col-span-8 grid grid-cols-1 sm:grid-cols-2", children: features.map(
570
+ (feature, index) => renderFeature ? /* @__PURE__ */ jsx8("div", { children: renderFeature(feature, index, HomeFeatureItem) }, index) : /* @__PURE__ */ jsx8(
550
571
  HomeFeatureItem,
551
572
  {
552
573
  feature,
@@ -560,11 +581,11 @@ function HomeFeatures({ renderFeature } = {}) {
560
581
  }
561
582
  function HomeCTA() {
562
583
  const { ctaHref } = useHomePage();
563
- return /* @__PURE__ */ jsx7("section", { className: "border-t border-gray-200", children: /* @__PURE__ */ jsxs5("div", { className: "grid grid-cols-12 items-center", children: [
584
+ return /* @__PURE__ */ jsx8("section", { className: "border-t border-gray-200", children: /* @__PURE__ */ jsxs5("div", { className: "grid grid-cols-12 items-center", children: [
564
585
  /* @__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(
586
+ /* @__PURE__ */ jsx8("h2", { className: "text-4xl lg:text-6xl font-bold tracking-tight mb-4", children: "Ready to start?" }),
587
+ /* @__PURE__ */ jsx8("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." }),
588
+ /* @__PURE__ */ jsx8(
568
589
  Link3,
569
590
  {
570
591
  href: ctaHref,
@@ -573,23 +594,23 @@ function HomeCTA() {
573
594
  }
574
595
  )
575
596
  ] }),
576
- /* @__PURE__ */ jsx7(
597
+ /* @__PURE__ */ jsx8(
577
598
  Link3,
578
599
  {
579
600
  href: ctaHref,
580
601
  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]",
581
- children: /* @__PURE__ */ jsx7("div", { className: "text-white text-8xl font-bold", children: "\u2192" })
602
+ children: /* @__PURE__ */ jsx8("div", { className: "text-white text-8xl font-bold", children: "\u2192" })
582
603
  }
583
604
  )
584
605
  ] }) });
585
606
  }
586
607
  function HomeFooter() {
587
608
  const { title, logoUrl, footerLogoUrl, navLinks, githubUrl } = useHomePage();
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" }) }),
609
+ return /* @__PURE__ */ jsx8("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: [
610
+ (footerLogoUrl || logoUrl) && /* @__PURE__ */ jsx8(Link3, { href: "/", children: /* @__PURE__ */ jsx8("img", { src: footerLogoUrl || logoUrl, alt: title, className: "h-6" }) }),
590
611
  /* @__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(
612
+ navLinks.map((link) => /* @__PURE__ */ jsx8(Link3, { href: link.href, className: "hover:text-black transition-colors", children: link.label }, link.href)),
613
+ githubUrl && /* @__PURE__ */ jsx8(
593
614
  "a",
594
615
  {
595
616
  href: githubUrl,
@@ -604,11 +625,11 @@ function HomeFooter() {
604
625
  }
605
626
  function DefaultHomeLayout() {
606
627
  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, {})
628
+ /* @__PURE__ */ jsx8(HomeHeader, {}),
629
+ /* @__PURE__ */ jsx8(HomeHero, {}),
630
+ /* @__PURE__ */ jsx8(HomeFeatures, {}),
631
+ /* @__PURE__ */ jsx8(HomeCTA, {}),
632
+ /* @__PURE__ */ jsx8(HomeFooter, {})
612
633
  ] });
613
634
  }
614
635
  function HomePage({
@@ -620,9 +641,9 @@ function HomePage({
620
641
  ...props,
621
642
  navLinks
622
643
  };
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, {})
644
+ return /* @__PURE__ */ jsx8(HomePageContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs5("div", { className: "min-h-screen bg-white", children: [
645
+ /* @__PURE__ */ jsx8(Head2, { title: props.title }),
646
+ children || /* @__PURE__ */ jsx8(DefaultHomeLayout, {})
626
647
  ] }) });
627
648
  }
628
649
  HomePage.Header = HomeHeader;
@@ -635,9 +656,9 @@ HomePage.Footer = HomeFooter;
635
656
  // src/app.tsx
636
657
  import { createInertiaApp } from "@inertiajs/react";
637
658
  import { createRoot, hydrateRoot } from "react-dom/client";
638
- import { jsx as jsx8 } from "react/jsx-runtime";
659
+ import { jsx as jsx9 } from "react/jsx-runtime";
639
660
  function createDocsApp(config) {
640
- const { pages, title } = config;
661
+ const { pages, title, components } = config;
641
662
  if (typeof window !== "undefined") {
642
663
  window.history.scrollRestoration = "manual";
643
664
  window.scrollTo(0, 0);
@@ -652,10 +673,11 @@ function createDocsApp(config) {
652
673
  return page;
653
674
  },
654
675
  setup({ el, App, props }) {
676
+ const appElement = /* @__PURE__ */ jsx9(ComponentsProvider, { components, children: /* @__PURE__ */ jsx9(App, { ...props }) });
655
677
  if (el.hasChildNodes()) {
656
- hydrateRoot(el, /* @__PURE__ */ jsx8(App, { ...props }));
678
+ hydrateRoot(el, appElement);
657
679
  } else {
658
- createRoot(el).render(/* @__PURE__ */ jsx8(App, { ...props }));
680
+ createRoot(el).render(appElement);
659
681
  }
660
682
  }
661
683
  });
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/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\">&rarr;</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"]}
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/context/ComponentsContext.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 // Create lowercase mappings for custom components\n // HTML tag names are case-insensitive, so <TerminalExample> becomes <terminalexample>\n const lowercaseComponents = components\n ? Object.entries(components).reduce(\n (acc, [name, Component]) => {\n acc[name.toLowerCase()] = Component\n return acc\n },\n {} as Record<string, React.ComponentType<any>>\n )\n : {}\n\n return (\n <ReactMarkdown\n remarkPlugins={[remarkGfm]}\n rehypePlugins={[rehypeRaw]}\n components={{\n ...lowercaseComponents,\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 }}\n >\n {content}\n </ReactMarkdown>\n )\n}\n","import React, { createContext, useContext } from 'react'\n\ninterface ComponentsContextValue {\n components?: Record<string, React.ComponentType<any>>\n}\n\nconst ComponentsContext = createContext<ComponentsContextValue>({})\n\nexport function ComponentsProvider({\n children,\n components,\n}: {\n children: React.ReactNode\n components?: Record<string, React.ComponentType<any>>\n}) {\n return (\n <ComponentsContext.Provider value={{ components }}>\n {children}\n </ComponentsContext.Provider>\n )\n}\n\nexport function useComponents() {\n return useContext(ComponentsContext)\n}\n","import { DocsLayout } from './DocsLayout'\nimport { Markdown } from './Markdown'\nimport type { DocContent, DocsLayoutProps } from '../types'\nimport { useComponents } from '../context/ComponentsContext'\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 const { components } = useComponents()\n\n return (\n <DocsLayout title={content?.title ?? ''} description={content?.description} {...layoutProps}>\n <Markdown content={content?.body ?? ''} components={components} />\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\">&rarr;</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'\nimport { ComponentsProvider } from './context/ComponentsContext'\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, components } = 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 const appElement = (\n <ComponentsProvider components={components}>\n <App {...props} />\n </ComponentsProvider>\n )\n\n if (el.hasChildNodes()) {\n hydrateRoot(el, appElement)\n } else {\n createRoot(el).render(appElement)\n }\n },\n })\n}\n"],"mappings":"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","names":["Link","useState","jsx","jsxs","jsx","jsxs","useState","Link","jsx","jsx","jsx","useState","jsx","jsxs","Head","Link","createContext","useContext","useState","Fragment","jsx","jsxs","GitHubIcon","jsx"]}
package/dist/ssr.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { b as DocsAppConfig } from './types-Vodb50Bj.js';
1
+ import { b as DocsAppConfig } from './types-CCdOzu28.js';
2
2
  import 'react';
3
3
 
4
4
  /**
@@ -86,6 +86,8 @@ interface CodeBlockProps {
86
86
  interface DocsAppConfig {
87
87
  pages: Record<string, React.ComponentType<any>>;
88
88
  title?: (pageTitle: string) => string;
89
+ /** Custom components to use in markdown (e.g., Alert, Card, etc.) */
90
+ components?: Record<string, React.ComponentType<any>>;
89
91
  }
90
92
 
91
93
  export type { CodeBlockProps as C, DocsLayoutProps as D, MarkdownProps as M, NavItem as N, SidebarProps as S, DocContent as a, DocsAppConfig as b, NavSection as c, SharedProps as d };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usecross/docs",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Documentation framework built on Cross-Inertia",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
package/src/app.tsx CHANGED
@@ -1,6 +1,7 @@
1
1
  import { createInertiaApp } from '@inertiajs/react'
2
2
  import { createRoot, hydrateRoot } from 'react-dom/client'
3
3
  import type { DocsAppConfig } from './types'
4
+ import { ComponentsProvider } from './context/ComponentsContext'
4
5
 
5
6
  /**
6
7
  * Create and mount an Inertia.js documentation app.
@@ -18,7 +19,7 @@ import type { DocsAppConfig } from './types'
18
19
  * ```
19
20
  */
20
21
  export function createDocsApp(config: DocsAppConfig): void {
21
- const { pages, title } = config
22
+ const { pages, title, components } = config
22
23
 
23
24
  // Disable scroll restoration on initial page load
24
25
  if (typeof window !== 'undefined') {
@@ -36,10 +37,16 @@ export function createDocsApp(config: DocsAppConfig): void {
36
37
  return page
37
38
  },
38
39
  setup({ el, App, props }) {
40
+ const appElement = (
41
+ <ComponentsProvider components={components}>
42
+ <App {...props} />
43
+ </ComponentsProvider>
44
+ )
45
+
39
46
  if (el.hasChildNodes()) {
40
- hydrateRoot(el, <App {...props} />)
47
+ hydrateRoot(el, appElement)
41
48
  } else {
42
- createRoot(el).render(<App {...props} />)
49
+ createRoot(el).render(appElement)
43
50
  }
44
51
  },
45
52
  })
@@ -1,6 +1,7 @@
1
1
  import { DocsLayout } from './DocsLayout'
2
2
  import { Markdown } from './Markdown'
3
3
  import type { DocContent, DocsLayoutProps } from '../types'
4
+ import { useComponents } from '../context/ComponentsContext'
4
5
 
5
6
  interface DocsPageProps extends Omit<DocsLayoutProps, 'children' | 'title'> {
6
7
  content: DocContent
@@ -11,9 +12,11 @@ interface DocsPageProps extends Omit<DocsLayoutProps, 'children' | 'title'> {
11
12
  * Renders markdown content within the DocsLayout.
12
13
  */
13
14
  export function DocsPage({ content, ...layoutProps }: DocsPageProps) {
15
+ const { components } = useComponents()
16
+
14
17
  return (
15
18
  <DocsLayout title={content?.title ?? ''} description={content?.description} {...layoutProps}>
16
- <Markdown content={content?.body ?? ''} />
19
+ <Markdown content={content?.body ?? ''} components={components} />
17
20
  </DocsLayout>
18
21
  )
19
22
  }
@@ -8,11 +8,24 @@ import type { MarkdownProps } from '../types'
8
8
  * Markdown renderer with syntax highlighting and GFM support.
9
9
  */
10
10
  export function Markdown({ content, components }: MarkdownProps) {
11
+ // Create lowercase mappings for custom components
12
+ // HTML tag names are case-insensitive, so <TerminalExample> becomes <terminalexample>
13
+ const lowercaseComponents = components
14
+ ? Object.entries(components).reduce(
15
+ (acc, [name, Component]) => {
16
+ acc[name.toLowerCase()] = Component
17
+ return acc
18
+ },
19
+ {} as Record<string, React.ComponentType<any>>
20
+ )
21
+ : {}
22
+
11
23
  return (
12
24
  <ReactMarkdown
13
25
  remarkPlugins={[remarkGfm]}
14
26
  rehypePlugins={[rehypeRaw]}
15
27
  components={{
28
+ ...lowercaseComponents,
16
29
  // Override pre to avoid double wrapping with CodeBlock
17
30
  pre({ children }) {
18
31
  return <>{children}</>
@@ -83,8 +96,6 @@ export function Markdown({ content, components }: MarkdownProps) {
83
96
  </td>
84
97
  )
85
98
  },
86
- // Allow component overrides
87
- ...components,
88
99
  }}
89
100
  >
90
101
  {content}
@@ -0,0 +1,25 @@
1
+ import React, { createContext, useContext } from 'react'
2
+
3
+ interface ComponentsContextValue {
4
+ components?: Record<string, React.ComponentType<any>>
5
+ }
6
+
7
+ const ComponentsContext = createContext<ComponentsContextValue>({})
8
+
9
+ export function ComponentsProvider({
10
+ children,
11
+ components,
12
+ }: {
13
+ children: React.ReactNode
14
+ components?: Record<string, React.ComponentType<any>>
15
+ }) {
16
+ return (
17
+ <ComponentsContext.Provider value={{ components }}>
18
+ {children}
19
+ </ComponentsContext.Provider>
20
+ )
21
+ }
22
+
23
+ export function useComponents() {
24
+ return useContext(ComponentsContext)
25
+ }
package/src/types.ts CHANGED
@@ -88,4 +88,6 @@ export interface CodeBlockProps {
88
88
  export interface DocsAppConfig {
89
89
  pages: Record<string, React.ComponentType<any>>
90
90
  title?: (pageTitle: string) => string
91
+ /** Custom components to use in markdown (e.g., Alert, Card, etc.) */
92
+ components?: Record<string, React.ComponentType<any>>
91
93
  }