@geenius/docs 0.1.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.
Files changed (158) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +53 -1
  3. package/package.json +96 -13
  4. package/packages/convex/dist/index.d.ts +503 -0
  5. package/packages/convex/dist/index.js +482 -0
  6. package/packages/convex/dist/index.js.map +1 -0
  7. package/packages/react/dist/index.d.ts +439 -0
  8. package/packages/react/dist/index.js +4954 -0
  9. package/packages/react/dist/index.js.map +1 -0
  10. package/packages/react-css/{src/styles.css → dist/index.css} +183 -223
  11. package/packages/react-css/dist/index.css.map +1 -0
  12. package/packages/react-css/dist/index.d.ts +443 -0
  13. package/packages/react-css/dist/index.js +5058 -0
  14. package/packages/react-css/dist/index.js.map +1 -0
  15. package/packages/shared/dist/index.d.ts +684 -0
  16. package/packages/shared/dist/index.js +788 -0
  17. package/packages/shared/dist/index.js.map +1 -0
  18. package/packages/solidjs/dist/index.d.ts +435 -0
  19. package/packages/solidjs/dist/index.js +4584 -0
  20. package/packages/solidjs/dist/index.js.map +1 -0
  21. package/packages/solidjs-css/{src/styles.css → dist/index.css} +183 -223
  22. package/packages/solidjs-css/dist/index.css.map +1 -0
  23. package/packages/solidjs-css/dist/index.d.ts +432 -0
  24. package/packages/solidjs-css/dist/index.js +4934 -0
  25. package/packages/solidjs-css/dist/index.js.map +1 -0
  26. package/.changeset/config.json +0 -11
  27. package/.github/CODEOWNERS +0 -1
  28. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -16
  29. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -11
  30. package/.github/PULL_REQUEST_TEMPLATE.md +0 -10
  31. package/.github/dependabot.yml +0 -11
  32. package/.github/workflows/ci.yml +0 -23
  33. package/.github/workflows/release.yml +0 -29
  34. package/.nvmrc +0 -1
  35. package/.project/ACCOUNT.yaml +0 -4
  36. package/.project/IDEAS.yaml +0 -7
  37. package/.project/PROJECT.yaml +0 -11
  38. package/.project/ROADMAP.yaml +0 -15
  39. package/CODE_OF_CONDUCT.md +0 -16
  40. package/CONTRIBUTING.md +0 -26
  41. package/SECURITY.md +0 -15
  42. package/SUPPORT.md +0 -8
  43. package/packages/convex/README.md +0 -1
  44. package/packages/convex/package.json +0 -12
  45. package/packages/convex/src/convex.config.ts +0 -3
  46. package/packages/convex/src/index.ts +0 -3
  47. package/packages/convex/src/mutations.ts +0 -270
  48. package/packages/convex/src/queries.ts +0 -175
  49. package/packages/convex/src/schema.ts +0 -55
  50. package/packages/react/README.md +0 -1
  51. package/packages/react/package.json +0 -36
  52. package/packages/react/src/DocsLayout.tsx +0 -116
  53. package/packages/react/src/DocsProvider.tsx +0 -93
  54. package/packages/react/src/RouterDocsContent.tsx +0 -148
  55. package/packages/react/src/RouterDocsLayout.tsx +0 -161
  56. package/packages/react/src/components/Breadcrumbs.tsx +0 -34
  57. package/packages/react/src/components/DocPage.tsx +0 -191
  58. package/packages/react/src/components/DocSearch.tsx +0 -140
  59. package/packages/react/src/components/DocSidebar.tsx +0 -86
  60. package/packages/react/src/components/DocsLayout.tsx +0 -62
  61. package/packages/react/src/components/EditButton.tsx +0 -26
  62. package/packages/react/src/components/PageNavigation.tsx +0 -45
  63. package/packages/react/src/components/TableOfContents.tsx +0 -46
  64. package/packages/react/src/components/VersionSelector.tsx +0 -60
  65. package/packages/react/src/components/index.ts +0 -9
  66. package/packages/react/src/hooks/index.ts +0 -8
  67. package/packages/react/src/hooks/useDocSearch.ts +0 -55
  68. package/packages/react/src/hooks/useDocs.ts +0 -57
  69. package/packages/react/src/hooks/useDocsAdmin.ts +0 -151
  70. package/packages/react/src/hooks/useTableOfContents.ts +0 -66
  71. package/packages/react/src/index.ts +0 -38
  72. package/packages/react/src/pages/DocSearchPage.tsx +0 -129
  73. package/packages/react/src/pages/DocViewPage.tsx +0 -158
  74. package/packages/react/src/pages/DocsAdminPage.tsx +0 -330
  75. package/packages/react/src/pages/DocsIndexPage.tsx +0 -172
  76. package/packages/react/src/pages/index.ts +0 -4
  77. package/packages/react/src/useDocs.ts +0 -58
  78. package/packages/react/tsup.config.ts +0 -12
  79. package/packages/react-css/README.md +0 -1
  80. package/packages/react-css/package.json +0 -37
  81. package/packages/react-css/src/DocsLayout.tsx +0 -117
  82. package/packages/react-css/src/DocsProvider.tsx +0 -93
  83. package/packages/react-css/src/RouterDocsContent.tsx +0 -60
  84. package/packages/react-css/src/RouterDocsLayout.tsx +0 -101
  85. package/packages/react-css/src/components/DocPage.tsx +0 -21
  86. package/packages/react-css/src/components/DocSearch.tsx +0 -55
  87. package/packages/react-css/src/components/DocSidebar.tsx +0 -56
  88. package/packages/react-css/src/components/DocsLayout.tsx +0 -28
  89. package/packages/react-css/src/components/common.tsx +0 -93
  90. package/packages/react-css/src/components/index.ts +0 -5
  91. package/packages/react-css/src/hooks/index.ts +0 -2
  92. package/packages/react-css/src/index.ts +0 -6
  93. package/packages/react-css/src/index.tsx +0 -3
  94. package/packages/react-css/src/pages/DocViewPage.tsx +0 -78
  95. package/packages/react-css/src/pages/DocsAdminPage.tsx +0 -101
  96. package/packages/react-css/src/pages/DocsIndexPage.tsx +0 -68
  97. package/packages/react-css/src/pages/index.ts +0 -3
  98. package/packages/react-css/src/useDocs.ts +0 -58
  99. package/packages/react-css/tsconfig.json +0 -19
  100. package/packages/react-css/tsup.config.ts +0 -10
  101. package/packages/shared/README.md +0 -1
  102. package/packages/shared/package.json +0 -31
  103. package/packages/shared/src/__tests__/docs.test.ts +0 -69
  104. package/packages/shared/src/config.ts +0 -80
  105. package/packages/shared/src/index.ts +0 -179
  106. package/packages/shared/src/providers/astro.ts +0 -94
  107. package/packages/shared/src/providers/fumadocs.ts +0 -116
  108. package/packages/shared/src/providers/internal.ts +0 -80
  109. package/packages/shared/src/types.ts +0 -73
  110. package/packages/shared/tsconfig.json +0 -18
  111. package/packages/shared/tsup.config.ts +0 -12
  112. package/packages/shared/vitest.config.ts +0 -4
  113. package/packages/solidjs/README.md +0 -1
  114. package/packages/solidjs/package.json +0 -33
  115. package/packages/solidjs/src/DocsLayout.tsx +0 -87
  116. package/packages/solidjs/src/DocsProvider.tsx +0 -95
  117. package/packages/solidjs/src/RouterDocsContent.tsx +0 -147
  118. package/packages/solidjs/src/RouterDocsLayout.tsx +0 -161
  119. package/packages/solidjs/src/components/Breadcrumbs.tsx +0 -27
  120. package/packages/solidjs/src/components/DocPage.tsx +0 -110
  121. package/packages/solidjs/src/components/DocSearch.tsx +0 -81
  122. package/packages/solidjs/src/components/DocSidebar.tsx +0 -92
  123. package/packages/solidjs/src/components/DocsLayout.tsx +0 -38
  124. package/packages/solidjs/src/components/EditButton.tsx +0 -15
  125. package/packages/solidjs/src/components/PageNavigation.tsx +0 -31
  126. package/packages/solidjs/src/components/TableOfContents.tsx +0 -41
  127. package/packages/solidjs/src/components/VersionSelector.tsx +0 -30
  128. package/packages/solidjs/src/components/index.ts +0 -9
  129. package/packages/solidjs/src/createDocs.ts +0 -62
  130. package/packages/solidjs/src/index.ts +0 -28
  131. package/packages/solidjs/src/pages/DocSearchPage.tsx +0 -72
  132. package/packages/solidjs/src/pages/DocViewPage.tsx +0 -80
  133. package/packages/solidjs/src/pages/DocsAdminPage.tsx +0 -123
  134. package/packages/solidjs/src/pages/DocsIndexPage.tsx +0 -85
  135. package/packages/solidjs/src/pages/index.ts +0 -4
  136. package/packages/solidjs/src/primitives/createDocSearch.ts +0 -42
  137. package/packages/solidjs/src/primitives/createDocs.ts +0 -35
  138. package/packages/solidjs/src/primitives/createDocsAdmin.ts +0 -63
  139. package/packages/solidjs/src/primitives/createTableOfContents.ts +0 -51
  140. package/packages/solidjs/src/primitives/index.ts +0 -4
  141. package/packages/solidjs/tsup.config.ts +0 -12
  142. package/packages/solidjs-css/README.md +0 -1
  143. package/packages/solidjs-css/package.json +0 -36
  144. package/packages/solidjs-css/src/DocsLayout.tsx +0 -106
  145. package/packages/solidjs-css/src/DocsProvider.tsx +0 -95
  146. package/packages/solidjs-css/src/RouterDocsContent.tsx +0 -54
  147. package/packages/solidjs-css/src/RouterDocsLayout.tsx +0 -104
  148. package/packages/solidjs-css/src/createDocs.ts +0 -62
  149. package/packages/solidjs-css/src/index.ts +0 -7
  150. package/packages/solidjs-css/src/index.tsx +0 -17
  151. package/packages/solidjs-css/src/pages/DocViewPage.tsx +0 -111
  152. package/packages/solidjs-css/src/pages/DocsAdminPage.tsx +0 -332
  153. package/packages/solidjs-css/src/pages/DocsIndexPage.tsx +0 -116
  154. package/packages/solidjs-css/src/pages/index.ts +0 -3
  155. package/packages/solidjs-css/src/primitives/index.ts +0 -1
  156. package/packages/solidjs-css/tsconfig.json +0 -20
  157. package/packages/solidjs-css/tsup.config.ts +0 -10
  158. package/pnpm-workspace.yaml +0 -2
