@kolkrabbi/kol-workshop 0.25.0 → 0.27.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kolkrabbi/kol-workshop",
3
- "version": "0.25.0",
3
+ "version": "0.27.0",
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",
@@ -25,10 +25,10 @@
25
25
  "react-router-dom": "^6.0.0 || ^7.0.0"
26
26
  },
27
27
  "devDependencies": {
28
- "@kolkrabbi/kol-component": "^0.145.0",
29
- "@kolkrabbi/kol-icons": "^0.25.0",
30
28
  "@kolkrabbi/kol-framework": "^0.36.0",
31
- "@kolkrabbi/kol-theme": "^0.112.0"
29
+ "@kolkrabbi/kol-icons": "^0.25.0",
30
+ "@kolkrabbi/kol-theme": "^0.122.0",
31
+ "@kolkrabbi/kol-component": "^0.153.0"
32
32
  },
33
33
  "files": [
34
34
  "src",
@@ -36,6 +36,15 @@ export const ShellContentWidthContext = createContext(null)
36
36
  // useLayoutEffect(() => { setTocCollapsed(true) ; return () => setTocCollapsed(false) }, [setTocCollapsed])
37
37
  export const ShellTocCollapsedContext = createContext(null)
38
38
 
39
+ // THE LEFT RAIL IS THE PAGE'S CALL TOO (2026-09-01). The TOC had this seam and
40
+ // the nav did not, so a landing page could shed one rail and not the other —
41
+ // the showcase home claimed "top nav (no sidebar)" in its docstring and rendered
42
+ // under both. Same shape as the TOC seam: set on mount, restore on unmount, and
43
+ // the header's own toggles keep working on top of it.
44
+ // Usage: const setNavCollapsed = useContext(ShellNavCollapsedContext)
45
+ // useLayoutEffect(() => { setNavCollapsed(true) ; return () => setNavCollapsed(false) }, [setNavCollapsed])
46
+ export const ShellNavCollapsedContext = createContext(null)
47
+
39
48
  /* overflow-x-hidden (2026-07-30): long tree rows (component names + counters)
40
49
  * overflowed the 256px rail into an internal horizontal scroll — with the
41
50
  * scrollbar hidden it read as content silently walking off, and the pan
@@ -117,6 +126,22 @@ const ShellLayout = ({ routes = [], basePath = '/', brand: brandProp, brandLogoS
117
126
  const setIsSearchOpen = tagMode.isProvided
118
127
  ? (v) => (v ? tagMode.openTagMode() : tagMode.closeTagMode())
119
128
  : setLocalOpen
129
+ /* CLOSE IS ONE CALL (WorkshopSearchCloseUndoneBySetText, kol-website
130
+ * 2026-09-01). Close-and-clear was two: `setIsSearchOpen(false)` then
131
+ * `setSearchQuery('')` — and on the provided path the second is
132
+ * `tagMode.setText`, which force-opens, so both landed in one React batch
133
+ * and the final state was OPEN. The scrim tap (and desktop click) was
134
+ * undone in its own event; Escape only worked because the context's window
135
+ * listener runs after and wins. `closeTagMode()` already resets `text`; the
136
+ * trailing clear is only the local path's job. */
137
+ const closeSearch = () => {
138
+ if (tagMode.isProvided) {
139
+ tagMode.closeTagMode()
140
+ } else {
141
+ setLocalOpen(false)
142
+ setLocalQuery('')
143
+ }
144
+ }
120
145
  const [tocContent, setTocContent] = useState(null)
121
146
  const [isFullHeight, setIsFullHeight] = useState(false)
122
147
  const [contentWidth, setContentWidth] = useState('canvas')
@@ -263,6 +288,7 @@ const ShellLayout = ({ routes = [], basePath = '/', brand: brandProp, brandLogoS
263
288
  <ShellFullHeightContext.Provider value={setIsFullHeight}>
264
289
  <ShellContentWidthContext.Provider value={setContentWidth}>
265
290
  <ShellTocCollapsedContext.Provider value={setTocCollapsed}>
291
+ <ShellNavCollapsedContext.Provider value={setNavCollapsed}>
266
292
  <div className="fixed inset-0 flex flex-col bg-surface-primary text-auto">
267
293
  <ShellHeader
268
294
  brand={brand}
@@ -362,7 +388,7 @@ const ShellLayout = ({ routes = [], basePath = '/', brand: brandProp, brandLogoS
362
388
  * Selecting routes to item.href; matchSearchItems is the engine's. */}
363
389
  <ShellSearchOverlay
364
390
  open={isSearchOpen}
365
- onClose={() => { setIsSearchOpen(false); setSearchQuery('') }}
391
+ onClose={closeSearch}
366
392
  query={searchQuery}
367
393
  onQueryChange={setSearchQuery}
368
394
  results={searchResults}
@@ -385,8 +411,7 @@ const ShellLayout = ({ routes = [], basePath = '/', brand: brandProp, brandLogoS
385
411
  setSearchQuery('')
386
412
  return
387
413
  }
388
- setIsSearchOpen(false)
389
- setSearchQuery('')
414
+ closeSearch()
390
415
  if (item?.href) navigate(item.href)
391
416
  }}
392
417
  >
@@ -437,6 +462,7 @@ const ShellLayout = ({ routes = [], basePath = '/', brand: brandProp, brandLogoS
437
462
  </div>
438
463
  )}
439
464
  </div>
465
+ </ShellNavCollapsedContext.Provider>
440
466
  </ShellTocCollapsedContext.Provider>
441
467
  </ShellContentWidthContext.Provider>
442
468
  </ShellFullHeightContext.Provider>
@@ -7,7 +7,7 @@
7
7
  * against.
8
8
  */
9
9
  export { default as ShellLayout } from './ShellLayout.jsx'
10
- export { ShellTocContext, ShellFullHeightContext, ShellTocCollapsedContext, ShellContentWidthContext } from './ShellLayout.jsx'
10
+ export { ShellTocContext, ShellFullHeightContext, ShellTocCollapsedContext, ShellNavCollapsedContext, ShellContentWidthContext } from './ShellLayout.jsx'
11
11
  export { default as ShellSidebar } from './ShellSidebar.jsx'
12
12
  /* RailSection — THE rail ladder. Every rail header at every rung comes from
13
13
  * here, in both rails; see the file header for why a class alone was not