@usecross/docs 0.1.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 +178 -0
- package/dist/index.js +616 -0
- package/dist/index.js.map +1 -0
- package/dist/ssr.d.ts +21 -0
- package/dist/ssr.js +27 -0
- package/dist/ssr.js.map +1 -0
- package/dist/types-Vodb50Bj.d.ts +91 -0
- package/package.json +71 -0
- package/src/app.tsx +46 -0
- package/src/components/CodeBlock.tsx +87 -0
- package/src/components/DocsLayout.tsx +178 -0
- package/src/components/DocsPage.tsx +19 -0
- package/src/components/HomePage.tsx +434 -0
- package/src/components/Markdown.tsx +93 -0
- package/src/components/Sidebar.tsx +37 -0
- package/src/components/index.ts +6 -0
- package/src/index.ts +49 -0
- package/src/lib/shiki.ts +59 -0
- package/src/lib/utils.ts +9 -0
- package/src/ssr.tsx +39 -0
- package/src/styles.css +128 -0
- package/src/tailwind.preset.cjs +118 -0
- package/src/types.ts +91 -0
package/src/lib/utils.ts
ADDED
package/src/ssr.tsx
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { createInertiaApp } from '@inertiajs/react'
|
|
2
|
+
import createServer from '@inertiajs/react/server'
|
|
3
|
+
import ReactDOMServer from 'react-dom/server'
|
|
4
|
+
import type { DocsAppConfig } from './types'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Create an SSR server for documentation.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* import { createDocsServer, DocsPage } from '@usecross/docs'
|
|
12
|
+
*
|
|
13
|
+
* createDocsServer({
|
|
14
|
+
* pages: {
|
|
15
|
+
* 'docs/DocsPage': DocsPage,
|
|
16
|
+
* },
|
|
17
|
+
* title: (title) => `${title} - My Docs`,
|
|
18
|
+
* })
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export function createDocsServer(config: DocsAppConfig): void {
|
|
22
|
+
const { pages, title } = config
|
|
23
|
+
|
|
24
|
+
createServer((page) =>
|
|
25
|
+
createInertiaApp({
|
|
26
|
+
page,
|
|
27
|
+
render: ReactDOMServer.renderToString,
|
|
28
|
+
title: title ?? ((pageTitle) => (pageTitle ? `${pageTitle}` : 'Documentation')),
|
|
29
|
+
resolve: (name) => {
|
|
30
|
+
const pageComponent = pages[name]
|
|
31
|
+
if (!pageComponent) {
|
|
32
|
+
throw new Error(`Page component "${name}" not found`)
|
|
33
|
+
}
|
|
34
|
+
return pageComponent
|
|
35
|
+
},
|
|
36
|
+
setup: ({ App, props }) => <App {...props} />,
|
|
37
|
+
})
|
|
38
|
+
)
|
|
39
|
+
}
|
package/src/styles.css
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-Docs default styles
|
|
3
|
+
*
|
|
4
|
+
* Import this file in your app's CSS entry point:
|
|
5
|
+
* @import '@usecross/docs/styles.css';
|
|
6
|
+
*
|
|
7
|
+
* Then add Tailwind directives:
|
|
8
|
+
* @tailwind base;
|
|
9
|
+
* @tailwind components;
|
|
10
|
+
* @tailwind utilities;
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
@import url('https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600&display=swap');
|
|
14
|
+
|
|
15
|
+
@layer base {
|
|
16
|
+
:root {
|
|
17
|
+
/* Font stacks */
|
|
18
|
+
--font-sans: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial,
|
|
19
|
+
sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
|
|
20
|
+
--font-heading: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
|
|
21
|
+
--font-mono: 'Fira Code', Consolas, Monaco, 'Andale Mono', monospace;
|
|
22
|
+
|
|
23
|
+
/* Code highlighting - matches Starlight/Expressive Code dark theme */
|
|
24
|
+
--shiki-color-text: #e2e8f0;
|
|
25
|
+
--shiki-color-background: #24292f;
|
|
26
|
+
--shiki-token-constant: #7dd3fc;
|
|
27
|
+
--shiki-token-string: #86efac;
|
|
28
|
+
--shiki-token-comment: #64748b;
|
|
29
|
+
--shiki-token-keyword: #f472b6;
|
|
30
|
+
--shiki-token-parameter: #e2e8f0;
|
|
31
|
+
--shiki-token-function: #c4b5fd;
|
|
32
|
+
--shiki-token-string-expression: #86efac;
|
|
33
|
+
--shiki-token-punctuation: #94a3b8;
|
|
34
|
+
--shiki-token-link: #38bdf8;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
html {
|
|
38
|
+
/* Note: scroll-behavior: smooth removed to prevent animated scroll on page refresh */
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/* Only apply smooth scrolling when navigating to anchor links */
|
|
42
|
+
html:focus-within {
|
|
43
|
+
scroll-behavior: smooth;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
body {
|
|
47
|
+
@apply antialiased;
|
|
48
|
+
font-family: var(--font-sans);
|
|
49
|
+
font-weight: 400;
|
|
50
|
+
background: #ffffff;
|
|
51
|
+
color: #1f2937;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/* Headings use heading font */
|
|
55
|
+
h1, h2, h3, h4, h5, h6 {
|
|
56
|
+
font-family: var(--font-heading);
|
|
57
|
+
font-weight: 700;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/* Monospace fonts for code */
|
|
61
|
+
code, pre, kbd, samp {
|
|
62
|
+
font-family: var(--font-mono);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
@layer components {
|
|
67
|
+
/* Prose content styles */
|
|
68
|
+
.prose {
|
|
69
|
+
font-size: 1rem;
|
|
70
|
+
line-height: 1.75;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/* Scroll margin for headings (so they don't hide under fixed header) */
|
|
74
|
+
.prose h1,
|
|
75
|
+
.prose h2,
|
|
76
|
+
.prose h3,
|
|
77
|
+
.prose h4,
|
|
78
|
+
.prose h5,
|
|
79
|
+
.prose h6 {
|
|
80
|
+
scroll-margin-top: 6rem;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/* Code block styling - rounded corners like Starlight */
|
|
84
|
+
.prose pre {
|
|
85
|
+
@apply !bg-[#24292f] !p-0 overflow-hidden rounded-lg;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.prose pre code {
|
|
89
|
+
@apply !bg-transparent !p-4 block overflow-x-auto text-sm;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/* Inline code styling */
|
|
93
|
+
.prose :not(pre) > code {
|
|
94
|
+
@apply bg-gray-100 px-1.5 py-0.5 rounded text-sm font-medium text-gray-800;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.prose :not(pre) > code::before,
|
|
98
|
+
.prose :not(pre) > code::after {
|
|
99
|
+
content: none;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/* Syntax highlighting - rounded corners like Starlight */
|
|
104
|
+
.shiki {
|
|
105
|
+
@apply !bg-[#24292f] overflow-hidden rounded-lg;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.shiki code {
|
|
109
|
+
@apply block p-4 overflow-x-auto text-sm leading-relaxed;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/* Scrollbar styling */
|
|
113
|
+
::-webkit-scrollbar {
|
|
114
|
+
width: 8px;
|
|
115
|
+
height: 8px;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
::-webkit-scrollbar-track {
|
|
119
|
+
@apply bg-transparent;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
::-webkit-scrollbar-thumb {
|
|
123
|
+
@apply bg-gray-300 rounded-full;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
::-webkit-scrollbar-thumb:hover {
|
|
127
|
+
@apply bg-gray-400;
|
|
128
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-Docs Tailwind CSS preset
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```js
|
|
6
|
+
* // tailwind.config.js
|
|
7
|
+
* const docsPreset = require('@usecross/docs/tailwind.preset')
|
|
8
|
+
*
|
|
9
|
+
* module.exports = {
|
|
10
|
+
* presets: [docsPreset],
|
|
11
|
+
* content: [
|
|
12
|
+
* './frontend/**\/*.{ts,tsx}',
|
|
13
|
+
* './node_modules/@usecross/docs/**\/*.{js,tsx}',
|
|
14
|
+
* ],
|
|
15
|
+
* theme: {
|
|
16
|
+
* extend: {
|
|
17
|
+
* colors: {
|
|
18
|
+
* primary: { // Override with your brand colors },
|
|
19
|
+
* },
|
|
20
|
+
* },
|
|
21
|
+
* },
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
module.exports = {
|
|
26
|
+
darkMode: 'class',
|
|
27
|
+
theme: {
|
|
28
|
+
extend: {
|
|
29
|
+
maxWidth: {
|
|
30
|
+
'8xl': '88rem',
|
|
31
|
+
},
|
|
32
|
+
fontFamily: {
|
|
33
|
+
sans: [
|
|
34
|
+
'system-ui',
|
|
35
|
+
'-apple-system',
|
|
36
|
+
'Segoe UI',
|
|
37
|
+
'Roboto',
|
|
38
|
+
'Helvetica',
|
|
39
|
+
'Arial',
|
|
40
|
+
'sans-serif',
|
|
41
|
+
'Apple Color Emoji',
|
|
42
|
+
'Segoe UI Emoji',
|
|
43
|
+
'Segoe UI Symbol',
|
|
44
|
+
],
|
|
45
|
+
heading: [
|
|
46
|
+
'system-ui',
|
|
47
|
+
'-apple-system',
|
|
48
|
+
'Segoe UI',
|
|
49
|
+
'Roboto',
|
|
50
|
+
'sans-serif',
|
|
51
|
+
],
|
|
52
|
+
mono: ['Fira Code', 'Consolas', 'Monaco', 'Andale Mono', 'monospace'],
|
|
53
|
+
},
|
|
54
|
+
colors: {
|
|
55
|
+
// Default primary colors - sky blue (can be overridden)
|
|
56
|
+
primary: {
|
|
57
|
+
50: '#f0f9ff',
|
|
58
|
+
100: '#e0f2fe',
|
|
59
|
+
200: '#bae6fd',
|
|
60
|
+
300: '#7dd3fc',
|
|
61
|
+
400: '#38bdf8',
|
|
62
|
+
500: '#0ea5e9',
|
|
63
|
+
600: '#0284c7',
|
|
64
|
+
700: '#0369a1',
|
|
65
|
+
800: '#075985',
|
|
66
|
+
900: '#0c4a6e',
|
|
67
|
+
950: '#082f49',
|
|
68
|
+
},
|
|
69
|
+
// Dark colors for code blocks
|
|
70
|
+
dark: {
|
|
71
|
+
800: '#1e293b',
|
|
72
|
+
900: '#0f172a',
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
typography: (theme) => ({
|
|
76
|
+
DEFAULT: {
|
|
77
|
+
css: {
|
|
78
|
+
maxWidth: 'none',
|
|
79
|
+
color: theme('colors.gray.700'),
|
|
80
|
+
a: {
|
|
81
|
+
color: theme('colors.primary.600'),
|
|
82
|
+
'&:hover': {
|
|
83
|
+
color: theme('colors.primary.700'),
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
'code::before': {
|
|
87
|
+
content: '""',
|
|
88
|
+
},
|
|
89
|
+
'code::after': {
|
|
90
|
+
content: '""',
|
|
91
|
+
},
|
|
92
|
+
code: {
|
|
93
|
+
backgroundColor: theme('colors.gray.100'),
|
|
94
|
+
padding: '0.25rem 0.375rem',
|
|
95
|
+
borderRadius: '0.25rem',
|
|
96
|
+
fontWeight: '500',
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
invert: {
|
|
101
|
+
css: {
|
|
102
|
+
color: theme('colors.gray.300'),
|
|
103
|
+
a: {
|
|
104
|
+
color: theme('colors.primary.400'),
|
|
105
|
+
'&:hover': {
|
|
106
|
+
color: theme('colors.primary.300'),
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
code: {
|
|
110
|
+
backgroundColor: theme('colors.gray.800'),
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
}),
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
plugins: [require('@tailwindcss/typography')],
|
|
118
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-Docs TypeScript type definitions
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { ReactNode } from 'react'
|
|
6
|
+
|
|
7
|
+
/** Single navigation item */
|
|
8
|
+
export interface NavItem {
|
|
9
|
+
title: string
|
|
10
|
+
href: string
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** Navigation section containing multiple items */
|
|
14
|
+
export interface NavSection {
|
|
15
|
+
title: string
|
|
16
|
+
items: NavItem[]
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Shared props passed to all pages via Inertia */
|
|
20
|
+
export interface SharedProps {
|
|
21
|
+
nav: NavSection[]
|
|
22
|
+
currentPath: string
|
|
23
|
+
/** Logo image URL (from Python backend) */
|
|
24
|
+
logoUrl?: string
|
|
25
|
+
/** Logo image URL for dark/inverted contexts (from Python backend) */
|
|
26
|
+
logoInvertedUrl?: string
|
|
27
|
+
/** Footer logo image URL (from Python backend) */
|
|
28
|
+
footerLogoUrl?: string
|
|
29
|
+
/** GitHub repository URL (from Python backend) */
|
|
30
|
+
githubUrl?: string
|
|
31
|
+
/** Additional navigation links (from Python backend) */
|
|
32
|
+
navLinks?: Array<{ label: string; href: string }>
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Document content structure */
|
|
36
|
+
export interface DocContent {
|
|
37
|
+
title: string
|
|
38
|
+
description: string
|
|
39
|
+
body: string
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Props for DocsLayout component */
|
|
43
|
+
export interface DocsLayoutProps {
|
|
44
|
+
children: ReactNode
|
|
45
|
+
title: string
|
|
46
|
+
description?: string
|
|
47
|
+
/** Custom logo component (React node) */
|
|
48
|
+
logo?: ReactNode
|
|
49
|
+
/** Custom logo for dark/inverted contexts (React node) */
|
|
50
|
+
logoInverted?: ReactNode
|
|
51
|
+
/** Logo image URL (alternative to logo prop, can be passed from backend) */
|
|
52
|
+
logoUrl?: string
|
|
53
|
+
/** Logo image URL for dark/inverted contexts */
|
|
54
|
+
logoInvertedUrl?: string
|
|
55
|
+
/** GitHub repository URL (shows GitHub icon in nav) */
|
|
56
|
+
githubUrl?: string
|
|
57
|
+
/** Additional navigation links */
|
|
58
|
+
navLinks?: Array<{ label: string; href: string }>
|
|
59
|
+
/** Custom footer component */
|
|
60
|
+
footer?: ReactNode
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Props for Sidebar component */
|
|
64
|
+
export interface SidebarProps {
|
|
65
|
+
nav: NavSection[]
|
|
66
|
+
currentPath: string
|
|
67
|
+
className?: string
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** Props for Markdown component */
|
|
71
|
+
export interface MarkdownProps {
|
|
72
|
+
content: string
|
|
73
|
+
/** Override default markdown components */
|
|
74
|
+
components?: Record<string, React.ComponentType<any>>
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Props for CodeBlock component */
|
|
78
|
+
export interface CodeBlockProps {
|
|
79
|
+
code: string
|
|
80
|
+
language?: string
|
|
81
|
+
filename?: string
|
|
82
|
+
showLineNumbers?: boolean
|
|
83
|
+
theme?: string
|
|
84
|
+
className?: string
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** Configuration for createDocsApp */
|
|
88
|
+
export interface DocsAppConfig {
|
|
89
|
+
pages: Record<string, React.ComponentType<any>>
|
|
90
|
+
title?: (pageTitle: string) => string
|
|
91
|
+
}
|