@mrmeg/expo-ui 0.23.0 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/CHANGELOG.md +84 -0
  2. package/LLM_USAGE.md +172 -157
  3. package/README.md +447 -352
  4. package/dist/components/Avatar.js +6 -1
  5. package/dist/components/BottomSheet.js +1 -1
  6. package/dist/components/Button.d.ts +1 -1
  7. package/dist/components/Carousel.js +2 -0
  8. package/dist/components/Dialog.d.ts +15 -93
  9. package/dist/components/Dialog.js +5 -0
  10. package/dist/components/DismissKeyboard.d.ts +14 -3
  11. package/dist/components/DismissKeyboard.js +17 -48
  12. package/dist/components/DropdownMenu.d.ts +5 -34
  13. package/dist/components/DropdownMenu.js +2 -1
  14. package/dist/components/InputOTP.js +6 -1
  15. package/dist/components/Popover.d.ts +11 -11
  16. package/dist/components/Popover.js +3 -2
  17. package/dist/components/Select.d.ts +12 -20
  18. package/dist/components/Select.js +2 -1
  19. package/dist/components/StatusBar.js +2 -6
  20. package/dist/components/StyledText.context.d.ts +1 -1
  21. package/dist/components/StyledText.d.ts +6 -2
  22. package/dist/components/TextInput.d.ts +6 -2
  23. package/dist/components/TextInput.js +189 -42
  24. package/dist/components/Tooltip.d.ts +10 -24
  25. package/dist/components/Tooltip.js +5 -2
  26. package/dist/components/index.d.ts +1 -0
  27. package/dist/components/index.js +1 -0
  28. package/dist/components/keyboardController.d.ts +4 -2
  29. package/dist/components/keyboardController.js +4 -0
  30. package/dist/components/keyboardDismiss.d.ts +37 -0
  31. package/dist/components/keyboardDismiss.js +170 -0
  32. package/dist/components/keyboardFocusRegistry.d.ts +10 -14
  33. package/dist/components/keyboardFocusRegistry.js +8 -24
  34. package/dist/design-system.json +2236 -0
  35. package/dist/hooks/useTheme.d.ts +11 -3
  36. package/llms-full.md +134 -124
  37. package/llms.txt +24 -22
  38. package/package.json +11 -8
@@ -81,12 +81,17 @@ export function getAvatarInitials(name) {
81
81
  * `{ bundle, name }`, a resolved asset object). Keying those as "no image"
82
82
  * silently degraded a perfectly good source to initials.
83
83
  */
