first commit

This commit is contained in:
2026-03-10 16:18:05 +00:00
commit 11f9c069b5
31635 changed files with 3187747 additions and 0 deletions

View File

@@ -0,0 +1,6 @@
"use strict";
export function NativeBottomTabView(_) {
throw new Error('Native Bottom Tabs are not supported on this platform.');
}
//# sourceMappingURL=NativeBottomTabView.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["NativeBottomTabView","_","Error"],"sourceRoot":"../../../src","sources":["unstable/NativeBottomTabView.tsx"],"mappings":";;AAiBA,OAAO,SAASA,mBAAmBA,CAACC,CAAQ,EAAE;EAC5C,MAAM,IAAIC,KAAK,CAAC,wDAAwD,CAAC;AAC3E","ignoreList":[]}

View File

@@ -0,0 +1,328 @@
"use strict";
import { getLabel, Lazy, SafeAreaProviderCompat, Screen as ScreenContent } from '@react-navigation/elements';
import { CommonActions, NavigationMetaContext, StackActions, useTheme } from '@react-navigation/native';
import Color from 'color';
import * as React from 'react';
import { Platform, PlatformColor } from 'react-native';
import { Tabs } from 'react-native-screens';
import { NativeScreen } from "./NativeScreen/NativeScreen.js";
import { jsx as _jsx } from "react/jsx-runtime";
const meta = {
type: 'native-tabs'
};
export function NativeBottomTabView({
state,
navigation,
descriptors
}) {
const {
dark,
colors,
fonts
} = useTheme();
const focusedRouteKey = state.routes[state.index].key;
const previousRouteKeyRef = React.useRef(focusedRouteKey);
React.useEffect(() => {
const previousRouteKey = previousRouteKeyRef.current;
if (previousRouteKey !== focusedRouteKey && descriptors[previousRouteKey]?.options.popToTopOnBlur) {
const prevRoute = state.routes.find(route => route.key === previousRouteKey);
if (prevRoute?.state?.type === 'stack' && prevRoute.state.key) {
const popToTopAction = {
...StackActions.popToTop(),
target: prevRoute.state.key
};
navigation.dispatch(popToTopAction);
}
}
previousRouteKeyRef.current = focusedRouteKey;
}, [descriptors, focusedRouteKey, navigation, state.index, state.routes]);
const currentOptions = descriptors[state.routes[state.index].key]?.options;
const {
fontFamily = Platform.select({
ios: fonts.medium.fontFamily,
default: fonts.regular.fontFamily
}),
fontWeight = Platform.select({
ios: fonts.medium.fontWeight,
default: fonts.regular.fontWeight
}),
fontSize,
fontStyle,
color: fontColor
} = currentOptions.tabBarLabelStyle || {};
const activeTintColor = currentOptions.tabBarActiveTintColor ?? colors.primary;
const inactiveTintColor = currentOptions.tabBarInactiveTintColor ?? Platform.select({
ios: PlatformColor('label'),
default: colors.text
});
const activeIndicatorColor = currentOptions?.tabBarActiveIndicatorColor ?? typeof activeTintColor === 'string' ? Color(activeTintColor)?.alpha(0.1).string() : undefined;
const onTransitionStart = ({
closing,
route
}) => {
navigation.emit({
type: 'transitionStart',
data: {
closing
},
target: route.key
});
};
const onTransitionEnd = ({
closing,
route
}) => {
navigation.emit({
type: 'transitionEnd',
data: {
closing
},
target: route.key
});
};
const tabBarControllerMode = currentOptions.tabBarControllerMode === 'auto' ? 'automatic' : currentOptions.tabBarControllerMode;
const tabBarMinimizeBehavior = currentOptions.tabBarMinimizeBehavior === 'auto' ? 'automatic' : currentOptions.tabBarMinimizeBehavior;
const shouldHideTabBar = currentOptions.tabBarStyle?.display === 'none';
const bottomAccessory = currentOptions.bottomAccessory;
return /*#__PURE__*/_jsx(SafeAreaProviderCompat, {
children: /*#__PURE__*/_jsx(Tabs.Host, {
bottomAccessory: bottomAccessory ? environment => bottomAccessory({
placement: environment
}) : undefined,
tabBarHidden: shouldHideTabBar,
tabBarItemLabelVisibilityMode: currentOptions?.tabBarLabelVisibilityMode,
tabBarControllerMode: tabBarControllerMode,
tabBarMinimizeBehavior: tabBarMinimizeBehavior,
tabBarTintColor: activeTintColor,
tabBarItemIconColor: inactiveTintColor,
tabBarItemIconColorActive: activeTintColor,
tabBarItemTitleFontColor: inactiveTintColor ?? fontColor,
tabBarItemTitleFontColorActive: activeTintColor,
tabBarItemTitleFontFamily: fontFamily,
tabBarItemTitleFontWeight: fontWeight,
tabBarItemTitleFontSize: fontSize,
tabBarItemTitleFontSizeActive: fontSize,
tabBarItemTitleFontStyle: fontStyle,
tabBarBackgroundColor: currentOptions.tabBarStyle?.backgroundColor ?? colors.card,
tabBarItemActiveIndicatorColor: activeIndicatorColor,
tabBarItemActiveIndicatorEnabled: currentOptions?.tabBarActiveIndicatorEnabled,
tabBarItemRippleColor: currentOptions?.tabBarRippleColor,
experimentalControlNavigationStateInJS: false,
onNativeFocusChange: e => {
const route = state.routes.find(route => route.key === e.nativeEvent.tabKey);
if (route) {
navigation.emit({
type: 'tabPress',
target: route.key
});
const isFocused = state.index === state.routes.findIndex(r => r.key === route.key);
if (!isFocused) {
navigation.dispatch({
...CommonActions.navigate(route.name, route.params),
target: state.key
});
}
}
},
children: state.routes.map((route, index) => {
const {
options,
render,
navigation
} = descriptors[route.key];
const isFocused = state.index === index;
const isPreloaded = state.preloadedRouteKeys.includes(route.key);
const {
title,
lazy = true,
tabBarLabel,
tabBarBadgeStyle,
tabBarIcon,
tabBarBadge,
tabBarSystemItem,
tabBarBlurEffect = dark ? 'systemMaterialDark' : 'systemMaterial',
tabBarStyle,
overrideScrollViewContentInsetAdjustmentBehavior
} = options;
const {
backgroundColor: tabBarBackgroundColor,
shadowColor: tabBarShadowColor
} = tabBarStyle || {};
const tabTitle =
// On iOS, `systemItem` already provides a localized label
// So we should only use `tabBarLabel` if explicitly provided
Platform.OS === 'ios' && tabBarSystemItem != null ? tabBarLabel : getLabel({
label: tabBarLabel,
title
}, route.name);
const badgeBackgroundColor = tabBarBadgeStyle?.backgroundColor ?? colors.notification;
const badgeTextColor = tabBarBadgeStyle?.color ?? (typeof badgeBackgroundColor === 'string' ? Color(badgeBackgroundColor).isLight() ? 'black' : 'white' : undefined);
const tabItemAppearance = {
tabBarItemTitleFontFamily: fontFamily,
tabBarItemTitleFontSize: fontSize,
tabBarItemTitleFontWeight: fontWeight,
tabBarItemTitleFontStyle: fontStyle,
tabBarItemTitleFontColor: inactiveTintColor ?? fontColor,
tabBarItemIconColor: inactiveTintColor,
tabBarItemBadgeBackgroundColor: badgeBackgroundColor
};
const icon = typeof tabBarIcon === 'function' ? getPlatformIcon(tabBarIcon({
focused: false
})) : tabBarIcon != null ? getPlatformIcon(tabBarIcon) : undefined;
const selectedIcon = typeof tabBarIcon === 'function' ? getPlatformIcon(tabBarIcon({
focused: true
})) : undefined;
return /*#__PURE__*/_jsx(Tabs.Screen, {
onWillDisappear: () => onTransitionStart({
closing: true,
route
}),
onWillAppear: () => onTransitionStart({
closing: false,
route
}),
onDidAppear: () => onTransitionEnd({
closing: false,
route
}),
onDidDisappear: () => onTransitionEnd({
closing: true,
route
}),
tabKey: route.key,
icon: icon,
selectedIcon: selectedIcon?.ios ?? selectedIcon?.shared,
tabBarItemBadgeBackgroundColor: badgeBackgroundColor,
tabBarItemBadgeTextColor: badgeTextColor,
badgeValue: tabBarBadge?.toString(),
systemItem: tabBarSystemItem,
isFocused: isFocused,
title: tabTitle,
scrollEdgeAppearance: {
tabBarBackgroundColor,
tabBarShadowColor,
tabBarBlurEffect,
stacked: {
normal: tabItemAppearance
},
inline: {
normal: tabItemAppearance
},
compactInline: {
normal: tabItemAppearance
}
},
standardAppearance: {
tabBarBackgroundColor,
tabBarShadowColor,
tabBarBlurEffect,
stacked: {
normal: tabItemAppearance
},
inline: {
normal: tabItemAppearance
},
compactInline: {
normal: tabItemAppearance
}
},
specialEffects: {
repeatedTabSelection: {
popToRoot: true,
scrollToTop: true
}
},
overrideScrollViewContentInsetAdjustmentBehavior: overrideScrollViewContentInsetAdjustmentBehavior,
experimental_userInterfaceStyle: dark ? 'dark' : 'light',
children: /*#__PURE__*/_jsx(Lazy, {
enabled: lazy,
visible: isFocused || isPreloaded,
children: /*#__PURE__*/_jsx(ScreenWithHeader, {
isFocused: isFocused,
route: route,
navigation: navigation,
options: options,
children: /*#__PURE__*/_jsx(NavigationMetaContext.Provider, {
value: meta,
children: render()
})
})
})
}, route.key);
})
})
});
}
function ScreenWithHeader({
isFocused,
route,
navigation,
options,
children
}) {
const {
headerTransparent,
header: renderCustomHeader,
headerShown = renderCustomHeader != null
} = options;
const hasNativeHeader = headerShown && renderCustomHeader == null;
const [wasNativeHeaderShown] = React.useState(hasNativeHeader);
React.useEffect(() => {
if (wasNativeHeaderShown !== hasNativeHeader) {
throw new Error(`Changing 'headerShown' or 'header' options dynamically is not supported when using native header.`);
}
}, [wasNativeHeaderShown, hasNativeHeader]);
if (hasNativeHeader) {
return /*#__PURE__*/_jsx(NativeScreen, {
route: route,
navigation: navigation,
options: options,
children: children
});
}
return /*#__PURE__*/_jsx(ScreenContent, {
focused: isFocused,
route: route,
navigation: navigation,
headerShown: headerShown,
headerTransparent: headerTransparent,
header: renderCustomHeader?.({
route,
navigation,
options
}),
children: children
});
}
function getPlatformIcon(icon) {
switch (icon.type) {
case 'sfSymbol':
return {
ios: icon,
android: undefined,
shared: undefined
};
case 'image':
return {
ios: icon.tinted === false ? {
type: 'imageSource',
imageSource: icon.source
} : {
type: 'templateSource',
templateSource: icon.source
},
android: undefined,
shared: {
type: 'imageSource',
imageSource: icon.source
}
};
default:
{
const _exhaustiveCheck = icon;
return _exhaustiveCheck;
}
}
}
//# sourceMappingURL=NativeBottomTabView.native.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,152 @@
"use strict";
import { getDefaultHeaderHeight, HeaderHeightContext, HeaderShownContext, useFrameSize } from '@react-navigation/elements';
import * as React from 'react';
import { Animated, Platform, StyleSheet, useAnimatedValue, View } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { ScreenStack, ScreenStackItem } from 'react-native-screens';
import { debounce } from "./debounce.js";
import { AnimatedHeaderHeightContext } from "./useAnimatedHeaderHeight.js";
import { useHeaderConfig } from "./useHeaderConfig.js";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
const ANDROID_DEFAULT_HEADER_HEIGHT = 56;
export function NativeScreen({
route,
navigation,
options,
children
}) {
const {
header: renderCustomHeader,
headerShown = renderCustomHeader != null,
headerTransparent,
headerBackground
} = options;
const isModal = false;
const insets = useSafeAreaInsets();
// Modals are fullscreen in landscape only on iPhone
const isIPhone = Platform.OS === 'ios' && !(Platform.isPad || Platform.isTV);
const isParentHeaderShown = React.useContext(HeaderShownContext);
const parentHeaderHeight = React.useContext(HeaderHeightContext);
const isLandscape = useFrameSize(frame => frame.width > frame.height);
const topInset = isParentHeaderShown || Platform.OS === 'ios' && isModal || isIPhone && isLandscape ? 0 : insets.top;
const defaultHeaderHeight = useFrameSize(frame => Platform.select({
// FIXME: Currently screens isn't using Material 3
// So our `getDefaultHeaderHeight` doesn't return the correct value
// So we hardcode the value here for now until screens is updated
android: ANDROID_DEFAULT_HEADER_HEIGHT + topInset,
default: getDefaultHeaderHeight(frame, isModal, topInset)
}));
const [headerHeight, setHeaderHeight] = React.useState(defaultHeaderHeight);
// eslint-disable-next-line react-hooks/exhaustive-deps
const setHeaderHeightDebounced = React.useCallback(
// Debounce the header height updates to avoid excessive re-renders
debounce(setHeaderHeight, 100), []);
const hasCustomHeader = renderCustomHeader != null;
const animatedHeaderHeight = useAnimatedValue(defaultHeaderHeight);
const headerTopInsetEnabled = topInset !== 0;
const onHeaderHeightChange = Animated.event([{
nativeEvent: {
headerHeight: animatedHeaderHeight
}
}], {
useNativeDriver: true,
listener: e => {
if (hasCustomHeader) {
// If we have a custom header, don't use native header height
return;
}
if (e.nativeEvent && typeof e.nativeEvent === 'object' && 'headerHeight' in e.nativeEvent && typeof e.nativeEvent.headerHeight === 'number') {
const headerHeight = e.nativeEvent.headerHeight;
// Only debounce if header has large title or search bar
// As it's the only case where the header height can change frequently
const doesHeaderAnimate = Platform.OS === 'ios' && (options.headerLargeTitleEnabled || options.headerSearchBarOptions);
if (doesHeaderAnimate) {
setHeaderHeightDebounced(headerHeight);
} else {
setHeaderHeight(headerHeight);
}
}
}
});
const headerConfig = useHeaderConfig({
...options,
route,
headerHeight,
headerShown: hasCustomHeader ? false : headerShown === true,
headerTopInsetEnabled
});
return /*#__PURE__*/_jsx(ScreenStack, {
style: styles.container,
children: /*#__PURE__*/_jsx(ScreenStackItem, {
screenId: route.key
// Needed to show search bar in tab bar with systemItem=search
,
stackPresentation: "push",
headerConfig: headerConfig,
onHeaderHeightChange: onHeaderHeightChange,
children: /*#__PURE__*/_jsx(AnimatedHeaderHeightContext.Provider, {
value: animatedHeaderHeight,
children: /*#__PURE__*/_jsxs(HeaderHeightContext.Provider, {
value: headerShown ? headerHeight : parentHeaderHeight ?? 0,
children: [headerBackground != null ?
/*#__PURE__*/
/**
* To show a custom header background, we render it at the top of the screen below the header
* The header also needs to be positioned absolutely (with `translucent` style)
*/
_jsx(View, {
style: [styles.background, headerTransparent ? styles.translucent : null, {
height: headerHeight
}],
children: headerBackground()
}) : null, hasCustomHeader && headerShown ? /*#__PURE__*/_jsx(View, {
onLayout: e => {
const headerHeight = e.nativeEvent.layout.height;
setHeaderHeight(headerHeight);
animatedHeaderHeight.setValue(headerHeight);
},
style: [styles.header, headerTransparent ? styles.absolute : null],
children: renderCustomHeader?.({
route,
navigation,
options
})
}) : null, /*#__PURE__*/_jsx(HeaderShownContext.Provider, {
value: isParentHeaderShown || headerShown,
children: children
})]
})
})
})
});
}
const styles = StyleSheet.create({
container: {
flex: 1
},
header: {
zIndex: 1
},
absolute: {
position: 'absolute',
top: 0,
start: 0,
end: 0
},
translucent: {
position: 'absolute',
top: 0,
start: 0,
end: 0,
zIndex: 1,
elevation: 1
},
background: {
overflow: 'hidden'
}
});
//# sourceMappingURL=NativeScreen.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,12 @@
"use strict";
export function debounce(func, duration) {
let timeout;
return function (...args) {
clearTimeout(timeout);
timeout = setTimeout(() => {
func.apply(this, args);
}, duration);
};
}
//# sourceMappingURL=debounce.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["debounce","func","duration","timeout","args","clearTimeout","setTimeout","apply"],"sourceRoot":"../../../../src","sources":["unstable/NativeScreen/debounce.tsx"],"mappings":";;AAAA,OAAO,SAASA,QAAQA,CACtBC,IAAO,EACPC,QAAgB,EACb;EACH,IAAIC,OAAsC;EAE1C,OAAO,UAAyB,GAAGC,IAAI,EAAE;IACvCC,YAAY,CAACF,OAAO,CAAC;IAErBA,OAAO,GAAGG,UAAU,CAAC,MAAM;MACzBL,IAAI,CAACM,KAAK,CAAC,IAAI,EAAEH,IAAI,CAAC;IACxB,CAAC,EAAEF,QAAQ,CAAC;EACd,CAAC;AACH","ignoreList":[]}

