import { type ReactNode } from "react"; import { type TextStyle } from "./primitives.js"; import { type ColorTokens } from "./tokens.js"; /** * The label-placement slice a filled-field skin fulfills. iOS + web render the * label ABOVE the field (`floatingLabel: false`), Android floats the M3 * in-container label (`floatingLabel: true`, supplying the rest/floated/reserve * types). The label's COLOR (muted at rest, brand `ring` on focus, `destructive` * on error) is animated by `FloatingLabel` from the active tokens, so it is not * described here. */ export interface FloatingLabelStyles { /** true on the Android skin (floating label); false on iOS/web (label above). */ floatingLabel: boolean; /** iOS/web: the static above-field label type (color is applied by the shell). */ labelAbove?: (t: ColorTokens, size: S) => TextStyle; /** Android: the resting (unfocused, empty) label type — body-large, centered like a placeholder. */ labelRest?: (t: ColorTokens, size: S) => TextStyle; /** Android: the floated label type — body-small at the top. Only its `fontSize` * is used (to derive the transform scale = floated/rest); the label is RENDERED * at `labelRest` and scaled, never re-sized, so the animation stays on the * transform driver (Fabric/RNW-safe). */ labelFloated?: (t: ColorTokens, size: S) => TextStyle; /** Android: the state-independent top padding the field reserves for the floated * label, spread by the shell so the skin's field/trigger signature (and the * active-indicator invariant it is tested against) stays intact. */ labelReserve?: (size: S) => TextStyle; } export declare const HIDDEN_FROM_A11Y: { readonly accessibilityElementsHidden: true; readonly importantForAccessibility: "no-hide-descendants"; readonly "aria-hidden": true; }; /** * The label text plus, when required, a trailing destructive "*". The star is * hidden from assistive tech so the accessible name stays the bare label. Used * for BOTH the above-field label and the floated label so every field family * renders the required affordance identically. */ export declare function LabelContent({ label, required, starColor }: { label: string; required?: boolean; starColor: string; }): ReactNode; /** * The Material 3 in-container floating label (Android skin only). It overlays the * field, pinned to the leading edge, and animates between the resting (centered * placeholder-like, or top-aligned on a multiline field) and floated (top, small) * positions. * * Split-driver animation (the crux — must run on iOS, Android New-Arch/Fabric, * AND react-native-web): * - `pos` (0->1) drives ONLY the transform (translateY + scale 1->floated/rest), * on the native driver where available (a one-shot, so the loop-freeze caveat * does not apply) and the JS driver on web. It NEVER animates fontSize/top/width * (those are Fabric-stuck). Target = focused || populated. * - `tint` (0->1) drives ONLY the color, on the JS driver ALWAYS (color can't be * native-driven). Target = focused || error, so a filled-but-unfocused valid * field floats yet stays muted. * transformOrigin "0% 50%" pins the leading edge while it scales (no measurement, * no translateX); RTL uses the logical `start` inset. * * Geometry: the label's resting and floated vertical CENTERS are computed, and * translateY carries the resting center to the floated one: * - single-line: rest center = the field's vertical middle (`height / 2`); * - multiline: rest center aligns with the first value line (`reserve + line/2`), * since a multiline field's value is top-aligned below the reserved band. * The floated center lands the scaled label's bottom edge at `reserve` (where the * value begins), so the value always clears it. */ export declare function FloatingLabel({ styles, size, tokens, label, required, labelId, focused, populated, isError, height, inset, multiline, }: { styles: FloatingLabelStyles; size: S; tokens: ColorTokens; label: string; required?: boolean; labelId: string; focused: boolean; populated: boolean; isError: boolean; /** The single-line field's height (used to center the resting label). Ignored in `multiline` mode. */ height: number; /** Leading inset that matches the field's horizontal content padding (default 16dp). */ inset?: number; /** Multiline field (Textarea): rest the label at the top text line, not the box middle. */ multiline?: boolean; }): import("react").JSX.Element; //# sourceMappingURL=floating-label.d.ts.map