/** * Pure split-sizing math for the dock renderer — no react import. * * These functions translate between the model's raw per-child WEIGHTS (+ px * constraints) and the percentage/ratio bases the react-resizable-panels Group * consumes and reports. They are the single arithmetic authority behind * `SplitView`'s model→view sync and resize write-back; several are exported so * the sizing invariants can be unit-tested directly. */ import type { SizeConstraint } from '../layout/index.js'; /** Epsilon (in percentage points) within which two split layouts are treated as * equivalent. Guards BOTH sides of the model↔view loop: we skip pushing a * `setLayout` when the live layout already matches the target, and skip the * `onLayoutChanged` write-back when the incoming layout matches the model — so * `setLayout`→`onLayoutChanged`→write-back→re-sync cannot loop. */ export declare const LAYOUT_EPSILON = 0.5; /** TIGHT tolerance (percentage points) for the BASIS-NORMALIZED flexible-ratio * compare in `handleLayoutChanged`. We normalize the incoming layout's flexible * subset to ratios summing to 100 and compare them against the model's flexible * ratios (`computeFlexiblePercentages`, also summing to 100). If they match * within this tolerance the `onLayoutChanged` is either our own `setLayout` echo * OR a ratio-preserving spontaneous re-measure (mount / fixed-px re-pin / * container resize) — SKIP the write-back. If they differ it is a genuine user * resize (pointer OR keyboard) — WRITE BACK. * * Set to ~0.1pp: large enough to absorb rrp's ~3-decimal float noise on an echo, * yet FAR below a real drag's delta. R1's "sub-0.5%" drag moves a panel ~0.33pp * of the container; normalized over the two-flexible-child subset that is ~0.66pp * of ratio — comfortably above 0.1, so it is NOT mistaken for an echo and is * written back. * * CAVEAT: this is a flexible-RATIO tolerance (the flexible subset normalized to * sum 100), NOT a container-%. It is safe against rrp's 3-decimal echo noise. * In a pathologically WIDE split (~≥10 flexible children) a single arrow-key * nudge (±~5% of the container on one child) can, once normalized over many * flexible siblings, fall BELOW 0.1pp of ratio and be skipped — exotic and * self-healing (the next, larger resize writes back). If that ever matters, * scale the tolerance down by the flexible child count. */ export declare const FLEX_RATIO_TOLERANCE = 0.1; /** Normalize raw split weights to percentages summing ~100 for `defaultSize`. */ export declare function toPercentages(sizes: readonly number[]): number[]; /** * Compute the `defaultSize` percentage for each FLEXIBLE child, keyed by its * ORIGINAL child index. Px-sized children (a non-null `constraint` — `fixedPx` * locked OR `minPx` floored) are EXCLUDED from the pool: their size is px, not a * weight, so it must never pollute the flexible siblings' normalization (FIX E1). * `constraints[i]` non-null ⇒ child i is px-sized and absent from the returned map. */ export declare function computeFlexiblePercentages(sizes: readonly number[], constraints: readonly (SizeConstraint | null)[] | undefined): Map; /** * The minimum weight a FLEXIBLE child may hold, given how many flexible children * share the split (Bug #1). A flexible `` has no rrp `minSize` by default * (rrp floor is 0%), so a user can drag it to ~0 width; the resize write-back * would then persist a ~0 weight and the panel comes back invisible/stuck. * * The floor is `min(1, floor(90 / flexCount))` — i.e. ~1 weight unit (a flexible * split's weights are normalized to percentages downstream, so ~1 reads as ~1% * of the flexible pool). With any realistic flexible count this is exactly 1; the * `min(1, …)` only matters for a hypothetical 90+ flexible-child split. It is the * SAME value used for the rrp `minSize` (A) and the write-back clamp (B) so the * two defenses never disagree. */ export declare function flexibleFloor(flexCount: number): number; /** * Clamp the FLEXIBLE entries of a full-length weights array up to `floor` (Bug #1 * defense B). Px-sized children (a non-null constraint) are left untouched — their * `sizes[i]` is a preserved placeholder, not a live weight. Returns a new array; * a weight already ≥ floor is kept verbatim so a healthy ratio is undisturbed. */ export declare function clampFlexibleWeights(weights: readonly number[], constraints: readonly (SizeConstraint | null)[] | undefined): number[]; /** Are two panelId→percentage maps equivalent within `epsilon` percentage * points? Both maps must cover EXACTLY the `ids` key set — a missing key OR an * extra key (a key present in `a`/`b` but absent from `ids`) counts as NOT * equivalent so the sync is not falsely suppressed. A non-finite value * (NaN/±Infinity) is likewise NOT equivalent — `typeof NaN === 'number'` and * `Math.abs(NaN - x) > eps` is `false`, so without the `Number.isFinite` guard a * NaN would slip through as "equivalent" and wrongly suppress a legitimate * sync/write-back (N1). EXPORTED (pure) for direct unit coverage. */ export declare function layoutsEquivalent(a: Record, b: Record, ids: readonly string[], epsilon?: number): boolean; /** * Build the panel-ID→PERCENTAGE map for an imperative `setLayout`, given the * model's full-length raw `sizes` (per child) and `constraints`: * * - FIXED (px-pinned) children keep their CURRENT measured percentage (read * from the live `getLayout()`); they are NOT derived from weights, so a * flexible-weights change never disturbs their pixel lock. * - The REMAINING percentage (100 − Σ fixed%) is distributed across the * FLEXIBLE children in proportion to their weights. * * Returns `null` when the map can't be built faithfully (e.g. `live` is empty — * jsdom's stub — or a fixed child's live % is missing), so the caller skips the * `setLayout` rather than pushing a corrupt total. The result always sums to * ~100 over all children. */ export declare function buildSetLayoutMap(childIds: readonly string[], sizes: readonly number[], constraints: readonly (SizeConstraint | null)[] | undefined, live: Record): Record | null; /** * Extract an rrp `onLayoutChanged` map's FLEXIBLE subset (skipping fixed-px * children) in child order and NORMALIZE it by its own sum to ratios summing to * ~100 — the basis `computeFlexiblePercentages` already produces for the model, * so the two are directly comparable. Returns the original child `indices` * alongside the `ratios`. Null when the map is malformed (a flexible id is * missing / non-finite) or there is no flexible child — the caller then never * writes back from it. */ export declare function incomingFlexRatios(childIds: readonly string[], constraints: readonly (SizeConstraint | null)[] | undefined, layout: Record): { indices: number[]; ratios: number[]; } | null; //# sourceMappingURL=split-sizing.d.ts.map