View File

@@ -0,0 +1,4 @@
"use strict";
export {};
//# sourceMappingURL=types.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":[],"sourceRoot":"../../../../src","sources":["unstable/NativeScreen/types.ts"],"mappings":"","ignoreList":[]}

View File

@@ -0,0 +1,12 @@
"use strict";
import * as React from 'react';
export const AnimatedHeaderHeightContext = /*#__PURE__*/React.createContext(undefined);
export function useAnimatedHeaderHeight() {
const animatedValue = React.useContext(AnimatedHeaderHeightContext);
if (animatedValue === undefined) {
throw new Error("Couldn't find the header height. Are you inside a screen in a native stack navigator?");
}
return animatedValue;
}
//# sourceMappingURL=useAnimatedHeaderHeight.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","AnimatedHeaderHeightContext","createContext","undefined","useAnimatedHeaderHeight","animatedValue","useContext","Error"],"sourceRoot":"../../../../src","sources":["unstable/NativeScreen/useAnimatedHeaderHeight.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAG9B,OAAO,MAAMC,2BAA2B,gBAAGD,KAAK,CAACE,aAAa,CAE5DC,SAAS,CAAC;AAEZ,OAAO,SAASC,uBAAuBA,CAAA,EAAG;EACxC,MAAMC,aAAa,GAAGL,KAAK,CAACM,UAAU,CAACL,2BAA2B,CAAC;EAEnE,IAAII,aAAa,KAAKF,SAAS,EAAE;IAC/B,MAAM,IAAII,KAAK,CACb,uFACF,CAAC;EACH;EAEA,OAAOF,aAAa;AACtB","ignoreList":[]}

