Add TS JSDoc coverage and improve numeric step controls
This commit is contained in:
@@ -1,5 +1,11 @@
|
||||
/**
|
||||
* High-level edit session intents derived from keyboard input.
|
||||
*/
|
||||
export type EditSessionAction = 'submit' | 'cancel' | null;
|
||||
|
||||
/**
|
||||
* Maps Enter/Escape to submit/cancel semantics for text-editing flows.
|
||||
*/
|
||||
export function getEditSessionAction(code: string): EditSessionAction {
|
||||
if (code === 'Enter') return 'submit';
|
||||
if (code === 'Escape') return 'cancel';
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
import { cycleIndex, findNextIndexByInitial } from './listNavigation';
|
||||
|
||||
/**
|
||||
* Normalized control result for list-like menus.
|
||||
*/
|
||||
export type ListControlResult =
|
||||
| { type: 'move'; index: number; reason: 'arrow' | 'initial' }
|
||||
| { type: 'select' }
|
||||
| { type: 'cancel' }
|
||||
| { type: 'none' };
|
||||
|
||||
/**
|
||||
* Applies common list key handling (arrows, first-letter jump, enter, escape).
|
||||
*/
|
||||
export function handleListControlKey<T>(
|
||||
code: string,
|
||||
key: string,
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/**
|
||||
* Cycles an index through a fixed-length list.
|
||||
*/
|
||||
export function cycleIndex(currentIndex: number, length: number, direction: 'next' | 'prev'): number {
|
||||
if (length <= 0) return 0;
|
||||
if (direction === 'next') {
|
||||
@@ -6,6 +9,9 @@ export function cycleIndex(currentIndex: number, length: number, direction: 'nex
|
||||
return (currentIndex - 1 + length) % length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the next entry whose label starts with the pressed initial.
|
||||
*/
|
||||
export function findNextIndexByInitial<T>(
|
||||
entries: readonly T[],
|
||||
currentIndex: number,
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/**
|
||||
* Declarative command ids for the primary gameplay input mode.
|
||||
*/
|
||||
export type MainModeCommand =
|
||||
| 'editNickname'
|
||||
| 'toggleMute'
|
||||
@@ -28,6 +31,9 @@ export type MainModeCommand =
|
||||
| 'chatLast'
|
||||
| 'escape';
|
||||
|
||||
/**
|
||||
* Maps raw key events to a semantic command for main mode handling.
|
||||
*/
|
||||
export function resolveMainModeCommand(code: string, shiftKey: boolean): MainModeCommand | null {
|
||||
if (code === 'KeyN') return 'editNickname';
|
||||
if (code === 'KeyM') return shiftKey ? 'toggleOutputMode' : 'toggleMute';
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/**
|
||||
* Snaps a numeric value to the nearest step anchored to a minimum/base value.
|
||||
*/
|
||||
export function snapNumberToStep(value: number, step: number, anchor = 0): number {
|
||||
if (!(step > 0) || !Number.isFinite(value) || !Number.isFinite(anchor)) {
|
||||
return value;
|
||||
@@ -7,6 +10,9 @@ export function snapNumberToStep(value: number, step: number, anchor = 0): numbe
|
||||
return Number(normalized.toFixed(decimals));
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats stepped numeric values for speech/status without trailing decimal zeros.
|
||||
*/
|
||||
export function formatSteppedNumber(value: number, step: number): string {
|
||||
const decimals = step >= 1 ? 0 : Math.min(6, Math.ceil(Math.abs(Math.log10(step))) + 1);
|
||||
if (decimals <= 0) {
|
||||
|
||||
Reference in New Issue
Block a user