@kolkrabbi/kol-workshop 0.3.1 → 0.3.2
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kolkrabbi/kol-workshop",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "KOL workshop/docs system — a handrolled markdown engine, search, tag system (incl. a d3 tag graph), docs viewer, and docs shell. Sits above @kolkrabbi/kol-{theme,icons,component,framework}; content is consumer-injected (the package never globs docs).",
|
|
6
6
|
"license": "MIT",
|
|
@@ -14,10 +14,10 @@
|
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"d3": "^7.9.0",
|
|
16
16
|
"@kolkrabbi/kol-brand": "^0.1.2",
|
|
17
|
+
"@kolkrabbi/kol-component": "0.14.0",
|
|
17
18
|
"@kolkrabbi/kol-icons": "0.8.10",
|
|
18
|
-
"@kolkrabbi/kol-
|
|
19
|
-
"@kolkrabbi/kol-
|
|
20
|
-
"@kolkrabbi/kol-theme": "0.12.2"
|
|
19
|
+
"@kolkrabbi/kol-framework": "0.7.0",
|
|
20
|
+
"@kolkrabbi/kol-theme": "0.13.0"
|
|
21
21
|
},
|
|
22
22
|
"peerDependencies": {
|
|
23
23
|
"react": "^18.3.0 || ^19.0.0",
|
|
@@ -172,6 +172,13 @@ const DocumentationReader = ({
|
|
|
172
172
|
|
|
173
173
|
const rawMarkdown = useMemo(() => {
|
|
174
174
|
if (!doc) return null
|
|
175
|
+
/* Primary resolution (2026-07-30): through the doc's own file path — exact
|
|
176
|
+
* and collision-proof (the endsWith(docId) heuristic below grabbed the
|
|
177
|
+
* FIRST basename match, so duplicate filenames across folders rendered the
|
|
178
|
+
* wrong doc). The heuristic stays as a fallback for hand-built inventories
|
|
179
|
+
* whose `file` doesn't mirror the module keys. */
|
|
180
|
+
const byFile = doc.file && Object.keys(modules).find((p) => p.endsWith(doc.file))
|
|
181
|
+
if (byFile) return modules[byFile]
|
|
175
182
|
// For index files, the docId is like "00-metadata-index" but the file is "index.md"
|
|
176
183
|
// For regular files, docId matches the filename (e.g., "0.0.1-writing-guidelines")
|
|
177
184
|
const path = Object.keys(modules).find((p) => {
|
|
@@ -25,17 +25,27 @@ export function buildInventory(modules) {
|
|
|
25
25
|
const parentFolder = normalisedPath.split('/').slice(-2, -1)[0] ?? ''
|
|
26
26
|
const baseId = filename.replace(/\.md$/, '')
|
|
27
27
|
|
|
28
|
-
// Make index.md IDs unique by prefixing with parent folder
|
|
29
|
-
const id = baseId === 'index' ? `${parentFolder}
|
|
28
|
+
// Make index.md / INDEX.md IDs unique by prefixing with parent folder
|
|
29
|
+
const id = baseId.toLowerCase() === 'index' ? `${parentFolder}-${baseId}` : baseId
|
|
30
30
|
|
|
31
31
|
const rawTitle = title || metadata.title || id
|
|
32
32
|
const cleanTitle = rawTitle
|
|
33
33
|
.replace(/^Design System\s*[-–—:]\s*/i, '')
|
|
34
34
|
.replace(/\bCheat Sheet\b/i, 'Quicklook')
|
|
35
35
|
|
|
36
|
-
return { id, file: normalisedPath, title: cleanTitle, metadata }
|
|
36
|
+
return { id, file: normalisedPath, title: cleanTitle, metadata, parentFolder }
|
|
37
37
|
})
|
|
38
38
|
|
|
39
|
+
/* Collision safety (2026-07-30): filename-only ids collide across folders in
|
|
40
|
+
* any real vault (02-icons/01-inventory vs 03-components/01-inventory — the
|
|
41
|
+
* React dup-key bug from the 07-29 vault experiment). A collided id gains
|
|
42
|
+
* its parent folder, same convention the index handling already uses. */
|
|
43
|
+
const counts = inventory.reduce((m, d) => (m[d.id] = (m[d.id] ?? 0) + 1, m), {})
|
|
44
|
+
for (const d of inventory) {
|
|
45
|
+
if (counts[d.id] > 1) d.id = `${d.parentFolder}-${d.id}`
|
|
46
|
+
}
|
|
47
|
+
for (const d of inventory) delete d.parentFolder
|
|
48
|
+
|
|
39
49
|
inventory.sort((a, b) => a.file.localeCompare(b.file))
|
|
40
50
|
return inventory
|
|
41
51
|
}
|
|
@@ -21,8 +21,12 @@ export const ShellFullHeightContext = createContext(null)
|
|
|
21
21
|
// useLayoutEffect(() => { setTocCollapsed(true) ; return () => setTocCollapsed(false) }, [setTocCollapsed])
|
|
22
22
|
export const ShellTocCollapsedContext = createContext(null)
|
|
23
23
|
|
|
24
|
+
/* overflow-x-hidden (2026-07-30): long tree rows (component names + counters)
|
|
25
|
+
* overflowed the 256px rail into an internal horizontal scroll — with the
|
|
26
|
+
* scrollbar hidden it read as content silently walking off, and the pan
|
|
27
|
+
* gesture shoved the whole grid sideways exposing the outer padding. */
|
|
24
28
|
const NavColumn = ({ children }) => (
|
|
25
|
-
<aside aria-label="Navigation" className="shell-sidebar-sticky hidden lg:block shrink-0 h-full min-h-0 overflow-y-auto overscroll-none pt-6 md:pt-6 lg:pt-8 pb-8">
|
|
29
|
+
<aside aria-label="Navigation" className="shell-sidebar-sticky hidden lg:block shrink-0 h-full min-h-0 overflow-y-auto overflow-x-hidden overscroll-none pt-6 md:pt-6 lg:pt-8 pb-8">
|
|
26
30
|
{children}
|
|
27
31
|
</aside>
|
|
28
32
|
)
|
|
@@ -41,7 +45,7 @@ const MainColumn = ({ children, fullHeight }) => (
|
|
|
41
45
|
)
|
|
42
46
|
|
|
43
47
|
const TocColumn = ({ children }) => (
|
|
44
|
-
<aside aria-label="Table of contents" className="shell-sidebar-sticky hidden lg:block shrink-0 h-full min-h-0 overflow-y-auto overscroll-none pt-6 md:pt-6 lg:pt-8 pb-8">
|
|
48
|
+
<aside aria-label="Table of contents" className="shell-sidebar-sticky hidden lg:block shrink-0 h-full min-h-0 overflow-y-auto overflow-x-hidden overscroll-none pt-6 md:pt-6 lg:pt-8 pb-8">
|
|
45
49
|
{children}
|
|
46
50
|
</aside>
|
|
47
51
|
)
|