Route canvas keyboard claims through text and gesture boundaries

This commit is contained in:
2026-11-09 17:38:35 +08:00
parent 575b5a9256
commit 075bb79443
6 changed files with 30 additions and 9 deletions
+2
View File
@@ -10,3 +10,5 @@ export type * from './compat-types.ts';
export {createSelectorStore} from './selectors.ts';
export type {ExternalSource} from './selectors.ts';
export {routeCanvasKey} from './input-router.ts';
export type {CanvasKeyInput,InputClaim,KeyHandler} from './input-router.ts';
+11
View File
@@ -0,0 +1,11 @@
/** Host normalizes DOM/native input; only the winning layer consumes an event. */
export type CanvasKeyInput={readonly key:string;readonly composing?:boolean;readonly textEditing?:boolean;readonly overlay?:boolean;readonly defaultPrevented?:boolean;readonly ctrl?:boolean;readonly meta?:boolean;readonly alt?:boolean;readonly shift?:boolean};
export type InputClaim='text'|'overlay'|'gesture'|'tool'|'shortcut'|'unclaimed';
export type KeyHandler=(input:CanvasKeyInput)=>boolean;
export function routeCanvasKey(input:CanvasKeyInput,handlers:{gesture?:KeyHandler;tool?:KeyHandler;shortcut?:KeyHandler}):InputClaim{
if(input.defaultPrevented)return 'unclaimed';
if(input.composing||input.textEditing)return 'text';
if(input.overlay)return 'overlay';
for(const layer of ['gesture','tool','shortcut'] as const)if(handlers[layer]?.(input))return layer;
return 'unclaimed';
}