@@ -1,80 +0,0 @@
1
- import { createEffect, createMemo, Show } from 'solid-js'
2
- import type { DocPage as DocPageType, DocSection } from '@geenius-docs/shared'
3
- import { buildBreadcrumbs } from '@geenius-docs/shared'
4
- import { createDocs } from '../primitives/createDocs'
5
- import { createTableOfContents } from '../primitives/createTableOfContents'
6
- import { DocsLayout } from '../components/DocsLayout'
7
- import { DocPage } from '../components/DocPage'
8
- import { EditButton } from '../components/EditButton'
9
- import { PageNavigation } from '../components/PageNavigation'
10
-
11
- interface DocViewPageProps {
12
- tree: () => (DocSection & { pages: DocPageType[]; pageCount: number })[] | undefined
13
- page: () => DocPageType | null | undefined
14
- editPageUrl?: string
15
- onNavigate: (page: DocPageType, section: DocSection) => void
16
- onIncrementView?: (pageId: string) => void
17
- }
18
-
19
- export function DocViewPage(props: DocViewPageProps) {
20
- const docs = createDocs(props.tree)
21
- const { toc, activeId } = createTableOfContents(() => props.page()?.content)
22
-
23
- createEffect(() => {
24
- const p = props.page()
25
- if (p?.id && props.onIncrementView) props.onIncrementView(p.id)
26
- })
27
-
28
- const breadcrumbs = createMemo(() => {
29
- const p = props.page()
30
- if (!p) return []
31
- return buildBreadcrumbs(docs.sections(), p.sectionId, p.slug)
32
- })
33
-
34
- const nav = createMemo(() => {
35
- const p = props.page()
36
- if (!p) return { prev: undefined, next: undefined }
37
- const all = docs.flatPages()
38
- const idx = all.findIndex(pg => pg.id === p.id)
39
- const section = docs.sections().find(s => s.id === p.sectionId)
40
- return {
41
- prev: idx > 0 ? { title: all[idx - 1].title, href: `/docs/${section?.slug ?? ''}/${all[idx - 1].slug}` } : undefined,
42
- next: idx < all.length - 1 ? { title: all[idx + 1].title, href: `/docs/${section?.slug ?? ''}/${all[idx + 1].slug}` } : undefined,
43
- }
44
- })
45
-
46
- return (
47
- <Show when={!docs.isLoading() && props.page() !== undefined} fallback={
48
- <div class="flex min-h-screen bg-[#090a0f]">
49
- <div class="hidden w-[260px] shrink-0 border-r border-white/5 bg-[#0b0c12] lg:block"><div class="space-y-3 p-4">{Array.from({ length: 8 }).map(() => <div class="h-8 animate-pulse rounded-lg bg-white/5" />)}</div></div>
50
- <div class="flex-1 px-10 py-8"><div class="mx-auto max-w-3xl space-y-4"><div class="h-10 w-96 animate-pulse rounded bg-white/5" /></div></div>
51
- </div>
52
- }>
53
- <Show when={props.page()} fallback={
54
- <div class="flex min-h-screen flex-col items-center justify-center bg-[#090a0f] text-center">
55
- <div class="mb-4 text-6xl opacity-30">🔍</div>
56
- <h2 class="mb-2 text-xl font-semibold text-white/80">Page not found</h2>
57
- </div>
58
- }>
59
- {(page) => (
60
- <DocsLayout sections={docs.sections()} toc={toc()} activeHeadingId={activeId()} breadcrumbs={breadcrumbs()}
61
- currentPageId={page().id} onNavigate={props.onNavigate}>
62
- <div class="mb-8">
63
- <h1 class="mb-3 text-3xl font-bold tracking-tight">{page().title}</h1>
64
- <div class="flex flex-wrap items-center gap-4 text-sm text-white/40">
65
- <span>{page().author.name}</span>
66
- <Show when={page().readingTime > 0}><span>{page().readingTime} min read</span></Show>
67
- <Show when={page().viewCount > 0}><span>{page().viewCount.toLocaleString()} views</span></Show>
68
- </div>
69
- </div>
70
- <DocPage page={page()} />
71
- <div class="mt-10 flex items-center justify-between border-t border-white/5 pt-6">
72
- <EditButton pageSlug={page().slug} editUrl={props.editPageUrl} />
73
- </div>
74
- <PageNavigation prev={nav().prev} next={nav().next} />
75
- </DocsLayout>
76
- )}
77
- </Show>
78
- </Show>
79
- )
80
- }
@@ -1,123 +0,0 @@
1
- import { createSignal, createMemo, Show, For } from 'solid-js'
2
- import type { DocPage, DocSection } from '@geenius-docs/shared'
3
-
4
- interface DocsAdminPageProps {
5
- tree: () => (DocSection & { pages: DocPage[]; pageCount: number })[] | undefined
6
- allPages?: DocPage[]
7
- admin: {
8
- createSection: (d: Record<string, unknown>) => Promise<void>
9
- deleteSection: (id: string) => Promise<void>
10
- createPage: (d: Record<string, unknown>) => Promise<void>
11
- publishPage: (id: string) => Promise<void>
12
- archivePage: (id: string) => Promise<void>
13
- deletePage: (id: string) => Promise<void>
14
- }
15
- }
16
-
17
- export function DocsAdminPage(props: DocsAdminPageProps) {
18
- const sections = createMemo(() => props.tree?.() ?? [])
19
- const [selectedId, setSelectedId] = createSignal<string | null>(null)
20
- const [showSF, setShowSF] = createSignal(false)
21
- const [showPF, setShowPF] = createSignal(false)
22
- const [sf, setSf] = createSignal({ title: '', slug: '', description: '', icon: '', access: 'team' })
23
- const [pf, setPf] = createSignal({ title: '', slug: '', content: '', access: 'team', tags: '' })
24
-
25
- const selectedSection = createMemo(() => sections().find(s => s.id === selectedId()))
26
- const sectionPages = createMemo(() => {
27
- const sec = selectedSection()
28
- if (!sec) return []
29
- if (props.allPages) return props.allPages.filter(p => p.sectionId === selectedId())
30
- return sec.pages ?? []
31
- })
32
-
33
- return (
34
- <Show when={props.tree?.() !== undefined} fallback={
35
- <div class="min-h-screen bg-[#090a0f] px-6 py-12"><div class="mx-auto max-w-6xl"><div class="mb-8 h-10 w-48 animate-pulse rounded bg-white/5" /></div></div>
36
- }>
37
- <div class="min-h-screen bg-[#090a0f] text-white">
38
- <div class="mx-auto max-w-6xl px-6 py-12">
39
- <h1 class="mb-8 text-2xl font-bold">Docs Admin</h1>
40
- <div class="grid gap-6 md:grid-cols-2">
41
- {/* Sections */}
42
- <div class="rounded-xl border border-white/8 bg-white/[0.02] p-5">
43
- <div class="mb-4 flex items-center justify-between">
44
- <h2 class="text-lg font-semibold text-white/80">Sections</h2>
45
- <button type="button" onClick={() => setShowSF(!showSF())} class="rounded-lg bg-indigo-600 px-3 py-1.5 text-xs font-medium hover:bg-indigo-500">+ Add</button>
46
- </div>
47
- <Show when={showSF()}>
48
- <div class="mb-4 space-y-2 rounded-lg border border-white/10 bg-white/5 p-4">
49
- <input type="text" placeholder="Title" value={sf().title} onInput={e => setSf({...sf(), title: e.currentTarget.value})} class="w-full rounded-lg border border-white/10 bg-white/5 px-3 py-2 text-sm outline-none focus:border-indigo-500/40" />
50
- <input type="text" placeholder="Slug" value={sf().slug} onInput={e => setSf({...sf(), slug: e.currentTarget.value})} class="w-full rounded-lg border border-white/10 bg-white/5 px-3 py-2 text-sm outline-none focus:border-indigo-500/40" />
51
- <input type="text" placeholder="Icon" value={sf().icon} onInput={e => setSf({...sf(), icon: e.currentTarget.value})} class="w-full rounded-lg border border-white/10 bg-white/5 px-3 py-2 text-sm outline-none focus:border-indigo-500/40" />
52
- <input type="text" placeholder="Description" value={sf().description} onInput={e => setSf({...sf(), description: e.currentTarget.value})} class="w-full rounded-lg border border-white/10 bg-white/5 px-3 py-2 text-sm outline-none focus:border-indigo-500/40" />
53
- <div class="flex gap-2">
54
- <button type="button" onClick={async () => { await props.admin.createSection({...sf(), order: sections().length}); setSf({title:'',slug:'',description:'',icon:'',access:'team'}); setShowSF(false) }} class="rounded-lg bg-indigo-600 px-4 py-2 text-xs font-medium hover:bg-indigo-500">Create</button>
55
- <button type="button" onClick={() => setShowSF(false)} class="rounded-lg border border-white/10 px-4 py-2 text-xs hover:bg-white/5">Cancel</button>
56
- </div>
57
- </div>
58
- </Show>
59
- <div class="space-y-1">
60
- <Show when={sections().length === 0}><p class="py-8 text-center text-sm text-white/30">No sections</p></Show>
61
- <For each={sections()}>
62
- {(section) => (
63
- <div class={`group flex items-center gap-2 rounded-lg px-3 py-2.5 cursor-pointer ${selectedId() === section.id ? 'bg-indigo-500/15 text-indigo-300' : 'hover:bg-white/5 text-white/70'}`}
64
- onClick={() => setSelectedId(section.id)}>
65
- <Show when={section.icon}><span>{section.icon}</span></Show>
66
- <span class="flex-1 text-sm font-medium truncate">{section.title}</span>
67
- <span class="text-[11px] tabular-nums opacity-40">{section.pageCount ?? 0}</span>
68
- <button type="button" onClick={(e) => { e.stopPropagation(); if (confirm(`Delete "${section.title}"?`)) props.admin.deleteSection(section.id) }}
69
- class="rounded p-1 text-white/20 opacity-0 group-hover:opacity-100 hover:text-red-400">✕</button>
70
- </div>
71
- )}
72
- </For>
73
- </div>
74
- </div>
75
- {/* Pages */}
76
- <div class="rounded-xl border border-white/8 bg-white/[0.02] p-5">
77
- <div class="mb-4 flex items-center justify-between">
78
- <h2 class="text-lg font-semibold text-white/80">{selectedSection() ? `Pages — ${selectedSection()!.title}` : 'Pages'}</h2>
79
- <Show when={selectedSection()}><button type="button" onClick={() => setShowPF(!showPF())} class="rounded-lg bg-indigo-600 px-3 py-1.5 text-xs font-medium hover:bg-indigo-500">+ Add</button></Show>
80
- </div>
81
- <Show when={!selectedSection()}><p class="py-16 text-center text-sm text-white/30">Select a section</p></Show>
82
- <Show when={showPF() && selectedSection()}>
83
- <div class="mb-4 space-y-2 rounded-lg border border-white/10 bg-white/5 p-4">
84
- <input type="text" placeholder="Title" value={pf().title} onInput={e => setPf({...pf(), title: e.currentTarget.value})} class="w-full rounded-lg border border-white/10 bg-white/5 px-3 py-2 text-sm outline-none focus:border-indigo-500/40" />
85
- <input type="text" placeholder="Slug" value={pf().slug} onInput={e => setPf({...pf(), slug: e.currentTarget.value})} class="w-full rounded-lg border border-white/10 bg-white/5 px-3 py-2 text-sm outline-none focus:border-indigo-500/40" />
86
- <textarea placeholder="Content (MDX)" value={pf().content} onInput={e => setPf({...pf(), content: e.currentTarget.value})} rows={4} class="w-full rounded-lg border border-white/10 bg-white/5 px-3 py-2 text-sm outline-none focus:border-indigo-500/40 resize-y" />
87
- <input type="text" placeholder="Tags (comma)" value={pf().tags} onInput={e => setPf({...pf(), tags: e.currentTarget.value})} class="w-full rounded-lg border border-white/10 bg-white/5 px-3 py-2 text-sm outline-none focus:border-indigo-500/40" />
88
- <div class="flex gap-2">
89
- <button type="button" onClick={async () => { await props.admin.createPage({title:pf().title,slug:pf().slug,content:pf().content,sectionId:selectedId()!,access:pf().access as 'public'|'team'|'admin',tags:pf().tags?pf().tags.split(',').map(t=>t.trim()):[],order:sectionPages().length}); setPf({title:'',slug:'',content:'',access:'team',tags:''}); setShowPF(false) }} class="rounded-lg bg-indigo-600 px-4 py-2 text-xs font-medium hover:bg-indigo-500">Create</button>
90
- <button type="button" onClick={() => setShowPF(false)} class="rounded-lg border border-white/10 px-4 py-2 text-xs hover:bg-white/5">Cancel</button>
91
- </div>
92
- </div>
93
- </Show>
94
- <Show when={selectedSection() && sectionPages().length > 0}>
95
- <div class="space-y-1">
96
- <For each={sectionPages()}>
97
- {(page) => (
98
- <div class="group flex items-center gap-3 rounded-lg px-3 py-2.5 hover:bg-white/5">
99
- <div class="flex-1 min-w-0">
100
- <p class="text-sm font-medium text-white/80 truncate">{page.title}</p>
101
- <p class="text-[11px] text-white/30">/{page.slug}</p>
102
- </div>
103
- <span class={`shrink-0 rounded-full px-2 py-0.5 text-[10px] font-medium ${page.status === 'published' ? 'bg-emerald-500/15 text-emerald-400' : page.status === 'archived' ? 'bg-white/5 text-white/30' : 'bg-amber-500/15 text-amber-400'}`}>{page.status}</span>
104
- <div class="flex items-center gap-1 opacity-0 group-hover:opacity-100">
105
- <Show when={page.status === 'draft'}><button type="button" onClick={() => props.admin.publishPage(page.id)} class="rounded px-2 py-1 text-[11px] text-emerald-400 hover:bg-emerald-500/10">Publish</button></Show>
106
- <Show when={page.status === 'published'}><button type="button" onClick={() => props.admin.archivePage(page.id)} class="rounded px-2 py-1 text-[11px] text-amber-400 hover:bg-amber-500/10">Archive</button></Show>
107
- <button type="button" onClick={() => { if (confirm(`Delete "${page.title}"?`)) props.admin.deletePage(page.id) }} class="rounded p-1 text-white/20 hover:text-red-400">✕</button>
108
- </div>
109
- </div>
110
- )}
111
- </For>
112
- </div>
113
- </Show>
114
- <Show when={selectedSection() && sectionPages().length === 0 && !showPF()}>
115
- <p class="py-12 text-center text-sm text-white/30">No pages in this section</p>
116
- </Show>
117
- </div>
118
- </div>
119
- </div>
120
- </div>
121
- </Show>
122
- )
123
- }
@@ -1,85 +0,0 @@
1
- import { createSignal, createEffect, createMemo, For, Show, onCleanup } from 'solid-js'
2
- import type { DocPage, DocSection, SearchResult } from '@geenius-docs/shared'
3
- import { buildDocsIndex, searchDocs } from '@geenius-docs/shared'
4
- import { createDocs } from '../primitives/createDocs'
5
- import { createDocSearch } from '../primitives/createDocSearch'
6
- import { DocSearch } from '../components/DocSearch'
7
-
8
- interface DocsIndexPageProps {
9
- tree: () => (DocSection & { pages: DocPage[]; pageCount: number })[] | undefined
10
- onSelectPage?: (page: DocPage, section: DocSection) => void
11
- }
12
-
13
- export function DocsIndexPage(props: DocsIndexPageProps) {
14
- const docs = createDocs(props.tree)
15
- const [isSearchOpen, setIsSearchOpen] = createSignal(false)
16
-
17
- const searchFn = (q: string): SearchResult[] => {
18
- const index = buildDocsIndex(docs.flatPages(), docs.sections())
19
- return searchDocs(q, index)
20
- }
21
-
22
- const search = createDocSearch(searchFn)
23
-
24
- createEffect(() => {
25
- const handler = (e: KeyboardEvent) => {
26
- if ((e.metaKey || e.ctrlKey) && e.key === 'k') { e.preventDefault(); setIsSearchOpen(true) }
27
- }
28
- document.addEventListener('keydown', handler)
29
- onCleanup(() => document.removeEventListener('keydown', handler))
30
- })
31
-
32
- return (
33
- <Show when={!docs.isLoading()} fallback={
34
- <div class="min-h-screen bg-[#090a0f] px-6 py-16">
35
- <div class="mx-auto max-w-5xl">
36
- <div class="mb-10 h-10 w-64 animate-pulse rounded-lg bg-white/5" />
37
- <div class="mb-8 h-12 w-full max-w-xl animate-pulse rounded-xl bg-white/5" />
38
- <div class="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
39
- <For each={Array(6)}>{() => <div class="h-36 animate-pulse rounded-xl bg-white/5" />}</For>
40
- </div>
41
- </div>
42
- </div>
43
- }>
44
- <Show when={docs.sections().length > 0} fallback={
45
- <div class="flex min-h-screen flex-col items-center justify-center bg-[#090a0f] text-center">
46
- <div class="mb-4 text-6xl opacity-30">📚</div>
47
- <h2 class="mb-2 text-xl font-semibold text-white/80">No documentation yet</h2>
48
- <p class="max-w-sm text-sm text-white/40">Create your first section and pages to get started.</p>
49
- </div>
50
- }>
51
- <div class="min-h-screen bg-[#090a0f] text-white">
52
- <div class="mx-auto max-w-5xl px-6 py-16">
53
- <h1 class="mb-2 text-4xl font-bold tracking-tight">Documentation</h1>
54
- <p class="mb-10 text-lg text-white/50">Browse guides, API references, and tutorials.</p>
55
- <button type="button" onClick={() => setIsSearchOpen(true)}
56
- class="mb-12 flex w-full max-w-xl items-center gap-3 rounded-xl border border-white/10 bg-white/5 px-5 py-3.5 text-left text-sm text-white/30 transition-colors hover:border-white/20">
57
- <svg class="h-4.5 w-4.5 shrink-0" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M9 3.5a5.5 5.5 0 100 11 5.5 5.5 0 000-11zM2 9a7 7 0 1112.452 4.391l3.328 3.329a.75.75 0 11-1.06 1.06l-3.329-3.328A7 7 0 012 9z" clip-rule="evenodd" /></svg>
58
- <span class="flex-1">Search documentation…</span>
59
- <kbd class="rounded border border-white/10 bg-white/5 px-2 py-0.5 text-[11px]">⌘K</kbd>
60
- </button>
61
- <div class="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
62
- <For each={docs.sections().filter(s => !s.parentId)}>
63
- {(section) => (
64
- <button type="button" onClick={() => { const fp = section.pages?.[0]; if (fp && props.onSelectPage) props.onSelectPage(fp, section) }}
65
- class="group flex flex-col rounded-xl border border-white/8 bg-white/[0.03] p-5 text-left transition-all hover:border-indigo-500/30 hover:bg-white/[0.06]">
66
- <Show when={section.icon}><span class="mb-3 text-2xl">{section.icon}</span></Show>
67
- <h3 class="mb-1.5 text-base font-semibold text-white/90 group-hover:text-white">{section.title}</h3>
68
- <Show when={section.description}><p class="mb-3 flex-1 text-sm leading-relaxed text-white/40">{section.description}</p></Show>
69
- <div class="text-xs text-white/25"><span>{section.pageCount ?? 0} pages</span></div>
70
- </button>
71
- )}
72
- </For>
73
- </div>
74
- </div>
75
- <DocSearch results={search.results()} query={search.query()} onQuery={search.setQuery}
76
- onSelect={(result) => { setIsSearchOpen(false); search.clearSearch();
77
- const section = docs.sections().find(s => s.slug === result.sectionSlug)
78
- const page = docs.flatPages().find(p => p.id === result.pageId)
79
- if (page && section && props.onSelectPage) props.onSelectPage(page, section)
80
- }} isOpen={isSearchOpen()} onClose={() => setIsSearchOpen(false)} />
81
- </div>
82
- </Show>
83
- </Show>
84
- )
85
- }
@@ -1,4 +0,0 @@
1
- export { DocsIndexPage } from './DocsIndexPage'
2
- export { DocViewPage } from './DocViewPage'
3
- export { DocSearchPage } from './DocSearchPage'
4
- export { DocsAdminPage } from './DocsAdminPage'
@@ -1,42 +0,0 @@
1
- import { createSignal, createEffect, onCleanup } from 'solid-js'
2
- import type { SearchResult } from '@geenius-docs/shared'
3
-
4
- export function createDocSearch(
5
- searchFn: (query: string) => SearchResult[] | Promise<SearchResult[]>,
6
- debounceMs = 250
7
- ) {
8
- const [query, setQuery] = createSignal('')
9
- const [results, setResults] = createSignal<SearchResult[]>([])
10
- const [isSearching, setIsSearching] = createSignal(false)
11
-
12
- createEffect(() => {
13
- const q = query()
14
- if (!q.trim()) {
15
- setResults([])
16
- setIsSearching(false)
17
- return
18
- }
19
-
20
- setIsSearching(true)
21
- const timer = setTimeout(async () => {
22
- try {
23
- const r = await searchFn(q)
24
- setResults(r)
25
- } catch {
26
- setResults([])
27
- } finally {
28
- setIsSearching(false)
29
- }
30
- }, debounceMs)
31
-
32
- onCleanup(() => clearTimeout(timer))
33
- })
34
-
35
- const clearSearch = () => {
36
- setQuery('')
37
- setResults([])
38
- setIsSearching(false)
39
- }
40
-
41
- return { results, isSearching, query, setQuery, clearSearch }
42
- }
@@ -1,35 +0,0 @@
1
- import { createSignal, createMemo } from 'solid-js'
2
- import type { DocPage, DocSection, DocsConfig } from '@geenius-docs/shared'
3
- import { defaultDocsConfig } from '@geenius-docs/shared'
4
-
5
- export function createDocs(
6
- tree: () => (DocSection & { pages: DocPage[]; pageCount: number })[] | undefined,
7
- config?: Partial<DocsConfig>
8
- ) {
9
- const [currentSection, setSection] = createSignal<DocSection | null>(null)
10
- const [currentPage, setPage] = createSignal<DocPage | null>(null)
11
- const [searchQuery, setSearchQuery] = createSignal('')
12
-
13
- const mergedConfig = createMemo(() => ({ ...defaultDocsConfig, ...config }))
14
- const sections = createMemo(() => tree() ?? [])
15
- const flatPages = createMemo(() => sections().flatMap((s) => s.pages ?? []))
16
- const isLoading = createMemo(() => tree() === undefined)
17
-
18
- const handleSetSection = (section: DocSection | null) => {
19
- setSection(section)
20
- setPage(null)
21
- }
22
-
23
- return {
24
- sections,
25
- currentSection,
26
- setSection: handleSetSection,
27
- currentPage,
28
- setPage,
29
- searchQuery,
30
- setSearchQuery,
31
- isLoading,
32
- config: mergedConfig,
33
- flatPages,
34
- }
35
- }
@@ -1,63 +0,0 @@
1
- export function createDocsAdmin(mutations: {
2
- createSection: (args: Record<string, unknown>) => Promise<unknown>
3
- updateSection: (args: Record<string, unknown>) => Promise<unknown>
4
- deleteSection: (args: Record<string, unknown>) => Promise<unknown>
5
- reorderSections: (args: Record<string, unknown>) => Promise<unknown>
6
- createPage: (args: Record<string, unknown>) => Promise<unknown>
7
- updatePage: (args: Record<string, unknown>) => Promise<unknown>
8
- publishPage: (args: Record<string, unknown>) => Promise<unknown>
9
- archivePage: (args: Record<string, unknown>) => Promise<unknown>
10
- deletePage: (args: Record<string, unknown>) => Promise<unknown>
11
- reorderPages: (args: Record<string, unknown>) => Promise<unknown>
12
- movePage: (args: Record<string, unknown>) => Promise<unknown>
13
- }) {
14
- return {
15
- createSection: async (data: {
16
- title: string; slug: string; parentId?: string; order: number
17
- icon?: string; description?: string; access: 'public' | 'team' | 'admin'
18
- }) => { await mutations.createSection(data) },
19
-
20
- updateSection: async (sectionId: string, data: Record<string, unknown>) => {
21
- await mutations.updateSection({ sectionId, ...data })
22
- },
23
-
24
- deleteSection: async (sectionId: string) => {
25
- await mutations.deleteSection({ sectionId })
26
- },
27
-
28
- reorderSections: async (sectionIds: string[]) => {
29
- await mutations.reorderSections({ sectionIds })
30
- },
31
-
32
- createPage: async (data: {
33
- title: string; slug: string; content: string; sectionId: string
34
- access: 'public' | 'team' | 'admin'; tags?: string[]; version?: string
35
- status?: 'draft' | 'published' | 'archived'; author?: { name: string; avatar?: string }
36
- excerpt?: string; order?: number
37
- }) => { await mutations.createPage(data) },
38
-
39
- updatePage: async (pageId: string, data: Record<string, unknown>) => {
40
- await mutations.updatePage({ pageId, ...data })
41
- },
42
-
43
- publishPage: async (pageId: string) => {
44
- await mutations.publishPage({ pageId })
45
- },
46
-
47
- archivePage: async (pageId: string) => {
48
- await mutations.archivePage({ pageId })
49
- },
50
-
51
- deletePage: async (pageId: string) => {
52
- await mutations.deletePage({ pageId })
53
- },
54
-
55
- reorderPages: async (pageIds: string[]) => {
56
- await mutations.reorderPages({ pageIds })
57
- },
58
-
59
- movePage: async (pageId: string, newSectionId: string, newOrder: number) => {
60
- await mutations.movePage({ pageId, newSectionId, newOrder })
61
- },
62
- }
63
- }
@@ -1,51 +0,0 @@
1
- import { createSignal, createEffect, createMemo, onCleanup } from 'solid-js'
2
- import type { TocItem } from '@geenius-docs/shared'
3
- import { extractToc } from '@geenius-docs/shared'
4
-
5
- export function createTableOfContents(mdxContent: () => string | undefined) {
6
- const [activeId, setActiveId] = createSignal('')
7
-
8
- const toc = createMemo<TocItem[]>(() => {
9
- const content = mdxContent()
10
- if (!content) return []
11
- return extractToc(content)
12
- })
13
-
14
- const flatIds = createMemo(() => {
15
- const ids: string[] = []
16
- const collect = (items: TocItem[]) => {
17
- for (const item of items) {
18
- ids.push(item.id)
19
- collect(item.children)
20
- }
21
- }
22
- collect(toc())
23
- return ids
24
- })
25
-
26
- createEffect(() => {
27
- const ids = flatIds()
28
- if (ids.length === 0) return
29
-
30
- const observer = new IntersectionObserver(
31
- (entries) => {
32
- for (const entry of entries) {
33
- if (entry.isIntersecting) {
34
- setActiveId(entry.target.id)
35
- break
36
- }
37
- }
38
- },
39
- { rootMargin: '-80px 0px -70% 0px', threshold: 0 }
40
- )
41
-
42
- for (const id of ids) {
43
- const el = document.getElementById(id)
44
- if (el) observer.observe(el)
45
- }
46
-
47
- onCleanup(() => observer.disconnect())
48
- })
49
-
50
- return { toc, activeId, setActiveId }
51
- }
@@ -1,4 +0,0 @@
1
- export { createDocs } from './createDocs'
2
- export { createDocSearch } from './createDocSearch'
3
- export { createDocsAdmin } from './createDocsAdmin'
4
- export { createTableOfContents } from './createTableOfContents'
@@ -1,12 +0,0 @@
1
- import { defineConfig } from 'tsup'
2
-
3
- export default defineConfig({
4
- entry: { index: 'src/index.tsx' },
5
- outDir: 'dist',
6
- format: ['esm'],
7
- dts: true,
8
- sourcemap: true,
9
- clean: true,
10
- treeshake: true,
11
- external: ['solid-js'],
12
- })
@@ -1 +0,0 @@
1
- # ✦ @geenius-docs/solidjs-css\n\n> Geenius Docs — SolidJS components (vanilla CSS variant)\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-css\n```\n\n## Usage\n\n```typescript\nimport { init } from '@geenius-docs/solidjs-css';\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
@@ -1,36 +0,0 @@
1
- {
2
- "name": "@geenius-docs/solidjs-css",
3
- "version": "0.1.0",
4
- "description": "Geenius Docs \u2014 SolidJS components (vanilla CSS variant)",
5
- "type": "module",
6
- "main": "./src/index.ts",
7
- "types": "./src/index.ts",
8
- "exports": {
9
- ".": "./src/index.ts"
10
- },
11
- "scripts": {
12
- "type-check": "tsc --noEmit"
13
- },
14
- "peerDependencies": {
15
- "solid-js": ">=1.6.0",
16
- "@tanstack/solid-router": ">=1.0.0"
17
- },
18
- "dependencies": {
19
- "@geenius-docs/shared": "workspace:*",
20
- "lucide-solid": "^0.475.0",
21
- "solid-markdown": "^1.2.0",
22
- "remark-gfm": "^4.0.1"
23
- },
24
- "devDependencies": {
25
- "solid-js": "^1.9.5",
26
- "typescript": "~6.0.2"
27
- },
28
- "author": "Antigravity HQ",
29
- "license": "MIT",
30
- "engines": {
31
- "node": ">=20.0.0"
32
- },
33
- "publishConfig": {
34
- "access": "public"
35
- }
36
- }