@skyhook-io/k8s-ui 1.4.3 → 1.5.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 +31 -8
- package/src/hooks/useKeyboardShortcuts.tsx +19 -22
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skyhook-io/k8s-ui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/skyhook-io/radar",
|
|
@@ -12,10 +12,33 @@
|
|
|
12
12
|
"exports": {
|
|
13
13
|
".": "./src/index.ts",
|
|
14
14
|
"./types": "./src/types/index.ts",
|
|
15
|
+
"./types/*": "./src/types/*.ts",
|
|
15
16
|
"./utils": "./src/utils/index.ts",
|
|
16
|
-
"./
|
|
17
|
-
"./components/
|
|
18
|
-
|
|
17
|
+
"./utils/*": "./src/utils/*.ts",
|
|
18
|
+
"./components/resources/*": [
|
|
19
|
+
"./src/components/resources/*.ts",
|
|
20
|
+
"./src/components/resources/*.tsx"
|
|
21
|
+
],
|
|
22
|
+
"./components/resources/renderers/*": [
|
|
23
|
+
"./src/components/resources/renderers/*.tsx",
|
|
24
|
+
"./src/components/resources/renderers/*.ts"
|
|
25
|
+
],
|
|
26
|
+
"./components/ui/*": [
|
|
27
|
+
"./src/components/ui/*.tsx",
|
|
28
|
+
"./src/components/ui/*.ts"
|
|
29
|
+
],
|
|
30
|
+
"./components/gitops/*": [
|
|
31
|
+
"./src/components/gitops/*.tsx",
|
|
32
|
+
"./src/components/gitops/*.ts"
|
|
33
|
+
],
|
|
34
|
+
"./components/timeline/*": [
|
|
35
|
+
"./src/components/timeline/*.tsx",
|
|
36
|
+
"./src/components/timeline/*.ts"
|
|
37
|
+
],
|
|
38
|
+
"./hooks/*": [
|
|
39
|
+
"./src/hooks/*.ts",
|
|
40
|
+
"./src/hooks/*.tsx"
|
|
41
|
+
],
|
|
19
42
|
"./resources": "./src/components/resources/index.ts",
|
|
20
43
|
"./logs": "./src/components/logs/index.ts",
|
|
21
44
|
"./timeline": "./src/components/timeline/index.ts",
|
|
@@ -34,7 +57,7 @@
|
|
|
34
57
|
"dependencies": {
|
|
35
58
|
"@monaco-editor/react": "^4.7.0",
|
|
36
59
|
"html-to-image": "^1.11.0",
|
|
37
|
-
"react-virtuoso": "^4.18.
|
|
60
|
+
"react-virtuoso": "^4.18.5",
|
|
38
61
|
"shiki": "^4.0.0"
|
|
39
62
|
},
|
|
40
63
|
"peerDependencies": {
|
|
@@ -59,13 +82,13 @@
|
|
|
59
82
|
"@xterm/xterm": "^6.0.0",
|
|
60
83
|
"@xyflow/react": "^12.10.1",
|
|
61
84
|
"clsx": "^2.1.1",
|
|
62
|
-
"diff": "^
|
|
85
|
+
"diff": "^9.0.0",
|
|
63
86
|
"elkjs": "^0.11.1",
|
|
64
|
-
"lucide-react": "^
|
|
87
|
+
"lucide-react": "^1.8.0",
|
|
65
88
|
"react": "^19.2.4",
|
|
66
89
|
"react-dom": "^19.2.4",
|
|
67
90
|
"typescript": "^6.0.2",
|
|
68
|
-
"vitest": "^4.1.
|
|
91
|
+
"vitest": "^4.1.4",
|
|
69
92
|
"yaml": "^2.8.3"
|
|
70
93
|
}
|
|
71
94
|
}
|
|
@@ -30,6 +30,8 @@ export interface KeyboardShortcut {
|
|
|
30
30
|
handler: (e: KeyboardEvent) => void
|
|
31
31
|
/** Whether this shortcut is currently active */
|
|
32
32
|
enabled?: boolean
|
|
33
|
+
/** Fire even when focus is inside an input/textarea. For global modifier combos (⌘K, Ctrl+Shift+D) that can't collide with typing. */
|
|
34
|
+
allowInInputs?: boolean
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
// Internal registration with stable ID
|
|
@@ -46,28 +48,22 @@ const KeyboardShortcutContext = createContext<KeyboardShortcutContextType | null
|
|
|
46
48
|
|
|
47
49
|
let nextRegistrationId = 0
|
|
48
50
|
|
|
49
|
-
//
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
if (e.key === 'Escape') return false
|
|
51
|
+
// Classify suppression level for the currently-focused element.
|
|
52
|
+
// none — no suppression, all shortcuts fire
|
|
53
|
+
// soft — plain text inputs; bypassed by shortcuts with allowInInputs
|
|
54
|
+
// hard — rich editors (Monaco, xterm) that own their own keyboard UX;
|
|
55
|
+
// never bypassed, since Cmd+K / Ctrl+Shift+D have meaning there
|
|
56
|
+
type SuppressionLevel = 'none' | 'soft' | 'hard'
|
|
56
57
|
|
|
57
|
-
|
|
58
|
+
function getSuppressionLevel(e: KeyboardEvent): SuppressionLevel {
|
|
59
|
+
const target = e.target as HTMLElement
|
|
60
|
+
if (!target) return 'none'
|
|
61
|
+
if (e.key === 'Escape') return 'none'
|
|
62
|
+
if (target.closest('.monaco-editor') || target.closest('.xterm')) return 'hard'
|
|
58
63
|
const tagName = target.tagName
|
|
59
|
-
if (tagName === 'INPUT' || tagName === 'TEXTAREA' || tagName === 'SELECT') return
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if (target.isContentEditable) return true
|
|
63
|
-
|
|
64
|
-
// Suppress in Monaco editor
|
|
65
|
-
if (target.closest('.monaco-editor')) return true
|
|
66
|
-
|
|
67
|
-
// Suppress in xterm terminal
|
|
68
|
-
if (target.closest('.xterm')) return true
|
|
69
|
-
|
|
70
|
-
return false
|
|
64
|
+
if (tagName === 'INPUT' || tagName === 'TEXTAREA' || tagName === 'SELECT') return 'soft'
|
|
65
|
+
if (target.isContentEditable) return 'soft'
|
|
66
|
+
return 'none'
|
|
71
67
|
}
|
|
72
68
|
|
|
73
69
|
// Parse a key string like "Shift+N", "Cmd+K", "g g" into match criteria
|
|
@@ -158,7 +154,8 @@ export function KeyboardShortcutProvider({ children }: { children: ReactNode })
|
|
|
158
154
|
// Global keydown listener
|
|
159
155
|
useEffect(() => {
|
|
160
156
|
const handleKeyDown = (e: KeyboardEvent) => {
|
|
161
|
-
const
|
|
157
|
+
const suppression = getSuppressionLevel(e)
|
|
158
|
+
const suppressed = suppression !== 'none'
|
|
162
159
|
|
|
163
160
|
// Get all enabled shortcuts, sorted by scope priority (highest first)
|
|
164
161
|
const shortcuts = Array.from(shortcutsRef.current.values())
|
|
@@ -215,7 +212,7 @@ export function KeyboardShortcutProvider({ children }: { children: ReactNode })
|
|
|
215
212
|
return
|
|
216
213
|
}
|
|
217
214
|
|
|
218
|
-
if (suppressed) continue
|
|
215
|
+
if (suppressed && !(shortcut.allowInInputs && suppression === 'soft')) continue
|
|
219
216
|
|
|
220
217
|
if (matchesKey(e, matcher, '')) {
|
|
221
218
|
e.preventDefault()
|