@kolkrabbi/kol-shell 0.3.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.
- package/package.json +5 -5
- package/src/ShortcutsOverlay.jsx +56 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kolkrabbi/kol-shell",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "KOL application shell — fixed 48px NavRail + AppShell layout root, PageShell/PageHeader scaffolds, ContentFilters catalog organism, GridCard, SettingsScaffold, WalkthroughPanel, ShortcutsOverlay. App chrome (kol-framework owns site chrome). Nav items, content, shortcuts and settings are consumer-injected. Sits above @kolkrabbi/kol-{theme,component,framework}.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -20,10 +20,10 @@
|
|
|
20
20
|
"react-dom": "^18.3.0 || ^19.0.0"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@kolkrabbi/kol-
|
|
24
|
-
"@kolkrabbi/kol-
|
|
25
|
-
"@kolkrabbi/kol-theme": "^0.
|
|
26
|
-
"@kolkrabbi/kol-
|
|
23
|
+
"@kolkrabbi/kol-component": "^0.46.0",
|
|
24
|
+
"@kolkrabbi/kol-framework": "^0.22.0",
|
|
25
|
+
"@kolkrabbi/kol-theme": "^0.43.1",
|
|
26
|
+
"@kolkrabbi/kol-icons": "^0.17.0"
|
|
27
27
|
},
|
|
28
28
|
"files": [
|
|
29
29
|
"src",
|
package/src/ShortcutsOverlay.jsx
CHANGED
|
@@ -2,15 +2,50 @@ import { useEffect } from 'react'
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* ShortcutsOverlay — the keyboard-shortcut sheet: blurred scrim, centred
|
|
5
|
-
* panel,
|
|
5
|
+
* panel, a 2-col grid (label · keys), Esc / backdrop-click close.
|
|
6
6
|
* Ported from the shared cut (mirror's, "copied from kol-monitor").
|
|
7
7
|
*
|
|
8
8
|
* `shortcuts` is a prop — feed the SAME array your settings page renders
|
|
9
9
|
* (both repos hand-maintained the list twice and both pairs drifted).
|
|
10
10
|
* Stacks at `--kol-z-modal`, above the rail's sticky tier.
|
|
11
11
|
*
|
|
12
|
-
*
|
|
12
|
+
* TWO FORMS, DETECTED ON SHAPE (ShortcutsOverlaySections, kol-fxr 2026-08-15):
|
|
13
|
+
*
|
|
14
|
+
* flat `[{ label, keys }]` — one grid, as shipped
|
|
15
|
+
* sectioned `[{ section, items: [{label,keys}] }]` — headings between groups
|
|
16
|
+
*
|
|
17
|
+
* The flat form renders EXACTLY as it did before, so no existing caller moves.
|
|
18
|
+
* The sectioned form exists because a real keymap is grouped — kol-fxr's is
|
|
19
|
+
* Edit · Selection · Layer · Tools · View, and its `shortcutsBySection()`
|
|
20
|
+
* already emits this shape — and flattening it to adopt this component would
|
|
21
|
+
* have lost the grouping. That consumer kept a 99-line local overlay instead,
|
|
22
|
+
* which is the duplication this component exists to end.
|
|
23
|
+
*
|
|
24
|
+
* ONE GRID, NOT NESTED ONES. The headings span both columns
|
|
25
|
+
* (`gridColumn: 1 / -1`) so every `keys` cell in the sheet stays on the same
|
|
26
|
+
* axis — nesting a grid per section would let each group compute its own
|
|
27
|
+
* column width and the keys would stagger down the panel.
|
|
28
|
+
*
|
|
29
|
+
* `keys` is a DISPLAY STRING and is never bound — this component shows a
|
|
30
|
+
* keymap, it does not own one. Formatting a combo (⌘⇧Z) is the consumer's,
|
|
31
|
+
* next to wherever the binding actually lives.
|
|
32
|
+
*
|
|
33
|
+
* @param {Array} props.shortcuts - `[{ label, keys }]` or `[{ section, items }]`
|
|
34
|
+
* @param {Function} props.onClose
|
|
13
35
|
*/
|
|
36
|
+
|
|
37
|
+
const isSectioned = (list) => Array.isArray(list?.[0]?.items)
|
|
38
|
+
|
|
39
|
+
/* One row of the shared grid. `contents` keeps the pair on the parent grid
|
|
40
|
+
* rather than making the wrapper a cell of its own. */
|
|
41
|
+
function Row({ label, keys }) {
|
|
42
|
+
return (
|
|
43
|
+
<span className="contents">
|
|
44
|
+
<span>{label}</span><span className="text-fg-96">{keys}</span>
|
|
45
|
+
</span>
|
|
46
|
+
)
|
|
47
|
+
}
|
|
48
|
+
|
|
14
49
|
export default function ShortcutsOverlay({ shortcuts = [], onClose }) {
|
|
15
50
|
useEffect(() => {
|
|
16
51
|
const onKey = (e) => { if (e.key === 'Escape') onClose?.() }
|
|
@@ -18,6 +53,8 @@ export default function ShortcutsOverlay({ shortcuts = [], onClose }) {
|
|
|
18
53
|
return () => window.removeEventListener('keydown', onKey)
|
|
19
54
|
}, [onClose])
|
|
20
55
|
|
|
56
|
+
const sectioned = isSectioned(shortcuts)
|
|
57
|
+
|
|
21
58
|
return (
|
|
22
59
|
<div
|
|
23
60
|
onClick={onClose}
|
|
@@ -25,11 +62,23 @@ export default function ShortcutsOverlay({ shortcuts = [], onClose }) {
|
|
|
25
62
|
style={{ display: 'grid', placeItems: 'center', backdropFilter: 'blur(2px)', zIndex: 'var(--kol-z-modal)' }}
|
|
26
63
|
>
|
|
27
64
|
<div className="text-fg-64 kol-helper-12 bg-surface-primary border border-fg-16" style={{ display: 'grid', gridTemplateColumns: 'auto auto', gap: '10px 62px', padding: 24, borderRadius: 4 }}>
|
|
28
|
-
{
|
|
29
|
-
|
|
30
|
-
<span
|
|
31
|
-
|
|
32
|
-
|
|
65
|
+
{sectioned
|
|
66
|
+
? shortcuts.map(({ section, items = [] }, i) => (
|
|
67
|
+
<span key={section} className="contents">
|
|
68
|
+
<span
|
|
69
|
+
className="text-fg-32"
|
|
70
|
+
style={{ gridColumn: '1 / -1', marginTop: i === 0 ? 0 : 14 }}
|
|
71
|
+
>
|
|
72
|
+
{section}
|
|
73
|
+
</span>
|
|
74
|
+
{items.map(({ label, keys }) => (
|
|
75
|
+
<Row key={`${section}:${label}`} label={label} keys={keys} />
|
|
76
|
+
))}
|
|
77
|
+
</span>
|
|
78
|
+
))
|
|
79
|
+
: shortcuts.map(({ label, keys }) => (
|
|
80
|
+
<Row key={label} label={label} keys={keys} />
|
|
81
|
+
))}
|
|
33
82
|
</div>
|
|
34
83
|
</div>
|
|
35
84
|
)
|