View File

@@ -0,0 +1,304 @@
"use strict";
import { getHeaderTitle, HeaderTitle } from '@react-navigation/elements';
import { useLocale, useTheme } from '@react-navigation/native';
import Color from 'color';
import { Platform, StyleSheet, View } from 'react-native';
import { isSearchBarAvailableForCurrentPlatform, ScreenStackHeaderCenterView, ScreenStackHeaderLeftView, ScreenStackHeaderRightView, ScreenStackHeaderSearchBarView, SearchBar } from 'react-native-screens';
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
const processBarButtonItems = (items, colors, fonts) => {
return items?.map((item, index) => {
if (item.type === 'custom') {
// Handled with `ScreenStackHeaderLeftView` or `ScreenStackHeaderRightView`
return null;
}
if (item.type === 'spacing') {
if (item.spacing == null) {
throw new Error(`Spacing item must have a 'spacing' property defined: ${JSON.stringify(item)}`);
}
return item;
}
if (item.type === 'button' || item.type === 'menu') {
if (item.type === 'menu' && item.menu == null) {
throw new Error(`Menu item must have a 'menu' property defined: ${JSON.stringify(item)}`);
}
const {
badge,
label,
labelStyle,
icon,
...rest
} = item;
let processedItem = {
...rest,
index,
title: label,
titleStyle: {
...fonts.regular,
...labelStyle
},
icon: icon?.type === 'image' ? icon.tinted === false ? {
type: 'imageSource',
imageSource: icon.source
} : {
type: 'templateSource',
templateSource: icon.source
} : icon
};
if (processedItem.type === 'menu' && item.type === 'menu') {
const {
multiselectable,
layout
} = item.menu;
processedItem = {
...processedItem,
menu: {
...processedItem.menu,
singleSelection: !multiselectable,
displayAsPalette: layout === 'palette',
items: item.menu.items.map(getMenuItem)
}
};
}
if (badge) {
const badgeBackgroundColor = badge.style?.backgroundColor ?? colors.notification;
const badgeTextColor = typeof badgeBackgroundColor === 'string' && Color(badgeBackgroundColor)?.isLight() ? 'black' : 'white';
processedItem = {
...processedItem,
badge: {
...badge,
value: String(badge.value),
style: {
backgroundColor: badgeBackgroundColor,
color: badgeTextColor,
...fonts.regular,
...badge.style
}
}
};
}
return processedItem;
}
throw new Error(`Invalid item type: ${JSON.stringify(item)}. Valid types are 'button', 'menu', 'custom' and 'spacing'.`);
}).filter(item => item != null);
};
const getMenuItem = item => {
if (item.type === 'submenu') {
const {
label,
inline,
layout,
items,
multiselectable,
...rest
} = item;
return {
...rest,
title: label,
displayAsPalette: layout === 'palette',
displayInline: inline,
singleSelection: !multiselectable,
items: items.map(getMenuItem)
};
}
const {
label,
description,
...rest
} = item;
return {
...rest,
title: label,
subtitle: description
};
};
export function useHeaderConfig({
headerShadowVisible,
headerLargeStyle,
headerLargeTitleEnabled,
headerLargeTitleShadowVisible,
headerLargeTitleStyle,
headerBackground,
headerLeft,
headerRight,
headerShown,
headerStyle,
headerBlurEffect,
headerTintColor,
headerTitle,
headerTitleAlign,
headerTitleStyle,
headerTransparent,
headerSearchBarOptions,
headerTopInsetEnabled,
route,
title,
unstable_headerLeftItems: headerLeftItems,
unstable_headerRightItems: headerRightItems
}) {
const {
direction
} = useLocale();
const {
colors,
fonts,
dark
} = useTheme();
const tintColor = headerTintColor ?? (Platform.OS === 'ios' ? colors.primary : colors.text);
const headerLargeTitleStyleFlattened = StyleSheet.flatten([Platform.select({
ios: fonts.heavy,
default: fonts.medium
}), headerLargeTitleStyle]) || {};
const headerTitleStyleFlattened = StyleSheet.flatten([Platform.select({
ios: fonts.bold,
default: fonts.medium
}), headerTitleStyle]) || {};
const headerStyleFlattened = StyleSheet.flatten(headerStyle) || {};
const headerLargeStyleFlattened = StyleSheet.flatten(headerLargeStyle) || {};
const titleText = getHeaderTitle({
title,
headerTitle
}, route.name);
const titleColor = 'color' in headerTitleStyleFlattened ? headerTitleStyleFlattened.color : headerTintColor ?? colors.text;
const titleFontSize = 'fontSize' in headerTitleStyleFlattened ? headerTitleStyleFlattened.fontSize : undefined;
const titleFontFamily = headerTitleStyleFlattened.fontFamily;
const titleFontWeight = headerTitleStyleFlattened.fontWeight;
const largeTitleFontFamily = headerLargeTitleStyleFlattened.fontFamily;
const largeTitleBackgroundColor = headerLargeStyleFlattened.backgroundColor;
const largeTitleColor = 'color' in headerLargeTitleStyleFlattened ? headerLargeTitleStyleFlattened.color : undefined;
const largeTitleFontSize = 'fontSize' in headerLargeTitleStyleFlattened ? headerLargeTitleStyleFlattened.fontSize : undefined;
const largeTitleFontWeight = headerLargeTitleStyleFlattened.fontWeight;
const headerTitleStyleSupported = {
color: titleColor
};
if (headerTitleStyleFlattened.fontFamily != null) {
headerTitleStyleSupported.fontFamily = headerTitleStyleFlattened.fontFamily;
}
if (titleFontSize != null) {
headerTitleStyleSupported.fontSize = titleFontSize;
}
if (titleFontWeight != null) {
headerTitleStyleSupported.fontWeight = titleFontWeight;
}
const headerBackgroundColor = headerStyleFlattened.backgroundColor ?? (headerBackground != null || headerTransparent ? 'transparent' : colors.card);
const headerLeftElement = headerLeft?.({
tintColor
});
const headerRightElement = headerRight?.({
tintColor
});
const headerTitleElement = typeof headerTitle === 'function' ? headerTitle({
tintColor,
children: titleText
}) : null;
const hasHeaderSearchBar = isSearchBarAvailableForCurrentPlatform && headerSearchBarOptions != null;
const translucent = headerBackground != null || headerTransparent ||
// When using a SearchBar or large title, the header needs to be translucent for it to work on iOS
(hasHeaderSearchBar || headerLargeTitleEnabled) && Platform.OS === 'ios' && headerTransparent !== false;
const isCenterViewRenderedAndroid = headerTitleAlign === 'center';
const leftItems = headerLeftItems?.({
tintColor
});
let rightItems = headerRightItems?.({
tintColor
});
if (rightItems) {
// iOS renders right items in reverse order
// So we need to reverse them here to match the order
rightItems = [...rightItems].reverse();
}
const children = /*#__PURE__*/_jsxs(_Fragment, {
children: [Platform.OS === 'ios' ? /*#__PURE__*/_jsxs(_Fragment, {
children: [leftItems ? leftItems.map((item, index) => {
if (item.type === 'custom') {
return /*#__PURE__*/_jsx(ScreenStackHeaderLeftView
// eslint-disable-next-line @eslint-react/no-array-index-key
, {
hidesSharedBackground: item.hidesSharedBackground,
children: item.element
}, index);
}
return null;
}) : headerLeftElement != null ? /*#__PURE__*/_jsx(ScreenStackHeaderLeftView, {
children: headerLeftElement
}) : null, headerTitleElement != null ? /*#__PURE__*/_jsx(ScreenStackHeaderCenterView, {
children: headerTitleElement
}) : null]
}) : /*#__PURE__*/_jsxs(_Fragment, {
children: [headerLeftElement != null || typeof headerTitle === 'function' ?
/*#__PURE__*/
// The style passed to header left, together with title element being wrapped
// in flex view is reqruied for proper header layout, in particular,
// for the text truncation to work.
_jsxs(ScreenStackHeaderLeftView, {
style: !isCenterViewRenderedAndroid ? {
flex: 1
} : null,
children: [headerLeftElement, headerTitleAlign !== 'center' ? typeof headerTitle === 'function' ? /*#__PURE__*/_jsx(View, {
style: {
flex: 1
},
children: headerTitleElement
}) : /*#__PURE__*/_jsx(View, {
style: {
flex: 1
},
children: /*#__PURE__*/_jsx(HeaderTitle, {
tintColor: tintColor,
style: headerTitleStyleSupported,
children: titleText
})
}) : null]
}) : null, isCenterViewRenderedAndroid ? /*#__PURE__*/_jsx(ScreenStackHeaderCenterView, {
children: typeof headerTitle === 'function' ? headerTitleElement : /*#__PURE__*/_jsx(HeaderTitle, {
tintColor: tintColor,
style: headerTitleStyleSupported,
children: titleText
})
}) : null]
}), Platform.OS === 'ios' && rightItems ? rightItems.map((item, index) => {
if (item.type === 'custom') {
return /*#__PURE__*/_jsx(ScreenStackHeaderRightView
// eslint-disable-next-line @eslint-react/no-array-index-key
, {
hidesSharedBackground: item.hidesSharedBackground,
children: item.element
}, index);
}
return null;
}) : headerRightElement != null ? /*#__PURE__*/_jsx(ScreenStackHeaderRightView, {
children: headerRightElement
}) : null, hasHeaderSearchBar ? /*#__PURE__*/_jsx(ScreenStackHeaderSearchBarView, {
children: /*#__PURE__*/_jsx(SearchBar, {
...headerSearchBarOptions
})
}) : null]
});
return {
backgroundColor: headerBackgroundColor,
blurEffect: headerBlurEffect,
color: tintColor,
direction,
hidden: headerShown === false,
hideShadow: headerShadowVisible === false || headerBackground != null || headerTransparent && headerShadowVisible !== true,
largeTitle: headerLargeTitleEnabled,
largeTitleBackgroundColor,
largeTitleColor,
largeTitleFontFamily,
largeTitleFontSize,
largeTitleFontWeight,
largeTitleHideShadow: headerLargeTitleShadowVisible === false,
title: titleText,
titleColor,
titleFontFamily,
titleFontSize,
titleFontWeight: String(titleFontWeight),
topInsetEnabled: headerTopInsetEnabled,
translucent: translucent === true,
children,
headerLeftBarButtonItems: processBarButtonItems(leftItems, colors, fonts),
headerRightBarButtonItems: processBarButtonItems(rightItems, colors, fonts),
experimental_userInterfaceStyle: dark ? 'dark' : 'light'
};
}
//# sourceMappingURL=useHeaderConfig.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,6 @@
"use strict";
export const createNativeBottomTabNavigator = () => {
throw new Error('Native Bottom Tabs are not supported on this platform.');
};
//# sourceMappingURL=createNativeBottomTabNavigator.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["createNativeBottomTabNavigator","Error"],"sourceRoot":"../../../src","sources":["unstable/createNativeBottomTabNavigator.tsx"],"mappings":";;AAAA,OAAO,MAAMA,8BAAuH,GAClIA,CAAA,KAAM;EACJ,MAAM,IAAIC,KAAK,CAAC,wDAAwD,CAAC;AAC3E,CAAC","ignoreList":[]}

