@geenius/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.
Files changed (139) hide show
  1. package/.changeset/config.json +11 -0
  2. package/.github/CODEOWNERS +1 -0
  3. package/.github/ISSUE_TEMPLATE/bug_report.md +16 -0
  4. package/.github/ISSUE_TEMPLATE/feature_request.md +11 -0
  5. package/.github/PULL_REQUEST_TEMPLATE.md +10 -0
  6. package/.github/dependabot.yml +11 -0
  7. package/.github/workflows/ci.yml +23 -0
  8. package/.github/workflows/release.yml +29 -0
  9. package/.nvmrc +1 -0
  10. package/.project/ACCOUNT.yaml +4 -0
  11. package/.project/IDEAS.yaml +7 -0
  12. package/.project/PROJECT.yaml +11 -0
  13. package/.project/ROADMAP.yaml +15 -0
  14. package/CHANGELOG.md +11 -0
  15. package/CODE_OF_CONDUCT.md +16 -0
  16. package/CONTRIBUTING.md +26 -0
  17. package/LICENSE +21 -0
  18. package/README.md +1 -0
  19. package/SECURITY.md +15 -0
  20. package/SUPPORT.md +8 -0
  21. package/package.json +58 -0
  22. package/packages/convex/README.md +1 -0
  23. package/packages/convex/package.json +12 -0
  24. package/packages/convex/src/convex.config.ts +3 -0
  25. package/packages/convex/src/index.ts +3 -0
  26. package/packages/convex/src/mutations.ts +270 -0
  27. package/packages/convex/src/queries.ts +175 -0
  28. package/packages/convex/src/schema.ts +55 -0
  29. package/packages/react/README.md +1 -0
  30. package/packages/react/package.json +36 -0
  31. package/packages/react/src/DocsLayout.tsx +116 -0
  32. package/packages/react/src/DocsProvider.tsx +93 -0
  33. package/packages/react/src/RouterDocsContent.tsx +148 -0
  34. package/packages/react/src/RouterDocsLayout.tsx +161 -0
  35. package/packages/react/src/components/Breadcrumbs.tsx +34 -0
  36. package/packages/react/src/components/DocPage.tsx +191 -0
  37. package/packages/react/src/components/DocSearch.tsx +140 -0
  38. package/packages/react/src/components/DocSidebar.tsx +86 -0
  39. package/packages/react/src/components/DocsLayout.tsx +62 -0
  40. package/packages/react/src/components/EditButton.tsx +26 -0
  41. package/packages/react/src/components/PageNavigation.tsx +45 -0
  42. package/packages/react/src/components/TableOfContents.tsx +46 -0
  43. package/packages/react/src/components/VersionSelector.tsx +60 -0
  44. package/packages/react/src/components/index.ts +9 -0
  45. package/packages/react/src/hooks/index.ts +8 -0
  46. package/packages/react/src/hooks/useDocSearch.ts +55 -0
  47. package/packages/react/src/hooks/useDocs.ts +57 -0
  48. package/packages/react/src/hooks/useDocsAdmin.ts +151 -0
  49. package/packages/react/src/hooks/useTableOfContents.ts +66 -0
  50. package/packages/react/src/index.ts +38 -0
  51. package/packages/react/src/pages/DocSearchPage.tsx +129 -0
  52. package/packages/react/src/pages/DocViewPage.tsx +158 -0
  53. package/packages/react/src/pages/DocsAdminPage.tsx +330 -0
  54. package/packages/react/src/pages/DocsIndexPage.tsx +172 -0
  55. package/packages/react/src/pages/index.ts +4 -0
  56. package/packages/react/src/useDocs.ts +58 -0
  57. package/packages/react/tsup.config.ts +12 -0
  58. package/packages/react-css/README.md +1 -0
  59. package/packages/react-css/package.json +37 -0
  60. package/packages/react-css/src/DocsLayout.tsx +117 -0
  61. package/packages/react-css/src/DocsProvider.tsx +93 -0
  62. package/packages/react-css/src/RouterDocsContent.tsx +60 -0
  63. package/packages/react-css/src/RouterDocsLayout.tsx +101 -0
  64. package/packages/react-css/src/components/DocPage.tsx +21 -0
  65. package/packages/react-css/src/components/DocSearch.tsx +55 -0
  66. package/packages/react-css/src/components/DocSidebar.tsx +56 -0
  67. package/packages/react-css/src/components/DocsLayout.tsx +28 -0
  68. package/packages/react-css/src/components/common.tsx +93 -0
  69. package/packages/react-css/src/components/index.ts +5 -0
  70. package/packages/react-css/src/hooks/index.ts +2 -0
  71. package/packages/react-css/src/index.ts +6 -0
  72. package/packages/react-css/src/index.tsx +3 -0
  73. package/packages/react-css/src/pages/DocViewPage.tsx +78 -0
  74. package/packages/react-css/src/pages/DocsAdminPage.tsx +101 -0
  75. package/packages/react-css/src/pages/DocsIndexPage.tsx +68 -0
  76. package/packages/react-css/src/pages/index.ts +3 -0
  77. package/packages/react-css/src/styles.css +1271 -0
  78. package/packages/react-css/src/useDocs.ts +58 -0
  79. package/packages/react-css/tsconfig.json +19 -0
  80. package/packages/react-css/tsup.config.ts +10 -0
  81. package/packages/shared/README.md +1 -0
  82. package/packages/shared/package.json +31 -0
  83. package/packages/shared/src/__tests__/docs.test.ts +69 -0
  84. package/packages/shared/src/config.ts +80 -0
  85. package/packages/shared/src/index.ts +179 -0
  86. package/packages/shared/src/providers/astro.ts +94 -0
  87. package/packages/shared/src/providers/fumadocs.ts +116 -0
  88. package/packages/shared/src/providers/internal.ts +80 -0
  89. package/packages/shared/src/types.ts +73 -0
  90. package/packages/shared/tsconfig.json +18 -0
  91. package/packages/shared/tsup.config.ts +12 -0
  92. package/packages/shared/vitest.config.ts +4 -0
  93. package/packages/solidjs/README.md +1 -0
  94. package/packages/solidjs/package.json +33 -0
  95. package/packages/solidjs/src/DocsLayout.tsx +87 -0
  96. package/packages/solidjs/src/DocsProvider.tsx +95 -0
  97. package/packages/solidjs/src/RouterDocsContent.tsx +147 -0
  98. package/packages/solidjs/src/RouterDocsLayout.tsx +161 -0
  99. package/packages/solidjs/src/components/Breadcrumbs.tsx +27 -0
  100. package/packages/solidjs/src/components/DocPage.tsx +110 -0
  101. package/packages/solidjs/src/components/DocSearch.tsx +81 -0
  102. package/packages/solidjs/src/components/DocSidebar.tsx +92 -0
  103. package/packages/solidjs/src/components/DocsLayout.tsx +38 -0
  104. package/packages/solidjs/src/components/EditButton.tsx +15 -0
  105. package/packages/solidjs/src/components/PageNavigation.tsx +31 -0
  106. package/packages/solidjs/src/components/TableOfContents.tsx +41 -0
  107. package/packages/solidjs/src/components/VersionSelector.tsx +30 -0
  108. package/packages/solidjs/src/components/index.ts +9 -0
  109. package/packages/solidjs/src/createDocs.ts +62 -0
  110. package/packages/solidjs/src/index.ts +28 -0
  111. package/packages/solidjs/src/pages/DocSearchPage.tsx +72 -0
  112. package/packages/solidjs/src/pages/DocViewPage.tsx +80 -0
  113. package/packages/solidjs/src/pages/DocsAdminPage.tsx +123 -0
  114. package/packages/solidjs/src/pages/DocsIndexPage.tsx +85 -0
  115. package/packages/solidjs/src/pages/index.ts +4 -0
  116. package/packages/solidjs/src/primitives/createDocSearch.ts +42 -0
  117. package/packages/solidjs/src/primitives/createDocs.ts +35 -0
  118. package/packages/solidjs/src/primitives/createDocsAdmin.ts +63 -0
  119. package/packages/solidjs/src/primitives/createTableOfContents.ts +51 -0
  120. package/packages/solidjs/src/primitives/index.ts +4 -0
  121. package/packages/solidjs/tsup.config.ts +12 -0
  122. package/packages/solidjs-css/README.md +1 -0
  123. package/packages/solidjs-css/package.json +36 -0
  124. package/packages/solidjs-css/src/DocsLayout.tsx +106 -0
  125. package/packages/solidjs-css/src/DocsProvider.tsx +95 -0
  126. package/packages/solidjs-css/src/RouterDocsContent.tsx +54 -0
  127. package/packages/solidjs-css/src/RouterDocsLayout.tsx +104 -0
  128. package/packages/solidjs-css/src/createDocs.ts +62 -0
  129. package/packages/solidjs-css/src/index.ts +7 -0
  130. package/packages/solidjs-css/src/index.tsx +17 -0
  131. package/packages/solidjs-css/src/pages/DocViewPage.tsx +111 -0
  132. package/packages/solidjs-css/src/pages/DocsAdminPage.tsx +332 -0
  133. package/packages/solidjs-css/src/pages/DocsIndexPage.tsx +116 -0
  134. package/packages/solidjs-css/src/pages/index.ts +3 -0
  135. package/packages/solidjs-css/src/primitives/index.ts +1 -0
  136. package/packages/solidjs-css/src/styles.css +1271 -0
  137. package/packages/solidjs-css/tsconfig.json +20 -0
  138. package/packages/solidjs-css/tsup.config.ts +10 -0
  139. package/pnpm-workspace.yaml +2 -0
