import type { BoardChange, BoardColumnDef } from './types'; /** * Where a card being moved currently points: a lane, and a slot among the cards * ALREADY in it — the card being moved never counts as one of them. * * This is the board's ONE description of a landing place, and everything is * expressed in it: the pointer, the keyboard, the line that gets drawn and the * change that gets reported. An index cannot say the same thing two ways, which * matters more than it sounds — "below card X" and "above card Y" are the same * slot, and drawing a line for whichever one a hit test happened to return makes * it jump between two positions as the pointer crosses the boundary. */ export interface BoardAim { columnId: string; /** Insertion index among the other cards, so `0..others.length`. */ index: number; } export type ArrowKey = 'ArrowUp' | 'ArrowDown' | 'ArrowLeft' | 'ArrowRight'; /** Whether a lane will take this card — the board's own rules, passed in so this * module stays arithmetic. */ type LaneFilter = (column: BoardColumnDef) => boolean; /** The lane a card is in right now, or `null` if it is in none of them. */ export declare function laneOf(columns: readonly BoardColumnDef[], ticketId: string): BoardColumnDef | null; /** Where a card starts: exactly where it already sits. */ export declare function initialAim(columns: readonly BoardColumnDef[], ticketId: string): BoardAim | null; /** * The aim after one arrow key, or the aim unchanged when the move would leave * the board or land in a lane that will not take the card. * * Up and down step through slots; left and right step through lanes, skipping * any the card is not allowed into rather than stopping dead at it — a lane the * user cannot use should cost a keypress, not end the journey. */ /** * The slot a resolved drop target points at. * * Card targets carry the edge the pointer is nearest; a lane target means "past * the last card". Either way the answer comes out as an index, so the caller * never has to care which kind of target replied. */ export declare function aimFromTarget(columns: readonly BoardColumnDef[], ticketId: string, target: Record): BoardAim | null; export declare function moveAim(columns: readonly BoardColumnDef[], ticketId: string, aim: BoardAim, key: ArrowKey, accepts: LaneFilter): BoardAim; /** The card the preview hangs off, and which side of it — `null` for a lane with * nothing else in it. */ export declare function aimAnchor(columns: readonly BoardColumnDef[], ticketId: string, aim: BoardAim): { ticketId: string | null; edge: 'top' | 'bottom' | null; }; /** * The move to report, or `null` when the card would land back where it started. * * Same rule as a pointer drop, and deliberately so: a keyboard move that ends * where it began must be as silent as a card picked up and put down again. */ export declare function aimToChange(columns: readonly BoardColumnDef[], ticketId: string, aim: BoardAim): BoardChange | null; export {}; //# sourceMappingURL=aim.d.ts.map