@mrmeg/expo-ui 0.24.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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,32 @@
3
3
  All notable changes to `@mrmeg/expo-ui` are documented here. This project
4
4
  adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
5
5
 
6
+ ## [0.25.0]
7
+
8
+ ### Added
9
+
10
+ - **The build emits a design-system manifest.** `dist/design-system.json`
11
+ (`schemaVersion: 1`) carries the spacing, radius and icon scales, the palette,
12
+ the theme colors, the font variants, and every component's variant and size
13
+ values, exported as `@mrmeg/expo-ui/design-system.json`.
14
+ `@mrmeg/eslint-plugin-expo-ui` loads it when the design-system sources are not
15
+ on disk, so the design-system rules work against an installed release instead
16
+ of only inside the template repo. Adding an export means the next release is a
17
+ minor bump.
18
+
19
+ ### Changed
20
+
21
+ - **Peer ranges include Expo SDK 58.** `expo`, `expo-font`, `expo-haptics` and
22
+ `@expo/ui` now accept `>=56 <59` (58 pre-releases included), `react-native`
23
+ accepts `>=0.85 <0.89` (0.88 release candidates included), and
24
+ `react-native-gesture-handler` accepts `>=2.30 <4`. SDK 56 and 57 apps stay
25
+ in range; nothing else about the install changes for them.
26
+ - **`StatusBar` no longer sets an Android background color or translucency.**
27
+ React Native 0.88 removed `backgroundColor`, `translucent` and their setters.
28
+ Edge-to-edge has been mandatory since SDK 54, under which the bar was already
29
+ transparent and translucent, so this is a no-op on every supported SDK. The
30
+ component now only applies the theme-driven bar style.
31
+
6
32
  ## [0.24.0]
7
33
 
8
34
  ### Fixed
package/LLM_USAGE.md CHANGED
@@ -24,7 +24,8 @@ Importable paths: root, `components`, `components/*`, `constants`,
24
24
  `constants/*`, `hooks`, `hooks/*`, `state`, `state/*`, `lib`. Never import from
25
25
  `@mrmeg/expo-ui/dist/*` or a source checkout path.
26
26
 
27
- Hosts: Expo 56–57, React 19.2, React Native 0.85–0.86, React Native Web 0.21.
27
+ Hosts: Expo 56–58 (58 in beta), React 19.2, React Native 0.85–0.88, React
28
+ Native Web 0.21.
28
29
  Install the peer versions recommended by the consuming app's Expo SDK.
29
30
 
30
31
  ## Required App Setup
@@ -184,6 +185,18 @@ faces through `expo-font` / `@expo-google-fonts`, `"numeric"` (default) for one
184
185
  multi-weight CSS family. `setShape({ button: { borderRadius?, withShadow? } })`
185
186
  re-shapes Buttons globally. Per-instance props and caller `style` always win.
186
187
 
188
+ Enforce these rules mechanically with `@mrmeg/eslint-plugin-expo-ui`
189
+ (`bun add -d @mrmeg/eslint-plugin-expo-ui`), which reports raw colors, off-scale
190
+ spacing and radius, appearance overrides on package components, and raw
191
+ primitives as ESLint diagnostics. It reads this package's
192
+ `design-system.json` manifest out of `node_modules`, so the messages quote the
193
+ tokens, presets and sizes of the installed release. The plugin's first npm release is
194
+ still pending, and only `@mrmeg/expo-ui` releases built after the manifest was
195
+ added ship one: the installed release has it when
196
+ `node_modules/@mrmeg/expo-ui/dist/design-system.json` exists. Config block and
197
+ settings:
198
+ https://raw.githubusercontent.com/mrmeg/expo-template/main/packages/lint/README.md
199
+
187
200
  ## Component Use-Case Index
188
201
 
189
202
  Check this before creating a new app-local primitive. All components come from
package/README.md CHANGED
@@ -9,13 +9,24 @@ Read `node_modules/@mrmeg/expo-ui/llms.txt` first, then `LLM_USAGE.md` (concise
9
9
  rules) or `llms-full.md` (expanded contract), before creating app-local UI
