ink-cartridge 3.7.0 → 3.7.1
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.
|
@@ -137,9 +137,7 @@ export default function GlobalKeyDisplayBox({ top: initialTop, left }) {
|
|
|
137
137
|
React.createElement(Box, { paddingTop: 1 },
|
|
138
138
|
React.createElement(Text, { dimColor: true }, expandedEntry
|
|
139
139
|
? 'Enter: collapse | Esc: close'
|
|
140
|
-
: 'Tab: switch focus | Enter: details | Esc: close'))
|
|
141
|
-
!expandedEntry && (React.createElement(Box, null,
|
|
142
|
-
React.createElement(Text, { dimColor: true }, "After collapsing from detail, press Tab to restore the selection highlight.")))));
|
|
140
|
+
: 'Tab: switch focus | Enter: details | Esc: close'))));
|
|
143
141
|
}
|
|
144
142
|
registerComponent(GlobalKeyDisplayBox, {
|
|
145
143
|
top: 0,
|
|
@@ -145,8 +145,32 @@ export function KeyboardProvider({ children }) {
|
|
|
145
145
|
const pushOwner = useCallback((owner) => {
|
|
146
146
|
ownerStackRef.current = [...ownerStackRef.current, owner];
|
|
147
147
|
}, []);
|
|
148
|
+
// fix: _popOwner used `filter(o => o !== owner)` which deletes EVERY
|
|
149
|
+
// occurrence of owner from the stack. When multiple components inside
|
|
150
|
+
// the same modal/overlay each call `useKeyboard()`, they all push the
|
|
151
|
+
// same owner ID — e.g. GlobalKeyDisplayBox, SelectInput, and
|
|
152
|
+
// useFocusState() each push `modalId`, creating [modalId, modalId, modalId].
|
|
153
|
+
//
|
|
154
|
+
// When a nested component unmounts, its _popOwner cleanup would wipe
|
|
155
|
+
// ALL three entries, emptying the stack while the outer component is
|
|
156
|
+
// still mounted. This makes `getCurrentOwner()` return null, causing:
|
|
157
|
+
// - focusUnregister() to silently no-op (stale focus state remains)
|
|
158
|
+
// - focusCurrent/focusSet/focusNext/focusPrev all blind to the layer
|
|
159
|
+
// - re-mounting components (e.g. SelectInput after collapsing a
|
|
160
|
+
// detail view) unable to restore keyboard focus
|
|
161
|
+
//
|
|
162
|
+
// Switch to `lastIndexOf` + slice so only the LAST occurrence (the
|
|
163
|
+
// caller's own push) is removed — proper LIFO stack behaviour.
|
|
164
|
+
// @2026-06-25 v3.7.0
|
|
148
165
|
const popOwner = useCallback((owner) => {
|
|
149
|
-
|
|
166
|
+
const stack = ownerStackRef.current;
|
|
167
|
+
const idx = stack.lastIndexOf(owner);
|
|
168
|
+
if (idx !== -1) {
|
|
169
|
+
ownerStackRef.current = [
|
|
170
|
+
...stack.slice(0, idx),
|
|
171
|
+
...stack.slice(idx + 1),
|
|
172
|
+
];
|
|
173
|
+
}
|
|
150
174
|
}, []);
|
|
151
175
|
const enableWildcardPriority = useCallback(() => {
|
|
152
176
|
wildcardPriorityCountRef.current += 1;
|