UNPKG

@activecollab/components

Version:

ActiveCollab Components

111 lines 5.29 kB
/** * StackedCard resize policy — pure math. * * The card reports intent; the HOST applies a resize policy (spec §7). This * module is that policy, packaged as pure functions so the SAME code path * serves the pointer drag and the keyboard resize. Nothing here touches the * DOM, React or the card's content: it takes a start size, a delta and a * policy, and returns a clamped size. `useStackedCardResize` wires events to * it; the card's intrinsic content minimum is measured by the host and passed * in as `contentMin`, so this module knows nothing about heroes or footers. * * The policy has four parts: * - bounds — optional min/max per axis; unset means unbounded. * - proportional — lock the aspect ratio captured at the start of the gesture; * the scale is clamped by the BINDING axis so the ratio never * distorts at a bound. * - step — optional grid snap; proportion wins over the grid. * - content min — the effective min is max(policyMin, contentMin) per axis, * so a card can never be crushed below what its content needs. */ export interface StackedCardSize { w: number; h: number; } /** The card's intrinsic minimum, measured from its real content. */ export interface StackedCardContentMin { w: number; h: number; } export interface StackedCardResizePolicy { minW?: number; maxW?: number; minH?: number; maxH?: number; /** Lock the aspect ratio for the whole gesture. */ proportional: boolean; /** Grid snap increment in px; omitted / 0 means continuous. */ step?: number; } /** The size captured at the start of a gesture (pointer down or a key press). */ export interface StackedCardResizeStart { w: number; h: number; contentMin: StackedCardContentMin; } export interface StackedCardResizeDelta { dx: number; dy: number; } export interface StackedCardResizeBounds { wMin: number; wMax: number; hMin: number; hMax: number; } /** * `width` locks the vertical axis: an auto-height card takes a width and lets * its rows set the height, so the gesture's vertical component is ignored. */ export type StackedCardResizeAxis = "both" | "width"; /** Which input drove a resize event. Hosts log undo entries per source. */ export type StackedCardResizeSource = "pointer" | "keyboard"; /** Keyboard resize nudges by the policy step, or this when no step is set. */ export declare const DEFAULT_KEYBOARD_STEP = 8; /** Shift + arrow resizes by a larger increment (the familiar coarse nudge). */ export declare const SHIFT_STEP_MULTIPLIER = 4; /** Keys the separator handles; everything else falls through to the browser. */ export declare const RESIZE_KEYS: ReadonlyArray<string>; export declare const isResizeKey: (key: string) => boolean; export declare const clamp: (v: number, lo: number, hi?: number) => number; export declare const snap: (v: number, step?: number) => number; export declare const makeStart: (size: StackedCardSize, contentMin: StackedCardContentMin) => StackedCardResizeStart; /** * The effective bounds a size is clamped to: the policy min floored by the * content min, and the policy max (unbounded when unset). Independent of any * live gesture, so a host can also use it for the aria value and Home/End. */ export declare const effectiveBounds: (policy: StackedCardResizePolicy, contentMin: StackedCardContentMin) => StackedCardResizeBounds; /** * Apply a delta to the start size under the policy — the single path for both * inputs. * * `constrain` is the transient Shift-to-constrain lock: a free-form policy * behaves proportionally for that one gesture; a proportional policy is already * locked and ignores it. `axis: "width"` drops the gesture's vertical component; * the height then holds still in free-form mode, and still follows the ratio in * proportional mode (that is what proportional means). */ export declare const applyResize: (start: StackedCardResizeStart, delta: StackedCardResizeDelta, policy: StackedCardResizePolicy, opts?: { constrain?: boolean; axis?: StackedCardResizeAxis; }) => StackedCardSize; /** * Translate a resize key into the next size, reusing `applyResize` so the * keyboard clamps exactly like the pointer. Arrows nudge by the step (Shift ×4); * Home/End jump to the min/max of the allowed range, leaving any axis without * that bound where it is. Returns null for a key the handle does not own, and * for a vertical key on a width-only card. */ export declare const keyboardResize: (key: string, size: StackedCardSize, policy: StackedCardResizePolicy, contentMin: StackedCardContentMin, opts?: { shiftKey?: boolean; axis?: StackedCardResizeAxis; }) => StackedCardSize | null; /** * The handle's `aria-valuenow`: the current size as a percent (0–100) of its * allowed range. The corner resizes both axes, but the value must be a single * number, so it reports the WIDTH axis — the one axis the fixed-box and the * width-only cards share. Returns 0 when the range isn't finite (no max bound). */ export declare const measurePercent: (size: StackedCardSize, policy: StackedCardResizePolicy, contentMin: StackedCardContentMin) => number; //# sourceMappingURL=resizePolicy.d.ts.map