ink-cartridge 3.6.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.
- package/LICENSE +21 -0
- package/README.md +249 -0
- package/dist/binary-storage/BinaryStorage.d.ts +308 -0
- package/dist/binary-storage/BinaryStorage.js +548 -0
- package/dist/binary-storage/StreamingReader.d.ts +53 -0
- package/dist/binary-storage/StreamingReader.js +530 -0
- package/dist/binary-storage/index.d.ts +91 -0
- package/dist/binary-storage/index.js +91 -0
- package/dist/binary-storage/types.d.ts +400 -0
- package/dist/binary-storage/types.js +15 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +214 -0
- package/dist/cli/initTheme.d.ts +14 -0
- package/dist/cli/initTheme.js +124 -0
- package/dist/cli/makeLanguageType.d.ts +46 -0
- package/dist/cli/makeLanguageType.js +264 -0
- package/dist/cli/makeThemeType.d.ts +43 -0
- package/dist/cli/makeThemeType.js +222 -0
- package/dist/components/badge/Badge.d.ts +7 -0
- package/dist/components/badge/Badge.js +9 -0
- package/dist/components/dialog/ConfirmDialog.d.ts +23 -0
- package/dist/components/dialog/ConfirmDialog.js +57 -0
- package/dist/components/dialog/types.d.ts +20 -0
- package/dist/components/dialog/types.js +1 -0
- package/dist/components/divider/Divider.d.ts +8 -0
- package/dist/components/divider/Divider.js +10 -0
- package/dist/components/fold/Fold.d.ts +3 -0
- package/dist/components/fold/Fold.js +44 -0
- package/dist/components/fold/types.d.ts +28 -0
- package/dist/components/fold/types.js +1 -0
- package/dist/components/form/Field.d.ts +30 -0
- package/dist/components/form/Field.js +59 -0
- package/dist/components/form/Form.d.ts +32 -0
- package/dist/components/form/Form.js +163 -0
- package/dist/components/form/context.d.ts +14 -0
- package/dist/components/form/context.js +20 -0
- package/dist/components/form/types.d.ts +115 -0
- package/dist/components/form/types.js +1 -0
- package/dist/components/key-hint/KeyHint.d.ts +10 -0
- package/dist/components/key-hint/KeyHint.js +12 -0
- package/dist/components/multi-select/MultiSelectInput.d.ts +125 -0
- package/dist/components/multi-select/MultiSelectInput.js +287 -0
- package/dist/components/multi-select/types.d.ts +100 -0
- package/dist/components/multi-select/types.js +1 -0
- package/dist/components/number-input/NumberInput.d.ts +11 -0
- package/dist/components/number-input/NumberInput.js +44 -0
- package/dist/components/progress-bar/ProgressBar.d.ts +11 -0
- package/dist/components/progress-bar/ProgressBar.js +9 -0
- package/dist/components/search-input/SearchInput.d.ts +10 -0
- package/dist/components/search-input/SearchInput.js +15 -0
- package/dist/components/select/SelectInput.d.ts +100 -0
- package/dist/components/select/SelectInput.js +147 -0
- package/dist/components/select/types.d.ts +63 -0
- package/dist/components/select/types.js +1 -0
- package/dist/components/spinner/Spinner.d.ts +12 -0
- package/dist/components/spinner/Spinner.js +24 -0
- package/dist/components/tabs/Tabs.d.ts +3 -0
- package/dist/components/tabs/Tabs.js +57 -0
- package/dist/components/tabs/types.d.ts +32 -0
- package/dist/components/tabs/types.js +1 -0
- package/dist/components/text/TextInput.d.ts +39 -0
- package/dist/components/text/TextInput.js +233 -0
- package/dist/components/text/types.d.ts +62 -0
- package/dist/components/text/types.js +1 -0
- package/dist/dev/dev-screen.d.ts +36 -0
- package/dist/dev/dev-screen.js +142 -0
- package/dist/dev/entrance.d.ts +51 -0
- package/dist/dev/entrance.js +67 -0
- package/dist/dev/globalKey-display.d.ts +2 -0
- package/dist/dev/globalKey-display.js +8 -0
- package/dist/dev/types.d.ts +9 -0
- package/dist/dev/types.js +1 -0
- package/dist/index.d.ts +46 -0
- package/dist/index.js +50 -0
- package/dist/keyboard/check-global-key.d.ts +18 -0
- package/dist/keyboard/check-global-key.js +52 -0
- package/dist/keyboard/context.d.ts +398 -0
- package/dist/keyboard/context.js +9 -0
- package/dist/keyboard/global-key-processor/index.d.ts +16 -0
- package/dist/keyboard/global-key-processor/index.js +75 -0
- package/dist/keyboard/global-sequence-processor/index.d.ts +14 -0
- package/dist/keyboard/global-sequence-processor/index.js +165 -0
- package/dist/keyboard/hook.d.ts +51 -0
- package/dist/keyboard/hook.js +105 -0
- package/dist/keyboard/index.d.ts +5 -0
- package/dist/keyboard/index.js +3 -0
- package/dist/keyboard/keyNormalizer.d.ts +37 -0
- package/dist/keyboard/keyNormalizer.js +119 -0
- package/dist/keyboard/layer-handler.d.ts +57 -0
- package/dist/keyboard/layer-handler.js +274 -0
- package/dist/keyboard/modal-processor/index.d.ts +16 -0
- package/dist/keyboard/modal-processor/index.js +97 -0
- package/dist/keyboard/overlay-processor/index.d.ts +16 -0
- package/dist/keyboard/overlay-processor/index.js +30 -0
- package/dist/keyboard/pipeline/chain.d.ts +10 -0
- package/dist/keyboard/pipeline/chain.js +45 -0
- package/dist/keyboard/pipeline/context.d.ts +34 -0
- package/dist/keyboard/pipeline/context.js +42 -0
- package/dist/keyboard/pipeline/index.d.ts +3 -0
- package/dist/keyboard/pipeline/index.js +2 -0
- package/dist/keyboard/provider.d.ts +32 -0
- package/dist/keyboard/provider.js +985 -0
- package/dist/keyboard/screen-stack-processor/index.d.ts +14 -0
- package/dist/keyboard/screen-stack-processor/index.js +32 -0
- package/dist/keyboard/types.d.ts +632 -0
- package/dist/keyboard/types.js +1 -0
- package/dist/language/context.d.ts +7 -0
- package/dist/language/context.js +7 -0
- package/dist/language/hook.d.ts +19 -0
- package/dist/language/hook.js +26 -0
- package/dist/language/index.d.ts +3 -0
- package/dist/language/index.js +2 -0
- package/dist/language/provider.d.ts +30 -0
- package/dist/language/provider.js +155 -0
- package/dist/language/types.d.ts +124 -0
- package/dist/language/types.js +1 -0
- package/dist/screen/ModalContext.d.ts +11 -0
- package/dist/screen/ModalContext.js +12 -0
- package/dist/screen/OverlayContext.d.ts +9 -0
- package/dist/screen/OverlayContext.js +10 -0
- package/dist/screen/context.d.ts +61 -0
- package/dist/screen/context.js +8 -0
- package/dist/screen/current-screen.d.ts +16 -0
- package/dist/screen/current-screen.js +38 -0
- package/dist/screen/hook.d.ts +13 -0
- package/dist/screen/hook.js +20 -0
- package/dist/screen/index.d.ts +7 -0
- package/dist/screen/index.js +5 -0
- package/dist/screen/provider.d.ts +112 -0
- package/dist/screen/provider.js +577 -0
- package/dist/screen/registry.d.ts +27 -0
- package/dist/screen/registry.js +71 -0
- package/dist/screen/types.d.ts +227 -0
- package/dist/screen/types.js +1 -0
- package/dist/storage/index.d.ts +45 -0
- package/dist/storage/index.js +46 -0
- package/dist/storage/storage.d.ts +139 -0
- package/dist/storage/storage.js +236 -0
- package/dist/storage/types.d.ts +145 -0
- package/dist/storage/types.js +1 -0
- package/dist/theme/context.d.ts +7 -0
- package/dist/theme/context.js +7 -0
- package/dist/theme/hook.d.ts +11 -0
- package/dist/theme/hook.js +18 -0
- package/dist/theme/index.d.ts +4 -0
- package/dist/theme/index.js +2 -0
- package/dist/theme/provider.d.ts +18 -0
- package/dist/theme/provider.js +308 -0
- package/dist/theme/types.d.ts +53 -0
- package/dist/theme/types.js +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { handleLayer } from '../layer-handler.js';
|
|
2
|
+
/**
|
|
3
|
+
* Check whether a list of bindings contains one whose `keys` match
|
|
4
|
+
* the event but whose `when` returns `false`.
|
|
5
|
+
*/
|
|
6
|
+
function hasWhenFalseBinding(bindings, eventNames) {
|
|
7
|
+
return bindings.some((b) => b.when?.() === false &&
|
|
8
|
+
b.keys.some((k) => eventNames.includes(k)));
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Check whether any non-active focus target has a binding matching
|
|
12
|
+
* the event.
|
|
13
|
+
*/
|
|
14
|
+
function matchesOtherFocusTarget(layer, eventNames) {
|
|
15
|
+
for (const [fid, ft] of layer.focusTargets) {
|
|
16
|
+
if (fid === layer.currentFocusId)
|
|
17
|
+
continue;
|
|
18
|
+
if (ft.bindings.some((b) => b.keys.some((k) => eventNames.includes(k)))) {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Determine whether a key event is a "miss" and invoke the callback.
|
|
26
|
+
*
|
|
27
|
+
* @returns true if the callback was invoked with miss=true.
|
|
28
|
+
*/
|
|
29
|
+
function invokeMissIfNeeded(layer, handled, key, input, eventNames) {
|
|
30
|
+
if (!layer.onMiss)
|
|
31
|
+
return false;
|
|
32
|
+
const opts = layer.onMissOptions ?? {};
|
|
33
|
+
// fix: The stop API and blockedKey API cases are no longer handled.
|
|
34
|
+
// Instead, it is left to handlerLayer to handle natural
|
|
35
|
+
// So the expectation is that, So the Stop API returns miss: false, but the BlockedKeys API returns miss: true
|
|
36
|
+
// TODO: You need to modify the corresponding test and do it later.
|
|
37
|
+
// @2026-06-23 3.6.1
|
|
38
|
+
if (handled) {
|
|
39
|
+
layer.onMiss({ miss: false });
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
// handled === false — key was not consumed by handleLayer.
|
|
43
|
+
if (opts.monitorWhen && hasWhenFalseBinding(layer.bindings, eventNames)) {
|
|
44
|
+
layer.onMiss({ miss: true, key, input, eventNames });
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
if (opts.monitorWhen &&
|
|
48
|
+
layer.currentFocusId) {
|
|
49
|
+
const ft = layer.focusTargets.get(layer.currentFocusId);
|
|
50
|
+
if (ft && hasWhenFalseBinding(ft.bindings, eventNames)) {
|
|
51
|
+
layer.onMiss({ miss: true, key, input, eventNames });
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (opts.monitorFocusMismatch &&
|
|
56
|
+
matchesOtherFocusTarget(layer, eventNames)) {
|
|
57
|
+
layer.onMiss({ miss: true, key, input, eventNames });
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
// Definitely a miss — no mechanism handled this key.
|
|
61
|
+
layer.onMiss({ miss: true, key, input, eventNames });
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Create a processor for the modal stage (stage 0 — highest priority).
|
|
66
|
+
*
|
|
67
|
+
* When a modal is active (activeModalId is set), the modal's keyboard layer
|
|
68
|
+
* receives the event. The processor always returns `true`, consuming every
|
|
69
|
+
* event — even keys not bound in the modal — so that no event reaches
|
|
70
|
+
* lower-priority stages (global keys, overlays, or screens).
|
|
71
|
+
*
|
|
72
|
+
* Before blocking, if the layer has an {@link ScreenKeyboardLayer.onMiss}
|
|
73
|
+
* callback registered (via {@link useModalMissListener}), the processor
|
|
74
|
+
* determines whether the key was handled or missed and invokes the callback.
|
|
75
|
+
*
|
|
76
|
+
* @returns A PipelineProcessor for the modal stage.
|
|
77
|
+
*/
|
|
78
|
+
export function createModalProcessor() {
|
|
79
|
+
return {
|
|
80
|
+
process(ctx) {
|
|
81
|
+
if (!ctx.activeModalId)
|
|
82
|
+
return false;
|
|
83
|
+
const layer = ctx.layersRef.current.get(ctx.activeModalId);
|
|
84
|
+
let handled = false;
|
|
85
|
+
if (layer) {
|
|
86
|
+
handled = handleLayer(layer, ctx.eventNames, ctx.input, ctx.key, true, // isTop — modal is always the top layer
|
|
87
|
+
ctx.notifyFocusChange, 1, // activeCount — modal is singleton
|
|
88
|
+
true, // isOverlay — modal is treated as a floating layer for onlyThis semantics
|
|
89
|
+
ctx.wildcardFirst);
|
|
90
|
+
}
|
|
91
|
+
if (layer) {
|
|
92
|
+
invokeMissIfNeeded(layer, handled, ctx.key, ctx.input, ctx.eventNames);
|
|
93
|
+
}
|
|
94
|
+
return true;
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { PipelineProcessor } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Create a processor for the overlay broadcast stage.
|
|
4
|
+
*
|
|
5
|
+
* Iterates all active overlays (sorted by zIndex ascending) and offers
|
|
6
|
+
* the event to each one via {@link handleLayer}. Unlike other processors,
|
|
7
|
+
* this stage does NOT stop on the first consumer — every active overlay
|
|
8
|
+
* receives the event. The `anyOverlayConsumed` flag on the context is
|
|
9
|
+
* set if at least one overlay handled the event, which later determines
|
|
10
|
+
* whether the screen stack (stage ⑥) runs.
|
|
11
|
+
*
|
|
12
|
+
* @returns A PipelineProcessor for the overlay broadcast stage.
|
|
13
|
+
*
|
|
14
|
+
* @2026-06-14 v3.4.0
|
|
15
|
+
*/
|
|
16
|
+
export declare function createOverlayProcessor(): PipelineProcessor;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { handleLayer } from '../layer-handler.js';
|
|
2
|
+
/**
|
|
3
|
+
* Create a processor for the overlay broadcast stage.
|
|
4
|
+
*
|
|
5
|
+
* Iterates all active overlays (sorted by zIndex ascending) and offers
|
|
6
|
+
* the event to each one via {@link handleLayer}. Unlike other processors,
|
|
7
|
+
* this stage does NOT stop on the first consumer — every active overlay
|
|
8
|
+
* receives the event. The `anyOverlayConsumed` flag on the context is
|
|
9
|
+
* set if at least one overlay handled the event, which later determines
|
|
10
|
+
* whether the screen stack (stage ⑥) runs.
|
|
11
|
+
*
|
|
12
|
+
* @returns A PipelineProcessor for the overlay broadcast stage.
|
|
13
|
+
*
|
|
14
|
+
* @2026-06-14 v3.4.0
|
|
15
|
+
*/
|
|
16
|
+
export function createOverlayProcessor() {
|
|
17
|
+
return {
|
|
18
|
+
process(ctx) {
|
|
19
|
+
for (const overlay of ctx.activeOverlays) {
|
|
20
|
+
const layer = ctx.layersRef.current.get(overlay.id);
|
|
21
|
+
if (layer && handleLayer(layer, ctx.eventNames, ctx.input, ctx.key, true, ctx.notifyFocusChange, ctx.activeCount, true, ctx.wildcardFirst)) {
|
|
22
|
+
ctx.anyOverlayConsumed = true;
|
|
23
|
+
// Do not break — continue to next overlay (broadcast semantics).
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
// Always return false so the chain continues to subsequent stages.
|
|
27
|
+
return false;
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { PipelineContext } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Run a keyboard event through the full processor chain.
|
|
4
|
+
*
|
|
5
|
+
* Each processor's {@link PipelineProcessor.process} is called in order.
|
|
6
|
+
* The first processor to return `true` (event consumed) stops the chain.
|
|
7
|
+
*
|
|
8
|
+
* @param ctx - Snapshot context built by {@link buildPipelineContext}.
|
|
9
|
+
*/
|
|
10
|
+
export declare function runPipeline(ctx: PipelineContext): void;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { createModalProcessor } from '../modal-processor/index.js';
|
|
2
|
+
import { createGlobalSequenceProcessor } from '../global-sequence-processor/index.js';
|
|
3
|
+
import { createGlobalKeyProcessor } from '../global-key-processor/index.js';
|
|
4
|
+
import { createOverlayProcessor } from '../overlay-processor/index.js';
|
|
5
|
+
import { createScreenStackProcessor } from '../screen-stack-processor/index.js';
|
|
6
|
+
/**
|
|
7
|
+
* Build the canonical 7-stage processor chain.
|
|
8
|
+
*
|
|
9
|
+
* Priority order (highest first):
|
|
10
|
+
* ⓪ Modal — active modal, always blocks
|
|
11
|
+
* ① GlobalSequence (affectOverlay: true) — pending + start
|
|
12
|
+
* ② GlobalKey (affectOverlay: true) — fire before overlays
|
|
13
|
+
* ③ Overlay broadcast — all active overlays, zIndex asc
|
|
14
|
+
* ④ GlobalSequence (affectOverlay: false) — pending + start
|
|
15
|
+
* ⑤ GlobalKey (affectOverlay: false) — fire before screen stack
|
|
16
|
+
* ⑥ Screen stack — top → bottom, only if no overlay consumed
|
|
17
|
+
*
|
|
18
|
+
* @2026-06-22 v3.6.1
|
|
19
|
+
*/
|
|
20
|
+
function buildProcessors() {
|
|
21
|
+
return [
|
|
22
|
+
createModalProcessor(),
|
|
23
|
+
createGlobalSequenceProcessor({ affectOverlay: true }),
|
|
24
|
+
createGlobalKeyProcessor({ affectOverlay: true }),
|
|
25
|
+
createOverlayProcessor(),
|
|
26
|
+
createGlobalSequenceProcessor({ affectOverlay: false }),
|
|
27
|
+
createGlobalKeyProcessor({ affectOverlay: false }),
|
|
28
|
+
createScreenStackProcessor(),
|
|
29
|
+
];
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Run a keyboard event through the full processor chain.
|
|
33
|
+
*
|
|
34
|
+
* Each processor's {@link PipelineProcessor.process} is called in order.
|
|
35
|
+
* The first processor to return `true` (event consumed) stops the chain.
|
|
36
|
+
*
|
|
37
|
+
* @param ctx - Snapshot context built by {@link buildPipelineContext}.
|
|
38
|
+
*/
|
|
39
|
+
export function runPipeline(ctx) {
|
|
40
|
+
const processors = buildProcessors();
|
|
41
|
+
for (const processor of processors) {
|
|
42
|
+
if (processor.process(ctx))
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Key } from 'ink';
|
|
2
|
+
import type React from 'react';
|
|
3
|
+
import type { OverlayEntry } from '../../screen/types.js';
|
|
4
|
+
import type { LayerOwner } from '../context.js';
|
|
5
|
+
import type { PipelineContext, ScreenKeyboardLayer, ResolvedGlobalKeyEntry, ResolvedGlobalSequenceEntry } from '../types.js';
|
|
6
|
+
/**
|
|
7
|
+
* Collection of all provider refs needed by {@link buildPipelineContext}
|
|
8
|
+
* to snapshot the current keyboard state for a single event.
|
|
9
|
+
*/
|
|
10
|
+
export interface PipelineRefs {
|
|
11
|
+
pathRef: React.MutableRefObject<React.ComponentType<any>[]>;
|
|
12
|
+
globalKeysRef: React.MutableRefObject<ResolvedGlobalKeyEntry[]>;
|
|
13
|
+
globalSequencesRef: React.MutableRefObject<ResolvedGlobalSequenceEntry[]>;
|
|
14
|
+
activeOverlayIdsRef: React.MutableRefObject<Set<string>>;
|
|
15
|
+
displayedOverlaysRef: React.MutableRefObject<OverlayEntry[]>;
|
|
16
|
+
activeModalIdRef: React.MutableRefObject<string | null>;
|
|
17
|
+
layersRef: React.MutableRefObject<Map<LayerOwner, ScreenKeyboardLayer>>;
|
|
18
|
+
globalPendingSeqRef: React.MutableRefObject<import('../types.js').GlobalPendingSequence | null>;
|
|
19
|
+
wildcardPriorityCountRef: React.MutableRefObject<number>;
|
|
20
|
+
notifyFocusChange: () => void;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Build a {@link PipelineContext} snapshot from the provider's refs.
|
|
24
|
+
*
|
|
25
|
+
* Called once per key event at the top of the `useInput` callback.
|
|
26
|
+
* All `ref.current` values are read synchronously to produce a
|
|
27
|
+
* consistent snapshot for the current event.
|
|
28
|
+
*
|
|
29
|
+
* @param input - Raw character string from Ink's useInput.
|
|
30
|
+
* @param key - Full Key descriptor from Ink.
|
|
31
|
+
* @param refs - All mutable refs owned by the keyboard provider.
|
|
32
|
+
* @returns A frozen-in-time context for the pipeline chain.
|
|
33
|
+
*/
|
|
34
|
+
export declare function buildPipelineContext(input: string, key: Key, refs: PipelineRefs): PipelineContext;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { normalizeKeyNames } from '../keyNormalizer.js';
|
|
2
|
+
/**
|
|
3
|
+
* Build a {@link PipelineContext} snapshot from the provider's refs.
|
|
4
|
+
*
|
|
5
|
+
* Called once per key event at the top of the `useInput` callback.
|
|
6
|
+
* All `ref.current` values are read synchronously to produce a
|
|
7
|
+
* consistent snapshot for the current event.
|
|
8
|
+
*
|
|
9
|
+
* @param input - Raw character string from Ink's useInput.
|
|
10
|
+
* @param key - Full Key descriptor from Ink.
|
|
11
|
+
* @param refs - All mutable refs owned by the keyboard provider.
|
|
12
|
+
* @returns A frozen-in-time context for the pipeline chain.
|
|
13
|
+
*/
|
|
14
|
+
export function buildPipelineContext(input, key, refs) {
|
|
15
|
+
const eventNames = normalizeKeyNames(input, key);
|
|
16
|
+
const path = refs.pathRef.current;
|
|
17
|
+
const topComponent = path.length > 0 ? path[path.length - 1] : null;
|
|
18
|
+
const globalKeys = refs.globalKeysRef.current;
|
|
19
|
+
const globalSequences = refs.globalSequencesRef.current;
|
|
20
|
+
const activeIds = refs.activeOverlayIdsRef.current;
|
|
21
|
+
const overlays = refs.displayedOverlaysRef.current;
|
|
22
|
+
const activeOverlays = overlays.filter(n => activeIds.has(n.id));
|
|
23
|
+
const activeCount = activeIds.size;
|
|
24
|
+
const wildcardFirst = refs.wildcardPriorityCountRef.current > 0;
|
|
25
|
+
return {
|
|
26
|
+
input,
|
|
27
|
+
key,
|
|
28
|
+
eventNames,
|
|
29
|
+
topComponent,
|
|
30
|
+
globalKeys,
|
|
31
|
+
globalSequences,
|
|
32
|
+
activeOverlays,
|
|
33
|
+
activeCount,
|
|
34
|
+
wildcardFirst,
|
|
35
|
+
screenPath: path,
|
|
36
|
+
activeModalId: refs.activeModalIdRef.current,
|
|
37
|
+
layersRef: refs.layersRef,
|
|
38
|
+
pendingSeqRef: refs.globalPendingSeqRef,
|
|
39
|
+
notifyFocusChange: refs.notifyFocusChange,
|
|
40
|
+
anyOverlayConsumed: false,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Clear all registered shortcut operations.
|
|
4
|
+
*
|
|
5
|
+
* NOTE: Since the refactoring to per-instance useRef state, this function
|
|
6
|
+
* is a no-op at module level. Shortcut operations are now scoped to each
|
|
7
|
+
* {@link KeyboardProvider} instance and are automatically cleaned up when
|
|
8
|
+
* the provider unmounts.
|
|
9
|
+
*
|
|
10
|
+
* Kept for backward compatibility with tests and external consumers that
|
|
11
|
+
* call this function in cleanup routines.
|
|
12
|
+
*/
|
|
13
|
+
export declare function clearShortcutOperations(): void;
|
|
14
|
+
export interface KeyboardProviderProps {
|
|
15
|
+
children: ReactNode;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Keyboard context provider for layered key handling.
|
|
19
|
+
*
|
|
20
|
+
* Manages per-screen-layer key bindings, transparent keys (`blockedKey`),
|
|
21
|
+
* key-stop propagation barriers (`stop`), and global keys (`globalKeys`).
|
|
22
|
+
* Handles the full event priority chain:
|
|
23
|
+
* 1. Global keys with `affectOverlay: true`
|
|
24
|
+
* 2. Broadcast to all active overlays (sorted by zIndex ascending)
|
|
25
|
+
* 3. Global keys with `affectOverlay: false` (default)
|
|
26
|
+
* 4. Screen stack (top → bottom), only if no overlay consumed the event
|
|
27
|
+
* 5. Drop unhandled keys
|
|
28
|
+
*
|
|
29
|
+
* Must be nested inside a {@link ScenarioManagementProvider} so that the
|
|
30
|
+
* current screen path and overlay state are available.
|
|
31
|
+
*/
|
|
32
|
+
export declare function KeyboardProvider({ children }: KeyboardProviderProps): React.JSX.Element;
|