UNPKG

react-native-gesture-handler

Version:

Declarative API exposing native platform touch and gesture system to React Native

101 lines (93 loc) 3.89 kB
"use strict"; /** * Canonical representation of `hitSlop`, shared by every platform: * `[left, top, right, bottom, width, height]`, where `null` marks an edge that * the user did not specify. * * The public `HitSlop` type accepts a number, `horizontal`/`vertical` * shorthands and per-edge values; normalizing all of that here means each * platform only ever parses these six slots. `width` and `height` cannot be * flattened into the four edges because they are resolved against the measured * view bounds at hit-test time, so they are carried through as-is. */ /** * What actually travels to the platforms: either a plain number, which every * reader expands into four equal edges itself, or the six canonical slots. * A number stays a number on purpose — it avoids the array wrapper the bridge * would otherwise allocate for the far more common uniform case. */ const CLEARED_HIT_SLOP = [null, null, null, null, null, null]; export const HIT_SLOP_LEFT_IDX = 0; export const HIT_SLOP_TOP_IDX = 1; export const HIT_SLOP_RIGHT_IDX = 2; export const HIT_SLOP_BOTTOM_IDX = 3; export const HIT_SLOP_WIDTH_IDX = 4; export const HIT_SLOP_HEIGHT_IDX = 5; function validateHitSlop(hitSlop) { 'worklet'; const [left, top, right, bottom, width, height] = hitSlop; // Unlike the edges, `width` and `height` are absolute sizes rather than // deltas, so a negative value describes an inverted region that no pointer // can fall into. if (width !== null && width < 0) { throw new Error("HitSlop error: 'width' cannot be negative"); } if (height !== null && height < 0) { throw new Error("HitSlop error: 'height' cannot be negative"); } if (width !== null && left !== null && right !== null) { throw new Error("HitSlop error: cannot have all of 'left', 'right' and 'width' defined"); } if (width !== null && left === null && right === null) { throw new Error("HitSlop error: when 'width' is defined, either 'left' or 'right' has to be defined"); } if (height !== null && top !== null && bottom !== null) { throw new Error("HitSlop error: cannot have all of 'top', 'bottom' and 'height' defined"); } if (height !== null && top === null && bottom === null) { throw new Error("HitSlop error: when 'height' is defined, either 'top' or 'bottom' has to be defined"); } } /** * Converts the user-facing `hitSlop` into `CanonicalHitSlop`. * * `undefined` is passed through so that the property stays out of partial * config updates (the platforms leave the previous value alone when the key is * missing), while an explicit `null` becomes six unset slots, which is how the * platforms already represent a cleared hit slop. * * A plain number is forwarded untouched, so the uniform case never allocates an * array on the way to the platforms. * * Already normalized values are returned as-is, which keeps the function * idempotent. * * Runs on the UI thread as well, since `hitSlop` can be a shared value. */ export function normalizeHitSlop(hitSlop) { 'worklet'; if (hitSlop === undefined) { return undefined; } // An explicit `null` means "clear it", which is what six unset slots already // describe. It is sent that way rather than as a bare `null` because the iOS // TurboModule bridge drops null-valued keys, making a clear indistinguishable // from an absent one. if (hitSlop === null) { return CLEARED_HIT_SLOP; } if (typeof hitSlop === 'number' || Array.isArray(hitSlop)) { return hitSlop; } const slop = hitSlop; const { horizontal, vertical } = slop; const normalized = [slop.left ?? horizontal ?? null, slop.top ?? vertical ?? null, slop.right ?? horizontal ?? null, slop.bottom ?? vertical ?? null, slop.width ?? null, slop.height ?? null]; if (__DEV__) { validateHitSlop(normalized); } return normalized; } //# sourceMappingURL=hitSlop.js.map