Initial commit: code as received (Create/Anything export)

Insole-production time tracker exported from the Create/Anything AI
platform. Baseline snapshot before any reverse-engineering or cleanup.

- apps/mobile: Expo Router app (iOS/Android/web), the only workspace
- publisher/: standalone OpenNext/AWS deploy tooling for the web side
- Backend (/api/tasks, /api/logs + DB) lives remotely, not in this repo
This commit is contained in:
Bas van Rossem
2026-06-17 10:19:33 +02:00
commit d94d0b188b
192 changed files with 50705 additions and 0 deletions

View File

@@ -0,0 +1,15 @@
diff --git a/build/src/start/server/middleware/ExpoGoManifestHandlerMiddleware.js b/build/src/start/server/middleware/ExpoGoManifestHandlerMiddleware.js
index b5cba1b..2cbb2a5 100644
--- a/build/src/start/server/middleware/ExpoGoManifestHandlerMiddleware.js
+++ b/build/src/start/server/middleware/ExpoGoManifestHandlerMiddleware.js
@@ -143,7 +143,9 @@ class ExpoGoManifestHandlerMiddleware extends _ManifestMiddleware.ManifestMiddle
codeSigningInfo
});
const expoUpdatesManifest = {
- id: _crypto().default.randomUUID(),
+ id: _crypto().default.randomUUID({
+ disableEntropyCache: true
+ }),
createdAt: new Date().toISOString(),
runtimeVersion,
launchAsset: {

View File

@@ -0,0 +1,24 @@
diff --git a/src/error-overlay/ErrorOverlay.tsx b/src/error-overlay/ErrorOverlay.tsx
index 983dc52..bbe737c 100644
--- a/src/error-overlay/ErrorOverlay.tsx
+++ b/src/error-overlay/ErrorOverlay.tsx
@@ -30,6 +30,7 @@ const HEADER_TITLE_MAP = {
export function LogBoxInspectorContainer() {
const { selectedLogIndex, logs } = useLogs();
const log = logs[selectedLogIndex];
+ return null;
if (log == null) {
return null;
}
diff --git a/src/error-overlay/toast/ErrorToast.tsx b/src/error-overlay/toast/ErrorToast.tsx
index 87a0c8b..c044c8f 100644
--- a/src/error-overlay/toast/ErrorToast.tsx
+++ b/src/error-overlay/toast/ErrorToast.tsx
@@ -34,6 +34,7 @@ export function ErrorToast(props: Props) {
useSymbolicatedLog(log);
+ return null;
return (
<View style={toastStyles.container}>
<Pressable style={{ flex: 1 }} onPress={props.onPressOpen}>

View File

@@ -0,0 +1,42 @@
diff --git a/src/internal/nativeInterface.ts b/src/internal/nativeInterface.ts
index 8b514f4..9135364 100644
--- a/src/internal/nativeInterface.ts
+++ b/src/internal/nativeInterface.ts
@@ -7,28 +7,15 @@
* @format
*/
-import {NativeEventEmitter} from 'react-native';
+import { NativeEventEmitter } from 'react-native';
import RNCNetInfo from './nativeModule';
-// Produce an error if we don't have the native module
-if (!RNCNetInfo) {
- throw new Error(`@react-native-community/netinfo: NativeModule.RNCNetInfo is null. To fix this issue try these steps:
-
-• Run \`react-native link @react-native-community/netinfo\` in the project root.
-• Rebuild and re-run the app.
-• If you are using CocoaPods on iOS, run \`pod install\` in the \`ios\` directory and then rebuild and re-run the app. You may also need to re-open Xcode to get the new pods.
-• Check that the library was linked correctly when you used the link command by running through the manual installation instructions in the README.
-* If you are getting this error while unit testing you need to mock the native module. Follow the guide in the README.
-
-If none of these fix the issue, please open an issue on the Github repository: https://github.com/react-native-community/react-native-netinfo`);
-}
-
/**
* We export the native interface in this way to give easy shared access to it between the
* JavaScript code and the tests
*/
let nativeEventEmitter: NativeEventEmitter | null = null;
-const nativeInterface = Object.assign(RNCNetInfo, {
+const nativeInterface = RNCNetInfo ? Object.assign(RNCNetInfo, {
get eventEmitter(): NativeEventEmitter {
if (!nativeEventEmitter) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
@@ -39,5 +26,5 @@ const nativeInterface = Object.assign(RNCNetInfo, {
/// @ts-ignore
return nativeEventEmitter;
},
-});
+}) : {};
export default nativeInterface;

View File

@@ -0,0 +1,506 @@
diff --git a/assets/native-tabs.module.css b/assets/native-tabs.module.css
index f29cec5..0d71dad 100644
--- a/assets/native-tabs.module.css
+++ b/assets/native-tabs.module.css
@@ -22,22 +22,27 @@
}
.navigationMenuRoot {
- top: 24px;
+ bottom: 24px;
left: 50%;
transform: translateX(-50%);
position: fixed;
z-index: 10;
display: flex;
- background-color: var(--expo-router-tabs-background-color, #272727);
- height: 40px;
- border-radius: 25px;
+ background-color: var(--expo-router-tabs-background-color, rgba(30, 30, 30, 0.88));
+ backdrop-filter: blur(20px);
+ -webkit-backdrop-filter: blur(20px);
+ height: 56px;
+ border-radius: 28px;
align-items: center;
- justify-content: flex-start;
- padding: 5px;
+ justify-content: center;
+ padding: 4px;
box-sizing: border-box;
margin: 0;
- max-width: 90vw;
- overflow-x: auto;
+ max-width: 95vw;
+ overflow: hidden;
+ border: 1px solid rgba(255, 255, 255, 0.12);
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.08);
+ gap: 2px;
}
.navigationMenuTrigger {
@@ -48,36 +53,64 @@
height: 100%;
background-color: transparent;
border: none;
- margin: 0;
- height: 100%;
- border-radius: 20px;
- padding: 0 20px;
+ border-radius: 24px;
+ padding: 6px 16px;
+ transition: background-color 0.2s ease, backdrop-filter 0.2s ease;
cursor: pointer;
- outline-color: var(--expo-router-tabs-tab-outline-color, #444444);
+ outline-color: var(--expo-router-tabs-tab-outline-color, rgba(255, 255, 255, 0.2));
position: relative;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ gap: 2px;
+}
+
+.tabIcon {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: var(--expo-router-tabs-icon-color, rgba(255, 255, 255, 0.6));
+ font-size: 18px;
+ width: 20px;
+ height: 20px;
+}
+
+.tabIcon > * {
+ color: inherit;
+}
+
+.navigationMenuTrigger[data-state="active"] .tabIcon {
+ color: var(--expo-router-tabs-active-icon-color, #ffffff);
}
.navigationMenuTrigger[data-state="active"] {
- background-color: var(--expo-router-tabs-active-background-color, #444444);
+ background-color: var(--expo-router-tabs-active-background-color, rgba(255, 255, 255, 0.15));
+ backdrop-filter: blur(10px);
+ -webkit-backdrop-filter: blur(10px);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);
}
.tabText {
font-weight: var(--expo-router-tabs-font-weight, 500);
- font-size: var(--expo-router-tabs-font-size, 15px);
+ font-size: var(--expo-router-tabs-font-size, 11px);
font-family: var(--expo-router-tabs-font-family);
font-style: var(--expo-router-tabs-font-style, normal);
opacity: var(--expo-router-tabs-text-opacity, 1);
- color: var(--expo-router-tabs-text-color, #8b8b8b);
+ color: var(--expo-router-tabs-text-color, rgba(255, 255, 255, 0.6));
white-space: nowrap;
}
.navigationMenuTrigger[data-state="active"] .tabText {
color: var(--expo-router-tabs-active-text-color, #ffffff);
- font-size: var(--expo-router-tabs-active-font-size, var(--expo-router-tabs-font-size, 15px));
+}
+
+.navigationMenuTrigger:not([data-state="active"]):hover {
+ background-color: rgba(255, 255, 255, 0.08);
}
.navigationMenuTrigger:not([data-state="active"]) .tabText:hover {
- opacity: var(--expo-router-tabs-text-hover-opacity, 0.6);
+ opacity: var(--expo-router-tabs-text-hover-opacity, 0.9);
}
.tabBadge {
@@ -107,3 +140,101 @@
min-height: var(--expo-router-tabs-local-badge-size);
border-radius: calc(var(--expo-router-tabs-local-badge-size) / 2);
}
+
+/* More screen styles - Apple Settings inspired */
+.moreScreen {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ background-color: #000000;
+ max-height: 100%;
+ max-width: 100%;
+ overflow-y: auto;
+ padding-bottom: 120px;
+}
+
+.moreScreenHeader {
+ padding: 60px 20px 8px;
+}
+
+.moreScreenTitle {
+ font-family: var(--expo-router-tabs-font-family);
+ font-size: 34px;
+ font-weight: 700;
+ color: #ffffff;
+ margin: 0;
+ letter-spacing: 0.37px;
+}
+
+.moreScreenContent {
+ display: flex;
+ flex-direction: column;
+ padding: 20px 20px 0;
+}
+
+.moreScreenGroup {
+ background-color: #1c1c1e;
+ border-radius: 10px;
+ overflow: hidden;
+}
+
+.moreScreenItem {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ padding: 8px 16px 8px 12px;
+ min-height: 44px;
+ border: none;
+ background-color: transparent;
+ cursor: pointer;
+ font-family: var(--expo-router-tabs-font-family);
+ text-align: left;
+ transition: background-color 0.1s ease;
+ position: relative;
+ width: 100%;
+ box-sizing: border-box;
+}
+
+.moreScreenItem:hover {
+ background-color: rgba(255, 255, 255, 0.08);
+}
+
+.moreScreenItem:active {
+ background-color: rgba(255, 255, 255, 0.12);
+}
+
+/* Separator line between items */
+.moreScreenItem:not(:last-child)::after {
+ content: '';
+ position: absolute;
+ bottom: 0;
+ left: 54px;
+ right: 0;
+ height: 0.5px;
+ background-color: rgba(84, 84, 88, 0.65);
+}
+
+.moreScreenItemIcon {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 30px;
+ height: 30px;
+ border-radius: 6px;
+ background: linear-gradient(180deg, rgba(255, 255, 255, 0.17) 0%, rgba(255, 255, 255, 0) 100%), #636366;
+ color: #ffffff;
+ flex-shrink: 0;
+}
+
+.moreScreenItemLabel {
+ flex: 1;
+ font-size: 17px;
+ font-weight: 400;
+ color: #ffffff;
+ letter-spacing: -0.41px;
+}
+
+.moreScreenItemChevron {
+ color: rgba(235, 235, 245, 0.3);
+ flex-shrink: 0;
+}
diff --git a/build/getLinkingConfig.js b/build/getLinkingConfig.js
index 2a0ee73..302afc0 100644
--- a/build/getLinkingConfig.js
+++ b/build/getLinkingConfig.js
@@ -8,6 +8,7 @@ const constants_1 = require("./constants");
const getReactNavigationConfig_1 = require("./getReactNavigationConfig");
const getRoutesRedirects_1 = require("./getRoutesRedirects");
const linking_1 = require("./link/linking");
+const isAnythingApp = expo_modules_core_1.Platform.OS === 'ios' && !globalThis.expo?.modules?.ExpoGo;
function getNavigationConfig(routes, metaOnly, { sitemap, notFound }) {
const config = (0, getReactNavigationConfig_1.getReactNavigationConfig)(routes, metaOnly);
const sitemapRoute = (() => {
@@ -61,7 +62,10 @@ function getLinkingConfig(routes, context, getRouteInfo, { metaOnly = true, serv
// Expo Router calls `getInitialURL` twice, which may confuse the user if they provide a custom `getInitialURL`.
// Therefor we memoize the result.
if (!hasCachedInitialUrl) {
- if (expo_modules_core_1.Platform.OS === 'web') {
+ if (isAnythingApp) {
+ initialUrl = '/';
+ }
+ else if (expo_modules_core_1.Platform.OS === 'web') {
initialUrl = serverUrl ?? (0, linking_1.getInitialURL)();
}
else {
diff --git a/build/link/linking.js b/build/link/linking.js
index b9535b5..ec99c96 100644
--- a/build/link/linking.js
+++ b/build/link/linking.js
@@ -47,6 +47,7 @@ Object.defineProperty(exports, "getStateFromPath", { enumerable: true, get: func
const useLinking_1 = require("../fork/useLinking");
const getRoutesRedirects_1 = require("../getRoutesRedirects");
const isExpoGo = typeof expo !== 'undefined' && globalThis.expo?.modules?.ExpoGo;
+const isAnythingApp = react_native_1.Platform.OS === 'ios' && !globalThis.expo?.modules?.ExpoGo;
// A custom getInitialURL is used on native to ensure the app always starts at
// the root path if it's launched from something other than a deep link.
// This helps keep the native functionality working like the web functionality.
@@ -124,7 +125,12 @@ function subscribe(nativeLinking, redirects) {
}
};
}
- const subscription = Linking.addEventListener('url', callback);
+ let subscription;
+
+ if (!isAnythingApp) {
+ subscription = Linking.addEventListener('url', callback);
+ }
+
return () => {
// https://github.com/facebook/react-native/commit/6d1aca806cee86ad76de771ed3a1cc62982ebcd7
subscription?.remove?.();
diff --git a/build/native-tabs/NativeBottomTabs/NativeTabTrigger.js b/build/native-tabs/NativeBottomTabs/NativeTabTrigger.js
index cd3d597..8bc0b00 100644
--- a/build/native-tabs/NativeBottomTabs/NativeTabTrigger.js
+++ b/build/native-tabs/NativeBottomTabs/NativeTabTrigger.js
@@ -129,6 +129,16 @@ function appendLabelOptions(options, props) {
else {
options.title = props.children;
options.selectedLabelStyle = props.selectedStyle;
+ // Extract label color for web
+ if (props.style?.color) {
+ options.webLabelColor = props.style.color;
+ }
+ if (props.color) {
+ options.webLabelColor = props.color;
+ }
+ if (props.selectedStyle?.color) {
+ options.webLabelSelectedColor = props.selectedStyle.color;
+ }
}
}
function appendIconOptions(options, props) {
@@ -136,6 +146,21 @@ function appendIconOptions(options, props) {
const icon = convertIconSrcToIconOption(props);
options.icon = icon?.icon;
options.selectedIcon = icon?.selectedIcon;
+ // Preserve icon info for web rendering
+ const srcValue = typeof props.src === 'object' && 'selected' in props.src ? props.src.default : props.src;
+ if ((0, react_1.isValidElement)(srcValue) && srcValue.type === elements_1.VectorIcon) {
+ options.webIconFamily = srcValue.props.family;
+ options.webIconName = srcValue.props.name;
+ // Extract colors from VectorIcon props for web
+ if (srcValue.props.color) {
+ options.webIconColor = srcValue.props.color;
+ }
+ if (srcValue.props.selectedColor) {
+ options.webIconSelectedColor = srcValue.props.selectedColor;
+ }
+ } else {
+ options.webIcon = srcValue;
+ }
}
else if ('sf' in props && process.env.EXPO_OS === 'ios') {
if (typeof props.sf === 'string') {
@@ -169,6 +194,13 @@ function appendIconOptions(options, props) {
options.selectedIcon = undefined;
}
options.selectedIconColor = props.selectedColor;
+ // Extract icon color for web
+ if (props.color) {
+ options.webIconColor = props.color;
+ }
+ if (props.selectedColor) {
+ options.webIconSelectedColor = props.selectedColor;
+ }
}
function convertIconSrcToIconOption(icon) {
if (icon && icon.src) {
diff --git a/build/native-tabs/NativeBottomTabs/NativeTabsView.web.js b/build/native-tabs/NativeBottomTabs/NativeTabsView.web.js
index d3d738b..a27f83d 100644
--- a/build/native-tabs/NativeBottomTabs/NativeTabsView.web.js
+++ b/build/native-tabs/NativeBottomTabs/NativeTabsView.web.js
@@ -41,16 +41,45 @@ const react_tabs_1 = require("@radix-ui/react-tabs");
const react_1 = __importStar(require("react"));
const utils_1 = require("./utils");
const native_tabs_module_css_1 = __importDefault(require("../../../assets/native-tabs.module.css"));
+
+const MAX_VISIBLE_TABS = 5;
+
function NativeTabsView(props) {
const { builder, focusedIndex } = props;
const { state, descriptors, navigation } = builder;
const { routes } = state;
+ const [showMoreScreen, setShowMoreScreen] = (0, react_1.useState)(false);
const defaultTabName = (0, react_1.useMemo)(() => state.routes[focusedIndex]?.name ?? state.routes[0].name, []);
const value = state.routes[focusedIndex]?.name ?? state.routes[0].name;
const currentTabKey = state.routes[focusedIndex]?.key ?? state.routes[0].key;
- const items = routes
- .filter(({ key }) => (0, utils_1.shouldTabBeVisible)(descriptors[key].options))
- .map((route) => (<TabItem key={route.key} route={route} title={descriptors[route.key].options.title ?? route.name} badgeValue={descriptors[route.key].options.badgeValue}/>));
+
+ const visibleRoutes = routes.filter(({ key }) => (0, utils_1.shouldTabBeVisible)(descriptors[key].options));
+ const hasOverflow = visibleRoutes.length > MAX_VISIBLE_TABS;
+ const primaryRoutes = hasOverflow ? visibleRoutes.slice(0, MAX_VISIBLE_TABS - 1) : visibleRoutes;
+ const overflowRoutes = hasOverflow ? visibleRoutes.slice(MAX_VISIBLE_TABS - 1) : [];
+
+ // Check if an overflow tab is currently active
+ const isOverflowTabActive = overflowRoutes.some(route => route.name === value);
+
+ const items = primaryRoutes.map((route) => (
+ <TabItem
+ key={route.key}
+ route={route}
+ title={descriptors[route.key].options.title ?? route.name}
+ badgeValue={descriptors[route.key].options.badgeValue}
+ webIcon={descriptors[route.key].options.webIcon}
+ webIconFamily={descriptors[route.key].options.webIconFamily}
+ webIconName={descriptors[route.key].options.webIconName}
+ webIconColor={descriptors[route.key].options.webIconColor}
+ webIconSelectedColor={descriptors[route.key].options.webIconSelectedColor}
+ webLabelColor={descriptors[route.key].options.webLabelColor}
+ webLabelSelectedColor={descriptors[route.key].options.webLabelSelectedColor}
+ onClick={() => setShowMoreScreen(false)}
+ forceInactive={showMoreScreen}
+ isActive={route.name === value && !showMoreScreen}
+ />
+ ));
+
const children = routes
.filter(({ key }) => (0, utils_1.shouldTabBeVisible)(descriptors[key].options))
.map((route) => {
@@ -58,26 +87,116 @@ function NativeTabsView(props) {
{descriptors[route.key].render()}
</react_tabs_1.TabsContent>);
});
- return (<react_tabs_1.Tabs className={native_tabs_module_css_1.default.nativeTabsContainer} defaultValue={defaultTabName} value={value} onValueChange={(value) => {
- navigation.dispatch({
- type: 'JUMP_TO',
- target: state.key,
- payload: {
- name: value,
- },
- });
+
+ const handleNavigate = (routeName) => {
+ navigation.dispatch({
+ type: 'JUMP_TO',
+ target: state.key,
+ payload: {
+ name: routeName,
+ },
+ });
+ setShowMoreScreen(false);
+ };
+
+ return (<react_tabs_1.Tabs className={native_tabs_module_css_1.default.nativeTabsContainer} defaultValue={defaultTabName} value={value} onValueChange={(newValue) => {
+ handleNavigate(newValue);
}} style={convertNativeTabsPropsToStyleVars(props, descriptors[currentTabKey]?.options)}>
+
+ {/* More Screen - shown when More tab is active */}
+ {showMoreScreen && (
+ <div className={native_tabs_module_css_1.default.moreScreen}>
+ <div className={native_tabs_module_css_1.default.moreScreenHeader}>
+ <h1 className={native_tabs_module_css_1.default.moreScreenTitle}>More</h1>
+ </div>
+ <div className={native_tabs_module_css_1.default.moreScreenContent}>
+ <div className={native_tabs_module_css_1.default.moreScreenGroup}>
+ {overflowRoutes.map((route) => (
+ <button
+ key={route.key}
+ type="button"
+ className={native_tabs_module_css_1.default.moreScreenItem}
+ onClick={() => handleNavigate(route.name)}
+ >
+ <div className={native_tabs_module_css_1.default.moreScreenItemIcon}>
+ <OverflowTabIcon
+ webIcon={descriptors[route.key].options.webIcon}
+ webIconFamily={descriptors[route.key].options.webIconFamily}
+ webIconName={descriptors[route.key].options.webIconName}
+ />
+ </div>
+ <span className={native_tabs_module_css_1.default.moreScreenItemLabel}>
+ {descriptors[route.key].options.title ?? route.name}
+ </span>
+ <svg className={native_tabs_module_css_1.default.moreScreenItemChevron} width="7" height="12" viewBox="0 0 7 12" fill="none">
+ <path d="M1 1L6 6L1 11" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
+ </svg>
+ </button>
+ ))}
+ </div>
+ </div>
+ </div>
+ )}
+
+ {/* Tab Content - hidden when More screen is shown */}
+ {!showMoreScreen && children}
+
<react_tabs_1.TabsList aria-label="Main" className={native_tabs_module_css_1.default.navigationMenuRoot}>
{items}
+ {hasOverflow && (
+ <button
+ type="button"
+ className={native_tabs_module_css_1.default.navigationMenuTrigger}
+ data-state={showMoreScreen ? "active" : "inactive"}
+ onClick={() => setShowMoreScreen(true)}
+ >
+ <span className={native_tabs_module_css_1.default.tabIcon}>
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
+ <circle cx="12" cy="12" r="1"></circle>
+ <circle cx="19" cy="12" r="1"></circle>
+ <circle cx="5" cy="12" r="1"></circle>
+ </svg>
+ </span>
+ <span className={native_tabs_module_css_1.default.tabText}>More</span>
+ </button>
+ )}
</react_tabs_1.TabsList>
- {children}
</react_tabs_1.Tabs>);
}
+
+function OverflowTabIcon(props) {
+ const { webIcon, webIconFamily, webIconName } = props;
+ if (webIconFamily && webIconName) {
+ const IconComponent = webIconFamily;
+ return <IconComponent name={webIconName} size={20} />;
+ } else if (webIcon) {
+ return webIcon;
+ }
+ return null;
+}
+
function TabItem(props) {
- const { title, badgeValue, route } = props;
+ const { title, badgeValue, route, webIcon, webIconFamily, webIconName, webIconColor, webIconSelectedColor, webLabelColor, webLabelSelectedColor, onClick, forceInactive, isActive } = props;
const isBadgeEmpty = badgeValue === ' ';
- return (<react_tabs_1.TabsTrigger value={route.name} className={native_tabs_module_css_1.default.navigationMenuTrigger}>
- <span className={native_tabs_module_css_1.default.tabText}>{title}</span>
+ const dataState = forceInactive ? "inactive" : (isActive ? "active" : "inactive");
+
+ // Resolve colors based on active state
+ const resolvedIconColor = isActive && webIconSelectedColor ? webIconSelectedColor : webIconColor;
+ const resolvedLabelColor = isActive && webLabelSelectedColor ? webLabelSelectedColor : webLabelColor;
+
+ const iconStyle = resolvedIconColor ? { color: resolvedIconColor } : {};
+ const labelStyle = resolvedLabelColor ? { color: resolvedLabelColor } : {};
+
+ let iconElement = null;
+ if (webIconFamily && webIconName) {
+ const IconComponent = webIconFamily;
+ iconElement = (<span className={native_tabs_module_css_1.default.tabIcon} style={iconStyle}><IconComponent name={webIconName} size={18} color={resolvedIconColor} /></span>);
+ } else if (webIcon) {
+ iconElement = (<span className={native_tabs_module_css_1.default.tabIcon} style={iconStyle}>{webIcon}</span>);
+ }
+ return (<react_tabs_1.TabsTrigger value={route.name} className={native_tabs_module_css_1.default.navigationMenuTrigger} onClick={onClick} data-state={dataState}>
+ {iconElement}
+ <span className={native_tabs_module_css_1.default.tabText} style={labelStyle}>{title}</span>
{badgeValue && (<div className={`${native_tabs_module_css_1.default.tabBadge} ${isBadgeEmpty ? native_tabs_module_css_1.default.emptyTabBadge : ''}`}>
{badgeValue}
</div>)}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,30 @@
diff --git a/index.js b/index.js
index c737c93..f3edd25 100644
--- a/index.js
+++ b/index.js
@@ -336,6 +336,9 @@ module.exports = {
return require('./src/private/components/virtualview/VirtualView')
.VirtualViewMode;
},
+ get Slider() {
+ return require('@react-native-community/slider').default;
+ },
// #endregion
} as ReactNativePublicAPI;
@@ -405,15 +408,4 @@ if (__DEV__) {
* attempting to access Slider. */
/* $FlowFixMe[invalid-export] This is intentional: Flow will error when
* attempting to access Slider. */
- Object.defineProperty(module.exports, 'Slider', {
- configurable: true,
- get() {
- invariant(
- false,
- 'Slider has been removed from react-native core. ' +
- "It can now be installed and imported from '@react-native-community/slider' instead of 'react-native'. " +
- 'See https://github.com/callstack/react-native-slider',
- );
- },
- });
}

View File

@@ -0,0 +1,17 @@
diff --git a/dist/utils/environment.js b/dist/utils/environment.js
index 7c5d453..8457e4b 100644
--- a/dist/utils/environment.js
+++ b/dist/utils/environment.js
@@ -31,6 +31,12 @@ exports.shouldUseBrowserMode = shouldUseBrowserMode;
* Detects if the app is running in Expo Go
*/
function isExpoGo() {
+ if (!__DEV__) {
+ return false;
+ }
+ if (globalThis.expo && globalThis.expo.modules && globalThis.expo.modules.AnythingLauncherModule) {
+ return true;
+ }
var _a, _b;
if (!!react_native_1.NativeModules.RNPurchases) {
return false;

View File

@@ -0,0 +1,59 @@
diff --git a/lib/commonjs/utils/environment.js b/lib/commonjs/utils/environment.js
index 43e5e6a..b67d36a 100644
--- a/lib/commonjs/utils/environment.js
+++ b/lib/commonjs/utils/environment.js
@@ -31,6 +31,12 @@ function shouldUsePreviewAPIMode() {
*/
function isExpoGo() {
var _globalThis$expo;
+ if (!__DEV__) {
+ return false;
+ }
+ if (globalThis.expo && globalThis.expo.modules && globalThis.expo.modules.AnythingLauncherModule) {
+ return true;
+ }
if (!!_reactNative.NativeModules.RNPaywalls && !!_reactNative.NativeModules.RNCustomerCenter) {
return false;
}
diff --git a/lib/module/utils/environment.js b/lib/module/utils/environment.js
index 435d456..4002fe2 100644
--- a/lib/module/utils/environment.js
+++ b/lib/module/utils/environment.js
@@ -26,6 +26,12 @@ export function shouldUsePreviewAPIMode() {
*/
function isExpoGo() {
var _globalThis$expo;
+ if (!__DEV__) {
+ return false;
+ }
+ if (globalThis.expo && globalThis.expo.modules && globalThis.expo.modules.AnythingLauncherModule) {
+ return true;
+ }
if (!!NativeModules.RNPaywalls && !!NativeModules.RNCustomerCenter) {
return false;
}
diff --git a/src/utils/environment.ts b/src/utils/environment.ts
index 5605bf2..ed86595 100644
--- a/src/utils/environment.ts
+++ b/src/utils/environment.ts
@@ -26,6 +26,7 @@ declare global {
var expo: {
modules?: {
ExpoGo?: boolean;
+ AnythingLauncherModule?: boolean;
};
};
}
@@ -34,6 +35,12 @@ declare global {
* Detects if the app is running in Expo Go
*/
function isExpoGo(): boolean {
+ if (!__DEV__) {
+ return false;
+ }
+ if (globalThis.expo && globalThis.expo.modules && globalThis.expo.modules.AnythingLauncherModule) {
+ return true;
+ }
if (!!NativeModules.RNPaywalls && !!NativeModules.RNCustomerCenter) {
return false;
}

View File

@@ -0,0 +1,24 @@
diff --git a/src/RefreshControl.web.js b/src/RefreshControl.web.js
index b2351e6..c638d23 100644
--- a/src/RefreshControl.web.js
+++ b/src/RefreshControl.web.js
@@ -1,5 +1,5 @@
import React, { useRef, useEffect, useCallback, useMemo } from 'react'
-import { View, Text, PanResponder, Animated, ActivityIndicator, findNodeHandle } from 'react-native'
+import { View, Text, PanResponder, Animated, ActivityIndicator } from 'react-native'
import PropTypes from 'prop-types'
const arrowIcon =
@@ -77,9 +77,9 @@ export default function RefreshControl({
onStartShouldSetPanResponderCapture: () => false,
onMoveShouldSetPanResponder: (_,gestureState) => {
if (!containerRef.current) return false
- const containerDOM = findNodeHandle(containerRef.current)
- if (!containerDOM) return false
- return containerDOM.children[0].scrollTop === 0
+ const scrollContainer = containerRef.current?.firstChild
+ if (!scrollContainer) return false
+ return scrollContainer.scrollTop === 0
&& (Math.abs(gestureState.dy) > Math.abs(gestureState.dx) * 2 && Math.abs(gestureState.vy) > Math.abs(gestureState.vx) * 2.5)
},
onMoveShouldSetPanResponderCapture: () => false,

View File

@@ -0,0 +1,43 @@
diff --git a/lib/commonjs/positioner.js b/lib/commonjs/positioner.js
index cac0f68..ec816b7 100644
--- a/lib/commonjs/positioner.js
+++ b/lib/commonjs/positioner.js
@@ -55,8 +55,12 @@ const Positioner = ({
return {};
}, [position, bottom, top, offset]);
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
+ ...(_reactNative.Platform.OS === 'web' ? {
+ style: [{ pointerEvents: 'box-none' }, containerStyle, insetValues, style],
+ } :{
style: [containerStyle, insetValues, style],
pointerEvents: "box-none",
+ }),
...props,
children: children
});
diff --git a/lib/module/positioner.js b/lib/module/positioner.js
index 476f6bb..40f1968 100644
--- a/lib/module/positioner.js
+++ b/lib/module/positioner.js
@@ -1,7 +1,7 @@
"use strict";
import React from 'react';
-import { View } from 'react-native';
+import { View, Platform } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { useToastContext } from "./context.js";
import { jsx as _jsx } from "react/jsx-runtime";
@@ -50,8 +50,12 @@ export const Positioner = ({
return {};
}, [position, bottom, top, offset]);
return /*#__PURE__*/_jsx(View, {
+...(Platform.OS === 'web' ? {
+ style: [{ pointerEvents: 'box-none' }, containerStyle, insetValues, style],
+ } :{
style: [containerStyle, insetValues, style],
pointerEvents: "box-none",
+ }),
...props,
children: children
});