@kolkrabbi/kol-shell 0.64.0 → 0.65.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-shell",
3
- "version": "0.64.0",
3
+ "version": "0.65.0",
4
4
  "private": false,
5
5
  "description": "The application shell",
6
6
  "license": "MIT",
@@ -12,7 +12,7 @@
12
12
  "./src/*": "./src/*"
13
13
  },
14
14
  "peerDependencies": {
15
- "@kolkrabbi/kol-component": ">=0.246.0",
15
+ "@kolkrabbi/kol-component": ">=0.265.0",
16
16
  "@kolkrabbi/kol-icons": ">=0.16.0",
17
17
  "@kolkrabbi/kol-theme": ">=0.165.0",
18
18
  "gsap": "^3.13.0",
@@ -20,10 +20,10 @@
20
20
  "react-dom": "^18.3.0 || ^19.0.0"
21
21
  },
22
22
  "devDependencies": {
23
+ "@kolkrabbi/kol-component": "^0.265.0",
24
+ "@kolkrabbi/kol-icons": "^0.39.0",
23
25
  "@kolkrabbi/kol-framework": "^0.49.0",
24
- "@kolkrabbi/kol-theme": "^0.174.0",
25
- "@kolkrabbi/kol-icons": "^0.38.0",
26
- "@kolkrabbi/kol-component": "^0.261.0"
26
+ "@kolkrabbi/kol-theme": "^0.174.0"
27
27
  },