10
10
  primitives. All three ship in the npm tarball.
11
11
 
12
+ The same rules are available as an ESLint plugin: `@mrmeg/eslint-plugin-expo-ui`
13
+ turns the theme and text rules into diagnostics at the call site — raw colors,
14
+ off-scale spacing and radius, appearance overrides on package components, and raw
15
+ primitives that have a wrapper here. See [`../lint/README.md`](../lint/README.md)
16
+ for the config block. It reads the design-system facts from
17
+ `@mrmeg/expo-ui/design-system.json`, the manifest this package's build ships, so
18
+ the diagnostics quote the tokens, presets and sizes of the installed release. The
19
+ plugin's first npm release is still pending, and only `@mrmeg/expo-ui` releases
20
+ built after the manifest was added ship it: the installed release has one when
21
+ `node_modules/@mrmeg/expo-ui/dist/design-system.json` exists.
22
+
12
23
  ## Install
13
24
 
14
25
  ```sh
15
26
  bun add @mrmeg/expo-ui
16
27
  ```
17
28
 
18
- Tested hosts: Expo SDK 56–57, React 19.2, React Native 0.85–0.86, React Native
29
+ Tested hosts: Expo SDK 56–58 (58 in beta), React 19.2, React Native 0.85–0.88, React Native
19
30
  Web 0.21. Install these peers at the versions your Expo SDK recommends: `expo`,
20
31
  `@expo/ui`, `expo-font`, `expo-haptics`, `react`, `react-native`,
21
32
  `react-native-web`, `react-native-gesture-handler`,
@@ -656,3 +667,18 @@ inspected before release. `ui:consumer-smoke` installs the packed tarball into
656
667
  a clean fixture, checks every documented export-map target resolves,
657
668
  type-checks all public entrypoints, and runs an iOS `expo export` against the
658
669
  packed package at the workspace's Expo version, without a custom Metro config.
670
+
671
+ ### Design-system manifest
672
+
673
+ `ui:build` also writes `dist/design-system.json`
674
+ ([`scripts/build-design-system-manifest.mjs`](../../scripts/build-design-system-manifest.mjs)):
675
+ the spacing, radius and icon scales, the palette, the light and dark themes, the
676
+ font variants, and every component's variant and size values, serialized out of
677
+ `src` by the same extractor the lint rules use. It is exported as
678
+ `@mrmeg/expo-ui/design-system.json`, and `@mrmeg/eslint-plugin-expo-ui` reads it
679
+ in projects that install this package instead of checking out its sources — which
680
+ is what lets the design-system rules quote this release's presets and tokens.
681
+ `ui:consumer-smoke` asserts the packed tarball carries it and that it parses at
682
+ `schemaVersion: 1` with a non-empty component list. The build fails rather than
683
+ writing an empty manifest, so a broken extractor cannot ship as "no rules to
684
+ enforce".
@@ -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;
@@ -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,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);
@@ -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"
@@ -1,19 +1,11 @@
1
1
  import * as React from "react";
2
- import { View, ViewProps } from "react-native";
2
+ import { ViewProps } from "react-native";
3
3
  import * as TooltipPrimitive from "@rn-primitives/tooltip";
4
4
  /**
5
5
  * Tooltip Trigger Component
6
6
  * The element that triggers the tooltip to appear on hover (web) or press (native)
7
7
  */
8
- declare const TooltipTrigger: {
9
- ({ asChild, onPress: onPressProp, disabled, ref, ...props }: Omit<import("react-native").PressableProps & React.RefAttributes<View>, "ref"> & {
10
- asChild?: boolean;
11
- } & {
12
- onKeyDown?: (ev: React.KeyboardEvent) => void;
13
- onKeyUp?: (ev: React.KeyboardEvent) => void;
14
- } & React.RefAttributes<import("@rn-primitives/tooltip").TriggerRef>): React.JSX.Element;
15
- displayName: string;
16
- };
8
+ declare const TooltipTrigger: typeof TooltipPrimitive.Trigger;
17
9
  /**
18
10
  * Tooltip variant styles
19
11
  */
