@mrmeg/expo-ui 0.1.0 → 0.1.1
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/README.md +134 -2
- package/dist/components/Accordion.js +4 -4
- package/dist/components/AnimatedView.js +1 -1
- package/dist/components/Badge.js +3 -3
- package/dist/components/BottomSheet.js +4 -4
- package/dist/components/Button.js +31 -15
- package/dist/components/Card.js +4 -4
- package/dist/components/Checkbox.js +5 -5
- package/dist/components/Collapsible.js +3 -3
- package/dist/components/Dialog.js +6 -6
- package/dist/components/Drawer.js +4 -4
- package/dist/components/DropdownMenu.js +5 -5
- package/dist/components/EmptyState.js +5 -5
- package/dist/components/ErrorBoundary.d.ts +4 -0
- package/dist/components/ErrorBoundary.js +1 -9
- package/dist/components/Icon.js +1 -1
- package/dist/components/InputOTP.js +4 -4
- package/dist/components/Label.js +4 -4
- package/dist/components/MaxWidthContainer.js +1 -1
- package/dist/components/Notification.js +6 -6
- package/dist/components/Popover.js +5 -5
- package/dist/components/Progress.js +2 -2
- package/dist/components/RadioGroup.js +4 -4
- package/dist/components/Select.js +6 -6
- package/dist/components/Separator.js +2 -2
- package/dist/components/Skeleton.js +3 -3
- package/dist/components/Slider.js +4 -4
- package/dist/components/StatusBar.js +1 -1
- package/dist/components/StyledText.js +2 -2
- package/dist/components/Switch.js +6 -6
- package/dist/components/Tabs.js +4 -4
- package/dist/components/TextInput.js +7 -7
- package/dist/components/Toggle.js +5 -5
- package/dist/components/ToggleGroup.js +4 -4
- package/dist/components/Tooltip.js +5 -5
- package/dist/components/index.js +35 -35
- package/dist/constants/colors.js +5 -5
- package/dist/constants/fonts.js +75 -71
- package/dist/constants/index.js +3 -3
- package/dist/hooks/index.js +6 -6
- package/dist/hooks/useScalePress.js +1 -1
- package/dist/hooks/useTheme.js +3 -3
- package/dist/index.js +5 -5
- package/dist/lib/index.d.ts +0 -1
- package/dist/lib/index.js +2 -3
- package/dist/state/index.js +2 -2
- package/package.json +52 -34
- package/dist/lib/sentry.d.ts +0 -16
- package/dist/lib/sentry.js +0 -55
package/README.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
Reusable Expo and React Native UI primitives shared by the template and consumer apps. The package does not ship font files; web consumers load Lato from Google Fonts and native consumers use platform sans-serif fallbacks.
|
|
4
4
|
|
|
5
|
+
This package is public for installability, reuse across MrMeg projects, and
|
|
6
|
+
discoverability. It is a personal reusable Expo / React Native design-system
|
|
7
|
+
package, not a generally supported open-source UI library. The package is
|
|
8
|
+
published as `UNLICENSED`; use outside MrMeg projects requires explicit
|
|
9
|
+
permission.
|
|
10
|
+
|
|
5
11
|
## Install
|
|
6
12
|
|
|
7
13
|
Install from npm after publishing:
|
|
@@ -10,7 +16,12 @@ Install from npm after publishing:
|
|
|
10
16
|
bun add @mrmeg/expo-ui
|
|
11
17
|
```
|
|
12
18
|
|
|
13
|
-
Consumers must also install the peer dependencies listed in `package.json`.
|
|
19
|
+
Consumers must also install the peer dependencies listed in `package.json`.
|
|
20
|
+
The tested baseline is Expo SDK 55 with React 19.2, React Native 0.83,
|
|
21
|
+
React Native Web 0.21, Reanimated 4.2, Worklets 0.7, and
|
|
22
|
+
`@rn-primitives/*` 1.4. Start consumer apps from the same Expo SDK family
|
|
23
|
+
or update the package and peer ranges deliberately. Keep npm auth tokens in
|
|
24
|
+
developer or CI configuration, not in this repository.
|
|
14
25
|
|
|
15
26
|
## Imports
|
|
16
27
|
|
|
@@ -20,7 +31,7 @@ import { Button as ButtonDirect } from "@mrmeg/expo-ui/components/Button";
|
|
|
20
31
|
import { colors, spacing, typography } from "@mrmeg/expo-ui/constants";
|
|
21
32
|
import { useResources, useTheme } from "@mrmeg/expo-ui/hooks";
|
|
22
33
|
import { globalUIStore, useThemeStore } from "@mrmeg/expo-ui/state";
|
|
23
|
-
import { hapticLight
|
|
34
|
+
import { hapticLight } from "@mrmeg/expo-ui/lib";
|
|
24
35
|
```
|
|
25
36
|
|
|
26
37
|
The root barrel also exports the public surface:
|
|
@@ -29,6 +40,123 @@ The root barrel also exports the public surface:
|
|
|
29
40
|
import { Button, colors, useTheme } from "@mrmeg/expo-ui";
|
|
30
41
|
```
|
|
31
42
|
|
|
43
|
+
## Theme System
|
|
44
|
+
|
|
45
|
+
Use `useTheme()` for theme-aware app styles:
|
|
46
|
+
|
|
47
|
+
```tsx
|
|
48
|
+
import { StyleSheet, View } from "react-native";
|
|
49
|
+
import { StyledText } from "@mrmeg/expo-ui/components";
|
|
50
|
+
import { spacing } from "@mrmeg/expo-ui/constants";
|
|
51
|
+
import { useTheme } from "@mrmeg/expo-ui/hooks";
|
|
52
|
+
|
|
53
|
+
export function Panel() {
|
|
54
|
+
const { theme, getShadowStyle } = useTheme();
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<View
|
|
58
|
+
style={[
|
|
59
|
+
styles.panel,
|
|
60
|
+
{
|
|
61
|
+
backgroundColor: theme.colors.card,
|
|
62
|
+
borderColor: theme.colors.border,
|
|
63
|
+
},
|
|
64
|
+
getShadowStyle("subtle"),
|
|
65
|
+
]}
|
|
66
|
+
>
|
|
67
|
+
<StyledText semantic="heading">Theme-aware panel</StyledText>
|
|
68
|
+
<StyledText semantic="body" style={{ color: theme.colors.mutedForeground }}>
|
|
69
|
+
Uses package tokens instead of hardcoded colors.
|
|
70
|
+
</StyledText>
|
|
71
|
+
</View>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const styles = StyleSheet.create({
|
|
76
|
+
panel: {
|
|
77
|
+
borderWidth: StyleSheet.hairlineWidth,
|
|
78
|
+
borderRadius: spacing.radiusLg,
|
|
79
|
+
padding: spacing.cardPadding,
|
|
80
|
+
gap: spacing.sm,
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
`useTheme()` returns the active `theme`, resolved `scheme`, persisted `currentTheme`, `setTheme`, `toggleTheme`, shadow helpers, contrast helpers, and `withAlpha`. Use semantic tokens such as `theme.colors.background`, `foreground`, `card`, `border`, `primary`, `secondary`, `accent`, `mutedForeground`, `destructive`, `success`, and `warning`. `primary` is the neutral action color, `secondary` is a neutral secondary surface, and `accent` is the teal highlight color.
|
|
86
|
+
|
|
87
|
+
Use `StyledText` for theme-aware text:
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
import { BodyText, CaptionText, HeadingText, StyledText } from "@mrmeg/expo-ui/components";
|
|
91
|
+
|
|
92
|
+
<HeadingText>Settings</HeadingText>
|
|
93
|
+
<BodyText>Manage your account.</BodyText>
|
|
94
|
+
<CaptionText>Changes sync automatically.</CaptionText>
|
|
95
|
+
<StyledText semantic="label" tx="common.email" />
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Useful `StyledText` props:
|
|
99
|
+
|
|
100
|
+
- `semantic`: `title`, `heading`, `subheading`, `body`, `caption`, `label`
|
|
101
|
+
- `size`: `xs`, `sm`, `base`, `body`, `lg`, `xl`, `xxl`, `display`
|
|
102
|
+
- `fontWeight`: `light`, `regular`, `medium`, `semibold`, `bold`
|
|
103
|
+
- `variant`: `sansSerif`, `serif`
|
|
104
|
+
- `align`, `tx`, `txOptions`
|
|
105
|
+
|
|
106
|
+
## Component Guide
|
|
107
|
+
|
|
108
|
+
All components are exported from `@mrmeg/expo-ui/components`; direct imports such as `@mrmeg/expo-ui/components/Button` are supported.
|
|
109
|
+
|
|
110
|
+
Layout:
|
|
111
|
+
|
|
112
|
+
- `AnimatedView` - Reanimated visibility/entrance wrapper.
|
|
113
|
+
- `Card` - Framed content with `variant`: `default`, `outline`, `ghost`; includes `CardHeader`, `CardTitle`, `CardDescription`, `CardContent`, `CardFooter`.
|
|
114
|
+
- `MaxWidthContainer` - Centered responsive content width.
|
|
115
|
+
- `Separator` - Theme-aware divider.
|
|
116
|
+
- `DismissKeyboard` - Tap-away keyboard dismissal wrapper.
|
|
117
|
+
|
|
118
|
+
Forms and actions:
|
|
119
|
+
|
|
120
|
+
- `Button` - Commands with `preset`: `default` for primary neutral actions, `secondary` for neutral secondary actions, plus `outline`, `ghost`, `link`, and `destructive`; `size`: `sm`, `md`, `lg`; supports `loading`, `fullWidth`, accessories, and shadows.
|
|
121
|
+
- `TextInput` - Inputs with `variant`: `outline`, `filled`, `underlined`; `size`: `sm`, `md`, `lg`; supports labels, helper/error text, clear/password affordances, and left/right elements.
|
|
122
|
+
- `Checkbox`, `RadioGroup`, `Select`, `Switch`, `Toggle`, `ToggleGroup`, `InputOTP`, `Slider`, `Label` - Form controls built on package tokens and `@rn-primitives` where applicable.
|
|
123
|
+
|
|
124
|
+
Feedback:
|
|
125
|
+
|
|
126
|
+
- `Alert`, `Badge`, `Notification`, `Progress`, `Skeleton`, `SkeletonText`, `SkeletonAvatar`, `SkeletonCard`, `EmptyState`, `StatusBar`.
|
|
127
|
+
- Mount `Notification` once near the app root; trigger it with `globalUIStore`.
|
|
128
|
+
|
|
129
|
+
Overlays and navigation:
|
|
130
|
+
|
|
131
|
+
- `Dialog`, `BottomSheet`, `Drawer`, `DropdownMenu`, `Popover`, `Tooltip` require `PortalHost` near the app root.
|
|
132
|
+
- `Tabs`, `Accordion`, and `Collapsible` cover in-page navigation and disclosure.
|
|
133
|
+
|
|
134
|
+
Example:
|
|
135
|
+
|
|
136
|
+
```tsx
|
|
137
|
+
import { Badge, Button, Card, CardContent, CardHeader, CardTitle } from "@mrmeg/expo-ui/components";
|
|
138
|
+
|
|
139
|
+
<Card variant="outline">
|
|
140
|
+
<CardHeader>
|
|
141
|
+
<CardTitle>Subscription</CardTitle>
|
|
142
|
+
<Badge variant="secondary">Active</Badge>
|
|
143
|
+
</CardHeader>
|
|
144
|
+
<CardContent>
|
|
145
|
+
<Button preset="default" fullWidth>
|
|
146
|
+
Manage billing
|
|
147
|
+
</Button>
|
|
148
|
+
</CardContent>
|
|
149
|
+
</Card>
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
LLM rules:
|
|
153
|
+
|
|
154
|
+
- Prefer `StyledText` semantic variants over raw `Text`.
|
|
155
|
+
- Use `useTheme()` and semantic tokens instead of hardcoded colors.
|
|
156
|
+
- Use `Button.preset`, not `variant`, for buttons.
|
|
157
|
+
- Mount `PortalHost` before using overlays, menus, select content, popovers, or tooltips.
|
|
158
|
+
- Import from package exports, not `packages/ui/src/*`.
|
|
159
|
+
|
|
32
160
|
## App Startup
|
|
33
161
|
|
|
34
162
|
Call `useResources()` once near the Expo app root before hiding the splash screen:
|
|
@@ -94,3 +222,7 @@ bun run ui:consumer-smoke
|
|
|
94
222
|
```
|
|
95
223
|
|
|
96
224
|
`bun run ui:pack` runs a dry pack so the published file list and package size can be inspected before release.
|
|
225
|
+
`bun run ui:consumer-smoke` installs the packed tarball into a clean fixture,
|
|
226
|
+
checks the documented export-map files, type-checks all public package
|
|
227
|
+
entrypoints, and verifies that `@mrmeg/expo-ui/constants` can be imported
|
|
228
|
+
by plain Node ESM for token inspection.
|
|
@@ -2,10 +2,10 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
|
|
|
2
2
|
import { useEffect, useState } from "react";
|
|
3
3
|
import { Platform, Pressable, View } from "react-native";
|
|
4
4
|
import Animated, { useSharedValue, useAnimatedStyle, withTiming, useReducedMotion, } from "react-native-reanimated";
|
|
5
|
-
import { Icon } from "./Icon";
|
|
6
|
-
import { TextClassContext } from "./StyledText";
|
|
7
|
-
import { useTheme } from "../hooks/useTheme";
|
|
8
|
-
import { spacing } from "../constants/spacing";
|
|
5
|
+
import { Icon } from "./Icon.js";
|
|
6
|
+
import { TextClassContext } from "./StyledText.js";
|
|
7
|
+
import { useTheme } from "../hooks/useTheme.js";
|
|
8
|
+
import { spacing } from "../constants/spacing.js";
|
|
9
9
|
import * as AccordionPrimitive from "@rn-primitives/accordion";
|
|
10
10
|
function normalizeSingleValue(value) {
|
|
11
11
|
return value ?? "";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import Animated from "react-native-reanimated";
|
|
3
|
-
import { useStaggeredEntrance } from "../hooks/useStaggeredEntrance";
|
|
3
|
+
import { useStaggeredEntrance } from "../hooks/useStaggeredEntrance.js";
|
|
4
4
|
/**
|
|
5
5
|
* Cross-Platform Animated View Component
|
|
6
6
|
* Uses Reanimated for smooth 60fps animations on all platforms
|
package/dist/components/Badge.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import React from "react";
|
|
3
3
|
import { View, StyleSheet } from "react-native";
|
|
4
|
-
import { useTheme } from "../hooks/useTheme";
|
|
5
|
-
import { spacing } from "../constants/spacing";
|
|
6
|
-
import { StyledText } from "./StyledText";
|
|
4
|
+
import { useTheme } from "../hooks/useTheme.js";
|
|
5
|
+
import { spacing } from "../constants/spacing.js";
|
|
6
|
+
import { StyledText } from "./StyledText.js";
|
|
7
7
|
/**
|
|
8
8
|
* Badge Component
|
|
9
9
|
*
|
|
@@ -4,10 +4,10 @@ import { View, Pressable, Animated, StyleSheet, Platform, Dimensions, PanRespond
|
|
|
4
4
|
import { Portal } from "@rn-primitives/portal";
|
|
5
5
|
import { FullWindowOverlay as RNFullWindowOverlay } from "react-native-screens";
|
|
6
6
|
import { Pressable as SlotPressable } from "@rn-primitives/slot";
|
|
7
|
-
import { useTheme } from "../hooks/useTheme";
|
|
8
|
-
import { spacing } from "../constants/spacing";
|
|
9
|
-
import { shouldUseNativeDriver } from "../lib/animations";
|
|
10
|
-
import { TextColorContext, TextClassContext } from "./StyledText";
|
|
7
|
+
import { useTheme } from "../hooks/useTheme.js";
|
|
8
|
+
import { spacing } from "../constants/spacing.js";
|
|
9
|
+
import { shouldUseNativeDriver } from "../lib/animations.js";
|
|
10
|
+
import { TextColorContext, TextClassContext } from "./StyledText.js";
|
|
11
11
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
12
12
|
/**
|
|
13
13
|
* BottomSheet Component with Sub-components
|
|
@@ -2,12 +2,12 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState } from "react";
|
|
3
3
|
import { Pressable, StyleSheet, View, Platform, ActivityIndicator, } from "react-native";
|
|
4
4
|
import Animated from "react-native-reanimated";
|
|
5
|
-
import { spacing } from "../constants/spacing";
|
|
6
|
-
import { StyledText, TextColorContext } from "./StyledText";
|
|
7
|
-
import { fontFamilies } from "../constants/fonts";
|
|
8
|
-
import { palette } from "../constants/colors";
|
|
9
|
-
import { useTheme } from "../hooks/useTheme";
|
|
10
|
-
import { useScalePress } from "../hooks/useScalePress";
|
|
5
|
+
import { spacing } from "../constants/spacing.js";
|
|
6
|
+
import { StyledText, TextColorContext } from "./StyledText.js";
|
|
7
|
+
import { fontFamilies } from "../constants/fonts.js";
|
|
8
|
+
import { palette } from "../constants/colors.js";
|
|
9
|
+
import { useTheme } from "../hooks/useTheme.js";
|
|
10
|
+
import { useScalePress } from "../hooks/useScalePress.js";
|
|
11
11
|
const SIZE_CONFIGS = {
|
|
12
12
|
sm: {
|
|
13
13
|
paddingVertical: spacing.xs,
|
|
@@ -64,7 +64,7 @@ const SIZE_CONFIGS = {
|
|
|
64
64
|
* ```
|
|
65
65
|
*/
|
|
66
66
|
export function Button(props) {
|
|
67
|
-
const { tx, text, txOptions, style: styleOverride, pressedStyle: pressedStyleOverride, textStyle: textStyleOverride, pressedTextStyle: pressedTextStyleOverride, disabledTextStyle: disabledTextStyleOverride, children, RightAccessory, LeftAccessory, disabled, disabledStyle: disabledStyleOverride, withShadow = false, preset = "default", size = "md", loading = false, fullWidth = false, ...rest } = props;
|
|
67
|
+
const { tx, text, txOptions, style: styleOverride, pressedStyle: pressedStyleOverride, textStyle: textStyleOverride, pressedTextStyle: pressedTextStyleOverride, disabledTextStyle: disabledTextStyleOverride, children, RightAccessory, LeftAccessory, disabled, disabledStyle: disabledStyleOverride, withShadow = false, preset = "default", size = "md", loading = false, fullWidth = false, onFocus, onBlur, onPressIn, onPressOut, ...rest } = props;
|
|
68
68
|
const { theme, getContrastingColor, getShadowStyle } = useTheme();
|
|
69
69
|
const styles = createStyles(theme, size);
|
|
70
70
|
const shadowStyle = getShadowStyle("base");
|
|
@@ -79,10 +79,10 @@ export function Button(props) {
|
|
|
79
79
|
backgroundColor = customBgColor;
|
|
80
80
|
}
|
|
81
81
|
else if (preset === "default") {
|
|
82
|
-
backgroundColor = theme.colors.
|
|
82
|
+
backgroundColor = theme.colors.primary;
|
|
83
83
|
}
|
|
84
84
|
else if (preset === "secondary") {
|
|
85
|
-
backgroundColor = theme.colors.
|
|
85
|
+
backgroundColor = theme.colors.secondary;
|
|
86
86
|
}
|
|
87
87
|
else if (preset === "destructive") {
|
|
88
88
|
backgroundColor = theme.colors.destructive;
|
|
@@ -91,7 +91,7 @@ export function Button(props) {
|
|
|
91
91
|
backgroundColor = "transparent";
|
|
92
92
|
}
|
|
93
93
|
else {
|
|
94
|
-
backgroundColor = theme.colors.
|
|
94
|
+
backgroundColor = theme.colors.primary;
|
|
95
95
|
}
|
|
96
96
|
// Determine text color per preset for readable contrast
|
|
97
97
|
const textColor = preset === "outline"
|
|
@@ -101,9 +101,9 @@ export function Button(props) {
|
|
|
101
101
|
: preset === "link"
|
|
102
102
|
? theme.colors.accent
|
|
103
103
|
: preset === "default"
|
|
104
|
-
? theme.colors.
|
|
104
|
+
? theme.colors.primaryForeground
|
|
105
105
|
: preset === "secondary"
|
|
106
|
-
? theme.colors.
|
|
106
|
+
? theme.colors.secondaryForeground
|
|
107
107
|
: getContrastingColor(backgroundColor, palette.white, palette.black);
|
|
108
108
|
const [focused, setFocused] = useState(false);
|
|
109
109
|
const isDisabled = disabled || loading;
|
|
@@ -112,7 +112,23 @@ export function Button(props) {
|
|
|
112
112
|
haptic: false,
|
|
113
113
|
scaleTo: preset === "link" ? 1 : 0.97,
|
|
114
114
|
});
|
|
115
|
-
|
|
115
|
+
const handleFocus = (event) => {
|
|
116
|
+
setFocused(true);
|
|
117
|
+
onFocus?.(event);
|
|
118
|
+
};
|
|
119
|
+
const handleBlur = (event) => {
|
|
120
|
+
setFocused(false);
|
|
121
|
+
onBlur?.(event);
|
|
122
|
+
};
|
|
123
|
+
const handlePressIn = (event) => {
|
|
124
|
+
pressHandlers.onPressIn();
|
|
125
|
+
onPressIn?.(event);
|
|
126
|
+
};
|
|
127
|
+
const handlePressOut = (event) => {
|
|
128
|
+
pressHandlers.onPressOut();
|
|
129
|
+
onPressOut?.(event);
|
|
130
|
+
};
|
|
131
|
+
return (_jsx(TextColorContext.Provider, { value: textColor, children: _jsx(Pressable, { accessibilityRole: "button", accessibilityState: { disabled: !!isDisabled, busy: loading }, ...rest, onPressIn: handlePressIn, onPressOut: handlePressOut, onFocus: handleFocus, onBlur: handleBlur, style: { alignSelf: fullWidth ? "stretch" : flattenedStyle?.alignSelf ?? "flex-start" }, disabled: isDisabled, children: (state) => (_jsx(Animated.View, { style: scaleStyle, children: _jsxs(View, { style: [
|
|
116
132
|
styles.button,
|
|
117
133
|
preset === "default" && styles.buttonDefault,
|
|
118
134
|
preset === "outline" && styles.buttonOutline,
|
|
@@ -162,10 +178,10 @@ const createStyles = (theme, size) => {
|
|
|
162
178
|
...(Platform.OS === "web" && { cursor: "pointer" }),
|
|
163
179
|
},
|
|
164
180
|
buttonDefault: {
|
|
165
|
-
backgroundColor: theme.colors.
|
|
181
|
+
backgroundColor: theme.colors.primary,
|
|
166
182
|
},
|
|
167
183
|
buttonSecondary: {
|
|
168
|
-
backgroundColor: theme.colors.
|
|
184
|
+
backgroundColor: theme.colors.secondary,
|
|
169
185
|
},
|
|
170
186
|
buttonDestructive: {
|
|
171
187
|
backgroundColor: theme.colors.destructive,
|
package/dist/components/Card.js
CHANGED
|
@@ -2,10 +2,10 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { createContext, useContext } from "react";
|
|
3
3
|
import { View, Pressable, StyleSheet, Platform } from "react-native";
|
|
4
4
|
import Animated from "react-native-reanimated";
|
|
5
|
-
import { StyledText } from "./StyledText";
|
|
6
|
-
import { useTheme } from "../hooks/useTheme";
|
|
7
|
-
import { useScalePress } from "../hooks/useScalePress";
|
|
8
|
-
import { spacing } from "../constants/spacing";
|
|
5
|
+
import { StyledText } from "./StyledText.js";
|
|
6
|
+
import { useTheme } from "../hooks/useTheme.js";
|
|
7
|
+
import { useScalePress } from "../hooks/useScalePress.js";
|
|
8
|
+
import { spacing } from "../constants/spacing.js";
|
|
9
9
|
/**
|
|
10
10
|
* Card Component
|
|
11
11
|
*
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { View, StyleSheet, Pressable } from "react-native";
|
|
3
3
|
import Animated, { useSharedValue, useAnimatedStyle, withTiming, useReducedMotion, } from "react-native-reanimated";
|
|
4
|
-
import { Icon } from "./Icon";
|
|
5
|
-
import { StyledText } from "./StyledText";
|
|
6
|
-
import { useTheme } from "../hooks/useTheme";
|
|
7
|
-
import { spacing } from "../constants/spacing";
|
|
8
|
-
import { hapticLight } from "../lib/haptics";
|
|
4
|
+
import { Icon } from "./Icon.js";
|
|
5
|
+
import { StyledText } from "./StyledText.js";
|
|
6
|
+
import { useTheme } from "../hooks/useTheme.js";
|
|
7
|
+
import { spacing } from "../constants/spacing.js";
|
|
8
|
+
import { hapticLight } from "../lib/haptics.js";
|
|
9
9
|
import * as CheckboxPrimitive from "@rn-primitives/checkbox";
|
|
10
10
|
const DEFAULT_HIT_SLOP = 8;
|
|
11
11
|
const SIZE_CONFIGS = {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { Animated, Platform, StyleSheet, View } from "react-native";
|
|
4
|
-
import { TextClassContext } from "./StyledText";
|
|
5
|
-
import { spacing } from "../constants/spacing";
|
|
6
|
-
import { useTheme } from "../hooks/useTheme";
|
|
4
|
+
import { TextClassContext } from "./StyledText.js";
|
|
5
|
+
import { spacing } from "../constants/spacing.js";
|
|
6
|
+
import { useTheme } from "../hooks/useTheme.js";
|
|
7
7
|
import * as CollapsiblePrimitive from "@rn-primitives/collapsible";
|
|
8
8
|
function Collapsible({ children, ...props }) {
|
|
9
9
|
return (_jsx(CollapsiblePrimitive.Root, { ...props, asChild: Platform.OS !== "web", children: _jsx(View, { children: children }) }));
|
|
@@ -4,12 +4,12 @@ import { Platform, StyleSheet, View } from "react-native";
|
|
|
4
4
|
import { FullWindowOverlay as RNFullWindowOverlay } from "react-native-screens";
|
|
5
5
|
import * as DialogPrimitive from "@rn-primitives/dialog";
|
|
6
6
|
import * as AlertDialogPrimitive from "@rn-primitives/alert-dialog";
|
|
7
|
-
import { AnimatedView } from "./AnimatedView";
|
|
8
|
-
import { TextClassContext, TextColorContext } from "./StyledText";
|
|
9
|
-
import { StyledText } from "./StyledText";
|
|
10
|
-
import { useTheme } from "../hooks/useTheme";
|
|
11
|
-
import { spacing } from "../constants/spacing";
|
|
12
|
-
import { palette } from "../constants/colors";
|
|
7
|
+
import { AnimatedView } from "./AnimatedView.js";
|
|
8
|
+
import { TextClassContext, TextColorContext } from "./StyledText.js";
|
|
9
|
+
import { StyledText } from "./StyledText.js";
|
|
10
|
+
import { useTheme } from "../hooks/useTheme.js";
|
|
11
|
+
import { spacing } from "../constants/spacing.js";
|
|
12
|
+
import { palette } from "../constants/colors.js";
|
|
13
13
|
const FullWindowOverlay = Platform.OS === "ios" ? RNFullWindowOverlay : React.Fragment;
|
|
14
14
|
// ============================================================================
|
|
15
15
|
// Dialog
|
|
@@ -4,10 +4,10 @@ import { View, Pressable, Animated, StyleSheet, Platform, Dimensions, PanRespond
|
|
|
4
4
|
import { Portal } from "@rn-primitives/portal";
|
|
5
5
|
import { FullWindowOverlay as RNFullWindowOverlay } from "react-native-screens";
|
|
6
6
|
import { Pressable as SlotPressable } from "@rn-primitives/slot";
|
|
7
|
-
import { useTheme } from "../hooks/useTheme";
|
|
8
|
-
import { shouldUseNativeDriver } from "../lib/animations";
|
|
9
|
-
import { spacing } from "../constants/spacing";
|
|
10
|
-
import { TextColorContext, TextClassContext } from "./StyledText";
|
|
7
|
+
import { useTheme } from "../hooks/useTheme.js";
|
|
8
|
+
import { shouldUseNativeDriver } from "../lib/animations.js";
|
|
9
|
+
import { spacing } from "../constants/spacing.js";
|
|
10
|
+
import { TextColorContext, TextClassContext } from "./StyledText.js";
|
|
11
11
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
12
12
|
/**
|
|
13
13
|
* Drawer Component with Sub-components
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { Platform, StyleSheet, Text, View } from "react-native";
|
|
4
|
-
import { Icon } from "./Icon";
|
|
5
|
-
import { AnimatedView } from "./AnimatedView";
|
|
6
|
-
import { TextClassContext } from "./StyledText";
|
|
7
|
-
import { useTheme } from "../hooks/useTheme";
|
|
8
|
-
import { spacing } from "../constants/spacing";
|
|
4
|
+
import { Icon } from "./Icon.js";
|
|
5
|
+
import { AnimatedView } from "./AnimatedView.js";
|
|
6
|
+
import { TextClassContext } from "./StyledText.js";
|
|
7
|
+
import { useTheme } from "../hooks/useTheme.js";
|
|
8
|
+
import { spacing } from "../constants/spacing.js";
|
|
9
9
|
import * as DropdownMenuPrimitive from "@rn-primitives/dropdown-menu";
|
|
10
10
|
import { FullWindowOverlay as RNFullWindowOverlay } from "react-native-screens";
|
|
11
11
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { View, StyleSheet } from "react-native";
|
|
3
|
-
import { SansSerifBoldText, SansSerifText } from "./StyledText";
|
|
4
|
-
import { Button } from "./Button";
|
|
5
|
-
import { Icon } from "./Icon";
|
|
6
|
-
import { useTheme } from "../hooks/useTheme";
|
|
7
|
-
import { spacing } from "../constants/spacing";
|
|
3
|
+
import { SansSerifBoldText, SansSerifText } from "./StyledText.js";
|
|
4
|
+
import { Button } from "./Button.js";
|
|
5
|
+
import { Icon } from "./Icon.js";
|
|
6
|
+
import { useTheme } from "../hooks/useTheme.js";
|
|
7
|
+
import { spacing } from "../constants/spacing.js";
|
|
8
8
|
/**
|
|
9
9
|
* EmptyState Component
|
|
10
10
|
*
|
|
@@ -20,6 +20,10 @@ interface ErrorBoundaryProps {
|
|
|
20
20
|
errorInfo: ErrorInfo | null;
|
|
21
21
|
resetError: () => void;
|
|
22
22
|
}>;
|
|
23
|
+
/**
|
|
24
|
+
* Optional app-owned error reporter.
|
|
25
|
+
*/
|
|
26
|
+
onError?: (error: Error, errorInfo: ErrorInfo) => void;
|
|
23
27
|
}
|
|
24
28
|
interface ErrorBoundaryState {
|
|
25
29
|
error: Error | null;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { Component } from "react";
|
|
3
|
-
import { captureException } from "../lib/sentry";
|
|
4
3
|
/**
|
|
5
4
|
* ErrorBoundary catches JavaScript errors anywhere in the child component tree,
|
|
6
5
|
* logs those errors, and displays a fallback UI.
|
|
@@ -49,14 +48,7 @@ export class ErrorBoundary extends Component {
|
|
|
49
48
|
console.error("ErrorBoundary caught an error:", error);
|
|
50
49
|
console.error("Error info:", errorInfo);
|
|
51
50
|
}
|
|
52
|
-
|
|
53
|
-
captureException(error, {
|
|
54
|
-
contexts: {
|
|
55
|
-
react: {
|
|
56
|
-
componentStack: errorInfo?.componentStack ?? undefined,
|
|
57
|
-
},
|
|
58
|
-
},
|
|
59
|
-
});
|
|
51
|
+
this.props.onError?.(error, errorInfo);
|
|
60
52
|
}
|
|
61
53
|
render() {
|
|
62
54
|
const { children, FallbackComponent } = this.props;
|
package/dist/components/Icon.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { View } from "react-native";
|
|
3
|
-
import { useTheme } from "../hooks/useTheme";
|
|
3
|
+
import { useTheme } from "../hooks/useTheme.js";
|
|
4
4
|
import Feather from "@expo/vector-icons/Feather";
|
|
5
5
|
const THEME_COLOR_KEYS = [
|
|
6
6
|
"primary", "primaryForeground", "secondary", "muted",
|
|
@@ -2,10 +2,10 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import React, { useRef, useState, useCallback } from "react";
|
|
3
3
|
import { View, TextInput as RNTextInput, Pressable, StyleSheet, Platform, } from "react-native";
|
|
4
4
|
import Animated, { useSharedValue, useAnimatedStyle, withTiming, useReducedMotion, } from "react-native-reanimated";
|
|
5
|
-
import { useTheme } from "../hooks/useTheme";
|
|
6
|
-
import { spacing } from "../constants/spacing";
|
|
7
|
-
import { fontFamilies } from "../constants/fonts";
|
|
8
|
-
import { StyledText } from "./StyledText";
|
|
5
|
+
import { useTheme } from "../hooks/useTheme.js";
|
|
6
|
+
import { spacing } from "../constants/spacing.js";
|
|
7
|
+
import { fontFamilies } from "../constants/fonts.js";
|
|
8
|
+
import { StyledText } from "./StyledText.js";
|
|
9
9
|
const CELL_WIDTH = 36;
|
|
10
10
|
const CELL_HEIGHT = 40;
|
|
11
11
|
const CELL_FONT_SIZE = 20;
|
package/dist/components/Label.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { StyleSheet, Platform } from "react-native";
|
|
3
3
|
import * as LabelPrimitive from "@rn-primitives/label";
|
|
4
|
-
import { useTheme } from "../hooks/useTheme";
|
|
5
|
-
import { spacing } from "../constants/spacing";
|
|
6
|
-
import { fontFamilies } from "../constants/fonts";
|
|
7
|
-
import { StyledText } from "./StyledText";
|
|
4
|
+
import { useTheme } from "../hooks/useTheme.js";
|
|
5
|
+
import { spacing } from "../constants/spacing.js";
|
|
6
|
+
import { fontFamilies } from "../constants/fonts.js";
|
|
7
|
+
import { StyledText } from "./StyledText.js";
|
|
8
8
|
const SIZE_CONFIGS = {
|
|
9
9
|
sm: { fontSize: 12 },
|
|
10
10
|
md: { fontSize: 14 },
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { View, StyleSheet, Platform } from "react-native";
|
|
3
|
-
import { useDimensions } from "../hooks/useDimensions";
|
|
3
|
+
import { useDimensions } from "../hooks/useDimensions.js";
|
|
4
4
|
const MAX_WIDTH_PRESETS = {
|
|
5
5
|
sm: 640,
|
|
6
6
|
md: 768,
|
|
@@ -4,12 +4,12 @@ import { StyleSheet, View, ActivityIndicator, Pressable, Platform } from "react-
|
|
|
4
4
|
import Animated, { useSharedValue, useAnimatedStyle, withTiming, runOnJS, useReducedMotion, Easing, } from "react-native-reanimated";
|
|
5
5
|
import { useTranslation } from "react-i18next";
|
|
6
6
|
import { SafeAreaInsetsContext } from "react-native-safe-area-context";
|
|
7
|
-
import { fontFamilies } from "../constants/fonts";
|
|
8
|
-
import { Icon } from "./Icon";
|
|
9
|
-
import { useTheme } from "../hooks/useTheme";
|
|
10
|
-
import { spacing } from "../constants/spacing";
|
|
11
|
-
import { StyledText } from "./StyledText";
|
|
12
|
-
import { globalUIStore } from "../state/globalUIStore";
|
|
7
|
+
import { fontFamilies } from "../constants/fonts.js";
|
|
8
|
+
import { Icon } from "./Icon.js";
|
|
9
|
+
import { useTheme } from "../hooks/useTheme.js";
|
|
10
|
+
import { spacing } from "../constants/spacing.js";
|
|
11
|
+
import { StyledText } from "./StyledText.js";
|
|
12
|
+
import { globalUIStore } from "../state/globalUIStore.js";
|
|
13
13
|
/**
|
|
14
14
|
* Notification
|
|
15
15
|
*
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { AnimatedView } from "./AnimatedView";
|
|
3
|
-
import { TextClassContext, TextColorContext } from "./StyledText";
|
|
4
|
-
import { useTheme } from "../hooks/useTheme";
|
|
5
|
-
import { spacing } from "../constants/spacing";
|
|
2
|
+
import { AnimatedView } from "./AnimatedView.js";
|
|
3
|
+
import { TextClassContext, TextColorContext } from "./StyledText.js";
|
|
4
|
+
import { useTheme } from "../hooks/useTheme.js";
|
|
5
|
+
import { spacing } from "../constants/spacing.js";
|
|
6
6
|
import * as PopoverPrimitive from "@rn-primitives/popover";
|
|
7
7
|
import * as React from "react";
|
|
8
8
|
import { Platform, StyleSheet, View } from "react-native";
|
|
9
9
|
import { FullWindowOverlay as RNFullWindowOverlay } from "react-native-screens";
|
|
10
|
-
import { palette } from "../constants/colors";
|
|
10
|
+
import { palette } from "../constants/colors.js";
|
|
11
11
|
/**
|
|
12
12
|
* Popover Trigger Component
|
|
13
13
|
* The element that triggers the popover to open/close
|
|
@@ -2,8 +2,8 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { useEffect, useRef, useState } from "react";
|
|
3
3
|
import { Animated, StyleSheet, View } from "react-native";
|
|
4
4
|
import Reanimated, { useSharedValue, useAnimatedStyle, withTiming, useReducedMotion, } from "react-native-reanimated";
|
|
5
|
-
import { useTheme } from "../hooks/useTheme";
|
|
6
|
-
import { shouldUseNativeDriver } from "../lib/animations";
|
|
5
|
+
import { useTheme } from "../hooks/useTheme.js";
|
|
6
|
+
import { shouldUseNativeDriver } from "../lib/animations.js";
|
|
7
7
|
// ============================================================================
|
|
8
8
|
// Constants
|
|
9
9
|
// ============================================================================
|
|
@@ -2,10 +2,10 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { createContext, useContext, useEffect } from "react";
|
|
3
3
|
import { View, StyleSheet, Pressable } from "react-native";
|
|
4
4
|
import Animated, { useSharedValue, useAnimatedStyle, withTiming, useReducedMotion, } from "react-native-reanimated";
|
|
5
|
-
import { StyledText } from "./StyledText";
|
|
6
|
-
import { useTheme } from "../hooks/useTheme";
|
|
7
|
-
import { spacing } from "../constants/spacing";
|
|
8
|
-
import { hapticLight } from "../lib/haptics";
|
|
5
|
+
import { StyledText } from "./StyledText.js";
|
|
6
|
+
import { useTheme } from "../hooks/useTheme.js";
|
|
7
|
+
import { spacing } from "../constants/spacing.js";
|
|
8
|
+
import { hapticLight } from "../lib/haptics.js";
|
|
9
9
|
import * as RadioGroupPrimitive from "@rn-primitives/radio-group";
|
|
10
10
|
const DEFAULT_HIT_SLOP = 8;
|
|
11
11
|
const SIZE_CONFIGS = {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { Platform, StyleSheet, View } from "react-native";
|
|
4
|
-
import { Icon } from "./Icon";
|
|
5
|
-
import { AnimatedView } from "./AnimatedView";
|
|
6
|
-
import { TextClassContext, TextColorContext } from "./StyledText";
|
|
7
|
-
import { useTheme } from "../hooks/useTheme";
|
|
8
|
-
import { spacing } from "../constants/spacing";
|
|
9
|
-
import { palette } from "../constants/colors";
|
|
4
|
+
import { Icon } from "./Icon.js";
|
|
5
|
+
import { AnimatedView } from "./AnimatedView.js";
|
|
6
|
+
import { TextClassContext, TextColorContext } from "./StyledText.js";
|
|
7
|
+
import { useTheme } from "../hooks/useTheme.js";
|
|
8
|
+
import { spacing } from "../constants/spacing.js";
|
|
9
|
+
import { palette } from "../constants/colors.js";
|
|
10
10
|
import * as SelectPrimitive from "@rn-primitives/select";
|
|
11
11
|
import { FullWindowOverlay as RNFullWindowOverlay } from "react-native-screens";
|
|
12
12
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { StyleSheet } from "react-native";
|
|
3
|
-
import { useTheme } from "../hooks/useTheme";
|
|
4
|
-
import { spacing } from "../constants/spacing";
|
|
3
|
+
import { useTheme } from "../hooks/useTheme.js";
|
|
4
|
+
import { spacing } from "../constants/spacing.js";
|
|
5
5
|
import * as SeparatorPrimitive from "@rn-primitives/separator";
|
|
6
6
|
const SIZE_CONFIGS = {
|
|
7
7
|
sm: 1,
|