import React from "react"; import type { ReactElement, ReactNode, Ref } from "react"; import { Keyboard, View } from "react-native"; import { type TriggerRef, useRootContext } from "@rn-primitives/select"; import { useStyles } from "./SelectTrigger.style"; import { useSelectFieldState } from "./SelectFieldContext"; import { FieldLabel } from "./SelectLabel"; import { SELECT_TRIGGER_DEFAULT_TEST_ID, SelectPrimitive, } from "../../primitives/Select"; import { Icon } from "../../Icon"; export interface SelectTriggerProps { /** Trigger content — typically `Select.Value` (and optionally a label part). */ readonly children?: ReactNode; /** Used verbatim to locate the trigger in end-to-end tests. Defaults to `ATL-Select-Trigger`. */ readonly testID?: string; /** * Imperative handle exposing `open()` / `close()`. Stays `null` when the field * is `readOnly` (no interactive trigger is mounted). */ readonly ref?: Ref; } /** * The styled field trigger: composes the chevron, the resolved `invalid` styling, * the accessible name, the inside label placement, and the static `readOnly` * presentation over `SelectPrimitive.Trigger`. State comes from `Select.Root` * (field context) and the primitive root context. */ export function SelectTrigger({ children, testID, ref, }: SelectTriggerProps): ReactElement { const styles = useStyles(); const { invalid, readOnly, accessibilityLabel, labelPlacement } = useSelectFieldState(); const { open, value, disabled } = useRootContext(); const isDisabled = disabled ?? false; // `disabled` wins over `readOnly`. const isReadOnly = !isDisabled && (readOnly ?? false); const isInsideLabel = labelPlacement === "inside"; const content = ( {isInsideLabel && } {children} ); if (isReadOnly) { return ( {content} ); } return ( Keyboard.dismiss()} > {content} ); } /** Trailing chevron: tinted `iconSecondary`, greyed when disabled, rotated when open. */ function Chevron({ open, disabled, }: { readonly open: boolean; readonly disabled: boolean; }): ReactElement { return ( ); }