@@ -100,22 +92,16 @@ interface TooltipProps extends TooltipPrimitive.RootProps {
100
92
  * ```
101
93
  */
102
94
  declare function Tooltip({ delayDuration, skipDelayDuration, ...props }: TooltipProps): React.JSX.Element;
103
- /**
104
- * Tooltip Component with Sub-components
105
- * Properly typed interface for dot notation access (e.g., Tooltip.Trigger)
106
- */
107
- declare const TooltipComponent: typeof Tooltip & {
108
- Trigger: {
109
- ({ asChild, onPress: onPressProp, disabled, ref, ...props }: Omit<import("react-native").PressableProps & React.RefAttributes<View>, "ref"> & {
110
- asChild?: boolean;
111
- } & {
112
- onKeyDown?: (ev: React.KeyboardEvent) => void;
113
- onKeyUp?: (ev: React.KeyboardEvent) => void;
114
- } & React.RefAttributes<import("@rn-primitives/tooltip").TriggerRef>): React.JSX.Element;
115
- displayName: string;
116
- };
95
+ type TooltipCompound = typeof Tooltip & {
96
+ Trigger: typeof TooltipTrigger;
117
97
  Content: typeof TooltipContent;
118
98
  Body: typeof TooltipBody;
119
99
  };
100
+ /**
101
+ * Tooltip Component with Sub-components
102
+ * Properly typed interface for dot notation access (e.g., Tooltip.Trigger).
103
+ * The annotation is what keeps declaration emit portable — see Dialog.tsx (TS2883).
104
+ */
105
+ declare const TooltipComponent: TooltipCompound;
120
106
  export { TooltipComponent as Tooltip, TooltipTrigger, TooltipContent, TooltipBody, };
121
107
  export type { TooltipContentProps, TooltipBodyProps, TooltipProps, };
@@ -12,6 +12,8 @@ import { palette } from "../constants/colors.js";
12
12
  * Tooltip Trigger Component
13
13
  * The element that triggers the tooltip to appear on hover (web) or press (native)
14
14
  */
15
+ // Annotated with `typeof` for portable declaration emit — see the note in
16
+ // Dialog.tsx (TS2883). Without it the .d.ts inlines RN 0.88's `PressableInstance`.
15
17
  const TooltipTrigger = TooltipPrimitive.Trigger;
16
18
  /**
17
19
  * FullWindowOverlay wrapper - uses native overlay on iOS for proper z-index handling
@@ -68,7 +70,7 @@ function TooltipContent({ side = "top", align = "center", sideOffset = 4, portal
68
70
  maxWidth: 250,
69
71
  ...getShadowStyle("soft"),
70
72
  },
71
- ]);
73
+ ]) ?? undefined;
72
74
  return (_jsx(TooltipPrimitive.Portal, { hostName: portalHost, children: _jsx(FullWindowOverlay, { children: _jsx(TooltipPrimitive.Overlay, { style: Platform.select({ native: StyleSheet.absoluteFill }), children: _jsx(AnimatedView, { type: "fade", enterDuration: 150, children: _jsx(TextColorContext.Provider, { value: colors.text, children: _jsx(TextClassContext.Provider, { value: "", children: _jsx(TextSelectabilityContext.Provider, { value: false, children: _jsx(TooltipPrimitive.Content, { side: side, align: align, sideOffset: sideOffset, style: contentStyle, ...props }) }) }) }) }) }) }) }));
73
75
  }
74
76
  function TooltipBody({ children, style, ...props }) {
@@ -122,7 +124,8 @@ function Tooltip({ delayDuration = 700, skipDelayDuration = 300, ...props }) {
122
124
  }
123
125
  /**
124
126
  * Tooltip Component with Sub-components
125
- * Properly typed interface for dot notation access (e.g., Tooltip.Trigger)
127
+ * Properly typed interface for dot notation access (e.g., Tooltip.Trigger).
128
+ * The annotation is what keeps declaration emit portable — see Dialog.tsx (TS2883).
126
129
  */
127
130
  const TooltipComponent = Object.assign(Tooltip, {
128
131
  Trigger: TooltipTrigger,