/**
 * Vision analyzer field projection.
 *
 * The runner's vision pipeline (`POST /ui-bridge/vision/{analyze,assert}`)
 * deserializes a snapshot's `elements[]` straight into the Rust
 * `qontinui_vision_core::Element` struct. Beyond geometry (`bbox` — see
 * {@link projectBbox}), the analyzers read these per-element fields:
 *
 *   - `interactable: bool`          — elements analyzer (interactive coverage),
 *                                     layout analyzer (WCAG target size).
 *   - `text: Option<String>`        — elements (no_text), color (contrast gate).
 *   - `role: Option<String>`        — elements analyzer role vocabulary.
 *   - `fg_color`/`bg_color: Rgb`    — color analyzer (WCAG contrast).
 *   - `font_size_px: f32`           — typography analyzer (size drift).
 *   - `font_family: String`         — typography analyzer (family drift).
 *
 * The web SDK populates the runner-facing equivalents via `getComputedStyle`
 * (`state.computedStyles.{color,backgroundColor,fontSize,fontFamily}`) and
 * the DOM (`textContent`, aria `role`, event handlers / tag → interactable);
 * the runner projects those into the snake_case Rust shape. React Native has
 * NO `getComputedStyle`, so the native SDK derives the same signals from what
 * the registry already carries:
 *
 *   - `interactable` ← the element's `actions` (press/click/tap/...) or its
 *     interactive `type` (button/input/switch/...). Mirrors web's
 *     "has a click-type handler OR is an interactive tag".
 *   - `text` ← `state.value` / `state.textContent` / `label` (human-visible).
 *   - `role` ← `type` mapped to the ARIA-ish vocabulary the analyzer expects.
 *   - `fg_color`/`bg_color` ← parsed from `flatStyle.color` /
 *     `flatStyle.backgroundColor` when the host wired styles via
 *     `captureStyle`/`updateElementStyle`. Same source the design inspector
 *     reads. Absent when no style was wired (analyzer soft-skips).
 *   - `font_size_px` ← `flatStyle.fontSize` (RN number is already px).
 *   - `font_family` ← `flatStyle.fontFamily`.
 *
 * These fields are emitted directly in the runner-native snake_case shape so a
 * visual-audit caller can post the snapshot through with no transform — same
 * rationale as `bbox` emitting `{x,y,w,h}` (see {@link NativeElementBbox}).
 */
import type { NativeElementState, NativeElementType } from './types';
/** Linear RGB triple, runner-native shape (`qontinui_vision_core::Rgb`). */
export interface VisionRgb {
    r: number;
    g: number;
    b: number;
}
/**
 * Analyzer-facing fields projected onto a snapshot element. Every field is
 * optional/absent-when-unknown so the Rust deserializer's serde defaults
 * (`interactable: false`, the rest `None`) only kick in when we genuinely
 * couldn't derive the value — matching the "soft skip on missing field"
 * contract in `element_snapshot.rs`.
 */
export interface VisionElementFields {
    interactable: boolean;
    text?: string;
    role?: string;
    fg_color?: VisionRgb;
    bg_color?: VisionRgb;
    font_size_px?: number;
    font_family?: string;
}
/**
 * Map a native element `type` to the ARIA-ish `role` vocabulary the runner's
 * elements analyzer expects (matches the web SDK's aria/role values). Returns
 * `undefined` for generic containers so the analyzer doesn't over-count roles.
 */
export declare function roleForType(type: NativeElementType): string | undefined;
/**
 * Derive whether an element accepts input. True when it is an
 * inherently-interactive `type` (button/input/switch/...) OR the host wired a
 * REAL interactive handler to it (`onPress`/`onChangeText`/...). Matches web's
 * "has a real click-type handler OR is an interactive tag".
 *
 * The `handlerNames` come from `extractHandlerNames(props)` — the names of the
 * element's props whose values are actually functions (the snapshot's
 * `registeredHandlers`). This is the genuine interactivity signal. The
 * element's inferred `actions` array is deliberately NOT consulted:
 * `inferActions` synthesizes `click`/`press` for plain `text`/`view`/`custom`,
 * so an action-based check would mark every node interactive (the very
 * over-count this function exists to avoid). A plain `text`/`view`/`heading`
 * with no real handler is therefore `interactable: false`, mirroring web.
 */
export declare function deriveInteractable(type: NativeElementType, handlerNames: readonly string[] | undefined): boolean;
/**
 * Derive the human-visible text for an element, preferring the most
 * "what the user reads" source. Mirrors web's `textContent`/accessibleName
 * precedence adapted to RN's registry shape:
 *   1. `state.value`       — current input value / text element's mirrored label.
 *   2. `state.textContent` — explicit text content if the host set it.
 *   3. `label`             — registration label (often the visible string).
 * Returns `undefined` when none carry a non-empty string so the analyzer's
 * `text.is_none()` gate stays accurate.
 */
export declare function deriveText(state: Pick<NativeElementState, 'value' | 'textContent'>, label: string | undefined): string | undefined;
/**
 * Parse an RN/CSS color string into a runner-native `{r,g,b}` triple, dropping
 * alpha (the runner's `Rgb` has no alpha; the analyzers convert to Lab/sRGB on
 * demand). Supports:
 *   - `#rgb`, `#rgba`, `#rrggbb`, `#rrggbbaa`
 *   - `rgb(r,g,b)` / `rgba(r,g,b,a)` (integer or %),
 *   - named colors (subset).
 * Returns `undefined` for `undefined`, non-strings, or unrecognized formats so
 * the snapshot omits the field and the analyzer soft-skips rather than seeing a
 * bogus color. RN integer colors (e.g. `processColor` output) are not handled —
 * inline styles in app source are strings.
 */
export declare function parseColorToRgb(input: unknown): VisionRgb | undefined;
/**
 * Parse an RN `fontSize` into CSS pixels. RN `fontSize` is a unitless number
 * already in density-independent pixels (the analyzer compares relative sizes,
 * so dp vs px scaling is consistent across all elements in one snapshot).
 * Accepts a bare number or a `"16px"`/`"16"` string. Returns `undefined` for
 * anything non-numeric so typography soft-skips.
 */
export declare function parseFontSizePx(input: unknown): number | undefined;
/**
 * Project the analyzer-facing fields for one registered element. Pure — takes
 * the already-resolved state + the element's static metadata, returns the
 * snake_case field bag to spread onto the snapshot element. Visual fields
 * (colors/fonts) are present only when `flatStyle` carried them; the runner's
 * serde defaults handle their absence.
 *
 * Unlike `bbox` (gated on `visibility === 'visible'`), interactable/text/role
 * are populated for ALL elements so the elements analyzer's coverage counts
 * are accurate — matching the web SDK, which emits role/text/interactable for
 * every element it discovers regardless of viewport position.
 */
export declare function projectVisionFields(args: {
    type: NativeElementType;
    label: string | undefined;
    /**
     * Names of the element's props that are real functions (from
     * `extractHandlerNames(props)` — the snapshot's `registeredHandlers`). The
     * genuine interactivity signal; the inferred `actions` array is NOT used here
     * because `inferActions` synthesizes press/click for every element.
     */
    handlerNames: readonly string[] | undefined;
    state: Pick<NativeElementState, 'value' | 'textContent'>;
    flatStyle: Record<string, unknown> | undefined;
}): VisionElementFields;
//# sourceMappingURL=vision-fields.d.ts.map