@@ -0,0 +1,80 @@
1
+ import type { DocsProvider, DocsPage, DocsSidebar, DocsSection, DocsSearchResult, TocEntry } from '../types'
2
+
3
+ /**
4
+ * Internal docs provider — renders docs from an in-memory page array.
5
+ * Use when loading docs from CMS, API, or static JSON.
6
+ */
7
+ export class InternalDocsProvider implements DocsProvider {
8
+ readonly name = 'internal' as const
9
+ private pages: DocsPage[] = []
10
+
11
+ constructor(pages?: DocsPage[]) { if (pages) this.pages = pages }
12
+
13
+ setPages(pages: DocsPage[]): void { this.pages = this.linkPages(pages) }
14
+
15
+ private linkPages(pages: DocsPage[]): DocsPage[] {
16
+ const sorted = [...pages].sort((a, b) => (a.order ?? 0) - (b.order ?? 0))
17
+ return sorted.map((page, i) => ({
18
+ ...page,
19
+ prev: i > 0 ? { slug: sorted[i - 1].slug, title: sorted[i - 1].title } : undefined,
20
+ next: i < sorted.length - 1 ? { slug: sorted[i + 1].slug, title: sorted[i + 1].title } : undefined,
21
+ toc: page.toc ?? this.extractToc(page.content),
22
+ }))
23
+ }
24
+
25
+ private extractToc(content: string): TocEntry[] {
26
+ const regex = /^(#{2,4})\s+(.+)$/gm
27
+ const entries: TocEntry[] = []
28
+ let match
29
+ while ((match = regex.exec(content)) !== null) {
30
+ const title = match[2].trim()
31
+ entries.push({ id: title.toLowerCase().replace(/[^a-z0-9]+/g, '-'), title, depth: match[1].length })
32
+ }
33
+ return entries
34
+ }
35
+
36
+ async getSidebar(): Promise<DocsSidebar> {
37
+ const sectionMap = new Map<string, DocsPage[]>()
38
+ for (const page of this.pages.filter(p => !p.draft)) {
39
+ const section = page.section || 'General'
40
+ if (!sectionMap.has(section)) sectionMap.set(section, [])
41
+ sectionMap.get(section)!.push(page)
42
+ }
43
+ const sections: DocsSection[] = [...sectionMap.entries()].map(([title, pages]) => ({
44
+ title, slug: title.toLowerCase().replace(/[^a-z0-9]+/g, '-'),
45
+ pages: pages.sort((a, b) => (a.order ?? 0) - (b.order ?? 0)),
46
+ }))
47
+ return { sections }
48
+ }
49
+
50
+ async getPage(slug: string): Promise<DocsPage | null> {
51
+ return this.pages.find(p => p.slug === slug) ?? null
52
+ }
53
+
54
+ async getAllPages(): Promise<DocsPage[]> {
55
+ return this.pages.filter(p => !p.draft)
56
+ }
57
+
58
+ async search(query: string): Promise<DocsSearchResult[]> {
59
+ const q = query.toLowerCase()
60
+ return this.pages.filter(p => !p.draft).map(page => {
61
+ const matches: DocsSearchResult['matches'] = []
62
+ if (page.title.toLowerCase().includes(q)) matches.push({ field: 'title', snippet: page.title })
63
+ if (page.description?.toLowerCase().includes(q)) matches.push({ field: 'description', snippet: page.description })
64
+ if (page.content.toLowerCase().includes(q)) {
65
+ const idx = page.content.toLowerCase().indexOf(q)
66
+ matches.push({ field: 'content', snippet: page.content.slice(Math.max(0, idx - 40), idx + q.length + 40) })
67
+ }
68
+ return matches.length > 0 ? { page, matches, score: matches.length } : null
69
+ }).filter(Boolean) as DocsSearchResult[]
70
+ }
71
+
72
+ async getNavigation(slug: string): Promise<{ prev: DocsPage | null; next: DocsPage | null }> {
73
+ const page = this.pages.find(p => p.slug === slug)
74
+ if (!page) return { prev: null, next: null }
75
+ return {
76
+ prev: page.prev ? (this.pages.find(p => p.slug === page.prev!.slug) ?? null) : null,
77
+ next: page.next ? (this.pages.find(p => p.slug === page.next!.slug) ?? null) : null,
78
+ }
79
+ }
80
+ }
@@ -0,0 +1,73 @@
1
+ // ─── Docs Types ──────────────────────────────────────────────
2
+
3
+ export type DocAccess = 'public' | 'team' | 'admin'
4
+ export type DocStatus = 'draft' | 'published' | 'archived'
5
+
6
+ export interface DocPage {
7
+ id: string
8
+ title: string
9
+ slug: string
10
+ content: string // MDX
11
+ excerpt?: string
12
+ sectionId: string
13
+ order: number
14
+ author: { name: string; avatar?: string }
15
+ lastEditedBy?: { name: string; editedAt: string }
16
+ version?: string // e.g. "2.1.0"
17
+ access: DocAccess
18
+ tags: string[]
19
+ status: DocStatus
20
+ createdAt: string
21
+ updatedAt: string
22
+ wordCount: number
23
+ readingTime: number
24
+ viewCount: number
25
+ }
26
+
27
+ export interface DocSection {
28
+ id: string
29
+ title: string
30
+ slug: string
31
+ parentId?: string // max 3 levels
32
+ order: number
33
+ icon?: string
34
+ description?: string
35
+ access: DocAccess
36
+ pageCount?: number
37
+ }
38
+
39
+ export interface SearchResult {
40
+ pageId: string
41
+ pageTitle: string
42
+ sectionTitle: string
43
+ sectionSlug: string
44
+ slug: string
45
+ highlight: string
46
+ score: number
47
+ tags: string[]
48
+ }
49
+
50
+ export interface TocItem {
51
+ id: string
52
+ text: string
53
+ level: 2 | 3 | 4
54
+ children: TocItem[]
55
+ }
56
+
57
+ export interface BreadcrumbItem {
58
+ title: string
59
+ href: string
60
+ }
61
+
62
+ export interface DocsConfig {
63
+ siteName?: string
64
+ baseUrl?: string
65
+ defaultAccess?: DocAccess
66
+ versionsEnabled?: boolean
67
+ cmdKEnabled?: boolean
68
+ editPageUrl?: string // e.g. 'https://github.com/org/repo/edit/main/docs'
69
+ showReadingTime?: boolean
70
+ showLastEdited?: boolean
71
+ showViewCount?: boolean
72
+ printModeEnabled?: boolean
73
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "./dist",
5
+ "rootDir": "./src",
6
+ "strict": true,
7
+ "skipLibCheck": true,
8
+ "forceConsistentCasingInFileNames": true,
9
+ "resolveJsonModule": true,
10
+ "isolatedModules": true,
11
+ "target": "ES2022",
12
+ "module": "ESNext",
13
+ "moduleResolution": "bundler"
14
+ },
15
+ "include": [
16
+ "src"
17
+ ]
18
+ }
@@ -0,0 +1,12 @@
1
+ import { defineConfig } from 'tsup'
2
+
3
+ export default defineConfig({
4
+ entry: { index: 'src/index.ts' },
5
+ outDir: 'dist',
6
+ format: ['esm'],
7
+ dts: true,
8
+ sourcemap: true,
9
+ clean: true,
10
+ treeshake: true,
11
+ external: [],
12
+ })
@@ -0,0 +1,4 @@
1
+ import { defineConfig } from 'vitest/config'
2
+ export default defineConfig({
3
+ test: { globals: true, environment: 'node' },
4
+ })
@@ -0,0 +1 @@
1
+ # ✦ @geenius-docs/solidjs\n\n> A premium module for the Geenius Boilerplate Ecosystem.\n\n---\n\n## Overview\nBuilt with Steve Jobs-level minimalism and Jony Ive-level craftsmanship, this package is designed to deliver unparalleled developer experience (DX) and rock-solid performance.\n\n## Installation\n\n```bash\npnpm add @geenius-docs/solidjs\n```\n\n## Usage\n\n```typescript\nimport { init } from '@geenius-docs/solidjs';\n\n// Initialize the module with absolute precision\ninit({\n mode: 'premium',\n});\n```\n\n## Architecture\n- **Zero-config**: It just works.\n- **Strictly Typed**: Fully written in TypeScript for flawless IntelliSense.\n- **Framework Agnostic**: seamlessly integrates into the Geenius ecosystem.\n\n---\n\n*Designed by Antigravity HQ*\n
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@geenius-docs/solidjs",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "main": "./src/index.ts",
6
+ "types": "./src/index.ts",
7
+ "exports": {
8
+ ".": "./src/index.ts"
9
+ },
10
+ "peerDependencies": {
11
+ "solid-js": ">=1.8.0"
12
+ },
13
+ "dependencies": {
14
+ "@geenius-docs/shared": "workspace:*",
15
+ "lucide-solid": "^0.577.0",
16
+ "remark-gfm": "^4.0.1",
17
+ "solid-markdown": "^2.1.1"
18
+ },
19
+ "scripts": {
20
+ "type-check": "tsc --noEmit"
21
+ },
22
+ "devDependencies": {
23
+ "@tanstack/solid-router": "^1.168.1"
24
+ },
25
+ "author": "Antigravity HQ",
26
+ "license": "MIT",
27
+ "engines": {
28
+ "node": ">=20.0.0"
29
+ },
30
+ "publishConfig": {
31
+ "access": "public"
32
+ }
33
+ }
@@ -0,0 +1,87 @@
1
+ // @geenius-docs/solidjs — src/DocsLayout.tsx
2
+
3
+ import { For, Show, type ParentComponent } from 'solid-js'
4
+ import { useDocs } from './DocsProvider'
5
+
6
+ export interface DocsLayoutProps {
7
+ currentPageId?: string
8
+ onSelectPage?: (id: string) => void
9
+ searchQuery?: string
10
+ onSearch?: (query: string) => void
11
+ searchResults?: unknown[]
12
+ }
13
+
14
+ /**
15
+ * DocsLayout — SolidJS sidebar + content layout for documentation.
16
+ * Uses data-* attributes and ga-docs-* classes for CSS styling.
17
+ */
18
+ export const DocsLayout: ParentComponent<DocsLayoutProps> = (props) => {
19
+ const docs = useDocs()
20
+
21
+ const q = () => props.searchQuery ?? docs.searchQuery()
22
+ const results = () => (props.searchResults ?? docs.searchResults()) as Array<{ id: string; title: string; description?: string }>
23
+ const onSelect = (id: string) => (props.onSelectPage ?? docs.selectPage)(id)
24
+ const onSearch = (query: string) => (props.onSearch ?? docs.setSearchQuery)(query)
25
+
26
+ return (
27
+ <div class="ga-docs-layout">
28
+ {/* Sidebar */}
29
+ <aside class="ga-docs-sidebar">
30
+ <div class="ga-docs-search">
31
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><circle cx="11" cy="11" r="8" /><path d="m21 21-4.3-4.3" /></svg>
32
+ <input
33
+ type="text"
34
+ value={q()}
35
+ onInput={(e) => onSearch(e.currentTarget.value)}
36
+ placeholder="Search docs..."
37
+ />
38
+ </div>
39
+
40
+ <nav>
41
+ <Show
42
+ when={!q() || results().length === 0}
43
+ fallback={
44
+ <div data-docs-search-results>
45
+ <p class="ga-docs-nav-group-title">Search Results ({results().length})</p>
46
+ <For each={results()}>
47
+ {(page) => (
48
+ <button
49
+ class="ga-docs-nav-item"
50
+ onClick={() => { onSelect(page.id); onSearch('') }}
51
+ >
52
+ {page.title}
53
+ </button>
54
+ )}
55
+ </For>
56
+ </div>
57
+ }
58
+ >
59
+ <For each={docs.tree}>
60
+ {(group) => (
61
+ <div class="ga-docs-nav-group">
62
+ <p class="ga-docs-nav-group-title">{group.title}</p>
63
+ <For each={group.children}>
64
+ {(page) => (
65
+ <button
66
+ class="ga-docs-nav-item"
67
+ data-active={page.id === props.currentPageId || undefined}
68
+ onClick={() => onSelect(page.id)}
69
+ >
70
+ {page.title}
71
+ </button>
72
+ )}
73
+ </For>
74
+ </div>
75
+ )}
76
+ </For>
77
+ </Show>
78
+ </nav>
79
+ </aside>
80
+
81
+ {/* Content */}
82
+ <main class="ga-docs-content">
83
+ {props.children}
84
+ </main>
85
+ </div>
86
+ )
87
+ }
@@ -0,0 +1,95 @@
1
+ // @geenius-docs/solidjs — src/DocsProvider.tsx
2
+
3
+ import { createContext, useContext, type ParentComponent } from 'solid-js'
4
+ import { createSignal, createMemo } from 'solid-js'
5
+
6
+ export interface DocsPage {
7
+ id: string
8
+ title: string
9
+ description?: string
10
+ content: unknown
11
+ }
12
+
13
+ export interface DocsGroup {
14
+ id: string
15
+ title: string
16
+ children: DocsPage[]
17
+ }
18
+
19
+ export type DocsTree = DocsGroup[]
20
+
21
+ export interface DocsContextValue {
22
+ tree: DocsTree
23
+ currentPage: () => DocsPage | null
24
+ selectPage: (id: string) => void
25
+ searchQuery: () => string
26
+ setSearchQuery: (query: string) => void
27
+ searchResults: () => DocsPage[]
28
+ }
29
+
30
+ const DocsContext = createContext<DocsContextValue>()
31
+
32
+ export interface DocsProviderProps {
33
+ tree: DocsTree
34
+ }
35
+
36
+ /**
37
+ * DocsProvider — SolidJS context managing docs state:
38
+ * current page, search, and tree navigation.
39
+ */
40
+ export const DocsProvider: ParentComponent<DocsProviderProps> = (props) => {
41
+ const firstPageId = () => props.tree[0]?.children[0]?.id || null
42
+ const [currentPageId, setCurrentPageId] = createSignal<string | null>(firstPageId())
43
+ const [searchQuery, setSearchQuery] = createSignal('')
44
+
45
+ const currentPage = createMemo(() => {
46
+ const id = currentPageId()
47
+ if (!id) return null
48
+ for (const group of props.tree) {
49
+ const page = group.children.find(p => p.id === id)
50
+ if (page) return page
51
+ }
52
+ return null
53
+ })
54
+
55
+ const selectPage = (id: string) => setCurrentPageId(id)
56
+
57
+ const searchResults = createMemo(() => {
58
+ const q = searchQuery().toLowerCase()
59
+ if (!q) return []
60
+ const results: DocsPage[] = []
61
+ for (const group of props.tree) {
62
+ for (const page of group.children) {
63
+ if (
64
+ page.title.toLowerCase().includes(q) ||
65
+ page.description?.toLowerCase().includes(q) ||
66
+ (typeof page.content === 'string' && page.content.toLowerCase().includes(q))
67
+ ) {
68
+ results.push(page)
69
+ }
70
+ }
71
+ }
72
+ return results
73
+ })
74
+
75
+ const value: DocsContextValue = {
76
+ tree: props.tree,
77
+ currentPage,
78
+ selectPage,
79
+ searchQuery,
80
+ setSearchQuery,
81
+ searchResults,
82
+ }
83
+
84
+ return (
85
+ <DocsContext.Provider value={value}>
86
+ {props.children}
87
+ </DocsContext.Provider>
88
+ )
89
+ }
90
+
91
+ export function useDocs(): DocsContextValue {
92
+ const ctx = useContext(DocsContext)
93
+ if (!ctx) throw new Error('useDocs must be used within a DocsProvider')
94
+ return ctx
95
+ }
@@ -0,0 +1,147 @@
1
+ // src/components/docs/DocsContent.tsx
2
+
3
+ import { SolidMarkdown as ReactMarkdown } from 'solid-markdown'
4
+ import remarkGfm from 'remark-gfm'
5
+ import { Link } from '@tanstack/solid-router'
6
+
7
+ interface DocsContentProps {
8
+ content: string
9
+ title: string
10
+ description: string
11
+ }
12
+
13
+ export const DocsContent: Component<DocsContentProps> = ({
14
+ content,
15
+ title,
16
+ description,
17
+ }) => {
18
+ return (
19
+ <article class="prose prose-lg dark:prose-invert max-w-none">
20
+ {/* Header */}
21
+ <header class="mb-8 pb-8 border-b border-border not-prose">
22
+ <h1 class="text-4xl font-extrabold text-text-main mb-3">{title}</h1>
23
+ <p class="text-lg text-text-muted">{description}</p>
24
+ </header>
25
+
26
+ {/* Markdown Content */}
27
+ <ReactMarkdown
28
+ remarkPlugins={[remarkGfm]}
29
+ components={{
30
+ // Custom heading styles
31
+ h1: ({ children }) => (
32
+ <h1 class="text-3xl font-bold text-text-main mt-12 mb-6">
33
+ {children}
34
+ </h1>
35
+ ),
36
+ h2: ({ children }) => (
37
+ <h2 class="text-2xl font-bold text-text-main mt-10 mb-4 pb-2 border-b border-border">
38
+ {children}
39
+ </h2>
40
+ ),
41
+ h3: ({ children }) => (
42
+ <h3 class="text-xl font-bold text-text-main mt-8 mb-3">
43
+ {children}
44
+ </h3>
45
+ ),
46
+ h4: ({ children }) => (
47
+ <h4 class="text-lg font-semibold text-text-main mt-6 mb-2">
48
+ {children}
49
+ </h4>
50
+ ),
51
+ // Paragraph
52
+ p: ({ children }) => (
53
+ <p class="text-text-muted leading-relaxed mb-4">{children}</p>
54
+ ),
55
+ // Links
56
+ a: ({ href, children }) => {
57
+ const isInternal = href?.startsWith('/')
58
+ if (isInternal) {
59
+ return (
60
+ <Link
61
+ to={href!}
62
+ class="text-primary hover:underline font-medium"
63
+ >
64
+ {children}
65
+ </Link>
66
+ )
67
+ }
68
+ return (
69
+ <a
70
+ href={href}
71
+ target="_blank"
72
+ rel="noopener noreferrer"
73
+ class="text-primary hover:underline font-medium"
74
+ >
75
+ {children}
76
+ </a>
77
+ )
78
+ },
79
+ // Code blocks
80
+ code: ({ className, children, ...props }) => {
81
+ const isInline = !className
82
+ if (isInline) {
83
+ return (
84
+ <code class="bg-bg-muted px-1.5 py-0.5 rounded text-sm font-mono text-primary">
85
+ {children}
86
+ </code>
87
+ )
88
+ }
89
+ return (
90
+ <code class={`${className} block`} {...props}>
91
+ {children}
92
+ </code>
93
+ )
94
+ },
95
+ pre: ({ children }) => (
96
+ <pre class="bg-[#1e1e2e] text-gray-100 p-4 rounded-xl overflow-x-auto text-sm my-6 border border-border">
97
+ {children}
98
+ </pre>
99
+ ),
100
+ // Lists
101
+ ul: ({ children }) => (
102
+ <ul class="list-disc list-inside space-y-2 text-text-muted mb-4">
103
+ {children}
104
+ </ul>
105
+ ),
106
+ ol: ({ children }) => (
107
+ <ol class="list-decimal list-inside space-y-2 text-text-muted mb-4">
108
+ {children}
109
+ </ol>
110
+ ),
111
+ li: ({ children }) => <li class="text-text-muted">{children}</li>,
112
+ // Tables
113
+ table: ({ children }) => (
114
+ <div class="overflow-x-auto my-6">
115
+ <table class="min-w-full divide-y divide-border border border-border rounded-lg overflow-hidden">
116
+ {children}
117
+ </table>
118
+ </div>
119
+ ),
120
+ thead: ({ children }) => (
121
+ <thead class="bg-bg-muted">{children}</thead>
122
+ ),
123
+ th: ({ children }) => (
124
+ <th class="px-4 py-3 text-left text-sm font-bold text-text-main">
125
+ {children}
126
+ </th>
127
+ ),
128
+ td: ({ children }) => (
129
+ <td class="px-4 py-3 text-sm text-text-muted border-t border-border">
130
+ {children}
131
+ </td>
132
+ ),
133
+ // Blockquotes
134
+ blockquote: ({ children }) => (
135
+ <blockquote class="border-l-4 border-primary pl-4 py-2 my-6 bg-primary/5 rounded-r-lg">
136
+ {children}
137
+ </blockquote>
138
+ ),
139
+ // Horizontal rules
140
+ hr: () => <hr class="border-border my-8" />,
141
+ }}
142
+ >
143
+ {content}
144
+ </ReactMarkdown>
145
+ </article>
146
+ )
147
+ }