28
28
  "files": [
29
29
  "src",
package/src/AppHub.jsx CHANGED
@@ -2,6 +2,7 @@ import { useEffect, useState } from 'react'
2
2
  import AppShell from './AppShell.jsx'
3
3
  import HubHome from './HubHome.jsx'
4
4
  import HubSettings from './HubSettings.jsx'
5
+ import HubDev from './HubDev.jsx'
5
6
  import { ShortcutsOverlay } from '@kolkrabbi/kol-component'
6
7
 
7
8
  /* taxonomy-ok: organism — nests AppShell / HubHome / HubSettings / ShortcutsOverlay (relative) */
@@ -37,6 +38,9 @@ import { ShortcutsOverlay } from '@kolkrabbi/kol-component'
37
38
  * OPT-IN like AppShell's `bottomItems` (apps review 2026-09-29: *"not sure it makes sense
38
39
  * to neccessarily have settings manditory part of the rail"*) — no `settings`, no rail
39
40
  * row, no route, no `,` key. It was pinned whether the app had settings or not.
41
+ * @param {Object} dev HubDev's props (`tabs`, `title`, `subtitle`) + `path` (default `/dev`). OPT-IN, and only on
42
+ * a dev server (`import.meta.env.DEV`; `always: true` overrides) — a `code` row above
43
+ * Settings (CompareGridDevTab, kol-monitor 2026-10-17)
40
44
  * @param {Array} shortcuts `[{ section, items: [{ id, label, combo }] }]` — the sheet AND Settings
41
45
  * @param {ReactNode} themeToggle Settings' masthead toggle (a node — kol-framework is not a peer)
42
46
  * @param {string} shortcutsKey default `s`; `null` turns the sheet key off (a tool that owns S)
@@ -55,6 +59,7 @@ export default function AppHub({
55
59
  home,
56
60
  walkthrough,
57
61
  settings,
62
+ dev,
58
63
  shortcuts = [],
59
64
  themeToggle,
60
65
  settingsPath = '/settings',
@@ -79,12 +84,18 @@ export default function AppHub({
79
84
  return () => window.removeEventListener('keydown', onKey)
80
85
  }, [shortcutsKey])
81
86
 
87
+ /* the dev page is a dev server's only — a production build never routes it or draws its row */
88
+ const devOn = !!dev && (dev.always || !!import.meta.env?.DEV)
89
+ const devPath = dev?.path ?? '/dev'
90
+ const { path: _dp, always: _da, ...devProps } = dev ?? {}
82
91
  const page = home && currentPath === homePath
83
92
  ? <HubHome app={app} iconComponent={iconComponent} walkthrough={walkthrough} {...home} />
84
93
  : settings && currentPath === settingsPath
85
94
  ? <HubSettings app={app} shortcuts={shortcuts} themeToggle={themeToggle} {...settings} />
86
- : children
87
- const bottom = settings ? SETTINGS_ROW(settingsPath) : []
95
+ : devOn && (currentPath === devPath || currentPath?.startsWith(`${devPath}/`))
96
+ ? <HubDev storageKey={`kol-dev-tab:${app.name ?? 'app'}`} {...devProps} />
97
+ : children
98
+ const bottom = [...(devOn ? [{ icon: 'code', path: devPath, label: 'Dev' }] : []), ...(settings ? SETTINGS_ROW(settingsPath) : [])]
88
99
  /* the phone bar lists Home as a tab — the rail draws it as the mark, the bar has no mark */
89
100
  const barItems = [...(home ? [{ icon: 'home-01', path: homePath, label: 'Home' }] : []), ...items, ...bottom]
90
101
 
@@ -111,7 +122,7 @@ export default function AppHub({
111
122
  {...shell}
112
123
  >
113
124
  {page}
114
- {sheet && <ShortcutsOverlay shortcuts={shortcuts} onClose={() => setSheet(false)} />}
125
+ {sheet && <ShortcutsOverlay shortcuts={shortcuts} currentPath={currentPath} onClose={() => setSheet(false)} />}
115
126
  </AppShell>
116
127
  )
117
128
  }
package/src/AppStudio.jsx CHANGED
@@ -37,6 +37,7 @@ import PageShell from './PageShell.jsx'
37
37
  * @param {Object} [use] `{ children, path, label, icon }` — the tool
38
38
  * @param {Array} [pages] `[{ path, icon, label, children }]` — opt-in pages, after Use
39
39
  * @param {Object} [settings] HubSettings' props
40
+ * @param {Object} [dev] HubDev's props — AppHub's `dev`: a dev server's `code` page at `/dev`
40
41
  * @param {'mono'|'display'} [masthead='mono']
41
42
  * @param {Object} [shell] any AppShell prop, spread last
42
43
  */
@@ -51,6 +52,7 @@ export default function AppStudio({
51
52
  use,
52
53
  pages = [],
53
54
  settings,
55
+ dev,
54
56
  walkthrough,
55
57
  shortcuts,
56
58
  themeToggle,
@@ -92,6 +94,7 @@ export default function AppStudio({
92
94
  home={home}
93
95
  walkthrough={walkthrough}
94
96
  settings={settings}
97
+ dev={dev}
95
98
  shortcuts={shortcuts}
96
99
  themeToggle={themeToggle}
97
100
  shortcutsKey={shortcutsKey}
package/src/HubDev.jsx ADDED
@@ -0,0 +1,46 @@
1
+ import { useState } from 'react'
2
+ import { PageHeader } from '@kolkrabbi/kol-component'
3
+ import PageShell from './PageShell.jsx'
4
+ import TabStrip from './TabStrip.jsx'
5
+
6
+ /* taxonomy-ok: organism — nests PageShell / TabStrip (relative) + kol-component's PageHeader */
7
+
8
+ const read = (key, fallback) => { try { return localStorage.getItem(key) ?? fallback } catch { return fallback } }
9
+ const write = (key, value) => { try { localStorage.setItem(key, value) } catch { /* private mode: the tab just resets */ } }
10
+
11
+ /**
12
+ * HubDev — A hub's development page. The one rail row for everything that is not the app yet: experiments,
13
+ * references, comparisons (CompareGridDevTab, kol-monitor 2026-10-17 — user: *"I would also maybe add
14
+ * instructions for making the dev tab to the hub … localhost only using the </> icon"*). Each app had built
15
+ * this page by hand and each read differently; this is the page made once, for reading.
16
+ *
17
+ * The shape: a small mono masthead with one line saying what the page is, the tabs on their own row under
18
+ * it, the active tab's one-line description, then the tab's content at full width. Detail belongs in the
19
+ * content's own toggles, not in more text here. The open tab is remembered per app.
20
+ *
21
+ * Rendered by `AppHub` / `AppStudio` from their `dev` prop, only on a dev server (`import.meta.env.DEV`),
22
+ * at `/dev`, behind the `code` rail row.
23
+ *
24
+ * @param {Array} tabs `[{ value, label, description?, content }]`
25
+ * @param {string} [title='Dev']
26
+ * @param {string} [subtitle] one line: what the page is
27
+ * @param {string} [storageKey] where the open tab is remembered
28
+ */
29
+ export default function HubDev({ tabs = [], title = 'Dev', subtitle = 'Experiments and reference, not the app', storageKey = 'kol-dev-tab' }) {
30
+ const [stored, setStored] = useState(() => read(storageKey, tabs[0]?.value))
31
+ const active = tabs.find((t) => t.value === stored) ?? tabs[0]
32
+ const pick = (v) => { setStored(v); write(storageKey, v) }
33
+
34
+ return (
35
+ <PageShell className="gap-6">
36
+ <PageHeader size="sm" voice="mono" title={title} subtitle={subtitle} />
37
+ {tabs.length > 1 && (
38
+ <div className="flex flex-col gap-2 border-b border-fg-08 pb-4">
39
+ <TabStrip options={tabs.map(({ value, label }) => ({ value, label }))} value={active?.value} onChange={pick} tracked />
40
+ {active?.description && <p className="kol-helper-12 text-meta">{active.description}</p>}
41
+ </div>
42
+ )}
43
+ {active && <div className="min-w-0">{active.content}</div>}
44
+ </PageShell>
45
+ )
46
+ }
package/src/index.js CHANGED
@@ -26,7 +26,7 @@ export { default as TabStrip } from './TabStrip.jsx'
26
26
  export { default as SettingsScaffold } from './SettingsScaffold.jsx'
27
27
  export { default as WalkthroughPanel } from './WalkthroughPanel.jsx'
28
28
  /* lives in kol-component since 0.228.0 — re-exported so every kol-shell import keeps resolving */
29
- export { ShortcutsOverlay } from '@kolkrabbi/kol-component'
29
+ export { ShortcutsOverlay, shortcutInScope } from '@kolkrabbi/kol-component'
30
30
  export { default as Logomark } from './Logomark.jsx'
31
31
  // the app tier, shipped once (ShellHomeSystem, kol-fxr 2026-08-27)
32
32
  export { default as CatalogPage } from './CatalogPage.jsx'
@@ -37,6 +37,7 @@ export { default as TouchDeviceOverlay, useTouchPrimary } from './TouchDeviceOve
37
37
  export { default as AppHub } from './AppHub.jsx'
38
38
  export { default as HubHome } from './HubHome.jsx'
39
39
  export { default as HubSettings } from './HubSettings.jsx'
40
+ export { default as HubDev } from './HubDev.jsx'
40
41
  // the Studio — the Hub + Home · Library · Create · Use · pages · Settings, the workstation (apps review §6c, 2026-09-29)
41
42
  export { default as AppStudio } from './AppStudio.jsx'
42
43
  // a consumer slot in the opened rail — the page portals into it (NavRailConsumerSlot, kol-monitor 2026-10-15)