84
+ // `Array.isArray` narrows to `any[]`, which cannot subtract the readonly array
85
+ // arm of the source union, so the predicate spells the arm out.
86
+ function isSourceList(source) {
87
+ return Array.isArray(source);
88
+ }
84
89
  function getSourceKey(source) {
85
90
  if (source == null)
86
91
  return null;
87
92
  if (typeof source === "number")
88
93
  return `asset:${source}`;
89
- if (Array.isArray(source)) {
94
+ if (isSourceList(source)) {
90
95
  // An empty array carries no image; anything else does.
91
96
  const keys = source.map((entry) => getSourceKey(entry) ?? "").filter(Boolean);
92
97
  return keys.length > 0 ? keys.join("|") : null;
@@ -181,7 +181,7 @@ function SheetCloseButton({ style }) {
181
181
  * dispatched across the `RNHostView` boundary on Android — only `Pressable`
182
182
  * hit-testing (native `measure()`) works inside the host. So this is a
183
183
  * transparent `Pressable` mounted ONLY while a field is focused, mirroring
184
- * the app's `DismissKeyboardOverlay`. The tap blurs the focused field via
184
+ * a tap-to-dismiss overlay in the app. The tap blurs the focused field via
185
185
  * its own native ref (`dismissKeyboardFocusedInput`), which resigns the
186
186
  * responder regardless of window; `KeyboardController.dismiss()` is a
187
187
  * best-effort fallback for the (rare) case with no registered blur handle.
@@ -40,7 +40,7 @@ export interface ButtonProps extends PressableProps {
40
40
  */
41
41
  txOptions?: TextProps["txOptions"];
42
42
  /**
43
- * An optional style override useful for padding & margin.
43
+ * An optional style override useful for margin and layout.
44
44
  */
45
45
  style?: StyleProp<ViewStyle>;
46
46
  /**
@@ -94,6 +94,8 @@ export function Carousel({ children, itemWidth = 0.85, gap = spacing.md, content
94
94
  // state: web's throttled ticks report the same page many times over, and
95
95
  // onIndexChange must fire once per page.
96
96
  const activeIndexRef = useRef(activeIndex);
97
+ // `ComponentRef<typeof ScrollView>` rather than RN 0.88's `ScrollViewInstance`,
98
+ // which RN 0.85/0.86 typings do not export.
97
99
  const scrollRef = useRef(null);
98
100
  const hasScrolledToInitial = useRef(false);
99
101
  const commitIndex = useCallback((next) => {
@@ -1,25 +1,9 @@
1
1
  import * as React from "react";
2
- import { View, ViewProps } from "react-native";
2
+ import { ViewProps } from "react-native";
3
3
  import * as DialogPrimitive from "@rn-primitives/dialog";
4
4
  import * as AlertDialogPrimitive from "@rn-primitives/alert-dialog";
5
- declare const DialogTrigger: {
6
- ({ asChild, onPress: onPressProp, disabled, ref, ...props }: Omit<import("react-native").PressableProps & React.RefAttributes<View>, "ref"> & {
7
- asChild?: boolean;
8
- } & {
9
- onKeyDown?: (ev: React.KeyboardEvent) => void;
10
- onKeyUp?: (ev: React.KeyboardEvent) => void;
11
- } & React.RefAttributes<View>): React.JSX.Element;
12
- displayName: string;
13
- };
14
- declare const DialogClose: {
15
- ({ asChild, onPress: onPressProp, disabled, ref, ...props }: Omit<import("react-native").PressableProps & React.RefAttributes<View>, "ref"> & {
16
- asChild?: boolean;
17
- } & {
18
- onKeyDown?: (ev: React.KeyboardEvent) => void;
19
- onKeyUp?: (ev: React.KeyboardEvent) => void;
20
- } & React.RefAttributes<View>): React.JSX.Element;
21
- displayName: string;
22
- };
5
+ declare const DialogTrigger: typeof DialogPrimitive.Trigger;
6
+ declare const DialogClose: typeof DialogPrimitive.Close;
23
7
  interface DialogProps extends DialogPrimitive.RootProps {
24
8
  children: React.ReactNode;
25
9
  }
@@ -36,58 +20,19 @@ declare function DialogTitle({ children, style, ...props }: DialogPrimitive.Titl
36
20
  declare function DialogDescription({ children, style, ...props }: DialogPrimitive.DescriptionProps & {
37
21
  children: React.ReactNode;
38
22
  }): React.JSX.Element;
39
- declare const Dialog: typeof DialogRoot & {
40
- Trigger: {
41
- ({ asChild, onPress: onPressProp, disabled, ref, ...props }: Omit<import("react-native").PressableProps & React.RefAttributes<View>, "ref"> & {
42
- asChild?: boolean;
43
- } & {
44
- onKeyDown?: (ev: React.KeyboardEvent) => void;
45
- onKeyUp?: (ev: React.KeyboardEvent) => void;
46
- } & React.RefAttributes<View>): React.JSX.Element;
47
- displayName: string;
48
- };
23
+ type DialogComponent = typeof DialogRoot & {
24
+ Trigger: typeof DialogTrigger;
49
25
  Content: typeof DialogContent;
50
26
  Header: typeof DialogHeader;
51
27
  Footer: typeof DialogFooter;
52
28
  Title: typeof DialogTitle;
53
29
  Description: typeof DialogDescription;
54
- Close: {
55
- ({ asChild, onPress: onPressProp, disabled, ref, ...props }: Omit<import("react-native").PressableProps & React.RefAttributes<View>, "ref"> & {
56
- asChild?: boolean;
57
- } & {
58
- onKeyDown?: (ev: React.KeyboardEvent) => void;
59
- onKeyUp?: (ev: React.KeyboardEvent) => void;
60
- } & React.RefAttributes<View>): React.JSX.Element;
61
- displayName: string;
62
- };
63
- };
64
- declare const AlertDialogTrigger: {
65
- ({ asChild, onPress: onPressProp, disabled, ref, ...props }: Omit<import("react-native").PressableProps & React.RefAttributes<View>, "ref"> & {
66
- asChild?: boolean;
67
- } & {
68
- onKeyDown?: (ev: React.KeyboardEvent) => void;
69
- onKeyUp?: (ev: React.KeyboardEvent) => void;
70
- } & React.RefAttributes<View>): React.JSX.Element;
71
- displayName: string;
72
- };
73
- declare const AlertDialogAction: {
74
- ({ asChild, onPress: onPressProp, disabled, ref, ...props }: Omit<import("react-native").PressableProps & React.RefAttributes<View>, "ref"> & {
75
- asChild?: boolean;
76
- } & {
77
- onKeyDown?: (ev: React.KeyboardEvent) => void;
78
- onKeyUp?: (ev: React.KeyboardEvent) => void;
79
- } & React.RefAttributes<View>): React.JSX.Element;
80
- displayName: string;
81
- };
82
- declare const AlertDialogCancel: {
83
- ({ asChild, onPress: onPressProp, disabled, ref, ...props }: Omit<import("react-native").PressableProps & React.RefAttributes<View>, "ref"> & {
84
- asChild?: boolean;
85
- } & {
86
- onKeyDown?: (ev: React.KeyboardEvent) => void;
87
- onKeyUp?: (ev: React.KeyboardEvent) => void;
88
- } & React.RefAttributes<View>): React.JSX.Element;
89
- displayName: string;
30
+ Close: typeof DialogClose;
90
31
  };
32
+ declare const Dialog: DialogComponent;
33
+ declare const AlertDialogTrigger: typeof AlertDialogPrimitive.Trigger;
34
+ declare const AlertDialogAction: typeof AlertDialogPrimitive.Action;
35
+ declare const AlertDialogCancel: typeof AlertDialogPrimitive.Cancel;
91
36
  interface AlertDialogProps extends AlertDialogPrimitive.RootProps {
92
37
  children: React.ReactNode;
93
38
  }
@@ -102,39 +47,16 @@ declare function AlertDialogTitle({ children, style, ...props }: AlertDialogPrim
102
47
  declare function AlertDialogDescription({ children, style, ...props }: AlertDialogPrimitive.DescriptionProps & {
103
48
  children: React.ReactNode;
104
49
  }): React.JSX.Element;
105
- declare const AlertDialog: typeof AlertDialogRoot & {
106
- Trigger: {
107
- ({ asChild, onPress: onPressProp, disabled, ref, ...props }: Omit<import("react-native").PressableProps & React.RefAttributes<View>, "ref"> & {
108
- asChild?: boolean;
109
- } & {
110
- onKeyDown?: (ev: React.KeyboardEvent) => void;
111
- onKeyUp?: (ev: React.KeyboardEvent) => void;
112
- } & React.RefAttributes<View>): React.JSX.Element;
113
- displayName: string;
114
- };
50
+ type AlertDialogComponent = typeof AlertDialogRoot & {
51
+ Trigger: typeof AlertDialogTrigger;
115
52
  Content: typeof AlertDialogContent;
116
53
  Header: typeof DialogHeader;
117
54
  Footer: typeof DialogFooter;
118
55
  Title: typeof AlertDialogTitle;
119
56
  Description: typeof AlertDialogDescription;
120
- Action: {
121
- ({ asChild, onPress: onPressProp, disabled, ref, ...props }: Omit<import("react-native").PressableProps & React.RefAttributes<View>, "ref"> & {
122
- asChild?: boolean;
123
- } & {
124
- onKeyDown?: (ev: React.KeyboardEvent) => void;
125
- onKeyUp?: (ev: React.KeyboardEvent) => void;
126
- } & React.RefAttributes<View>): React.JSX.Element;
127
- displayName: string;
128
- };
129
- Cancel: {
130
- ({ asChild, onPress: onPressProp, disabled, ref, ...props }: Omit<import("react-native").PressableProps & React.RefAttributes<View>, "ref"> & {
131
- asChild?: boolean;
132
- } & {
133
- onKeyDown?: (ev: React.KeyboardEvent) => void;
134
- onKeyUp?: (ev: React.KeyboardEvent) => void;
135
- } & React.RefAttributes<View>): React.JSX.Element;
136
- displayName: string;
137
- };
57
+ Action: typeof AlertDialogAction;
58
+ Cancel: typeof AlertDialogCancel;
138
59
  };
60
+ declare const AlertDialog: AlertDialogComponent;
139
61
  export { Dialog, DialogTrigger, DialogContent, DialogHeader, DialogFooter, DialogTitle, DialogDescription, DialogClose, AlertDialog, AlertDialogTrigger, AlertDialogContent, AlertDialogTitle, AlertDialogDescription, AlertDialogAction, AlertDialogCancel, };
140
62
  export type { DialogProps, DialogContentProps, AlertDialogProps, AlertDialogContentProps, };
@@ -14,6 +14,11 @@ const FullWindowOverlay = Platform.OS === "ios" ? RNFullWindowOverlay : React.Fr
14
14
  // ============================================================================
15
15
  // Dialog
16
16
  // ============================================================================
17
+ // These re-exports and the compound components below carry explicit type
18
+ // annotations because React Native 0.88 resolves primitive ref types through
19
+ // its private `ReactNativeElement`, which declaration emit cannot name
20
+ // portably (TS2883). Annotating with `typeof <primitive>` keeps the emitted
21
+ // .d.ts pointing at the primitive's own public types instead.
17
22
  const DialogTrigger = DialogPrimitive.Trigger;
18
23
  const DialogClose = DialogPrimitive.Close;
19
24
  function DialogRoot({ children, ...props }) {
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import { StyleProp, ViewStyle } from "react-native";
2
+ import { type StyleProp, type ViewStyle } from "react-native";
3
3
  type Props = {
4
4
  children: React.ReactNode;
5
5
  style?: StyleProp<ViewStyle>;
@@ -9,7 +9,18 @@ type Props = {
9
9
  scrollable?: boolean;
10
10
  };
11
11
  /**
12
- * @returns Wrapper for a view that dismisses the keyboard when tapped outside of a text input
12
+ * Wrapper for a screen (or form) that dismisses the keyboard when the user taps
13
+ * outside of a text input.
14
+ *
15
+ * Mirrors RN's `keyboardShouldPersistTaps="handled"` for the native `@expo/ui`
16
+ * field, which RN itself cannot see: the wrapper never claims the touch, so
17
+ * buttons, other fields and the focused field's own gestures win, and it
18
+ * dismisses on release only when nothing else took the tap and the finger did
19
+ * not scroll. See `useKeyboardDismissResponder`.
20
+ *
21
+ * A drag on the inner ScrollView also hides the keyboard: `interactive` on iOS
22
+ * (UIKit resigns any first responder, SwiftUI fields included) and an explicit
23
+ * dismiss on drag start on Android, where RN's `on-drag` only knows RN inputs.
13
24
  */
14
- export declare const DismissKeyboard: (props: Props) => React.JSX.Element;
25
+ export declare function DismissKeyboard({ children, style, avoidKeyboard, scrollable, }: Props): React.JSX.Element;
15
26
  export {};
@@ -1,58 +1,27 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import React from "react";
3
- import { Platform, ScrollView, View, } from "react-native";
4
- import { KeyboardController, useKeyboardContext, useKeyboardState, } from "./keyboardController";
2
+ import { Platform, ScrollView, View } from "react-native";
5
3
  import { KeyboardAvoidingView, useKeyboardAvoidance } from "./KeyboardAvoidingView.js";
6
- import { isTouchInsideKeyboardFocusedInput } from "./keyboardFocusRegistry.js";
4
+ import { dismissKeyboard, useKeyboardDismissResponder } from "./keyboardDismiss.js";
7
5
  /**
8
- * Native tap-away keyboard dismissal.
6
+ * Wrapper for a screen (or form) that dismisses the keyboard when the user taps
7
+ * outside of a text input.
9
8
  *
10
- * Why window-level dismissal: the native `@expo/ui` TextInput is a SwiftUI /
11
- * Compose field that never registers with React Native's `TextInputState`, so
12
- * `Keyboard.dismiss()` (which only blurs RN-tracked inputs) does nothing for it.
13
- * `KeyboardController.dismiss()` resigns the focused responder at the IME level,
14
- * which works for both native and RN fields.
9
+ * Mirrors RN's `keyboardShouldPersistTaps="handled"` for the native `@expo/ui`
10
+ * field, which RN itself cannot see: the wrapper never claims the touch, so
11
+ * buttons, other fields and the focused field's own gestures win, and it
12
+ * dismisses on release only when nothing else took the tap and the finger did
13
+ * not scroll. See `useKeyboardDismissResponder`.
15
14
  *
16
- * Why responder capture: a full-screen overlay also catches taps on the focused
17
- * input, which breaks double-tap text selection. Capture lets the tap continue
18
- * to children while still dismissing when the touch starts outside the focused
19
- * input bounds.
15
+ * A drag on the inner ScrollView also hides the keyboard: `interactive` on iOS
16
+ * (UIKit resigns any first responder, SwiftUI fields included) and an explicit
17
+ * dismiss on drag start on Android, where RN's `on-drag` only knows RN inputs.
20
18
  */
21
- function useDismissKeyboardOnOutsideTouch() {
22
- const isVisible = useKeyboardState((state) => state.isVisible);
23
- const { layout: focusedInput } = useKeyboardContext();
24
- return React.useCallback((event) => {
25
- if (Platform.OS === "web" || !isVisible) {
26
- return false;
27
- }
28
- if (isTouchInsideKeyboardFocusedInput(event, focusedInput.value?.layout)) {
29
- return false;
30
- }
31
- KeyboardController.dismiss();
32
- return false;
33
- }, [focusedInput, isVisible]);
34
- }
35
- /**
36
- * @returns Wrapper for a view that dismisses the keyboard when tapped outside of a text input
37
- */
38
- function DismissKeyboardLayout({ children, style, avoidKeyboard = true, scrollable = true, dismissOnTouchStart, }) {
19
+ export function DismissKeyboard({ children, style, avoidKeyboard = true, scrollable = true, }) {
20
+ const responderProps = useKeyboardDismissResponder();
39
21
  const hasKeyboardAvoidance = useKeyboardAvoidance();
40
- const content = scrollable ? (_jsx(ScrollView, { style: { flex: 1 }, contentContainerStyle: { flexGrow: 1, justifyContent: "center" }, keyboardShouldPersistTaps: "handled", showsVerticalScrollIndicator: false, children: children })) : (children);
22
+ const content = scrollable ? (_jsx(ScrollView, { style: { flex: 1 }, contentContainerStyle: { flexGrow: 1, justifyContent: "center" }, keyboardShouldPersistTaps: "handled", keyboardDismissMode: Platform.OS === "ios" ? "interactive" : "none", onScrollBeginDrag: Platform.OS === "android" ? dismissKeyboard : undefined, showsVerticalScrollIndicator: false, children: children })) : (children);
41
23
  if (!avoidKeyboard || hasKeyboardAvoidance) {
42
- return (_jsx(View, { style: { flex: 1 }, onStartShouldSetResponderCapture: dismissOnTouchStart, children: content }));
24
+ return (_jsx(View, { style: { flex: 1 }, ...responderProps, children: content }));
43
25
  }
44
- return (_jsx(KeyboardAvoidingView, { style: [{ flex: 1, width: "100%" }, style], keyboardVerticalOffset: Platform.OS === "ios" ? 0 : 0, onStartShouldSetResponderCapture: dismissOnTouchStart, children: content }));
45
- }
46
- function NativeDismissKeyboard(props) {
47
- const dismissOnTouchStart = useDismissKeyboardOnOutsideTouch();
48
- return (_jsx(DismissKeyboardLayout, { ...props, dismissOnTouchStart: dismissOnTouchStart }));
26
+ return (_jsx(KeyboardAvoidingView, { style: [{ flex: 1, width: "100%" }, style], keyboardVerticalOffset: 0, ...responderProps, children: content }));
49
27
  }
50
- /**
51
- * @returns Wrapper for a view that dismisses the keyboard when tapped outside of a text input
52
- */
53
- export const DismissKeyboard = (props) => {
54
- if (Platform.OS === "web") {
55
- return _jsx(DismissKeyboardLayout, { ...props });
56
- }
57
- return _jsx(NativeDismissKeyboard, { ...props });
58
- };
@@ -1,40 +1,11 @@
1
1
  import * as React from "react";
2
- import { type TextStyle, View } from "react-native";
2
+ import { type TextStyle } from "react-native";
3
3
  import * as DropdownMenuPrimitive from "@rn-primitives/dropdown-menu";
4
- declare const DropdownMenu: {
5
- ({ asChild, onOpenChange: onOpenChangeProp, ref, ...viewProps }: import("react-native").ViewProps & {
6
- asChild?: boolean;
7
- } & {
8
- onOpenChange?: (open: boolean) => void;
9
- } & React.RefAttributes<View>): React.JSX.Element;
10
- displayName: string;
11
- };
12
- declare const DropdownMenuGroup: {
13
- ({ asChild, ref, ...props }: import("react-native").ViewProps & {
14
- asChild?: boolean;
15
- } & React.RefAttributes<View>): React.JSX.Element;
16
- displayName: string;
17
- };
4
+ declare const DropdownMenu: typeof DropdownMenuPrimitive.Root;
5
+ declare const DropdownMenuGroup: typeof DropdownMenuPrimitive.Group;
18
6
  declare const DropdownMenuPortal: typeof DropdownMenuPrimitive.Portal;
19
- declare const DropdownMenuSub: {
20
- ({ asChild, defaultOpen, open: openProp, onOpenChange: onOpenChangeProp, ref, ...props }: import("react-native").ViewProps & {
21
- asChild?: boolean;
22
- } & {
23
- defaultOpen?: boolean;
24
- open?: boolean;
25
- onOpenChange?: (value: boolean) => void;
26
- } & React.RefAttributes<View>): React.JSX.Element;
27
- displayName: string;
28
- };
29
- declare const DropdownMenuRadioGroup: {
30
- ({ asChild, value, onValueChange, ref, ...props }: import("react-native").ViewProps & {
31
- asChild?: boolean;
32
- } & {
33
- value: string | undefined;
34
- onValueChange: (value: string) => void;
35
- } & React.RefAttributes<View>): React.JSX.Element;
36
- displayName: string;
37
- };
7
+ declare const DropdownMenuSub: typeof DropdownMenuPrimitive.Sub;
8
+ declare const DropdownMenuRadioGroup: typeof DropdownMenuPrimitive.RadioGroup;
38
9
  /**
39
10
  * DropdownMenuTrigger Component
40
11
  * Wraps the primitive Trigger to default `accessibilityRole="button"`.
@@ -10,7 +10,8 @@ import { useScalePress } from "../hooks/useScalePress.js";
10
10
  import * as DropdownMenuPrimitive from "@rn-primitives/dropdown-menu";
11
11
  import { FullWindowOverlay as RNFullWindowOverlay } from "react-native-screens";
12
12
  import { useSafeAreaInsets } from "react-native-safe-area-context";
13
- // Re-export primitives that don't need styling
13
+ // Re-export primitives that don't need styling. Annotated with `typeof` for
14
+ // portable declaration emit — see the note in Dialog.tsx (TS2883).
14
15
  const DropdownMenu = DropdownMenuPrimitive.Root;
15
16
  const DropdownMenuGroup = DropdownMenuPrimitive.Group;
16
17
  const DropdownMenuPortal = DropdownMenuPrimitive.Portal;
@@ -27,6 +27,8 @@ const BULLET = "\u2022";
27
27
  */
28
28
  function InputOTP({ length = 6, value = "", onChangeText, onComplete, error = false, errorText, disabled = false, autoFocus = false, secureTextEntry = false, inputMode = "numeric", style: styleOverride, }) {
29
29
  const { theme } = useTheme();
30
+ // `ComponentRef<typeof RNTextInput>` rather than RN 0.88's `TextInputInstance`,
31
+ // which RN 0.85/0.86 typings do not export.
30
32
  const inputRef = useRef(null);
31
33
  const [focused, setFocused] = useState(false);
32
34
  const styles = themedStyles(theme);
@@ -63,7 +65,10 @@ function InputOTP({ length = 6, value = "", onChangeText, onComplete, error = fa
63
65
  const markOtpBlurred = useCallback(() => {
64
66
  setFocused(false);
65
67
  }, []);
66
- return (_jsxs(View, { style: StyleSheet.flatten([styles.container, styleOverride]), children: [_jsx(RNTextInput, { ref: inputRef, value: value, onChangeText: handleChangeText, onKeyPress: handleKeyPress, onFocus: markOtpFocused, onBlur: markOtpBlurred, maxLength: length, autoFocus: autoFocus, editable: !disabled, inputMode: inputMode, autoComplete: "one-time-code", textContentType: "oneTimeCode", caretHidden: true, style: styles.hiddenInput, accessibilityLabel: "Verification code input", importantForAccessibility: "yes" }), _jsx(View, { style: styles.cellRow, children: Array.from({ length }, (_, index) => {
68
+ return (_jsxs(View, { style: StyleSheet.flatten([styles.container, styleOverride]), children: [_jsx(RNTextInput, { ref: inputRef, value: value, onChangeText: handleChangeText, onKeyPress: handleKeyPress, onFocus: markOtpFocused, onBlur: markOtpBlurred, maxLength: length, autoFocus: autoFocus, editable: !disabled, inputMode: inputMode,
69
+ // Android only recognises the `sms-otp` autofill hint; iOS and web use
70
+ // `one-time-code` + `oneTimeCode` to offer codes from Messages / Mail.
71
+ autoComplete: Platform.OS === "android" ? "sms-otp" : "one-time-code", textContentType: "oneTimeCode", caretHidden: true, style: styles.hiddenInput, accessibilityLabel: "Verification code input", importantForAccessibility: "yes" }), _jsx(View, { style: styles.cellRow, children: Array.from({ length }, (_, index) => {
67
72
  const char = value[index] ?? "";
68
73
  const isActive = focused && index === activeIndex;
69
74
  const displayChar = char
@@ -1,6 +1,6 @@
1
1
  import * as PopoverPrimitive from "@rn-primitives/popover";
2
2
  import * as React from "react";
3
- import { View, ViewProps } from "react-native";
3
+ import { ViewProps } from "react-native";
4
4
  /**
5
5
  * Popover Trigger Component
6
6
  * The element that triggers the popover to open/close
@@ -44,21 +44,21 @@ interface PopoverFooterProps extends ViewProps {
44
44
  }
45
45
  declare function PopoverFooter({ children, style, ...props }: PopoverFooterProps): React.JSX.Element;
46
46
  /**
47
- * Popover Component with Sub-components
48
- * Properly typed interface for dot notation access (e.g., Popover.Trigger)
47
+ * Popover Root Component
48
+ * Manages popover state and provides context for trigger and content
49
49
  */
50
- declare const Popover: {
51
- ({ asChild, onOpenChange: onOpenChangeProp, ref, ...viewProps }: ViewProps & {
52
- asChild?: boolean;
53
- } & {
54
- onOpenChange?: (open: boolean) => void;
55
- } & React.RefAttributes<View>): React.JSX.Element;
56
- displayName: string;
57
- } & {
50
+ declare const PopoverRoot: typeof PopoverPrimitive.Root;
51
+ type PopoverComponent = typeof PopoverRoot & {
58
52
  Trigger: typeof PopoverTrigger;
59
53
  Content: typeof PopoverContent;
60
54
  Header: typeof PopoverHeader;
61
55
  Body: typeof PopoverBody;
62
56
  Footer: typeof PopoverFooter;
63
57
  };
58
+ /**
59
+ * Popover Component with Sub-components
60
+ * Properly typed interface for dot notation access (e.g., Popover.Trigger).
61
+ * The annotation is what keeps declaration emit portable — see Dialog.tsx (TS2883).
62
+ */
63
+ declare const Popover: PopoverComponent;
64
64
  export { Popover, PopoverTrigger, PopoverContent, PopoverHeader, PopoverBody, PopoverFooter, };
@@ -40,7 +40,7 @@ function PopoverContent({ side, align = "center", sideOffset = 4, portalHost, ..
40
40
  padding: spacing.xs,
41
41
  ...getShadowStyle("soft"),
42
42
  },
43
- ]);
43
+ ]) ?? undefined;
44
44
  return (_jsx(PopoverPrimitive.Portal, { hostName: portalHost, children: _jsx(FullWindowOverlay, { children: _jsx(PopoverPrimitive.Overlay, { style: Platform.select({ native: StyleSheet.absoluteFill }), children: _jsx(AnimatedView, { type: "fade", enterDuration: 200, children: _jsx(TextColorContext.Provider, { value: textColor, children: _jsx(TextClassContext.Provider, { value: "", children: _jsx(PopoverPrimitive.Content, { side: side, align: align, sideOffset: sideOffset, style: contentStyle, ...props }) }) }) }) }) }) }));
45
45
  }
46
46
  function PopoverHeader({ children, style, ...props }) {
@@ -83,7 +83,8 @@ function PopoverFooter({ children, style, ...props }) {
83
83
  const PopoverRoot = PopoverPrimitive.Root;
84
84
  /**
85
85
  * Popover Component with Sub-components
86
- * Properly typed interface for dot notation access (e.g., Popover.Trigger)
86
+ * Properly typed interface for dot notation access (e.g., Popover.Trigger).
87
+ * The annotation is what keeps declaration emit portable — see Dialog.tsx (TS2883).
87
88
  */
88
89
  const Popover = Object.assign(PopoverRoot, {
89
90
  Trigger: PopoverTrigger,
@@ -1,6 +1,10 @@
1
1
  import * as React from "react";
2
- import { View } from "react-native";
3
2
  import * as SelectPrimitive from "@rn-primitives/select";
3
+ /**
4
+ * SelectRoot Component
5
+ * Manages select state and provides context for trigger and content
6
+ */
7
+ declare const SelectRoot: typeof SelectPrimitive.Root;
4
8
  /**
5
9
  * Size variants for SelectTrigger
6
10
  */
@@ -57,25 +61,7 @@ declare function SelectLabel({ style: styleOverride, ...props }: SelectLabelProp
57
61
  */
58
62
  type SelectSeparatorProps = SelectPrimitive.SeparatorProps;
59
63
  declare function SelectSeparator({ style: styleOverride, ...props }: SelectSeparatorProps): React.JSX.Element;
60
- /**
61
- * Select Component with Sub-components
62
- * Properly typed interface for dot notation access (e.g., Select.Trigger)
63
- */
64
- declare const Select: {
65
- ({ asChild, value: valueProp, defaultValue, onValueChange: onValueChangeProp, onOpenChange: onOpenChangeProp, disabled, ref, ...viewProps }: import("react-native").ViewProps & {
66
- asChild?: boolean;
67
- } & {
68
- value?: import("@rn-primitives/select").Option;
69
- defaultValue?: import("@rn-primitives/select").Option;
70
- onValueChange?: (option: import("@rn-primitives/select").Option) => void;
71
- onOpenChange?: (open: boolean) => void;
72
- disabled?: boolean;
73
- dir?: "ltr" | "rtl";
74
- name?: string;
75
- required?: boolean;
76
- } & React.RefAttributes<View>): React.JSX.Element;
77
- displayName: string;
78
- } & {
64
+ type SelectComponent = typeof SelectRoot & {
79
65
  Trigger: typeof SelectTrigger;
80
66
  Value: typeof SelectValue;
81
67
  Content: typeof SelectContent;
@@ -84,5 +70,11 @@ declare const Select: {
84
70
  Label: typeof SelectLabel;
85
71
  Separator: typeof SelectSeparator;
86
72
  };
73
+ /**
74
+ * Select Component with Sub-components
75
+ * Properly typed interface for dot notation access (e.g., Select.Trigger).
76
+ * The annotation is what keeps declaration emit portable — see Dialog.tsx (TS2883).
77
+ */
78
+ declare const Select: SelectComponent;
87
79
  export { Select, SelectTrigger, SelectValue, SelectContent, SelectItem, SelectGroup, SelectLabel, SelectSeparator, };
88
80
  export type { SelectSize, SelectTriggerProps, SelectValueProps, SelectContentProps, SelectItemProps, SelectGroupProps, SelectLabelProps, SelectSeparatorProps, };
@@ -210,7 +210,8 @@ const styles = StyleSheet.create({
210
210
  });
211
211
  /**
212
212
  * Select Component with Sub-components
213
- * Properly typed interface for dot notation access (e.g., Select.Trigger)
213
+ * Properly typed interface for dot notation access (e.g., Select.Trigger).
214
+ * The annotation is what keeps declaration emit portable — see Dialog.tsx (TS2883).
214
215
  */
215
216
  const Select = Object.assign(SelectRoot, {
216
217
  Trigger: SelectTrigger,
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useEffect } from "react";
3
3
  import { useTheme } from "../hooks/useTheme.js";
4
- import { StatusBar as RNStatusBar, Platform } from "react-native";
4
+ import { StatusBar as RNStatusBar } from "react-native";
5
5
  export const StatusBar = () => {
6
6
  const { scheme, theme } = useTheme();
7
7
  const barStyle = scheme === "dark" ? "light-content" : "dark-content";
@@ -10,10 +10,6 @@ export const StatusBar = () => {
10
10
  */
11
11
  useEffect(() => {
12
12
  RNStatusBar.setBarStyle(barStyle, true);
13
- if (Platform.OS === "android") {
14
- RNStatusBar.setBackgroundColor("transparent", true);
15
- RNStatusBar.setTranslucent(true);
16
- }
17
13
  }, [barStyle]);
18
- return (_jsx(RNStatusBar, { barStyle: barStyle, backgroundColor: Platform.OS === "android" ? "transparent" : undefined, translucent: true }));
14
+ return _jsx(RNStatusBar, { barStyle: barStyle });
19
15
  };
@@ -2,5 +2,5 @@ import React from "react";
2
2
  import type { StyleProp, TextStyle } from "react-native";
3
3
  export declare const TextClassContext: React.Context<string | undefined>;
4
4
  export declare const TextColorContext: React.Context<string | undefined>;
5
- export declare const TextStyleContext: React.Context<StyleProp<TextStyle>>;
5
+ export declare const TextStyleContext: React.Context<StyleProp<TextStyle> | undefined>;
6
6
  export declare const TextSelectabilityContext: React.Context<boolean | undefined>;
@@ -1,4 +1,4 @@
1
- import { type Ref } from "react";
1
+ import { type ComponentRef, type Ref } from "react";
2
2
  import { Text as RNText, TextProps as RNTextProps } from "react-native";
3
3
  import { type FontVariant } from "../constants/fonts";
4
4
  /**
@@ -55,8 +55,12 @@ export type TextProps = RNTextProps & {
55
55
  txOptions?: object;
56
56
  /**
57
57
  * Forwarded ref to the underlying RNText element.
58
+ *
59
+ * Written as `ComponentRef<typeof RNText>` rather than RN 0.88's `TextInstance`
60
+ * alias so the emitted declarations stay valid on RN 0.85/0.86, whose typings
61
+ * do not export that name.
58
62
  */
59
- ref?: Ref<RNText>;
63
+ ref?: Ref<ComponentRef<typeof RNText>>;
60
64
  };
61
65
  /**
62
66
  * Base Text component with theme and variant support
@@ -1,4 +1,4 @@
1
- import { type ReactNode, type Ref } from "react";
1
+ import { type ComponentRef, type ReactNode, type Ref } from "react";
2
2
  import { TextInput as RNTextInput, ViewStyle, TextStyle, TextInputProps, StyleProp } from "react-native";
3
3
  /**
4
4
  * Size variants for TextInput
@@ -11,8 +11,12 @@ export type TextInputVariant = "outline" | "filled" | "underlined";
11
11
  interface TextInputCustomProps extends TextInputProps {
12
12
  /**
13
13
  * Forwarded ref to the underlying RNTextInput element.
14
+ *
15
+ * Written as `ComponentRef<typeof RNTextInput>` rather than RN 0.88's
16
+ * `TextInputInstance` alias so the emitted declarations stay valid on
17
+ * RN 0.85/0.86, whose typings do not export that name.
14
18
  */
15
- ref?: Ref<RNTextInput>;
19
+ ref?: Ref<ComponentRef<typeof RNTextInput>>;
16
20
  /**
17
21
  * Visual variant
18
22
  * @default "outline"