View File

@@ -0,0 +1,65 @@
"use strict";
import { createNavigatorFactory, StackActions, TabRouter, useNavigationBuilder } from '@react-navigation/native';
import * as React from 'react';
import { NativeBottomTabView } from "./NativeBottomTabView.native.js";
import { jsx as _jsx } from "react/jsx-runtime";
function NativeBottomTabNavigator({
id,
initialRouteName,
backBehavior,
children,
layout,
screenListeners,
screenOptions,
screenLayout,
UNSTABLE_router,
UNSTABLE_routeNamesChangeBehavior,
...rest
}) {
const {
state,
navigation,
descriptors,
NavigationContent
} = useNavigationBuilder(TabRouter, {
id,
initialRouteName,
backBehavior,
children,
layout,
screenListeners,
screenOptions,
screenLayout,
UNSTABLE_router,
UNSTABLE_routeNamesChangeBehavior
});
const focusedRouteKey = state.routes[state.index].key;
const previousRouteKeyRef = React.useRef(focusedRouteKey);
React.useEffect(() => {
const previousRouteKey = previousRouteKeyRef.current;
if (previousRouteKey !== focusedRouteKey && descriptors[previousRouteKey]?.options.popToTopOnBlur) {
const prevRoute = state.routes.find(route => route.key === previousRouteKey);
if (prevRoute?.state?.type === 'stack' && prevRoute.state.key) {
const popToTopAction = {
...StackActions.popToTop(),
target: prevRoute.state.key
};
navigation.dispatch(popToTopAction);
}
}
previousRouteKeyRef.current = focusedRouteKey;
}, [descriptors, focusedRouteKey, navigation, state.index, state.routes]);
return /*#__PURE__*/_jsx(NavigationContent, {
children: /*#__PURE__*/_jsx(NativeBottomTabView, {
...rest,
state: state,
navigation: navigation,
descriptors: descriptors
})
});
}
export function createNativeBottomTabNavigator(config) {
return createNavigatorFactory(NativeBottomTabNavigator)(config);
}
//# sourceMappingURL=createNativeBottomTabNavigator.native.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["createNavigatorFactory","StackActions","TabRouter","useNavigationBuilder","React","NativeBottomTabView","jsx","_jsx","NativeBottomTabNavigator","id","initialRouteName","backBehavior","children","layout","screenListeners","screenOptions","screenLayout","UNSTABLE_router","UNSTABLE_routeNamesChangeBehavior","rest","state","navigation","descriptors","NavigationContent","focusedRouteKey","routes","index","key","previousRouteKeyRef","useRef","useEffect","previousRouteKey","current","options","popToTopOnBlur","prevRoute","find","route","type","popToTopAction","popToTop","target","dispatch","createNativeBottomTabNavigator","config"],"sourceRoot":"../../../src","sources":["unstable/createNativeBottomTabNavigator.native.tsx"],"mappings":";;AAAA,SACEA,sBAAsB,EAGtBC,YAAY,EAIZC,SAAS,EAGTC,oBAAoB,QACf,0BAA0B;AACjC,OAAO,KAAKC,KAAK,MAAM,OAAO;AAE9B,SAASC,mBAAmB,QAAQ,iCAA8B;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAQnE,SAASC,wBAAwBA,CAAC;EAChCC,EAAE;EACFC,gBAAgB;EAChBC,YAAY;EACZC,QAAQ;EACRC,MAAM;EACNC,eAAe;EACfC,aAAa;EACbC,YAAY;EACZC,eAAe;EACfC,iCAAiC;EACjC,GAAGC;AAC0B,CAAC,EAAE;EAChC,MAAM;IAAEC,KAAK;IAAEC,UAAU;IAAEC,WAAW;IAAEC;EAAkB,CAAC,GACzDpB,oBAAoB,CAMlBD,SAAS,EAAE;IACXO,EAAE;IACFC,gBAAgB;IAChBC,YAAY;IACZC,QAAQ;IACRC,MAAM;IACNC,eAAe;IACfC,aAAa;IACbC,YAAY;IACZC,eAAe;IACfC;EACF,CAAC,CAAC;EAEJ,MAAMM,eAAe,GAAGJ,KAAK,CAACK,MAAM,CAACL,KAAK,CAACM,KAAK,CAAC,CAACC,GAAG;EACrD,MAAMC,mBAAmB,GAAGxB,KAAK,CAACyB,MAAM,CAACL,eAAe,CAAC;EAEzDpB,KAAK,CAAC0B,SAAS,CAAC,MAAM;IACpB,MAAMC,gBAAgB,GAAGH,mBAAmB,CAACI,OAAO;IAEpD,IACED,gBAAgB,KAAKP,eAAe,IACpCF,WAAW,CAACS,gBAAgB,CAAC,EAAEE,OAAO,CAACC,cAAc,EACrD;MACA,MAAMC,SAAS,GAAGf,KAAK,CAACK,MAAM,CAACW,IAAI,CAChCC,KAAK,IAAKA,KAAK,CAACV,GAAG,KAAKI,gBAC3B,CAAC;MAED,IAAII,SAAS,EAAEf,KAAK,EAAEkB,IAAI,KAAK,OAAO,IAAIH,SAAS,CAACf,KAAK,CAACO,GAAG,EAAE;QAC7D,MAAMY,cAAc,GAAG;UACrB,GAAGtC,YAAY,CAACuC,QAAQ,CAAC,CAAC;UAC1BC,MAAM,EAAEN,SAAS,CAACf,KAAK,CAACO;QAC1B,CAAC;QACDN,UAAU,CAACqB,QAAQ,CAACH,cAAc,CAAC;MACrC;IACF;IAEAX,mBAAmB,CAACI,OAAO,GAAGR,eAAe;EAC/C,CAAC,EAAE,CAACF,WAAW,EAAEE,eAAe,EAAEH,UAAU,EAAED,KAAK,CAACM,KAAK,EAAEN,KAAK,CAACK,MAAM,CAAC,CAAC;EAEzE,oBACElB,IAAA,CAACgB,iBAAiB;IAAAX,QAAA,eAChBL,IAAA,CAACF,mBAAmB;MAAA,GACdc,IAAI;MACRC,KAAK,EAAEA,KAAM;MACbC,UAAU,EAAEA,UAAW;MACvBC,WAAW,EAAEA;IAAY,CAC1B;EAAC,CACe,CAAC;AAExB;AAEA,OAAO,SAASqB,8BAA8BA,CAmB5CC,MAAe,EAAmC;EAClD,OAAO5C,sBAAsB,CAACQ,wBAAwB,CAAC,CAACoC,MAAM,CAAC;AACjE","ignoreList":[]}

View File

@@ -0,0 +1,16 @@
"use strict";
/**
* Navigators
*/
export { createNativeBottomTabNavigator } from './createNativeBottomTabNavigator';
/**
* Views
*/
export { NativeBottomTabView } from './NativeBottomTabView';
/**
* Types
*/
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["createNativeBottomTabNavigator","NativeBottomTabView"],"sourceRoot":"../../../src","sources":["unstable/index.tsx"],"mappings":";;AAAA;AACA;AACA;AACA,SAASA,8BAA8B,QAAQ,kCAAkC;;AAEjF;AACA;AACA;AACA,SAASC,mBAAmB,QAAQ,uBAAuB;;AAE3D;AACA;AACA","ignoreList":[]}

View File

@@ -0,0 +1,4 @@
"use strict";
export {};
//# sourceMappingURL=types.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":[],"sourceRoot":"../../../src","sources":["unstable/types.tsx"],"mappings":"","ignoreList":[]}