feat(smart-app): implement complete mobile app MVP

- App.tsx: full navigation (Auth stack + Main tabs with 5 screens)
- Auth: LoginScreen, RegisterScreen, ForgotPasswordScreen
- HomeScreen: dashboard with IoT metrics, weather widget, alerts, quick actions, sensors
- MapScreen: interactive map with layer toggles (6 layers)
- MarketplaceScreen: categories (6), products (5), search
- ChatScreen: AI chat with quick prompts (4), bot responses
- ProfileScreen: user info, stats, menu (9 items), logout
- AlertsScreen: alert list with severity, acknowledge
- SensorsScreen: sensor list with type filters (6 types), search
- ZonesScreen: zone cards with stats
- SettingsScreen: language picker (FR/EN/ES/DE), privacy, about
- Stores: iotStore (sensors, zones, alerts), notificationStore, uiStore + i18n
- Hooks: useSensors, useAlerts, useNotifications, useLocation
- Components: Card, Button, LoadingSpinner, ErrorBoundary, Header
- Services: iotService, notificationService (with axios API client)
- Utils: formatters (temp, AQI, noise, dates), validators (email, password, IBAN)
- Theme: colors.ts with full design system (Blue Ocean palette)
- Ditto: fixed MongoDB connection, new JWT secrets, official gateway image
This commit is contained in:
Eric FELIXINE
2026-06-01 18:00:35 -04:00
parent 08ca495bde
commit e30ae8ed09
35578 changed files with 3703534 additions and 43 deletions

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017 React Navigation Contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,5 @@
# `@react-navigation/bottom-tabs`
Bottom tab navigator for React Navigation following iOS design guidelines.
Installation instructions and documentation can be found on the [React Navigation website](https://reactnavigation.org/docs/bottom-tab-navigator/).

View File

@@ -0,0 +1,49 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "BottomTabBar", {
enumerable: true,
get: function () {
return _BottomTabBar.default;
}
});
Object.defineProperty(exports, "BottomTabBarHeightCallbackContext", {
enumerable: true,
get: function () {
return _BottomTabBarHeightCallbackContext.default;
}
});
Object.defineProperty(exports, "BottomTabBarHeightContext", {
enumerable: true,
get: function () {
return _BottomTabBarHeightContext.default;
}
});
Object.defineProperty(exports, "BottomTabView", {
enumerable: true,
get: function () {
return _BottomTabView.default;
}
});
Object.defineProperty(exports, "createBottomTabNavigator", {
enumerable: true,
get: function () {
return _createBottomTabNavigator.default;
}
});
Object.defineProperty(exports, "useBottomTabBarHeight", {
enumerable: true,
get: function () {
return _useBottomTabBarHeight.default;
}
});
var _createBottomTabNavigator = _interopRequireDefault(require("./navigators/createBottomTabNavigator"));
var _BottomTabBar = _interopRequireDefault(require("./views/BottomTabBar"));
var _BottomTabView = _interopRequireDefault(require("./views/BottomTabView"));
var _BottomTabBarHeightCallbackContext = _interopRequireDefault(require("./utils/BottomTabBarHeightCallbackContext"));
var _BottomTabBarHeightContext = _interopRequireDefault(require("./utils/BottomTabBarHeightContext"));
var _useBottomTabBarHeight = _interopRequireDefault(require("./utils/useBottomTabBarHeight"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":[],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA;AAKA;AACA;AAKA;AACA;AACA;AAAiF"}

View File

@@ -0,0 +1,86 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _native = require("@react-navigation/native");
var React = _interopRequireWildcard(require("react"));
var _warnOnce = _interopRequireDefault(require("warn-once"));
var _BottomTabView = _interopRequireDefault(require("../views/BottomTabView"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function BottomTabNavigator(_ref) {
let {
id,
initialRouteName,
backBehavior,
children,
screenListeners,
screenOptions,
sceneContainerStyle,
...restWithDeprecated
} = _ref;
const {
// @ts-expect-error: lazy is deprecated
lazy,
// @ts-expect-error: tabBarOptions is deprecated
tabBarOptions,
...rest
} = restWithDeprecated;
let defaultScreenOptions = {};
if (tabBarOptions) {
Object.assign(defaultScreenOptions, {
tabBarHideOnKeyboard: tabBarOptions.keyboardHidesTabBar,
tabBarActiveTintColor: tabBarOptions.activeTintColor,
tabBarInactiveTintColor: tabBarOptions.inactiveTintColor,
tabBarActiveBackgroundColor: tabBarOptions.activeBackgroundColor,
tabBarInactiveBackgroundColor: tabBarOptions.inactiveBackgroundColor,
tabBarAllowFontScaling: tabBarOptions.allowFontScaling,
tabBarShowLabel: tabBarOptions.showLabel,
tabBarLabelStyle: tabBarOptions.labelStyle,
tabBarIconStyle: tabBarOptions.iconStyle,
tabBarItemStyle: tabBarOptions.tabStyle,
tabBarLabelPosition: tabBarOptions.labelPosition ?? (tabBarOptions.adaptive === false ? 'below-icon' : undefined),
tabBarStyle: [{
display: tabBarOptions.tabBarVisible ? 'none' : 'flex'
}, defaultScreenOptions.tabBarStyle]
});
Object.keys(defaultScreenOptions).forEach(key => {
if (defaultScreenOptions[key] === undefined) {
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete defaultScreenOptions[key];
}
});
(0, _warnOnce.default)(tabBarOptions, `Bottom Tab Navigator: 'tabBarOptions' is deprecated. Migrate the options to 'screenOptions' instead.\n\nPlace the following in 'screenOptions' in your code to keep current behavior:\n\n${JSON.stringify(defaultScreenOptions, null, 2)}\n\nSee https://reactnavigation.org/docs/bottom-tab-navigator#options for more details.`);
}
if (typeof lazy === 'boolean') {
defaultScreenOptions.lazy = lazy;
(0, _warnOnce.default)(true, `Bottom Tab Navigator: 'lazy' in props is deprecated. Move it to 'screenOptions' instead.\n\nSee https://reactnavigation.org/docs/bottom-tab-navigator/#lazy for more details.`);
}
const {
state,
descriptors,
navigation,
NavigationContent
} = (0, _native.useNavigationBuilder)(_native.TabRouter, {
id,
initialRouteName,
backBehavior,
children,
screenListeners,
screenOptions,
defaultScreenOptions
});
return /*#__PURE__*/React.createElement(NavigationContent, null, /*#__PURE__*/React.createElement(_BottomTabView.default, _extends({}, rest, {
state: state,
navigation: navigation,
descriptors: descriptors,
sceneContainerStyle: sceneContainerStyle
})));
}
var _default = (0, _native.createNavigatorFactory)(BottomTabNavigator);
exports.default = _default;
//# sourceMappingURL=createBottomTabNavigator.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["BottomTabNavigator","id","initialRouteName","backBehavior","children","screenListeners","screenOptions","sceneContainerStyle","restWithDeprecated","lazy","tabBarOptions","rest","defaultScreenOptions","Object","assign","tabBarHideOnKeyboard","keyboardHidesTabBar","tabBarActiveTintColor","activeTintColor","tabBarInactiveTintColor","inactiveTintColor","tabBarActiveBackgroundColor","activeBackgroundColor","tabBarInactiveBackgroundColor","inactiveBackgroundColor","tabBarAllowFontScaling","allowFontScaling","tabBarShowLabel","showLabel","tabBarLabelStyle","labelStyle","tabBarIconStyle","iconStyle","tabBarItemStyle","tabStyle","tabBarLabelPosition","labelPosition","adaptive","undefined","tabBarStyle","display","tabBarVisible","keys","forEach","key","warnOnce","JSON","stringify","state","descriptors","navigation","NavigationContent","useNavigationBuilder","TabRouter","createNavigatorFactory"],"sourceRoot":"../../../src","sources":["navigators/createBottomTabNavigator.tsx"],"mappings":";;;;;;AAAA;AAUA;AACA;AAOA;AAAmD;AAAA;AAAA;AAAA;AAWnD,SAASA,kBAAkB,OASjB;EAAA,IATkB;IAC1BC,EAAE;IACFC,gBAAgB;IAChBC,YAAY;IACZC,QAAQ;IACRC,eAAe;IACfC,aAAa;IACbC,mBAAmB;IACnB,GAAGC;EACE,CAAC;EACN,MAAM;IACJ;IACAC,IAAI;IACJ;IACAC,aAAa;IACb,GAAGC;EACL,CAAC,GAAGH,kBAAkB;EAEtB,IAAII,oBAAgD,GAAG,CAAC,CAAC;EAEzD,IAAIF,aAAa,EAAE;IACjBG,MAAM,CAACC,MAAM,CAACF,oBAAoB,EAAE;MAClCG,oBAAoB,EAAEL,aAAa,CAACM,mBAAmB;MACvDC,qBAAqB,EAAEP,aAAa,CAACQ,eAAe;MACpDC,uBAAuB,EAAET,aAAa,CAACU,iBAAiB;MACxDC,2BAA2B,EAAEX,aAAa,CAACY,qBAAqB;MAChEC,6BAA6B,EAAEb,aAAa,CAACc,uBAAuB;MACpEC,sBAAsB,EAAEf,aAAa,CAACgB,gBAAgB;MACtDC,eAAe,EAAEjB,aAAa,CAACkB,SAAS;MACxCC,gBAAgB,EAAEnB,aAAa,CAACoB,UAAU;MAC1CC,eAAe,EAAErB,aAAa,CAACsB,SAAS;MACxCC,eAAe,EAAEvB,aAAa,CAACwB,QAAQ;MACvCC,mBAAmB,EACjBzB,aAAa,CAAC0B,aAAa,KAC1B1B,aAAa,CAAC2B,QAAQ,KAAK,KAAK,GAAG,YAAY,GAAGC,SAAS,CAAC;MAC/DC,WAAW,EAAE,CACX;QAAEC,OAAO,EAAE9B,aAAa,CAAC+B,aAAa,GAAG,MAAM,GAAG;MAAO,CAAC,EAC1D7B,oBAAoB,CAAC2B,WAAW;IAEpC,CAAC,CAAC;IAGA1B,MAAM,CAAC6B,IAAI,CAAC9B,oBAAoB,CAAC,CACjC+B,OAAO,CAAEC,GAAG,IAAK;MACjB,IAAIhC,oBAAoB,CAACgC,GAAG,CAAC,KAAKN,SAAS,EAAE;QAC3C;QACA,OAAO1B,oBAAoB,CAACgC,GAAG,CAAC;MAClC;IACF,CAAC,CAAC;IAEF,IAAAC,iBAAQ,EACNnC,aAAa,EACZ,4LAA2LoC,IAAI,CAACC,SAAS,CACxMnC,oBAAoB,EACpB,IAAI,EACJ,CAAC,CACD,yFAAwF,CAC3F;EACH;EAEA,IAAI,OAAOH,IAAI,KAAK,SAAS,EAAE;IAC7BG,oBAAoB,CAACH,IAAI,GAAGA,IAAI;IAEhC,IAAAoC,iBAAQ,EACN,IAAI,EACH,+KAA8K,CAChL;EACH;EAEA,MAAM;IAAEG,KAAK;IAAEC,WAAW;IAAEC,UAAU;IAAEC;EAAkB,CAAC,GACzD,IAAAC,4BAAoB,EAMlBC,iBAAS,EAAE;IACXpD,EAAE;IACFC,gBAAgB;IAChBC,YAAY;IACZC,QAAQ;IACRC,eAAe;IACfC,aAAa;IACbM;EACF,CAAC,CAAC;EAEJ,oBACE,oBAAC,iBAAiB,qBAChB,oBAAC,sBAAa,eACRD,IAAI;IACR,KAAK,EAAEqC,KAAM;IACb,UAAU,EAAEE,UAAW;IACvB,WAAW,EAAED,WAAY;IACzB,mBAAmB,EAAE1C;EAAoB,GACzC,CACgB;AAExB;AAAC,eAEc,IAAA+C,8BAAsB,EAKnCtD,kBAAkB,CAAC;AAAA"}

View File

@@ -0,0 +1,6 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
//# sourceMappingURL=types.js.map

View File

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

View File

@@ -0,0 +1,12 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var React = _interopRequireWildcard(require("react"));
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
var _default = /*#__PURE__*/React.createContext(undefined);
exports.default = _default;
//# sourceMappingURL=BottomTabBarHeightCallbackContext.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","createContext","undefined"],"sourceRoot":"../../../src","sources":["utils/BottomTabBarHeightCallbackContext.tsx"],"mappings":";;;;;;AAAA;AAA+B;AAAA;AAAA,4BAEhBA,KAAK,CAACC,aAAa,CAChCC,SAAS,CACV;AAAA"}

View File

@@ -0,0 +1,12 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var React = _interopRequireWildcard(require("react"));
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
var _default = /*#__PURE__*/React.createContext(undefined);
exports.default = _default;
//# sourceMappingURL=BottomTabBarHeightContext.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","createContext","undefined"],"sourceRoot":"../../../src","sources":["utils/BottomTabBarHeightContext.tsx"],"mappings":";;;;;;AAAA;AAA+B;AAAA;AAAA,4BAEhBA,KAAK,CAACC,aAAa,CAAqBC,SAAS,CAAC;AAAA"}

View File

@@ -0,0 +1,19 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = useBottomTabBarHeight;
var React = _interopRequireWildcard(require("react"));
var _BottomTabBarHeightContext = _interopRequireDefault(require("./BottomTabBarHeightContext"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function useBottomTabBarHeight() {
const height = React.useContext(_BottomTabBarHeightContext.default);
if (height === undefined) {
throw new Error("Couldn't find the bottom tab bar height. Are you inside a screen in Bottom Tab Navigator?");
}
return height;
}
//# sourceMappingURL=useBottomTabBarHeight.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["useBottomTabBarHeight","height","React","useContext","BottomTabBarHeightContext","undefined","Error"],"sourceRoot":"../../../src","sources":["utils/useBottomTabBarHeight.tsx"],"mappings":";;;;;;AAAA;AAEA;AAAoE;AAAA;AAAA;AAErD,SAASA,qBAAqB,GAAG;EAC9C,MAAMC,MAAM,GAAGC,KAAK,CAACC,UAAU,CAACC,kCAAyB,CAAC;EAE1D,IAAIH,MAAM,KAAKI,SAAS,EAAE;IACxB,MAAM,IAAIC,KAAK,CACb,2FAA2F,CAC5F;EACH;EAEA,OAAOL,MAAM;AACf"}

View File

@@ -0,0 +1,28 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = useIsKeyboardShown;
var React = _interopRequireWildcard(require("react"));
var _reactNative = require("react-native");
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function useIsKeyboardShown() {
const [isKeyboardShown, setIsKeyboardShown] = React.useState(false);
React.useEffect(() => {
const handleKeyboardShow = () => setIsKeyboardShown(true);
const handleKeyboardHide = () => setIsKeyboardShown(false);
let subscriptions;
if (_reactNative.Platform.OS === 'ios') {
subscriptions = [_reactNative.Keyboard.addListener('keyboardWillShow', handleKeyboardShow), _reactNative.Keyboard.addListener('keyboardWillHide', handleKeyboardHide)];
} else {
subscriptions = [_reactNative.Keyboard.addListener('keyboardDidShow', handleKeyboardShow), _reactNative.Keyboard.addListener('keyboardDidHide', handleKeyboardHide)];
}
return () => {
subscriptions.forEach(s => s.remove());
};
}, []);
return isKeyboardShown;
}
//# sourceMappingURL=useIsKeyboardShown.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["useIsKeyboardShown","isKeyboardShown","setIsKeyboardShown","React","useState","useEffect","handleKeyboardShow","handleKeyboardHide","subscriptions","Platform","OS","Keyboard","addListener","forEach","s","remove"],"sourceRoot":"../../../src","sources":["utils/useIsKeyboardShown.tsx"],"mappings":";;;;;;AAAA;AACA;AAAuE;AAAA;AAExD,SAASA,kBAAkB,GAAG;EAC3C,MAAM,CAACC,eAAe,EAAEC,kBAAkB,CAAC,GAAGC,KAAK,CAACC,QAAQ,CAAC,KAAK,CAAC;EAEnED,KAAK,CAACE,SAAS,CAAC,MAAM;IACpB,MAAMC,kBAAkB,GAAG,MAAMJ,kBAAkB,CAAC,IAAI,CAAC;IACzD,MAAMK,kBAAkB,GAAG,MAAML,kBAAkB,CAAC,KAAK,CAAC;IAE1D,IAAIM,aAAoC;IAExC,IAAIC,qBAAQ,CAACC,EAAE,KAAK,KAAK,EAAE;MACzBF,aAAa,GAAG,CACdG,qBAAQ,CAACC,WAAW,CAAC,kBAAkB,EAAEN,kBAAkB,CAAC,EAC5DK,qBAAQ,CAACC,WAAW,CAAC,kBAAkB,EAAEL,kBAAkB,CAAC,CAC7D;IACH,CAAC,MAAM;MACLC,aAAa,GAAG,CACdG,qBAAQ,CAACC,WAAW,CAAC,iBAAiB,EAAEN,kBAAkB,CAAC,EAC3DK,qBAAQ,CAACC,WAAW,CAAC,iBAAiB,EAAEL,kBAAkB,CAAC,CAC5D;IACH;IAEA,OAAO,MAAM;MACXC,aAAa,CAACK,OAAO,CAAEC,CAAC,IAAKA,CAAC,CAACC,MAAM,EAAE,CAAC;IAC1C,CAAC;EACH,CAAC,EAAE,EAAE,CAAC;EAEN,OAAOd,eAAe;AACxB"}

View File

@@ -0,0 +1,88 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = Badge;
var _native = require("@react-navigation/native");
var _color = _interopRequireDefault(require("color"));
var React = _interopRequireWildcard(require("react"));
var _reactNative = require("react-native");
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function Badge(_ref) {
let {
children,
style,
visible = true,
size = 18,
...rest
} = _ref;
const [opacity] = React.useState(() => new _reactNative.Animated.Value(visible ? 1 : 0));
const [rendered, setRendered] = React.useState(visible);
const theme = (0, _native.useTheme)();
React.useEffect(() => {
if (!rendered) {
return;
}
_reactNative.Animated.timing(opacity, {
toValue: visible ? 1 : 0,
duration: 150,
useNativeDriver: true
}).start(_ref2 => {
let {
finished
} = _ref2;
if (finished && !visible) {
setRendered(false);
}
});
return () => opacity.stopAnimation();
}, [opacity, rendered, visible]);
if (!rendered) {
if (visible) {
setRendered(true);
} else {
return null;
}
}
// @ts-expect-error: backgroundColor definitely exists
const {
backgroundColor = theme.colors.notification,
...restStyle
} = _reactNative.StyleSheet.flatten(style) || {};
const textColor = (0, _color.default)(backgroundColor).isLight() ? 'black' : 'white';
const borderRadius = size / 2;
const fontSize = Math.floor(size * 3 / 4);
return /*#__PURE__*/React.createElement(_reactNative.Animated.Text, _extends({
numberOfLines: 1,
style: [{
transform: [{
scale: opacity.interpolate({
inputRange: [0, 1],
outputRange: [0.5, 1]
})
}],
color: textColor,
lineHeight: size - 1,
height: size,
minWidth: size,
opacity,
backgroundColor,
fontSize,
borderRadius
}, styles.container, restStyle]
}, rest), children);
}
const styles = _reactNative.StyleSheet.create({
container: {
alignSelf: 'flex-end',
textAlign: 'center',
paddingHorizontal: 4,
overflow: 'hidden'
}
});
//# sourceMappingURL=Badge.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["Badge","children","style","visible","size","rest","opacity","React","useState","Animated","Value","rendered","setRendered","theme","useTheme","useEffect","timing","toValue","duration","useNativeDriver","start","finished","stopAnimation","backgroundColor","colors","notification","restStyle","StyleSheet","flatten","textColor","color","isLight","borderRadius","fontSize","Math","floor","transform","scale","interpolate","inputRange","outputRange","lineHeight","height","minWidth","styles","container","create","alignSelf","textAlign","paddingHorizontal","overflow"],"sourceRoot":"../../../src","sources":["views/Badge.tsx"],"mappings":";;;;;;AAAA;AACA;AACA;AACA;AAA0E;AAAA;AAAA;AAAA;AAqB3D,SAASA,KAAK,OAMnB;EAAA,IANoB;IAC5BC,QAAQ;IACRC,KAAK;IACLC,OAAO,GAAG,IAAI;IACdC,IAAI,GAAG,EAAE;IACT,GAAGC;EACE,CAAC;EACN,MAAM,CAACC,OAAO,CAAC,GAAGC,KAAK,CAACC,QAAQ,CAAC,MAAM,IAAIC,qBAAQ,CAACC,KAAK,CAACP,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;EAC3E,MAAM,CAACQ,QAAQ,EAAEC,WAAW,CAAC,GAAGL,KAAK,CAACC,QAAQ,CAACL,OAAO,CAAC;EAEvD,MAAMU,KAAK,GAAG,IAAAC,gBAAQ,GAAE;EAExBP,KAAK,CAACQ,SAAS,CAAC,MAAM;IACpB,IAAI,CAACJ,QAAQ,EAAE;MACb;IACF;IAEAF,qBAAQ,CAACO,MAAM,CAACV,OAAO,EAAE;MACvBW,OAAO,EAAEd,OAAO,GAAG,CAAC,GAAG,CAAC;MACxBe,QAAQ,EAAE,GAAG;MACbC,eAAe,EAAE;IACnB,CAAC,CAAC,CAACC,KAAK,CAAC,SAAkB;MAAA,IAAjB;QAAEC;MAAS,CAAC;MACpB,IAAIA,QAAQ,IAAI,CAAClB,OAAO,EAAE;QACxBS,WAAW,CAAC,KAAK,CAAC;MACpB;IACF,CAAC,CAAC;IAEF,OAAO,MAAMN,OAAO,CAACgB,aAAa,EAAE;EACtC,CAAC,EAAE,CAAChB,OAAO,EAAEK,QAAQ,EAAER,OAAO,CAAC,CAAC;EAEhC,IAAI,CAACQ,QAAQ,EAAE;IACb,IAAIR,OAAO,EAAE;MACXS,WAAW,CAAC,IAAI,CAAC;IACnB,CAAC,MAAM;MACL,OAAO,IAAI;IACb;EACF;;EAEA;EACA,MAAM;IAAEW,eAAe,GAAGV,KAAK,CAACW,MAAM,CAACC,YAAY;IAAE,GAAGC;EAAU,CAAC,GACjEC,uBAAU,CAACC,OAAO,CAAC1B,KAAK,CAAC,IAAI,CAAC,CAAC;EACjC,MAAM2B,SAAS,GAAG,IAAAC,cAAK,EAACP,eAAe,CAAC,CAACQ,OAAO,EAAE,GAAG,OAAO,GAAG,OAAO;EAEtE,MAAMC,YAAY,GAAG5B,IAAI,GAAG,CAAC;EAC7B,MAAM6B,QAAQ,GAAGC,IAAI,CAACC,KAAK,CAAE/B,IAAI,GAAG,CAAC,GAAI,CAAC,CAAC;EAE3C,oBACE,oBAAC,qBAAQ,CAAC,IAAI;IACZ,aAAa,EAAE,CAAE;IACjB,KAAK,EAAE,CACL;MACEgC,SAAS,EAAE,CACT;QACEC,KAAK,EAAE/B,OAAO,CAACgC,WAAW,CAAC;UACzBC,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;UAClBC,WAAW,EAAE,CAAC,GAAG,EAAE,CAAC;QACtB,CAAC;MACH,CAAC,CACF;MACDV,KAAK,EAAED,SAAS;MAChBY,UAAU,EAAErC,IAAI,GAAG,CAAC;MACpBsC,MAAM,EAAEtC,IAAI;MACZuC,QAAQ,EAAEvC,IAAI;MACdE,OAAO;MACPiB,eAAe;MACfU,QAAQ;MACRD;IACF,CAAC,EACDY,MAAM,CAACC,SAAS,EAChBnB,SAAS;EACT,GACErB,IAAI,GAEPJ,QAAQ,CACK;AAEpB;AAEA,MAAM2C,MAAM,GAAGjB,uBAAU,CAACmB,MAAM,CAAC;EAC/BD,SAAS,EAAE;IACTE,SAAS,EAAE,UAAU;IACrBC,SAAS,EAAE,QAAQ;IACnBC,iBAAiB,EAAE,CAAC;IACpBC,QAAQ,EAAE;EACZ;AACF,CAAC,CAAC"}

View File

@@ -0,0 +1,310 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = BottomTabBar;
exports.getTabBarHeight = void 0;
var _elements = require("@react-navigation/elements");
var _native = require("@react-navigation/native");
var _react = _interopRequireDefault(require("react"));
var _reactNative = require("react-native");
var _reactNativeSafeAreaContext = require("react-native-safe-area-context");
var _BottomTabBarHeightCallbackContext = _interopRequireDefault(require("../utils/BottomTabBarHeightCallbackContext"));
var _useIsKeyboardShown = _interopRequireDefault(require("../utils/useIsKeyboardShown"));
var _BottomTabItem = _interopRequireDefault(require("./BottomTabItem"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const DEFAULT_TABBAR_HEIGHT = 49;
const COMPACT_TABBAR_HEIGHT = 32;
const DEFAULT_MAX_TAB_ITEM_WIDTH = 125;
const useNativeDriver = _reactNative.Platform.OS !== 'web';
const shouldUseHorizontalLabels = _ref => {
let {
state,
descriptors,
layout,
dimensions
} = _ref;
const {
tabBarLabelPosition
} = descriptors[state.routes[state.index].key].options;
if (tabBarLabelPosition) {
switch (tabBarLabelPosition) {
case 'beside-icon':
return true;
case 'below-icon':
return false;
}
}
if (layout.width >= 768) {
// Screen size matches a tablet
const maxTabWidth = state.routes.reduce((acc, route) => {
const {
tabBarItemStyle
} = descriptors[route.key].options;
const flattenedStyle = _reactNative.StyleSheet.flatten(tabBarItemStyle);
if (flattenedStyle) {
if (typeof flattenedStyle.width === 'number') {
return acc + flattenedStyle.width;
} else if (typeof flattenedStyle.maxWidth === 'number') {
return acc + flattenedStyle.maxWidth;
}
}
return acc + DEFAULT_MAX_TAB_ITEM_WIDTH;
}, 0);
return maxTabWidth <= layout.width;
} else {
return dimensions.width > dimensions.height;
}
};
const getPaddingBottom = insets => Math.max(insets.bottom - _reactNative.Platform.select({
ios: 4,
default: 0
}), 0);
const getTabBarHeight = _ref2 => {
var _StyleSheet$flatten;
let {
state,
descriptors,
dimensions,
insets,
style,
...rest
} = _ref2;
// @ts-ignore
const customHeight = (_StyleSheet$flatten = _reactNative.StyleSheet.flatten(style)) === null || _StyleSheet$flatten === void 0 ? void 0 : _StyleSheet$flatten.height;
if (typeof customHeight === 'number') {
return customHeight;
}
const isLandscape = dimensions.width > dimensions.height;
const horizontalLabels = shouldUseHorizontalLabels({
state,
descriptors,
dimensions,
...rest
});
const paddingBottom = getPaddingBottom(insets);
if (_reactNative.Platform.OS === 'ios' && !_reactNative.Platform.isPad && isLandscape && horizontalLabels) {
return COMPACT_TABBAR_HEIGHT + paddingBottom;
}
return DEFAULT_TABBAR_HEIGHT + paddingBottom;
};
exports.getTabBarHeight = getTabBarHeight;
function BottomTabBar(_ref3) {
let {
state,
navigation,
descriptors,
insets,
style
} = _ref3;
const {
colors
} = (0, _native.useTheme)();
const buildLink = (0, _native.useLinkBuilder)();
const focusedRoute = state.routes[state.index];
const focusedDescriptor = descriptors[focusedRoute.key];
const focusedOptions = focusedDescriptor.options;
const {
tabBarShowLabel,
tabBarHideOnKeyboard = false,
tabBarVisibilityAnimationConfig,
tabBarStyle,
tabBarBackground,
tabBarActiveTintColor,
tabBarInactiveTintColor,
tabBarActiveBackgroundColor,
tabBarInactiveBackgroundColor
} = focusedOptions;
const dimensions = (0, _reactNativeSafeAreaContext.useSafeAreaFrame)();
const isKeyboardShown = (0, _useIsKeyboardShown.default)();
const onHeightChange = _react.default.useContext(_BottomTabBarHeightCallbackContext.default);
const shouldShowTabBar = !(tabBarHideOnKeyboard && isKeyboardShown);
const visibilityAnimationConfigRef = _react.default.useRef(tabBarVisibilityAnimationConfig);
_react.default.useEffect(() => {
visibilityAnimationConfigRef.current = tabBarVisibilityAnimationConfig;
});
const [isTabBarHidden, setIsTabBarHidden] = _react.default.useState(!shouldShowTabBar);
const [visible] = _react.default.useState(() => new _reactNative.Animated.Value(shouldShowTabBar ? 1 : 0));
_react.default.useEffect(() => {
const visibilityAnimationConfig = visibilityAnimationConfigRef.current;
if (shouldShowTabBar) {
var _visibilityAnimationC, _visibilityAnimationC2;
const animation = (visibilityAnimationConfig === null || visibilityAnimationConfig === void 0 ? void 0 : (_visibilityAnimationC = visibilityAnimationConfig.show) === null || _visibilityAnimationC === void 0 ? void 0 : _visibilityAnimationC.animation) === 'spring' ? _reactNative.Animated.spring : _reactNative.Animated.timing;
animation(visible, {
toValue: 1,
useNativeDriver,
duration: 250,
...(visibilityAnimationConfig === null || visibilityAnimationConfig === void 0 ? void 0 : (_visibilityAnimationC2 = visibilityAnimationConfig.show) === null || _visibilityAnimationC2 === void 0 ? void 0 : _visibilityAnimationC2.config)
}).start(_ref4 => {
let {
finished
} = _ref4;
if (finished) {
setIsTabBarHidden(false);
}
});
} else {
var _visibilityAnimationC3, _visibilityAnimationC4;
setIsTabBarHidden(true);
const animation = (visibilityAnimationConfig === null || visibilityAnimationConfig === void 0 ? void 0 : (_visibilityAnimationC3 = visibilityAnimationConfig.hide) === null || _visibilityAnimationC3 === void 0 ? void 0 : _visibilityAnimationC3.animation) === 'spring' ? _reactNative.Animated.spring : _reactNative.Animated.timing;
animation(visible, {
toValue: 0,
useNativeDriver,
duration: 200,
...(visibilityAnimationConfig === null || visibilityAnimationConfig === void 0 ? void 0 : (_visibilityAnimationC4 = visibilityAnimationConfig.hide) === null || _visibilityAnimationC4 === void 0 ? void 0 : _visibilityAnimationC4.config)
}).start();
}
return () => visible.stopAnimation();
}, [visible, shouldShowTabBar]);
const [layout, setLayout] = _react.default.useState({
height: 0,
width: dimensions.width
});
const handleLayout = e => {
const {
height,
width
} = e.nativeEvent.layout;
onHeightChange === null || onHeightChange === void 0 ? void 0 : onHeightChange(height);
setLayout(layout => {
if (height === layout.height && width === layout.width) {
return layout;
} else {
return {
height,
width
};
}
});
};
const {
routes
} = state;
const paddingBottom = getPaddingBottom(insets);
const tabBarHeight = getTabBarHeight({
state,
descriptors,
insets,
dimensions,
layout,
style: [tabBarStyle, style]
});
const hasHorizontalLabels = shouldUseHorizontalLabels({
state,
descriptors,
dimensions,
layout
});
const tabBarBackgroundElement = tabBarBackground === null || tabBarBackground === void 0 ? void 0 : tabBarBackground();
return /*#__PURE__*/_react.default.createElement(_reactNative.Animated.View, {
style: [styles.tabBar, {
backgroundColor: tabBarBackgroundElement != null ? 'transparent' : colors.card,
borderTopColor: colors.border
}, {
transform: [{
translateY: visible.interpolate({
inputRange: [0, 1],
outputRange: [layout.height + paddingBottom + _reactNative.StyleSheet.hairlineWidth, 0]
})
}],
// Absolutely position the tab bar so that the content is below it
// This is needed to avoid gap at bottom when the tab bar is hidden
position: isTabBarHidden ? 'absolute' : null
}, {
height: tabBarHeight,
paddingBottom,
paddingHorizontal: Math.max(insets.left, insets.right)
}, tabBarStyle],
pointerEvents: isTabBarHidden ? 'none' : 'auto',
onLayout: handleLayout
}, /*#__PURE__*/_react.default.createElement(_reactNative.View, {
pointerEvents: "none",
style: _reactNative.StyleSheet.absoluteFill
}, tabBarBackgroundElement), /*#__PURE__*/_react.default.createElement(_reactNative.View, {
accessibilityRole: "tablist",
style: styles.content
}, routes.map((route, index) => {
const focused = index === state.index;
const {
options
} = descriptors[route.key];
const onPress = () => {
const event = navigation.emit({
type: 'tabPress',
target: route.key,
canPreventDefault: true
});
if (!focused && !event.defaultPrevented) {
navigation.dispatch({
..._native.CommonActions.navigate({
name: route.name,
merge: true
}),
target: state.key
});
}
};
const onLongPress = () => {
navigation.emit({
type: 'tabLongPress',
target: route.key
});
};
const label = options.tabBarLabel !== undefined ? options.tabBarLabel : options.title !== undefined ? options.title : route.name;
const accessibilityLabel = options.tabBarAccessibilityLabel !== undefined ? options.tabBarAccessibilityLabel : typeof label === 'string' && _reactNative.Platform.OS === 'ios' ? `${label}, tab, ${index + 1} of ${routes.length}` : undefined;
return /*#__PURE__*/_react.default.createElement(_native.NavigationContext.Provider, {
key: route.key,
value: descriptors[route.key].navigation
}, /*#__PURE__*/_react.default.createElement(_native.NavigationRouteContext.Provider, {
value: route
}, /*#__PURE__*/_react.default.createElement(_BottomTabItem.default, {
route: route,
descriptor: descriptors[route.key],
focused: focused,
horizontal: hasHorizontalLabels,
onPress: onPress,
onLongPress: onLongPress,
accessibilityLabel: accessibilityLabel,
to: buildLink(route.name, route.params),
testID: options.tabBarTestID,
allowFontScaling: options.tabBarAllowFontScaling,
activeTintColor: tabBarActiveTintColor,
inactiveTintColor: tabBarInactiveTintColor,
activeBackgroundColor: tabBarActiveBackgroundColor,
inactiveBackgroundColor: tabBarInactiveBackgroundColor,
button: options.tabBarButton,
icon: options.tabBarIcon ?? (_ref5 => {
let {
color,
size
} = _ref5;
return /*#__PURE__*/_react.default.createElement(_elements.MissingIcon, {
color: color,
size: size
});
}),
badge: options.tabBarBadge,
badgeStyle: options.tabBarBadgeStyle,
label: label,
showLabel: tabBarShowLabel,
labelStyle: options.tabBarLabelStyle,
iconStyle: options.tabBarIconStyle,
style: options.tabBarItemStyle
})));
})));
}
const styles = _reactNative.StyleSheet.create({
tabBar: {
left: 0,
right: 0,
bottom: 0,
borderTopWidth: _reactNative.StyleSheet.hairlineWidth,
elevation: 8
},
content: {
flex: 1,
flexDirection: 'row'
}
});
//# sourceMappingURL=BottomTabBar.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,183 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = BottomTabBarItem;
var _native = require("@react-navigation/native");
var _color = _interopRequireDefault(require("color"));
var _react = _interopRequireDefault(require("react"));
var _reactNative = require("react-native");
var _TabBarIcon = _interopRequireDefault(require("./TabBarIcon"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function BottomTabBarItem(_ref) {
let {
focused,
route,
descriptor,
label,
icon,
badge,
badgeStyle,
to,
button = _ref2 => {
let {
children,
style,
onPress,
to,
accessibilityRole,
...rest
} = _ref2;
if (_reactNative.Platform.OS === 'web' && to) {
// React Native Web doesn't forward `onClick` if we use `TouchableWithoutFeedback`.
// We need to use `onClick` to be able to prevent default browser handling of links.
return /*#__PURE__*/_react.default.createElement(_native.Link, _extends({}, rest, {
to: to,
style: [styles.button, style],
onPress: e => {
if (!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey) && (
// ignore clicks with modifier keys
e.button == null || e.button === 0) // ignore everything but left clicks
) {
e.preventDefault();
onPress === null || onPress === void 0 ? void 0 : onPress(e);
}
}
}), children);
} else {
return /*#__PURE__*/_react.default.createElement(_reactNative.Pressable, _extends({}, rest, {
accessibilityRole: accessibilityRole,
onPress: onPress,
style: style
}), children);
}
},
accessibilityLabel,
testID,
onPress,
onLongPress,
horizontal,
activeTintColor: customActiveTintColor,
inactiveTintColor: customInactiveTintColor,
activeBackgroundColor = 'transparent',
inactiveBackgroundColor = 'transparent',
showLabel = true,
allowFontScaling,
labelStyle,
iconStyle,
style
} = _ref;
const {
colors
} = (0, _native.useTheme)();
const activeTintColor = customActiveTintColor === undefined ? colors.primary : customActiveTintColor;
const inactiveTintColor = customInactiveTintColor === undefined ? (0, _color.default)(colors.text).mix((0, _color.default)(colors.card), 0.5).hex() : customInactiveTintColor;
const renderLabel = _ref3 => {
let {
focused
} = _ref3;
if (showLabel === false) {
return null;
}
const color = focused ? activeTintColor : inactiveTintColor;
if (typeof label === 'string') {
return /*#__PURE__*/_react.default.createElement(_reactNative.Text, {
numberOfLines: 1,
style: [styles.label, {
color
}, horizontal ? styles.labelBeside : styles.labelBeneath, labelStyle],
allowFontScaling: allowFontScaling
}, label);
}
const {
options
} = descriptor;
const children = typeof options.tabBarLabel === 'string' ? options.tabBarLabel : options.title !== undefined ? options.title : route.name;
return label({
focused,
color,
position: horizontal ? 'beside-icon' : 'below-icon',
children
});
};
const renderIcon = _ref4 => {
let {
focused
} = _ref4;
if (icon === undefined) {
return null;
}
const activeOpacity = focused ? 1 : 0;
const inactiveOpacity = focused ? 0 : 1;
return /*#__PURE__*/_react.default.createElement(_TabBarIcon.default, {
route: route,
horizontal: horizontal,
badge: badge,
badgeStyle: badgeStyle,
activeOpacity: activeOpacity,
inactiveOpacity: inactiveOpacity,
activeTintColor: activeTintColor,
inactiveTintColor: inactiveTintColor,
renderIcon: icon,
style: iconStyle
});
};
const scene = {
route,
focused
};
const backgroundColor = focused ? activeBackgroundColor : inactiveBackgroundColor;
return button({
to,
onPress,
onLongPress,
testID,
accessibilityLabel,
// FIXME: accessibilityRole: 'tab' doesn't seem to work as expected on iOS
accessibilityRole: _reactNative.Platform.select({
ios: 'button',
default: 'tab'
}),
accessibilityState: {
selected: focused
},
// @ts-expect-error: keep for compatibility with older React Native versions
accessibilityStates: focused ? ['selected'] : [],
style: [styles.tab, {
backgroundColor
}, horizontal ? styles.tabLandscape : styles.tabPortrait, style],
children: /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, renderIcon(scene), renderLabel(scene))
});
}
const styles = _reactNative.StyleSheet.create({
tab: {
flex: 1,
alignItems: 'center'
},
tabPortrait: {
justifyContent: 'flex-end',
flexDirection: 'column'
},
tabLandscape: {
justifyContent: 'center',
flexDirection: 'row'
},
label: {
textAlign: 'center',
backgroundColor: 'transparent'
},
labelBeneath: {
fontSize: 10
},
labelBeside: {
fontSize: 13,
marginLeft: 20,
marginTop: 3
},
button: {
display: 'flex'
}
});
//# sourceMappingURL=BottomTabItem.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["BottomTabBarItem","focused","route","descriptor","label","icon","badge","badgeStyle","to","button","children","style","onPress","accessibilityRole","rest","Platform","OS","styles","e","metaKey","altKey","ctrlKey","shiftKey","preventDefault","accessibilityLabel","testID","onLongPress","horizontal","activeTintColor","customActiveTintColor","inactiveTintColor","customInactiveTintColor","activeBackgroundColor","inactiveBackgroundColor","showLabel","allowFontScaling","labelStyle","iconStyle","colors","useTheme","undefined","primary","Color","text","mix","card","hex","renderLabel","color","labelBeside","labelBeneath","options","tabBarLabel","title","name","position","renderIcon","activeOpacity","inactiveOpacity","scene","backgroundColor","select","ios","default","accessibilityState","selected","accessibilityStates","tab","tabLandscape","tabPortrait","StyleSheet","create","flex","alignItems","justifyContent","flexDirection","textAlign","fontSize","marginLeft","marginTop","display"],"sourceRoot":"../../../src","sources":["views/BottomTabItem.tsx"],"mappings":"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"}

View File

@@ -0,0 +1,134 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = BottomTabView;
var _elements = require("@react-navigation/elements");
var React = _interopRequireWildcard(require("react"));
var _reactNative = require("react-native");
var _reactNativeSafeAreaContext = require("react-native-safe-area-context");
var _BottomTabBarHeightCallbackContext = _interopRequireDefault(require("../utils/BottomTabBarHeightCallbackContext"));
var _BottomTabBarHeightContext = _interopRequireDefault(require("../utils/BottomTabBarHeightContext"));
var _BottomTabBar = _interopRequireWildcard(require("./BottomTabBar"));
var _ScreenFallback = require("./ScreenFallback");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function BottomTabView(props) {
const {
tabBar = props => /*#__PURE__*/React.createElement(_BottomTabBar.default, props),
state,
navigation,
descriptors,
safeAreaInsets,
detachInactiveScreens = _reactNative.Platform.OS === 'web' || _reactNative.Platform.OS === 'android' || _reactNative.Platform.OS === 'ios',
sceneContainerStyle
} = props;
const focusedRouteKey = state.routes[state.index].key;
const [loaded, setLoaded] = React.useState([focusedRouteKey]);
if (!loaded.includes(focusedRouteKey)) {
setLoaded([...loaded, focusedRouteKey]);
}
const dimensions = _elements.SafeAreaProviderCompat.initialMetrics.frame;
const [tabBarHeight, setTabBarHeight] = React.useState(() => (0, _BottomTabBar.getTabBarHeight)({
state,
descriptors,
dimensions,
layout: {
width: dimensions.width,
height: 0
},
insets: {
..._elements.SafeAreaProviderCompat.initialMetrics.insets,
...props.safeAreaInsets
},
style: descriptors[state.routes[state.index].key].options.tabBarStyle
}));
const renderTabBar = () => {
return /*#__PURE__*/React.createElement(_reactNativeSafeAreaContext.SafeAreaInsetsContext.Consumer, null, insets => tabBar({
state: state,
descriptors: descriptors,
navigation: navigation,
insets: {
top: (safeAreaInsets === null || safeAreaInsets === void 0 ? void 0 : safeAreaInsets.top) ?? (insets === null || insets === void 0 ? void 0 : insets.top) ?? 0,
right: (safeAreaInsets === null || safeAreaInsets === void 0 ? void 0 : safeAreaInsets.right) ?? (insets === null || insets === void 0 ? void 0 : insets.right) ?? 0,
bottom: (safeAreaInsets === null || safeAreaInsets === void 0 ? void 0 : safeAreaInsets.bottom) ?? (insets === null || insets === void 0 ? void 0 : insets.bottom) ?? 0,
left: (safeAreaInsets === null || safeAreaInsets === void 0 ? void 0 : safeAreaInsets.left) ?? (insets === null || insets === void 0 ? void 0 : insets.left) ?? 0
}
}));
};
const {
routes
} = state;
return /*#__PURE__*/React.createElement(_elements.SafeAreaProviderCompat, null, /*#__PURE__*/React.createElement(_ScreenFallback.MaybeScreenContainer, {
enabled: detachInactiveScreens,
hasTwoStates: true,
style: styles.container
}, routes.map((route, index) => {
const descriptor = descriptors[route.key];
const {
lazy = true,
unmountOnBlur
} = descriptor.options;
const isFocused = state.index === index;
if (unmountOnBlur && !isFocused) {
return null;
}
if (lazy && !loaded.includes(route.key) && !isFocused) {
// Don't render a lazy screen if we've never navigated to it
return null;
}
const {
freezeOnBlur,
header = _ref => {
let {
layout,
options
} = _ref;
return /*#__PURE__*/React.createElement(_elements.Header, _extends({}, options, {
layout: layout,
title: (0, _elements.getHeaderTitle)(options, route.name)
}));
},
headerShown,
headerStatusBarHeight,
headerTransparent
} = descriptor.options;
return /*#__PURE__*/React.createElement(_ScreenFallback.MaybeScreen, {
key: route.key,
style: [_reactNative.StyleSheet.absoluteFill, {
zIndex: isFocused ? 0 : -1
}],
visible: isFocused,
enabled: detachInactiveScreens,
freezeOnBlur: freezeOnBlur
}, /*#__PURE__*/React.createElement(_BottomTabBarHeightContext.default.Provider, {
value: tabBarHeight
}, /*#__PURE__*/React.createElement(_elements.Screen, {
focused: isFocused,
route: descriptor.route,
navigation: descriptor.navigation,
headerShown: headerShown,
headerStatusBarHeight: headerStatusBarHeight,
headerTransparent: headerTransparent,
header: header({
layout: dimensions,
route: descriptor.route,
navigation: descriptor.navigation,
options: descriptor.options
}),
style: sceneContainerStyle
}, descriptor.render())));
})), /*#__PURE__*/React.createElement(_BottomTabBarHeightCallbackContext.default.Provider, {
value: setTabBarHeight
}, renderTabBar()));
}
const styles = _reactNative.StyleSheet.create({
container: {
flex: 1,
overflow: 'hidden'
}
});
//# sourceMappingURL=BottomTabView.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["BottomTabView","props","tabBar","state","navigation","descriptors","safeAreaInsets","detachInactiveScreens","Platform","OS","sceneContainerStyle","focusedRouteKey","routes","index","key","loaded","setLoaded","React","useState","includes","dimensions","SafeAreaProviderCompat","initialMetrics","frame","tabBarHeight","setTabBarHeight","getTabBarHeight","layout","width","height","insets","style","options","tabBarStyle","renderTabBar","top","right","bottom","left","styles","container","map","route","descriptor","lazy","unmountOnBlur","isFocused","freezeOnBlur","header","getHeaderTitle","name","headerShown","headerStatusBarHeight","headerTransparent","StyleSheet","absoluteFill","zIndex","render","create","flex","overflow"],"sourceRoot":"../../../src","sources":["views/BottomTabView.tsx"],"mappings":"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"}

View File

@@ -0,0 +1,50 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.MaybeScreen = MaybeScreen;
exports.MaybeScreenContainer = void 0;
var _elements = require("@react-navigation/elements");
var React = _interopRequireWildcard(require("react"));
var _reactNative = require("react-native");
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
let Screens;
try {
Screens = require('react-native-screens');
} catch (e) {
// Ignore
}
const MaybeScreenContainer = _ref => {
var _Screens, _Screens$screensEnabl;
let {
enabled,
...rest
} = _ref;
if ((_Screens = Screens) !== null && _Screens !== void 0 && (_Screens$screensEnabl = _Screens.screensEnabled) !== null && _Screens$screensEnabl !== void 0 && _Screens$screensEnabl.call(_Screens)) {
return /*#__PURE__*/React.createElement(Screens.ScreenContainer, _extends({
enabled: enabled
}, rest));
}
return /*#__PURE__*/React.createElement(_reactNative.View, rest);
};
exports.MaybeScreenContainer = MaybeScreenContainer;
function MaybeScreen(_ref2) {
var _Screens2, _Screens2$screensEnab;
let {
visible,
children,
...rest
} = _ref2;
if ((_Screens2 = Screens) !== null && _Screens2 !== void 0 && (_Screens2$screensEnab = _Screens2.screensEnabled) !== null && _Screens2$screensEnab !== void 0 && _Screens2$screensEnab.call(_Screens2)) {
return /*#__PURE__*/React.createElement(Screens.Screen, _extends({
activityState: visible ? 2 : 0
}, rest), children);
}
return /*#__PURE__*/React.createElement(_elements.ResourceSavingView, _extends({
visible: visible
}, rest), children);
}
//# sourceMappingURL=ScreenFallback.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["Screens","require","e","MaybeScreenContainer","enabled","rest","screensEnabled","MaybeScreen","visible","children"],"sourceRoot":"../../../src","sources":["views/ScreenFallback.tsx"],"mappings":";;;;;;;AAAA;AACA;AACA;AAAqE;AAAA;AAAA;AAUrE,IAAIA,OAA0D;AAE9D,IAAI;EACFA,OAAO,GAAGC,OAAO,CAAC,sBAAsB,CAAC;AAC3C,CAAC,CAAC,OAAOC,CAAC,EAAE;EACV;AAAA;AAGK,MAAMC,oBAAoB,GAAG,QAO9B;EAAA;EAAA,IAP+B;IACnCC,OAAO;IACP,GAAGC;EAKL,CAAC;EACC,gBAAIL,OAAO,8DAAP,SAASM,cAAc,kDAAvB,oCAA2B,EAAE;IAC/B,oBAAO,oBAAC,OAAO,CAAC,eAAe;MAAC,OAAO,EAAEF;IAAQ,GAAKC,IAAI,EAAI;EAChE;EAEA,oBAAO,oBAAC,iBAAI,EAAKA,IAAI,CAAI;AAC3B,CAAC;AAAC;AAEK,SAASE,WAAW,QAAwC;EAAA;EAAA,IAAvC;IAAEC,OAAO;IAAEC,QAAQ;IAAE,GAAGJ;EAAY,CAAC;EAC/D,iBAAIL,OAAO,+DAAP,UAASM,cAAc,kDAAvB,qCAA2B,EAAE;IAC/B,oBACE,oBAAC,OAAO,CAAC,MAAM;MAAC,aAAa,EAAEE,OAAO,GAAG,CAAC,GAAG;IAAE,GAAKH,IAAI,GACrDI,QAAQ,CACM;EAErB;EAEA,oBACE,oBAAC,4BAAkB;IAAC,OAAO,EAAED;EAAQ,GAAKH,IAAI,GAC3CI,QAAQ,CACU;AAEzB"}

View File

@@ -0,0 +1,84 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = TabBarIcon;
var _react = _interopRequireDefault(require("react"));
var _reactNative = require("react-native");
var _Badge = _interopRequireDefault(require("./Badge"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function TabBarIcon(_ref) {
let {
route: _,
horizontal,
badge,
badgeStyle,
activeOpacity,
inactiveOpacity,
activeTintColor,
inactiveTintColor,
renderIcon,
style
} = _ref;
const size = 25;
// We render the icon twice at the same position on top of each other:
// active and inactive one, so we can fade between them.
return /*#__PURE__*/_react.default.createElement(_reactNative.View, {
style: [horizontal ? styles.iconHorizontal : styles.iconVertical, style]
}, /*#__PURE__*/_react.default.createElement(_reactNative.View, {
style: [styles.icon, {
opacity: activeOpacity
}]
}, renderIcon({
focused: true,
size,
color: activeTintColor
})), /*#__PURE__*/_react.default.createElement(_reactNative.View, {
style: [styles.icon, {
opacity: inactiveOpacity
}]
}, renderIcon({
focused: false,
size,
color: inactiveTintColor
})), /*#__PURE__*/_react.default.createElement(_Badge.default, {
visible: badge != null,
style: [styles.badge, horizontal ? styles.badgeHorizontal : styles.badgeVertical, badgeStyle],
size: size * 3 / 4
}, badge));
}
const styles = _reactNative.StyleSheet.create({
icon: {
// We render the icon twice at the same position on top of each other:
// active and inactive one, so we can fade between them:
// Cover the whole iconContainer:
position: 'absolute',
alignSelf: 'center',
alignItems: 'center',
justifyContent: 'center',
height: '100%',
width: '100%',
// Workaround for react-native >= 0.54 layout bug
minWidth: 25
},
iconVertical: {
flex: 1
},
iconHorizontal: {
height: '100%',
marginTop: 3
},
badge: {
position: 'absolute',
left: 3
},
badgeVertical: {
top: 3
},
badgeHorizontal: {
top: 7
}
});
//# sourceMappingURL=TabBarIcon.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["TabBarIcon","route","_","horizontal","badge","badgeStyle","activeOpacity","inactiveOpacity","activeTintColor","inactiveTintColor","renderIcon","style","size","styles","iconHorizontal","iconVertical","icon","opacity","focused","color","badgeHorizontal","badgeVertical","StyleSheet","create","position","alignSelf","alignItems","justifyContent","height","width","minWidth","flex","marginTop","left","top"],"sourceRoot":"../../../src","sources":["views/TabBarIcon.tsx"],"mappings":";;;;;;AACA;AACA;AAQA;AAA4B;AAmBb,SAASA,UAAU,OAWxB;EAAA,IAXyB;IACjCC,KAAK,EAAEC,CAAC;IACRC,UAAU;IACVC,KAAK;IACLC,UAAU;IACVC,aAAa;IACbC,eAAe;IACfC,eAAe;IACfC,iBAAiB;IACjBC,UAAU;IACVC;EACK,CAAC;EACN,MAAMC,IAAI,GAAG,EAAE;;EAEf;EACA;EACA,oBACE,6BAAC,iBAAI;IACH,KAAK,EAAE,CAACT,UAAU,GAAGU,MAAM,CAACC,cAAc,GAAGD,MAAM,CAACE,YAAY,EAAEJ,KAAK;EAAE,gBAEzE,6BAAC,iBAAI;IAAC,KAAK,EAAE,CAACE,MAAM,CAACG,IAAI,EAAE;MAAEC,OAAO,EAAEX;IAAc,CAAC;EAAE,GACpDI,UAAU,CAAC;IACVQ,OAAO,EAAE,IAAI;IACbN,IAAI;IACJO,KAAK,EAAEX;EACT,CAAC,CAAC,CACG,eACP,6BAAC,iBAAI;IAAC,KAAK,EAAE,CAACK,MAAM,CAACG,IAAI,EAAE;MAAEC,OAAO,EAAEV;IAAgB,CAAC;EAAE,GACtDG,UAAU,CAAC;IACVQ,OAAO,EAAE,KAAK;IACdN,IAAI;IACJO,KAAK,EAAEV;EACT,CAAC,CAAC,CACG,eACP,6BAAC,cAAK;IACJ,OAAO,EAAEL,KAAK,IAAI,IAAK;IACvB,KAAK,EAAE,CACLS,MAAM,CAACT,KAAK,EACZD,UAAU,GAAGU,MAAM,CAACO,eAAe,GAAGP,MAAM,CAACQ,aAAa,EAC1DhB,UAAU,CACV;IACF,IAAI,EAAGO,IAAI,GAAG,CAAC,GAAI;EAAE,GAEpBR,KAAK,CACA,CACH;AAEX;AAEA,MAAMS,MAAM,GAAGS,uBAAU,CAACC,MAAM,CAAC;EAC/BP,IAAI,EAAE;IACJ;IACA;IACA;IACAQ,QAAQ,EAAE,UAAU;IACpBC,SAAS,EAAE,QAAQ;IACnBC,UAAU,EAAE,QAAQ;IACpBC,cAAc,EAAE,QAAQ;IACxBC,MAAM,EAAE,MAAM;IACdC,KAAK,EAAE,MAAM;IACb;IACAC,QAAQ,EAAE;EACZ,CAAC;EACDf,YAAY,EAAE;IACZgB,IAAI,EAAE;EACR,CAAC;EACDjB,cAAc,EAAE;IACdc,MAAM,EAAE,MAAM;IACdI,SAAS,EAAE;EACb,CAAC;EACD5B,KAAK,EAAE;IACLoB,QAAQ,EAAE,UAAU;IACpBS,IAAI,EAAE;EACR,CAAC;EACDZ,aAAa,EAAE;IACba,GAAG,EAAE;EACP,CAAC;EACDd,eAAe,EAAE;IACfc,GAAG,EAAE;EACP;AACF,CAAC,CAAC"}

View File

@@ -0,0 +1,22 @@
/**
* Navigators
*/
export { default as createBottomTabNavigator } from './navigators/createBottomTabNavigator';
/**
* Views
*/
export { default as BottomTabBar } from './views/BottomTabBar';
export { default as BottomTabView } from './views/BottomTabView';
/**
* Utilities
*/
export { default as BottomTabBarHeightCallbackContext } from './utils/BottomTabBarHeightCallbackContext';
export { default as BottomTabBarHeightContext } from './utils/BottomTabBarHeightContext';
export { default as useBottomTabBarHeight } from './utils/useBottomTabBarHeight';
/**
* Types
*/
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["default","createBottomTabNavigator","BottomTabBar","BottomTabView","BottomTabBarHeightCallbackContext","BottomTabBarHeightContext","useBottomTabBarHeight"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"AAAA;AACA;AACA;AACA,SAASA,OAAO,IAAIC,wBAAwB,QAAQ,uCAAuC;;AAE3F;AACA;AACA;AACA,SAASD,OAAO,IAAIE,YAAY,QAAQ,sBAAsB;AAC9D,SAASF,OAAO,IAAIG,aAAa,QAAQ,uBAAuB;;AAEhE;AACA;AACA;AACA,SAASH,OAAO,IAAII,iCAAiC,QAAQ,2CAA2C;AACxG,SAASJ,OAAO,IAAIK,yBAAyB,QAAQ,mCAAmC;AACxF,SAASL,OAAO,IAAIM,qBAAqB,QAAQ,+BAA+B;;AAEhF;AACA;AACA"}

View File

@@ -0,0 +1,76 @@
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
import { createNavigatorFactory, TabRouter, useNavigationBuilder } from '@react-navigation/native';
import * as React from 'react';
import warnOnce from 'warn-once';
import BottomTabView from '../views/BottomTabView';
function BottomTabNavigator(_ref) {
let {
id,
initialRouteName,
backBehavior,
children,
screenListeners,
screenOptions,
sceneContainerStyle,
...restWithDeprecated
} = _ref;
const {
// @ts-expect-error: lazy is deprecated
lazy,
// @ts-expect-error: tabBarOptions is deprecated
tabBarOptions,
...rest
} = restWithDeprecated;
let defaultScreenOptions = {};
if (tabBarOptions) {
Object.assign(defaultScreenOptions, {
tabBarHideOnKeyboard: tabBarOptions.keyboardHidesTabBar,
tabBarActiveTintColor: tabBarOptions.activeTintColor,
tabBarInactiveTintColor: tabBarOptions.inactiveTintColor,
tabBarActiveBackgroundColor: tabBarOptions.activeBackgroundColor,
tabBarInactiveBackgroundColor: tabBarOptions.inactiveBackgroundColor,
tabBarAllowFontScaling: tabBarOptions.allowFontScaling,
tabBarShowLabel: tabBarOptions.showLabel,
tabBarLabelStyle: tabBarOptions.labelStyle,
tabBarIconStyle: tabBarOptions.iconStyle,
tabBarItemStyle: tabBarOptions.tabStyle,
tabBarLabelPosition: tabBarOptions.labelPosition ?? (tabBarOptions.adaptive === false ? 'below-icon' : undefined),
tabBarStyle: [{
display: tabBarOptions.tabBarVisible ? 'none' : 'flex'
}, defaultScreenOptions.tabBarStyle]
});
Object.keys(defaultScreenOptions).forEach(key => {
if (defaultScreenOptions[key] === undefined) {
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete defaultScreenOptions[key];
}
});
warnOnce(tabBarOptions, `Bottom Tab Navigator: 'tabBarOptions' is deprecated. Migrate the options to 'screenOptions' instead.\n\nPlace the following in 'screenOptions' in your code to keep current behavior:\n\n${JSON.stringify(defaultScreenOptions, null, 2)}\n\nSee https://reactnavigation.org/docs/bottom-tab-navigator#options for more details.`);
}
if (typeof lazy === 'boolean') {
defaultScreenOptions.lazy = lazy;
warnOnce(true, `Bottom Tab Navigator: 'lazy' in props is deprecated. Move it to 'screenOptions' instead.\n\nSee https://reactnavigation.org/docs/bottom-tab-navigator/#lazy for more details.`);
}
const {
state,
descriptors,
navigation,
NavigationContent
} = useNavigationBuilder(TabRouter, {
id,
initialRouteName,
backBehavior,
children,
screenListeners,
screenOptions,
defaultScreenOptions
});
return /*#__PURE__*/React.createElement(NavigationContent, null, /*#__PURE__*/React.createElement(BottomTabView, _extends({}, rest, {
state: state,
navigation: navigation,
descriptors: descriptors,
sceneContainerStyle: sceneContainerStyle
})));
}
export default createNavigatorFactory(BottomTabNavigator);
//# sourceMappingURL=createBottomTabNavigator.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["createNavigatorFactory","TabRouter","useNavigationBuilder","React","warnOnce","BottomTabView","BottomTabNavigator","id","initialRouteName","backBehavior","children","screenListeners","screenOptions","sceneContainerStyle","restWithDeprecated","lazy","tabBarOptions","rest","defaultScreenOptions","Object","assign","tabBarHideOnKeyboard","keyboardHidesTabBar","tabBarActiveTintColor","activeTintColor","tabBarInactiveTintColor","inactiveTintColor","tabBarActiveBackgroundColor","activeBackgroundColor","tabBarInactiveBackgroundColor","inactiveBackgroundColor","tabBarAllowFontScaling","allowFontScaling","tabBarShowLabel","showLabel","tabBarLabelStyle","labelStyle","tabBarIconStyle","iconStyle","tabBarItemStyle","tabStyle","tabBarLabelPosition","labelPosition","adaptive","undefined","tabBarStyle","display","tabBarVisible","keys","forEach","key","JSON","stringify","state","descriptors","navigation","NavigationContent"],"sourceRoot":"../../../src","sources":["navigators/createBottomTabNavigator.tsx"],"mappings":";AAAA,SACEA,sBAAsB,EAKtBC,SAAS,EAETC,oBAAoB,QACf,0BAA0B;AACjC,OAAO,KAAKC,KAAK,MAAM,OAAO;AAC9B,OAAOC,QAAQ,MAAM,WAAW;AAOhC,OAAOC,aAAa,MAAM,wBAAwB;AAWlD,SAASC,kBAAkB,OASjB;EAAA,IATkB;IAC1BC,EAAE;IACFC,gBAAgB;IAChBC,YAAY;IACZC,QAAQ;IACRC,eAAe;IACfC,aAAa;IACbC,mBAAmB;IACnB,GAAGC;EACE,CAAC;EACN,MAAM;IACJ;IACAC,IAAI;IACJ;IACAC,aAAa;IACb,GAAGC;EACL,CAAC,GAAGH,kBAAkB;EAEtB,IAAII,oBAAgD,GAAG,CAAC,CAAC;EAEzD,IAAIF,aAAa,EAAE;IACjBG,MAAM,CAACC,MAAM,CAACF,oBAAoB,EAAE;MAClCG,oBAAoB,EAAEL,aAAa,CAACM,mBAAmB;MACvDC,qBAAqB,EAAEP,aAAa,CAACQ,eAAe;MACpDC,uBAAuB,EAAET,aAAa,CAACU,iBAAiB;MACxDC,2BAA2B,EAAEX,aAAa,CAACY,qBAAqB;MAChEC,6BAA6B,EAAEb,aAAa,CAACc,uBAAuB;MACpEC,sBAAsB,EAAEf,aAAa,CAACgB,gBAAgB;MACtDC,eAAe,EAAEjB,aAAa,CAACkB,SAAS;MACxCC,gBAAgB,EAAEnB,aAAa,CAACoB,UAAU;MAC1CC,eAAe,EAAErB,aAAa,CAACsB,SAAS;MACxCC,eAAe,EAAEvB,aAAa,CAACwB,QAAQ;MACvCC,mBAAmB,EACjBzB,aAAa,CAAC0B,aAAa,KAC1B1B,aAAa,CAAC2B,QAAQ,KAAK,KAAK,GAAG,YAAY,GAAGC,SAAS,CAAC;MAC/DC,WAAW,EAAE,CACX;QAAEC,OAAO,EAAE9B,aAAa,CAAC+B,aAAa,GAAG,MAAM,GAAG;MAAO,CAAC,EAC1D7B,oBAAoB,CAAC2B,WAAW;IAEpC,CAAC,CAAC;IAGA1B,MAAM,CAAC6B,IAAI,CAAC9B,oBAAoB,CAAC,CACjC+B,OAAO,CAAEC,GAAG,IAAK;MACjB,IAAIhC,oBAAoB,CAACgC,GAAG,CAAC,KAAKN,SAAS,EAAE;QAC3C;QACA,OAAO1B,oBAAoB,CAACgC,GAAG,CAAC;MAClC;IACF,CAAC,CAAC;IAEF9C,QAAQ,CACNY,aAAa,EACZ,4LAA2LmC,IAAI,CAACC,SAAS,CACxMlC,oBAAoB,EACpB,IAAI,EACJ,CAAC,CACD,yFAAwF,CAC3F;EACH;EAEA,IAAI,OAAOH,IAAI,KAAK,SAAS,EAAE;IAC7BG,oBAAoB,CAACH,IAAI,GAAGA,IAAI;IAEhCX,QAAQ,CACN,IAAI,EACH,+KAA8K,CAChL;EACH;EAEA,MAAM;IAAEiD,KAAK;IAAEC,WAAW;IAAEC,UAAU;IAAEC;EAAkB,CAAC,GACzDtD,oBAAoB,CAMlBD,SAAS,EAAE;IACXM,EAAE;IACFC,gBAAgB;IAChBC,YAAY;IACZC,QAAQ;IACRC,eAAe;IACfC,aAAa;IACbM;EACF,CAAC,CAAC;EAEJ,oBACE,oBAAC,iBAAiB,qBAChB,oBAAC,aAAa,eACRD,IAAI;IACR,KAAK,EAAEoC,KAAM;IACb,UAAU,EAAEE,UAAW;IACvB,WAAW,EAAED,WAAY;IACzB,mBAAmB,EAAEzC;EAAoB,GACzC,CACgB;AAExB;AAEA,eAAeb,sBAAsB,CAKnCM,kBAAkB,CAAC"}

View File

@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=types.js.map

View File

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

View File

@@ -0,0 +1,3 @@
import * as React from 'react';
export default /*#__PURE__*/React.createContext(undefined);
//# sourceMappingURL=BottomTabBarHeightCallbackContext.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","createContext","undefined"],"sourceRoot":"../../../src","sources":["utils/BottomTabBarHeightCallbackContext.tsx"],"mappings":"AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAE9B,4BAAeA,KAAK,CAACC,aAAa,CAChCC,SAAS,CACV"}

View File

@@ -0,0 +1,3 @@
import * as React from 'react';
export default /*#__PURE__*/React.createContext(undefined);
//# sourceMappingURL=BottomTabBarHeightContext.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","createContext","undefined"],"sourceRoot":"../../../src","sources":["utils/BottomTabBarHeightContext.tsx"],"mappings":"AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAE9B,4BAAeA,KAAK,CAACC,aAAa,CAAqBC,SAAS,CAAC"}

View File

@@ -0,0 +1,10 @@
import * as React from 'react';
import BottomTabBarHeightContext from './BottomTabBarHeightContext';
export default function useBottomTabBarHeight() {
const height = React.useContext(BottomTabBarHeightContext);
if (height === undefined) {
throw new Error("Couldn't find the bottom tab bar height. Are you inside a screen in Bottom Tab Navigator?");
}
return height;
}
//# sourceMappingURL=useBottomTabBarHeight.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","BottomTabBarHeightContext","useBottomTabBarHeight","height","useContext","undefined","Error"],"sourceRoot":"../../../src","sources":["utils/useBottomTabBarHeight.tsx"],"mappings":"AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAE9B,OAAOC,yBAAyB,MAAM,6BAA6B;AAEnE,eAAe,SAASC,qBAAqB,GAAG;EAC9C,MAAMC,MAAM,GAAGH,KAAK,CAACI,UAAU,CAACH,yBAAyB,CAAC;EAE1D,IAAIE,MAAM,KAAKE,SAAS,EAAE;IACxB,MAAM,IAAIC,KAAK,CACb,2FAA2F,CAC5F;EACH;EAEA,OAAOH,MAAM;AACf"}

View File

@@ -0,0 +1,20 @@
import * as React from 'react';
import { Keyboard, Platform } from 'react-native';
export default function useIsKeyboardShown() {
const [isKeyboardShown, setIsKeyboardShown] = React.useState(false);
React.useEffect(() => {
const handleKeyboardShow = () => setIsKeyboardShown(true);
const handleKeyboardHide = () => setIsKeyboardShown(false);
let subscriptions;
if (Platform.OS === 'ios') {
subscriptions = [Keyboard.addListener('keyboardWillShow', handleKeyboardShow), Keyboard.addListener('keyboardWillHide', handleKeyboardHide)];
} else {
subscriptions = [Keyboard.addListener('keyboardDidShow', handleKeyboardShow), Keyboard.addListener('keyboardDidHide', handleKeyboardHide)];
}
return () => {
subscriptions.forEach(s => s.remove());
};
}, []);
return isKeyboardShown;
}
//# sourceMappingURL=useIsKeyboardShown.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","Keyboard","Platform","useIsKeyboardShown","isKeyboardShown","setIsKeyboardShown","useState","useEffect","handleKeyboardShow","handleKeyboardHide","subscriptions","OS","addListener","forEach","s","remove"],"sourceRoot":"../../../src","sources":["utils/useIsKeyboardShown.tsx"],"mappings":"AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAC9B,SAA8BC,QAAQ,EAAEC,QAAQ,QAAQ,cAAc;AAEtE,eAAe,SAASC,kBAAkB,GAAG;EAC3C,MAAM,CAACC,eAAe,EAAEC,kBAAkB,CAAC,GAAGL,KAAK,CAACM,QAAQ,CAAC,KAAK,CAAC;EAEnEN,KAAK,CAACO,SAAS,CAAC,MAAM;IACpB,MAAMC,kBAAkB,GAAG,MAAMH,kBAAkB,CAAC,IAAI,CAAC;IACzD,MAAMI,kBAAkB,GAAG,MAAMJ,kBAAkB,CAAC,KAAK,CAAC;IAE1D,IAAIK,aAAoC;IAExC,IAAIR,QAAQ,CAACS,EAAE,KAAK,KAAK,EAAE;MACzBD,aAAa,GAAG,CACdT,QAAQ,CAACW,WAAW,CAAC,kBAAkB,EAAEJ,kBAAkB,CAAC,EAC5DP,QAAQ,CAACW,WAAW,CAAC,kBAAkB,EAAEH,kBAAkB,CAAC,CAC7D;IACH,CAAC,MAAM;MACLC,aAAa,GAAG,CACdT,QAAQ,CAACW,WAAW,CAAC,iBAAiB,EAAEJ,kBAAkB,CAAC,EAC3DP,QAAQ,CAACW,WAAW,CAAC,iBAAiB,EAAEH,kBAAkB,CAAC,CAC5D;IACH;IAEA,OAAO,MAAM;MACXC,aAAa,CAACG,OAAO,CAAEC,CAAC,IAAKA,CAAC,CAACC,MAAM,EAAE,CAAC;IAC1C,CAAC;EACH,CAAC,EAAE,EAAE,CAAC;EAEN,OAAOX,eAAe;AACxB"}

View File

@@ -0,0 +1,79 @@
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
import { useTheme } from '@react-navigation/native';
import color from 'color';
import * as React from 'react';
import { Animated, StyleSheet } from 'react-native';
export default function Badge(_ref) {
let {
children,
style,
visible = true,
size = 18,
...rest
} = _ref;
const [opacity] = React.useState(() => new Animated.Value(visible ? 1 : 0));
const [rendered, setRendered] = React.useState(visible);
const theme = useTheme();
React.useEffect(() => {
if (!rendered) {
return;
}
Animated.timing(opacity, {
toValue: visible ? 1 : 0,
duration: 150,
useNativeDriver: true
}).start(_ref2 => {
let {
finished
} = _ref2;
if (finished && !visible) {
setRendered(false);
}
});
return () => opacity.stopAnimation();
}, [opacity, rendered, visible]);
if (!rendered) {
if (visible) {
setRendered(true);
} else {
return null;
}
}
// @ts-expect-error: backgroundColor definitely exists
const {
backgroundColor = theme.colors.notification,
...restStyle
} = StyleSheet.flatten(style) || {};
const textColor = color(backgroundColor).isLight() ? 'black' : 'white';
const borderRadius = size / 2;
const fontSize = Math.floor(size * 3 / 4);
return /*#__PURE__*/React.createElement(Animated.Text, _extends({
numberOfLines: 1,
style: [{
transform: [{
scale: opacity.interpolate({
inputRange: [0, 1],
outputRange: [0.5, 1]
})
}],
color: textColor,
lineHeight: size - 1,
height: size,
minWidth: size,
opacity,
backgroundColor,
fontSize,
borderRadius
}, styles.container, restStyle]
}, rest), children);
}
const styles = StyleSheet.create({
container: {
alignSelf: 'flex-end',
textAlign: 'center',
paddingHorizontal: 4,
overflow: 'hidden'
}
});
//# sourceMappingURL=Badge.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["useTheme","color","React","Animated","StyleSheet","Badge","children","style","visible","size","rest","opacity","useState","Value","rendered","setRendered","theme","useEffect","timing","toValue","duration","useNativeDriver","start","finished","stopAnimation","backgroundColor","colors","notification","restStyle","flatten","textColor","isLight","borderRadius","fontSize","Math","floor","transform","scale","interpolate","inputRange","outputRange","lineHeight","height","minWidth","styles","container","create","alignSelf","textAlign","paddingHorizontal","overflow"],"sourceRoot":"../../../src","sources":["views/Badge.tsx"],"mappings":"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"}

View File

@@ -0,0 +1,301 @@
import { MissingIcon } from '@react-navigation/elements';
import { CommonActions, NavigationContext, NavigationRouteContext, useLinkBuilder, useTheme } from '@react-navigation/native';
import React from 'react';
import { Animated, Platform, StyleSheet, View } from 'react-native';
import { useSafeAreaFrame } from 'react-native-safe-area-context';
import BottomTabBarHeightCallbackContext from '../utils/BottomTabBarHeightCallbackContext';
import useIsKeyboardShown from '../utils/useIsKeyboardShown';
import BottomTabItem from './BottomTabItem';
const DEFAULT_TABBAR_HEIGHT = 49;
const COMPACT_TABBAR_HEIGHT = 32;
const DEFAULT_MAX_TAB_ITEM_WIDTH = 125;
const useNativeDriver = Platform.OS !== 'web';
const shouldUseHorizontalLabels = _ref => {
let {
state,
descriptors,
layout,
dimensions
} = _ref;
const {
tabBarLabelPosition
} = descriptors[state.routes[state.index].key].options;
if (tabBarLabelPosition) {
switch (tabBarLabelPosition) {
case 'beside-icon':
return true;
case 'below-icon':
return false;
}
}
if (layout.width >= 768) {
// Screen size matches a tablet
const maxTabWidth = state.routes.reduce((acc, route) => {
const {
tabBarItemStyle
} = descriptors[route.key].options;
const flattenedStyle = StyleSheet.flatten(tabBarItemStyle);
if (flattenedStyle) {
if (typeof flattenedStyle.width === 'number') {
return acc + flattenedStyle.width;
} else if (typeof flattenedStyle.maxWidth === 'number') {
return acc + flattenedStyle.maxWidth;
}
}
return acc + DEFAULT_MAX_TAB_ITEM_WIDTH;
}, 0);
return maxTabWidth <= layout.width;
} else {
return dimensions.width > dimensions.height;
}
};
const getPaddingBottom = insets => Math.max(insets.bottom - Platform.select({
ios: 4,
default: 0
}), 0);
export const getTabBarHeight = _ref2 => {
var _StyleSheet$flatten;
let {
state,
descriptors,
dimensions,
insets,
style,
...rest
} = _ref2;
// @ts-ignore
const customHeight = (_StyleSheet$flatten = StyleSheet.flatten(style)) === null || _StyleSheet$flatten === void 0 ? void 0 : _StyleSheet$flatten.height;
if (typeof customHeight === 'number') {
return customHeight;
}
const isLandscape = dimensions.width > dimensions.height;
const horizontalLabels = shouldUseHorizontalLabels({
state,
descriptors,
dimensions,
...rest
});
const paddingBottom = getPaddingBottom(insets);
if (Platform.OS === 'ios' && !Platform.isPad && isLandscape && horizontalLabels) {
return COMPACT_TABBAR_HEIGHT + paddingBottom;
}
return DEFAULT_TABBAR_HEIGHT + paddingBottom;
};
export default function BottomTabBar(_ref3) {
let {
state,
navigation,
descriptors,
insets,
style
} = _ref3;
const {
colors
} = useTheme();
const buildLink = useLinkBuilder();
const focusedRoute = state.routes[state.index];
const focusedDescriptor = descriptors[focusedRoute.key];
const focusedOptions = focusedDescriptor.options;
const {
tabBarShowLabel,
tabBarHideOnKeyboard = false,
tabBarVisibilityAnimationConfig,
tabBarStyle,
tabBarBackground,
tabBarActiveTintColor,
tabBarInactiveTintColor,
tabBarActiveBackgroundColor,
tabBarInactiveBackgroundColor
} = focusedOptions;
const dimensions = useSafeAreaFrame();
const isKeyboardShown = useIsKeyboardShown();
const onHeightChange = React.useContext(BottomTabBarHeightCallbackContext);
const shouldShowTabBar = !(tabBarHideOnKeyboard && isKeyboardShown);
const visibilityAnimationConfigRef = React.useRef(tabBarVisibilityAnimationConfig);
React.useEffect(() => {
visibilityAnimationConfigRef.current = tabBarVisibilityAnimationConfig;
});
const [isTabBarHidden, setIsTabBarHidden] = React.useState(!shouldShowTabBar);
const [visible] = React.useState(() => new Animated.Value(shouldShowTabBar ? 1 : 0));
React.useEffect(() => {
const visibilityAnimationConfig = visibilityAnimationConfigRef.current;
if (shouldShowTabBar) {
var _visibilityAnimationC, _visibilityAnimationC2;
const animation = (visibilityAnimationConfig === null || visibilityAnimationConfig === void 0 ? void 0 : (_visibilityAnimationC = visibilityAnimationConfig.show) === null || _visibilityAnimationC === void 0 ? void 0 : _visibilityAnimationC.animation) === 'spring' ? Animated.spring : Animated.timing;
animation(visible, {
toValue: 1,
useNativeDriver,
duration: 250,
...(visibilityAnimationConfig === null || visibilityAnimationConfig === void 0 ? void 0 : (_visibilityAnimationC2 = visibilityAnimationConfig.show) === null || _visibilityAnimationC2 === void 0 ? void 0 : _visibilityAnimationC2.config)
}).start(_ref4 => {
let {
finished
} = _ref4;
if (finished) {
setIsTabBarHidden(false);
}
});
} else {
var _visibilityAnimationC3, _visibilityAnimationC4;
setIsTabBarHidden(true);
const animation = (visibilityAnimationConfig === null || visibilityAnimationConfig === void 0 ? void 0 : (_visibilityAnimationC3 = visibilityAnimationConfig.hide) === null || _visibilityAnimationC3 === void 0 ? void 0 : _visibilityAnimationC3.animation) === 'spring' ? Animated.spring : Animated.timing;
animation(visible, {
toValue: 0,
useNativeDriver,
duration: 200,
...(visibilityAnimationConfig === null || visibilityAnimationConfig === void 0 ? void 0 : (_visibilityAnimationC4 = visibilityAnimationConfig.hide) === null || _visibilityAnimationC4 === void 0 ? void 0 : _visibilityAnimationC4.config)
}).start();
}
return () => visible.stopAnimation();
}, [visible, shouldShowTabBar]);
const [layout, setLayout] = React.useState({
height: 0,
width: dimensions.width
});
const handleLayout = e => {
const {
height,
width
} = e.nativeEvent.layout;
onHeightChange === null || onHeightChange === void 0 ? void 0 : onHeightChange(height);
setLayout(layout => {
if (height === layout.height && width === layout.width) {
return layout;
} else {
return {
height,
width
};
}
});
};
const {
routes
} = state;
const paddingBottom = getPaddingBottom(insets);
const tabBarHeight = getTabBarHeight({
state,
descriptors,
insets,
dimensions,
layout,
style: [tabBarStyle, style]
});
const hasHorizontalLabels = shouldUseHorizontalLabels({
state,
descriptors,
dimensions,
layout
});
const tabBarBackgroundElement = tabBarBackground === null || tabBarBackground === void 0 ? void 0 : tabBarBackground();
return /*#__PURE__*/React.createElement(Animated.View, {
style: [styles.tabBar, {
backgroundColor: tabBarBackgroundElement != null ? 'transparent' : colors.card,
borderTopColor: colors.border
}, {
transform: [{
translateY: visible.interpolate({
inputRange: [0, 1],
outputRange: [layout.height + paddingBottom + StyleSheet.hairlineWidth, 0]
})
}],
// Absolutely position the tab bar so that the content is below it
// This is needed to avoid gap at bottom when the tab bar is hidden
position: isTabBarHidden ? 'absolute' : null
}, {
height: tabBarHeight,
paddingBottom,
paddingHorizontal: Math.max(insets.left, insets.right)
}, tabBarStyle],
pointerEvents: isTabBarHidden ? 'none' : 'auto',
onLayout: handleLayout
}, /*#__PURE__*/React.createElement(View, {
pointerEvents: "none",
style: StyleSheet.absoluteFill
}, tabBarBackgroundElement), /*#__PURE__*/React.createElement(View, {
accessibilityRole: "tablist",
style: styles.content
}, routes.map((route, index) => {
const focused = index === state.index;
const {
options
} = descriptors[route.key];
const onPress = () => {
const event = navigation.emit({
type: 'tabPress',
target: route.key,
canPreventDefault: true
});
if (!focused && !event.defaultPrevented) {
navigation.dispatch({
...CommonActions.navigate({
name: route.name,
merge: true
}),
target: state.key
});
}
};
const onLongPress = () => {
navigation.emit({
type: 'tabLongPress',
target: route.key
});
};
const label = options.tabBarLabel !== undefined ? options.tabBarLabel : options.title !== undefined ? options.title : route.name;
const accessibilityLabel = options.tabBarAccessibilityLabel !== undefined ? options.tabBarAccessibilityLabel : typeof label === 'string' && Platform.OS === 'ios' ? `${label}, tab, ${index + 1} of ${routes.length}` : undefined;
return /*#__PURE__*/React.createElement(NavigationContext.Provider, {
key: route.key,
value: descriptors[route.key].navigation
}, /*#__PURE__*/React.createElement(NavigationRouteContext.Provider, {
value: route
}, /*#__PURE__*/React.createElement(BottomTabItem, {
route: route,
descriptor: descriptors[route.key],
focused: focused,
horizontal: hasHorizontalLabels,
onPress: onPress,
onLongPress: onLongPress,
accessibilityLabel: accessibilityLabel,
to: buildLink(route.name, route.params),
testID: options.tabBarTestID,
allowFontScaling: options.tabBarAllowFontScaling,
activeTintColor: tabBarActiveTintColor,
inactiveTintColor: tabBarInactiveTintColor,
activeBackgroundColor: tabBarActiveBackgroundColor,
inactiveBackgroundColor: tabBarInactiveBackgroundColor,
button: options.tabBarButton,
icon: options.tabBarIcon ?? (_ref5 => {
let {
color,
size
} = _ref5;
return /*#__PURE__*/React.createElement(MissingIcon, {
color: color,
size: size
});
}),
badge: options.tabBarBadge,
badgeStyle: options.tabBarBadgeStyle,
label: label,
showLabel: tabBarShowLabel,
labelStyle: options.tabBarLabelStyle,
iconStyle: options.tabBarIconStyle,
style: options.tabBarItemStyle
})));
})));
}
const styles = StyleSheet.create({
tabBar: {
left: 0,
right: 0,
bottom: 0,
borderTopWidth: StyleSheet.hairlineWidth,
elevation: 8
},
content: {
flex: 1,
flexDirection: 'row'
}
});
//# sourceMappingURL=BottomTabBar.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,176 @@
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
import { Link, useTheme } from '@react-navigation/native';
import Color from 'color';
import React from 'react';
import { Platform, Pressable, StyleSheet, Text } from 'react-native';
import TabBarIcon from './TabBarIcon';
export default function BottomTabBarItem(_ref) {
let {
focused,
route,
descriptor,
label,
icon,
badge,
badgeStyle,
to,
button = _ref2 => {
let {
children,
style,
onPress,
to,
accessibilityRole,
...rest
} = _ref2;
if (Platform.OS === 'web' && to) {
// React Native Web doesn't forward `onClick` if we use `TouchableWithoutFeedback`.
// We need to use `onClick` to be able to prevent default browser handling of links.
return /*#__PURE__*/React.createElement(Link, _extends({}, rest, {
to: to,
style: [styles.button, style],
onPress: e => {
if (!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey) && (
// ignore clicks with modifier keys
e.button == null || e.button === 0) // ignore everything but left clicks
) {
e.preventDefault();
onPress === null || onPress === void 0 ? void 0 : onPress(e);
}
}
}), children);
} else {
return /*#__PURE__*/React.createElement(Pressable, _extends({}, rest, {
accessibilityRole: accessibilityRole,
onPress: onPress,
style: style
}), children);
}
},
accessibilityLabel,
testID,
onPress,
onLongPress,
horizontal,
activeTintColor: customActiveTintColor,
inactiveTintColor: customInactiveTintColor,
activeBackgroundColor = 'transparent',
inactiveBackgroundColor = 'transparent',
showLabel = true,
allowFontScaling,
labelStyle,
iconStyle,
style
} = _ref;
const {
colors
} = useTheme();
const activeTintColor = customActiveTintColor === undefined ? colors.primary : customActiveTintColor;
const inactiveTintColor = customInactiveTintColor === undefined ? Color(colors.text).mix(Color(colors.card), 0.5).hex() : customInactiveTintColor;
const renderLabel = _ref3 => {
let {
focused
} = _ref3;
if (showLabel === false) {
return null;
}
const color = focused ? activeTintColor : inactiveTintColor;
if (typeof label === 'string') {
return /*#__PURE__*/React.createElement(Text, {
numberOfLines: 1,
style: [styles.label, {
color
}, horizontal ? styles.labelBeside : styles.labelBeneath, labelStyle],
allowFontScaling: allowFontScaling
}, label);
}
const {
options
} = descriptor;
const children = typeof options.tabBarLabel === 'string' ? options.tabBarLabel : options.title !== undefined ? options.title : route.name;
return label({
focused,
color,
position: horizontal ? 'beside-icon' : 'below-icon',
children
});
};
const renderIcon = _ref4 => {
let {
focused
} = _ref4;
if (icon === undefined) {
return null;
}
const activeOpacity = focused ? 1 : 0;
const inactiveOpacity = focused ? 0 : 1;
return /*#__PURE__*/React.createElement(TabBarIcon, {
route: route,
horizontal: horizontal,
badge: badge,
badgeStyle: badgeStyle,
activeOpacity: activeOpacity,
inactiveOpacity: inactiveOpacity,
activeTintColor: activeTintColor,
inactiveTintColor: inactiveTintColor,
renderIcon: icon,
style: iconStyle
});
};
const scene = {
route,
focused
};
const backgroundColor = focused ? activeBackgroundColor : inactiveBackgroundColor;
return button({
to,
onPress,
onLongPress,
testID,
accessibilityLabel,
// FIXME: accessibilityRole: 'tab' doesn't seem to work as expected on iOS
accessibilityRole: Platform.select({
ios: 'button',
default: 'tab'
}),
accessibilityState: {
selected: focused
},
// @ts-expect-error: keep for compatibility with older React Native versions
accessibilityStates: focused ? ['selected'] : [],
style: [styles.tab, {
backgroundColor
}, horizontal ? styles.tabLandscape : styles.tabPortrait, style],
children: /*#__PURE__*/React.createElement(React.Fragment, null, renderIcon(scene), renderLabel(scene))
});
}
const styles = StyleSheet.create({
tab: {
flex: 1,
alignItems: 'center'
},
tabPortrait: {
justifyContent: 'flex-end',
flexDirection: 'column'
},
tabLandscape: {
justifyContent: 'center',
flexDirection: 'row'
},
label: {
textAlign: 'center',
backgroundColor: 'transparent'
},
labelBeneath: {
fontSize: 10
},
labelBeside: {
fontSize: 13,
marginLeft: 20,
marginTop: 3
},
button: {
display: 'flex'
}
});
//# sourceMappingURL=BottomTabItem.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,125 @@
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
import { getHeaderTitle, Header, SafeAreaProviderCompat, Screen } from '@react-navigation/elements';
import * as React from 'react';
import { Platform, StyleSheet } from 'react-native';
import { SafeAreaInsetsContext } from 'react-native-safe-area-context';
import BottomTabBarHeightCallbackContext from '../utils/BottomTabBarHeightCallbackContext';
import BottomTabBarHeightContext from '../utils/BottomTabBarHeightContext';
import BottomTabBar, { getTabBarHeight } from './BottomTabBar';
import { MaybeScreen, MaybeScreenContainer } from './ScreenFallback';
export default function BottomTabView(props) {
const {
tabBar = props => /*#__PURE__*/React.createElement(BottomTabBar, props),
state,
navigation,
descriptors,
safeAreaInsets,
detachInactiveScreens = Platform.OS === 'web' || Platform.OS === 'android' || Platform.OS === 'ios',
sceneContainerStyle
} = props;
const focusedRouteKey = state.routes[state.index].key;
const [loaded, setLoaded] = React.useState([focusedRouteKey]);
if (!loaded.includes(focusedRouteKey)) {
setLoaded([...loaded, focusedRouteKey]);
}
const dimensions = SafeAreaProviderCompat.initialMetrics.frame;
const [tabBarHeight, setTabBarHeight] = React.useState(() => getTabBarHeight({
state,
descriptors,
dimensions,
layout: {
width: dimensions.width,
height: 0
},
insets: {
...SafeAreaProviderCompat.initialMetrics.insets,
...props.safeAreaInsets
},
style: descriptors[state.routes[state.index].key].options.tabBarStyle
}));
const renderTabBar = () => {
return /*#__PURE__*/React.createElement(SafeAreaInsetsContext.Consumer, null, insets => tabBar({
state: state,
descriptors: descriptors,
navigation: navigation,
insets: {
top: (safeAreaInsets === null || safeAreaInsets === void 0 ? void 0 : safeAreaInsets.top) ?? (insets === null || insets === void 0 ? void 0 : insets.top) ?? 0,
right: (safeAreaInsets === null || safeAreaInsets === void 0 ? void 0 : safeAreaInsets.right) ?? (insets === null || insets === void 0 ? void 0 : insets.right) ?? 0,
bottom: (safeAreaInsets === null || safeAreaInsets === void 0 ? void 0 : safeAreaInsets.bottom) ?? (insets === null || insets === void 0 ? void 0 : insets.bottom) ?? 0,
left: (safeAreaInsets === null || safeAreaInsets === void 0 ? void 0 : safeAreaInsets.left) ?? (insets === null || insets === void 0 ? void 0 : insets.left) ?? 0
}
}));
};
const {
routes
} = state;
return /*#__PURE__*/React.createElement(SafeAreaProviderCompat, null, /*#__PURE__*/React.createElement(MaybeScreenContainer, {
enabled: detachInactiveScreens,
hasTwoStates: true,
style: styles.container
}, routes.map((route, index) => {
const descriptor = descriptors[route.key];
const {
lazy = true,
unmountOnBlur
} = descriptor.options;
const isFocused = state.index === index;
if (unmountOnBlur && !isFocused) {
return null;
}
if (lazy && !loaded.includes(route.key) && !isFocused) {
// Don't render a lazy screen if we've never navigated to it
return null;
}
const {
freezeOnBlur,
header = _ref => {
let {
layout,
options
} = _ref;
return /*#__PURE__*/React.createElement(Header, _extends({}, options, {
layout: layout,
title: getHeaderTitle(options, route.name)
}));
},
headerShown,
headerStatusBarHeight,
headerTransparent
} = descriptor.options;
return /*#__PURE__*/React.createElement(MaybeScreen, {
key: route.key,
style: [StyleSheet.absoluteFill, {
zIndex: isFocused ? 0 : -1
}],
visible: isFocused,
enabled: detachInactiveScreens,
freezeOnBlur: freezeOnBlur
}, /*#__PURE__*/React.createElement(BottomTabBarHeightContext.Provider, {
value: tabBarHeight
}, /*#__PURE__*/React.createElement(Screen, {
focused: isFocused,
route: descriptor.route,
navigation: descriptor.navigation,
headerShown: headerShown,
headerStatusBarHeight: headerStatusBarHeight,
headerTransparent: headerTransparent,
header: header({
layout: dimensions,
route: descriptor.route,
navigation: descriptor.navigation,
options: descriptor.options
}),
style: sceneContainerStyle
}, descriptor.render())));
})), /*#__PURE__*/React.createElement(BottomTabBarHeightCallbackContext.Provider, {
value: setTabBarHeight
}, renderTabBar()));
}
const styles = StyleSheet.create({
container: {
flex: 1,
overflow: 'hidden'
}
});
//# sourceMappingURL=BottomTabView.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["getHeaderTitle","Header","SafeAreaProviderCompat","Screen","React","Platform","StyleSheet","SafeAreaInsetsContext","BottomTabBarHeightCallbackContext","BottomTabBarHeightContext","BottomTabBar","getTabBarHeight","MaybeScreen","MaybeScreenContainer","BottomTabView","props","tabBar","state","navigation","descriptors","safeAreaInsets","detachInactiveScreens","OS","sceneContainerStyle","focusedRouteKey","routes","index","key","loaded","setLoaded","useState","includes","dimensions","initialMetrics","frame","tabBarHeight","setTabBarHeight","layout","width","height","insets","style","options","tabBarStyle","renderTabBar","top","right","bottom","left","styles","container","map","route","descriptor","lazy","unmountOnBlur","isFocused","freezeOnBlur","header","name","headerShown","headerStatusBarHeight","headerTransparent","absoluteFill","zIndex","render","create","flex","overflow"],"sourceRoot":"../../../src","sources":["views/BottomTabView.tsx"],"mappings":"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"}

View File

@@ -0,0 +1,40 @@
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
import { ResourceSavingView } from '@react-navigation/elements';
import * as React from 'react';
import { View } from 'react-native';
let Screens;
try {
Screens = require('react-native-screens');
} catch (e) {
// Ignore
}
export const MaybeScreenContainer = _ref => {
var _Screens, _Screens$screensEnabl;
let {
enabled,
...rest
} = _ref;
if ((_Screens = Screens) !== null && _Screens !== void 0 && (_Screens$screensEnabl = _Screens.screensEnabled) !== null && _Screens$screensEnabl !== void 0 && _Screens$screensEnabl.call(_Screens)) {
return /*#__PURE__*/React.createElement(Screens.ScreenContainer, _extends({
enabled: enabled
}, rest));
}
return /*#__PURE__*/React.createElement(View, rest);
};
export function MaybeScreen(_ref2) {
var _Screens2, _Screens2$screensEnab;
let {
visible,
children,
...rest
} = _ref2;
if ((_Screens2 = Screens) !== null && _Screens2 !== void 0 && (_Screens2$screensEnab = _Screens2.screensEnabled) !== null && _Screens2$screensEnab !== void 0 && _Screens2$screensEnab.call(_Screens2)) {
return /*#__PURE__*/React.createElement(Screens.Screen, _extends({
activityState: visible ? 2 : 0
}, rest), children);
}
return /*#__PURE__*/React.createElement(ResourceSavingView, _extends({
visible: visible
}, rest), children);
}
//# sourceMappingURL=ScreenFallback.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["ResourceSavingView","React","View","Screens","require","e","MaybeScreenContainer","enabled","rest","screensEnabled","MaybeScreen","visible","children"],"sourceRoot":"../../../src","sources":["views/ScreenFallback.tsx"],"mappings":";AAAA,SAASA,kBAAkB,QAAQ,4BAA4B;AAC/D,OAAO,KAAKC,KAAK,MAAM,OAAO;AAC9B,SAAoBC,IAAI,QAA8B,cAAc;AAUpE,IAAIC,OAA0D;AAE9D,IAAI;EACFA,OAAO,GAAGC,OAAO,CAAC,sBAAsB,CAAC;AAC3C,CAAC,CAAC,OAAOC,CAAC,EAAE;EACV;AAAA;AAGF,OAAO,MAAMC,oBAAoB,GAAG,QAO9B;EAAA;EAAA,IAP+B;IACnCC,OAAO;IACP,GAAGC;EAKL,CAAC;EACC,gBAAIL,OAAO,8DAAP,SAASM,cAAc,kDAAvB,oCAA2B,EAAE;IAC/B,oBAAO,oBAAC,OAAO,CAAC,eAAe;MAAC,OAAO,EAAEF;IAAQ,GAAKC,IAAI,EAAI;EAChE;EAEA,oBAAO,oBAAC,IAAI,EAAKA,IAAI,CAAI;AAC3B,CAAC;AAED,OAAO,SAASE,WAAW,QAAwC;EAAA;EAAA,IAAvC;IAAEC,OAAO;IAAEC,QAAQ;IAAE,GAAGJ;EAAY,CAAC;EAC/D,iBAAIL,OAAO,+DAAP,UAASM,cAAc,kDAAvB,qCAA2B,EAAE;IAC/B,oBACE,oBAAC,OAAO,CAAC,MAAM;MAAC,aAAa,EAAEE,OAAO,GAAG,CAAC,GAAG;IAAE,GAAKH,IAAI,GACrDI,QAAQ,CACM;EAErB;EAEA,oBACE,oBAAC,kBAAkB;IAAC,OAAO,EAAED;EAAQ,GAAKH,IAAI,GAC3CI,QAAQ,CACU;AAEzB"}

View File

@@ -0,0 +1,77 @@
import React from 'react';
import { StyleSheet, View } from 'react-native';
import Badge from './Badge';
export default function TabBarIcon(_ref) {
let {
route: _,
horizontal,
badge,
badgeStyle,
activeOpacity,
inactiveOpacity,
activeTintColor,
inactiveTintColor,
renderIcon,
style
} = _ref;
const size = 25;
// We render the icon twice at the same position on top of each other:
// active and inactive one, so we can fade between them.
return /*#__PURE__*/React.createElement(View, {
style: [horizontal ? styles.iconHorizontal : styles.iconVertical, style]
}, /*#__PURE__*/React.createElement(View, {
style: [styles.icon, {
opacity: activeOpacity
}]
}, renderIcon({
focused: true,
size,
color: activeTintColor
})), /*#__PURE__*/React.createElement(View, {
style: [styles.icon, {
opacity: inactiveOpacity
}]
}, renderIcon({
focused: false,
size,
color: inactiveTintColor
})), /*#__PURE__*/React.createElement(Badge, {
visible: badge != null,
style: [styles.badge, horizontal ? styles.badgeHorizontal : styles.badgeVertical, badgeStyle],
size: size * 3 / 4
}, badge));
}
const styles = StyleSheet.create({
icon: {
// We render the icon twice at the same position on top of each other:
// active and inactive one, so we can fade between them:
// Cover the whole iconContainer:
position: 'absolute',
alignSelf: 'center',
alignItems: 'center',
justifyContent: 'center',
height: '100%',
width: '100%',
// Workaround for react-native >= 0.54 layout bug
minWidth: 25
},
iconVertical: {
flex: 1
},
iconHorizontal: {
height: '100%',
marginTop: 3
},
badge: {
position: 'absolute',
left: 3
},
badgeVertical: {
top: 3
},
badgeHorizontal: {
top: 7
}
});
//# sourceMappingURL=TabBarIcon.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","StyleSheet","View","Badge","TabBarIcon","route","_","horizontal","badge","badgeStyle","activeOpacity","inactiveOpacity","activeTintColor","inactiveTintColor","renderIcon","style","size","styles","iconHorizontal","iconVertical","icon","opacity","focused","color","badgeHorizontal","badgeVertical","create","position","alignSelf","alignItems","justifyContent","height","width","minWidth","flex","marginTop","left","top"],"sourceRoot":"../../../src","sources":["views/TabBarIcon.tsx"],"mappings":"AACA,OAAOA,KAAK,MAAM,OAAO;AACzB,SAEEC,UAAU,EAEVC,IAAI,QAEC,cAAc;AAErB,OAAOC,KAAK,MAAM,SAAS;AAmB3B,eAAe,SAASC,UAAU,OAWxB;EAAA,IAXyB;IACjCC,KAAK,EAAEC,CAAC;IACRC,UAAU;IACVC,KAAK;IACLC,UAAU;IACVC,aAAa;IACbC,eAAe;IACfC,eAAe;IACfC,iBAAiB;IACjBC,UAAU;IACVC;EACK,CAAC;EACN,MAAMC,IAAI,GAAG,EAAE;;EAEf;EACA;EACA,oBACE,oBAAC,IAAI;IACH,KAAK,EAAE,CAACT,UAAU,GAAGU,MAAM,CAACC,cAAc,GAAGD,MAAM,CAACE,YAAY,EAAEJ,KAAK;EAAE,gBAEzE,oBAAC,IAAI;IAAC,KAAK,EAAE,CAACE,MAAM,CAACG,IAAI,EAAE;MAAEC,OAAO,EAAEX;IAAc,CAAC;EAAE,GACpDI,UAAU,CAAC;IACVQ,OAAO,EAAE,IAAI;IACbN,IAAI;IACJO,KAAK,EAAEX;EACT,CAAC,CAAC,CACG,eACP,oBAAC,IAAI;IAAC,KAAK,EAAE,CAACK,MAAM,CAACG,IAAI,EAAE;MAAEC,OAAO,EAAEV;IAAgB,CAAC;EAAE,GACtDG,UAAU,CAAC;IACVQ,OAAO,EAAE,KAAK;IACdN,IAAI;IACJO,KAAK,EAAEV;EACT,CAAC,CAAC,CACG,eACP,oBAAC,KAAK;IACJ,OAAO,EAAEL,KAAK,IAAI,IAAK;IACvB,KAAK,EAAE,CACLS,MAAM,CAACT,KAAK,EACZD,UAAU,GAAGU,MAAM,CAACO,eAAe,GAAGP,MAAM,CAACQ,aAAa,EAC1DhB,UAAU,CACV;IACF,IAAI,EAAGO,IAAI,GAAG,CAAC,GAAI;EAAE,GAEpBR,KAAK,CACA,CACH;AAEX;AAEA,MAAMS,MAAM,GAAGhB,UAAU,CAACyB,MAAM,CAAC;EAC/BN,IAAI,EAAE;IACJ;IACA;IACA;IACAO,QAAQ,EAAE,UAAU;IACpBC,SAAS,EAAE,QAAQ;IACnBC,UAAU,EAAE,QAAQ;IACpBC,cAAc,EAAE,QAAQ;IACxBC,MAAM,EAAE,MAAM;IACdC,KAAK,EAAE,MAAM;IACb;IACAC,QAAQ,EAAE;EACZ,CAAC;EACDd,YAAY,EAAE;IACZe,IAAI,EAAE;EACR,CAAC;EACDhB,cAAc,EAAE;IACda,MAAM,EAAE,MAAM;IACdI,SAAS,EAAE;EACb,CAAC;EACD3B,KAAK,EAAE;IACLmB,QAAQ,EAAE,UAAU;IACpBS,IAAI,EAAE;EACR,CAAC;EACDX,aAAa,EAAE;IACbY,GAAG,EAAE;EACP,CAAC;EACDb,eAAe,EAAE;IACfa,GAAG,EAAE;EACP;AACF,CAAC,CAAC"}

View File

@@ -0,0 +1,20 @@
/**
* Navigators
*/
export { default as createBottomTabNavigator } from './navigators/createBottomTabNavigator';
/**
* Views
*/
export { default as BottomTabBar } from './views/BottomTabBar';
export { default as BottomTabView } from './views/BottomTabView';
/**
* Utilities
*/
export { default as BottomTabBarHeightCallbackContext } from './utils/BottomTabBarHeightCallbackContext';
export { default as BottomTabBarHeightContext } from './utils/BottomTabBarHeightContext';
export { default as useBottomTabBarHeight } from './utils/useBottomTabBarHeight';
/**
* Types
*/
export type { BottomTabBarButtonProps, BottomTabBarProps, BottomTabHeaderProps, BottomTabNavigationEventMap, BottomTabNavigationOptions, BottomTabNavigationProp, BottomTabScreenProps, } from './types';
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,OAAO,IAAI,wBAAwB,EAAE,MAAM,uCAAuC,CAAC;AAE5F;;GAEG;AACH,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEjE;;GAEG;AACH,OAAO,EAAE,OAAO,IAAI,iCAAiC,EAAE,MAAM,2CAA2C,CAAC;AACzG,OAAO,EAAE,OAAO,IAAI,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AACzF,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAEjF;;GAEG;AACH,YAAY,EACV,uBAAuB,EACvB,iBAAiB,EACjB,oBAAoB,EACpB,2BAA2B,EAC3B,0BAA0B,EAC1B,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,SAAS,CAAC"}

View File

@@ -0,0 +1,7 @@
import { DefaultNavigatorOptions, ParamListBase, TabNavigationState, TabRouterOptions } from '@react-navigation/native';
import type { BottomTabNavigationConfig, BottomTabNavigationEventMap, BottomTabNavigationOptions } from '../types';
type Props = DefaultNavigatorOptions<ParamListBase, TabNavigationState<ParamListBase>, BottomTabNavigationOptions, BottomTabNavigationEventMap> & TabRouterOptions & BottomTabNavigationConfig;
declare function BottomTabNavigator({ id, initialRouteName, backBehavior, children, screenListeners, screenOptions, sceneContainerStyle, ...restWithDeprecated }: Props): JSX.Element;
declare const _default: <ParamList extends ParamListBase>() => import("@react-navigation/native").TypedNavigator<ParamList, TabNavigationState<ParamListBase>, BottomTabNavigationOptions, BottomTabNavigationEventMap, typeof BottomTabNavigator>;
export default _default;
//# sourceMappingURL=createBottomTabNavigator.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"createBottomTabNavigator.d.ts","sourceRoot":"","sources":["../../../../src/navigators/createBottomTabNavigator.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,uBAAuB,EACvB,aAAa,EAEb,kBAAkB,EAElB,gBAAgB,EAEjB,MAAM,0BAA0B,CAAC;AAIlC,OAAO,KAAK,EACV,yBAAyB,EACzB,2BAA2B,EAC3B,0BAA0B,EAC3B,MAAM,UAAU,CAAC;AAGlB,KAAK,KAAK,GAAG,uBAAuB,CAClC,aAAa,EACb,kBAAkB,CAAC,aAAa,CAAC,EACjC,0BAA0B,EAC1B,2BAA2B,CAC5B,GACC,gBAAgB,GAChB,yBAAyB,CAAC;AAE5B,iBAAS,kBAAkB,CAAC,EAC1B,EAAE,EACF,gBAAgB,EAChB,YAAY,EACZ,QAAQ,EACR,eAAe,EACf,aAAa,EACb,mBAAmB,EACnB,GAAG,kBAAkB,EACtB,EAAE,KAAK,eAwFP;;AAED,wBAKsB"}

View File

@@ -0,0 +1,242 @@
import type { HeaderOptions } from '@react-navigation/elements';
import type { Descriptor, NavigationHelpers, NavigationProp, ParamListBase, RouteProp, TabActionHelpers, TabNavigationState } from '@react-navigation/native';
import type * as React from 'react';
import type { Animated, GestureResponderEvent, StyleProp, TextStyle, TouchableWithoutFeedbackProps, ViewStyle } from 'react-native';
import type { EdgeInsets } from 'react-native-safe-area-context';
export type Layout = {
width: number;
height: number;
};
export type BottomTabNavigationEventMap = {
/**
* Event which fires on tapping on the tab in the tab bar.
*/
tabPress: {
data: undefined;
canPreventDefault: true;
};
/**
* Event which fires on long press on the tab in the tab bar.
*/
tabLongPress: {
data: undefined;
};
};
export type LabelPosition = 'beside-icon' | 'below-icon';
export type BottomTabNavigationHelpers = NavigationHelpers<ParamListBase, BottomTabNavigationEventMap> & TabActionHelpers<ParamListBase>;
export type BottomTabNavigationProp<ParamList extends ParamListBase, RouteName extends keyof ParamList = keyof ParamList, NavigatorID extends string | undefined = undefined> = NavigationProp<ParamList, RouteName, NavigatorID, TabNavigationState<ParamList>, BottomTabNavigationOptions, BottomTabNavigationEventMap> & TabActionHelpers<ParamList>;
export type BottomTabScreenProps<ParamList extends ParamListBase, RouteName extends keyof ParamList = keyof ParamList, NavigatorID extends string | undefined = undefined> = {
navigation: BottomTabNavigationProp<ParamList, RouteName, NavigatorID>;
route: RouteProp<ParamList, RouteName>;
};
export type TimingKeyboardAnimationConfig = {
animation: 'timing';
config?: Omit<Partial<Animated.TimingAnimationConfig>, 'toValue' | 'useNativeDriver'>;
};
export type SpringKeyboardAnimationConfig = {
animation: 'spring';
config?: Omit<Partial<Animated.SpringAnimationConfig>, 'toValue' | 'useNativeDriver'>;
};
export type TabBarVisibilityAnimationConfig = TimingKeyboardAnimationConfig | SpringKeyboardAnimationConfig;
export type BottomTabNavigationOptions = HeaderOptions & {
/**
* Title text for the screen.
*/
title?: string;
/**
* Title string of a tab displayed in the tab bar
* or a function that given { focused: boolean, color: string, position: 'below-icon' | 'beside-icon', children: string } returns a React.Node to display in tab bar.
*
* When undefined, scene title is used. Use `tabBarShowLabel` to hide the label.
*/
tabBarLabel?: string | ((props: {
focused: boolean;
color: string;
position: LabelPosition;
children: string;
}) => React.ReactNode);
/**
* Whether the tab label should be visible. Defaults to `true`.
*/
tabBarShowLabel?: boolean;
/**
* Whether the label is shown below the icon or beside the icon.
*
* - `below-icon`: the label is shown below the icon (typical for iPhones)
* - `beside-icon` the label is shown next to the icon (typical for iPad)
*
* By default, the position is chosen automatically based on device width.
*/
tabBarLabelPosition?: LabelPosition;
/**
* Style object for the tab label.
*/
tabBarLabelStyle?: StyleProp<TextStyle>;
/**
* Whether label font should scale to respect Text Size accessibility settings.
*/
tabBarAllowFontScaling?: boolean;
/**
* A function that given { focused: boolean, color: string } returns a React.Node to display in the tab bar.
*/
tabBarIcon?: (props: {
focused: boolean;
color: string;
size: number;
}) => React.ReactNode;
/**
* Style object for the tab icon.
*/
tabBarIconStyle?: StyleProp<TextStyle>;
/**
* Text to show in a badge on the tab icon.
*/
tabBarBadge?: number | string;
/**
* Custom style for the tab bar badge.
* You can specify a background color or text color here.
*/
tabBarBadgeStyle?: StyleProp<TextStyle>;
/**
* Accessibility label for the tab button. This is read by the screen reader when the user taps the tab.
* It's recommended to set this if you don't have a label for the tab.
*/
tabBarAccessibilityLabel?: string;
/**
* ID to locate this tab button in tests.
*/
tabBarTestID?: string;
/**
* Function which returns a React element to render as the tab bar button.
* Renders `Pressable` by default.
*/
tabBarButton?: (props: BottomTabBarButtonProps) => React.ReactNode;
/**
* Color for the icon and label in the active tab.
*/
tabBarActiveTintColor?: string;
/**
* Color for the icon and label in the inactive tabs.
*/
tabBarInactiveTintColor?: string;
/**
* Background color for the active tab.
*/
tabBarActiveBackgroundColor?: string;
/**
* Background color for the inactive tabs.
*/
tabBarInactiveBackgroundColor?: string;
/**
* Style object for the tab item container.
*/
tabBarItemStyle?: StyleProp<ViewStyle>;
/**
* Whether the tab bar gets hidden when the keyboard is shown. Defaults to `false`.
*/
tabBarHideOnKeyboard?: boolean;
/**
* Animation config for showing and hiding the tab bar when the keyboard is shown/hidden.
*/
tabBarVisibilityAnimationConfig?: {
show?: TabBarVisibilityAnimationConfig;
hide?: TabBarVisibilityAnimationConfig;
};
/**
* Style object for the tab bar container.
*/
tabBarStyle?: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
/**
* Function which returns a React Element to use as background for the tab bar.
* You could render an image, a gradient, blur view etc.
*
* When using `BlurView`, make sure to set `position: 'absolute'` in `tabBarStyle` as well.
* You'd also need to use `useBottomTabBarHeight()` to add a bottom padding to your content.
*/
tabBarBackground?: () => React.ReactNode;
/**
* Whether this screens should render the first time it's accessed. Defaults to `true`.
* Set it to `false` if you want to render the screen on initial render.
*/
lazy?: boolean;
/**
* Function that given returns a React Element to display as a header.
*/
header?: (props: BottomTabHeaderProps) => React.ReactNode;
/**
* Whether to show the header. Setting this to `false` hides the header.
* Defaults to `true`.
*/
headerShown?: boolean;
/**
* Whether this screen should be unmounted when navigating away from it.
* Defaults to `false`.
*/
unmountOnBlur?: boolean;
/**
* Whether inactive screens should be suspended from re-rendering. Defaults to `false`.
* Defaults to `true` when `enableFreeze()` is run at the top of the application.
* Requires `react-native-screens` version >=3.16.0.
*
* Only supported on iOS and Android.
*/
freezeOnBlur?: boolean;
};
export type BottomTabDescriptor = Descriptor<BottomTabNavigationOptions, BottomTabNavigationProp<ParamListBase>, RouteProp<ParamListBase>>;
export type BottomTabDescriptorMap = Record<string, BottomTabDescriptor>;
export type BottomTabNavigationConfig = {
/**
* Function that returns a React element to display as the tab bar.
*/
tabBar?: (props: BottomTabBarProps) => React.ReactNode;
/**
* Safe area insets for the tab bar. This is used to avoid elements like the navigation bar on Android and bottom safe area on iOS.
* By default, the device's safe area insets are automatically detected. You can override the behavior with this option.
*/
safeAreaInsets?: {
top?: number;
right?: number;
bottom?: number;
left?: number;
};
/**
* Whether inactive screens should be detached from the view hierarchy to save memory.
* Make sure to call `enableScreens` from `react-native-screens` to make it work.
* Defaults to `true` on Android.
*/
detachInactiveScreens?: boolean;
/**
* Style object for the component wrapping the screen content.
*/
sceneContainerStyle?: StyleProp<ViewStyle>;
};
export type BottomTabHeaderProps = {
/**
* Layout of the screen.
*/
layout: Layout;
/**
* Options for the current screen.
*/
options: BottomTabNavigationOptions;
/**
* Route object for the current screen.
*/
route: RouteProp<ParamListBase>;
/**
* Navigation prop for the header.
*/
navigation: BottomTabNavigationProp<ParamListBase>;
};
export type BottomTabBarProps = {
state: TabNavigationState<ParamListBase>;
descriptors: BottomTabDescriptorMap;
navigation: NavigationHelpers<ParamListBase, BottomTabNavigationEventMap>;
insets: EdgeInsets;
};
export type BottomTabBarButtonProps = Omit<TouchableWithoutFeedbackProps, 'onPress'> & {
to?: string;
children: React.ReactNode;
onPress?: (e: React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent) => void;
};
//# sourceMappingURL=types.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.tsx"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,4 @@
import * as React from 'react';
declare const _default: React.Context<((height: number) => void) | undefined>;
export default _default;
//# sourceMappingURL=BottomTabBarHeightCallbackContext.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"BottomTabBarHeightCallbackContext.d.ts","sourceRoot":"","sources":["../../../../src/utils/BottomTabBarHeightCallbackContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;gDAEc,MAAM,KAAK,IAAI;AAA5D,wBAEE"}

View File

@@ -0,0 +1,4 @@
import * as React from 'react';
declare const _default: React.Context<number | undefined>;
export default _default;
//# sourceMappingURL=BottomTabBarHeightContext.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"BottomTabBarHeightContext.d.ts","sourceRoot":"","sources":["../../../../src/utils/BottomTabBarHeightContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;;AAE/B,wBAAkE"}

View File

@@ -0,0 +1,2 @@
export default function useBottomTabBarHeight(): number;
//# sourceMappingURL=useBottomTabBarHeight.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"useBottomTabBarHeight.d.ts","sourceRoot":"","sources":["../../../../src/utils/useBottomTabBarHeight.tsx"],"names":[],"mappings":"AAIA,MAAM,CAAC,OAAO,UAAU,qBAAqB,WAU5C"}

View File

@@ -0,0 +1,2 @@
export default function useIsKeyboardShown(): boolean;
//# sourceMappingURL=useIsKeyboardShown.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"useIsKeyboardShown.d.ts","sourceRoot":"","sources":["../../../../src/utils/useIsKeyboardShown.tsx"],"names":[],"mappings":"AAGA,MAAM,CAAC,OAAO,UAAU,kBAAkB,YA2BzC"}

View File

@@ -0,0 +1,22 @@
import { Animated, StyleProp, TextStyle } from 'react-native';
type Props = {
/**
* Whether the badge is visible
*/
visible: boolean;
/**
* Content of the `Badge`.
*/
children?: string | number;
/**
* Size of the `Badge`.
*/
size?: number;
/**
* Style object for the tab bar container.
*/
style?: Animated.WithAnimatedValue<StyleProp<TextStyle>>;
};
export default function Badge({ children, style, visible, size, ...rest }: Props): JSX.Element | null;
export {};
//# sourceMappingURL=Badge.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"Badge.d.ts","sourceRoot":"","sources":["../../../../src/views/Badge.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAc,SAAS,EAAE,MAAM,cAAc,CAAC;AAE1E,KAAK,KAAK,GAAG;IACX;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,KAAK,CAAC,EAAE,QAAQ,CAAC,iBAAiB,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC;CAC1D,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,KAAK,CAAC,EAC5B,QAAQ,EACR,KAAK,EACL,OAAc,EACd,IAAS,EACT,GAAG,IAAI,EACR,EAAE,KAAK,sBAsEP"}

View File

@@ -0,0 +1,26 @@
import { ParamListBase, TabNavigationState } from '@react-navigation/native';
import { Animated, StyleProp, ViewStyle } from 'react-native';
import { EdgeInsets } from 'react-native-safe-area-context';
import type { BottomTabBarProps, BottomTabDescriptorMap } from '../types';
type Props = BottomTabBarProps & {
style?: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
};
type Options = {
state: TabNavigationState<ParamListBase>;
descriptors: BottomTabDescriptorMap;
layout: {
height: number;
width: number;
};
dimensions: {
height: number;
width: number;
};
};
export declare const getTabBarHeight: ({ state, descriptors, dimensions, insets, style, ...rest }: Options & {
insets: EdgeInsets;
style: Animated.WithAnimatedValue<StyleProp<ViewStyle>> | undefined;
}) => number;
export default function BottomTabBar({ state, navigation, descriptors, insets, style, }: Props): JSX.Element;
export {};
//# sourceMappingURL=BottomTabBar.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"BottomTabBar.d.ts","sourceRoot":"","sources":["../../../../src/views/BottomTabBar.tsx"],"names":[],"mappings":"AACA,OAAO,EAIL,aAAa,EACb,kBAAkB,EAGnB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,QAAQ,EAGR,SAAS,EAGT,SAAS,EACV,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,UAAU,EAAoB,MAAM,gCAAgC,CAAC;AAE9E,OAAO,KAAK,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAK1E,KAAK,KAAK,GAAG,iBAAiB,GAAG;IAC/B,KAAK,CAAC,EAAE,QAAQ,CAAC,iBAAiB,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC;CAC1D,CAAC;AAQF,KAAK,OAAO,GAAG;IACb,KAAK,EAAE,kBAAkB,CAAC,aAAa,CAAC,CAAC;IACzC,WAAW,EAAE,sBAAsB,CAAC;IACpC,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,UAAU,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/C,CAAC;AA8CF,eAAO,MAAM,eAAe;YAQlB,UAAU;WACX,SAAS,iBAAiB,CAAC,UAAU,SAAS,CAAC,CAAC,GAAG,SAAS;YA4BpE,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,EACnC,KAAK,EACL,UAAU,EACV,WAAW,EACX,MAAM,EACN,KAAK,GACN,EAAE,KAAK,eAoPP"}

View File

@@ -0,0 +1,111 @@
import { Route } from '@react-navigation/native';
import React from 'react';
import { GestureResponderEvent, StyleProp, TextStyle, ViewStyle } from 'react-native';
import type { BottomTabBarButtonProps, BottomTabDescriptor, LabelPosition } from '../types';
type Props = {
/**
* Whether the tab is focused.
*/
focused: boolean;
/**
* The route object which should be specified by the tab.
*/
route: Route<string>;
/**
* The descriptor object for the route.
*/
descriptor: BottomTabDescriptor;
/**
* The label text of the tab.
*/
label: string | ((props: {
focused: boolean;
color: string;
position: LabelPosition;
children: string;
}) => React.ReactNode);
/**
* Icon to display for the tab.
*/
icon: (props: {
focused: boolean;
size: number;
color: string;
}) => React.ReactNode;
/**
* Text to show in a badge on the tab icon.
*/
badge?: number | string;
/**
* Custom style for the badge.
*/
badgeStyle?: StyleProp<TextStyle>;
/**
* URL to use for the link to the tab.
*/
to?: string;
/**
* The button for the tab. Uses a `TouchableWithoutFeedback` by default.
*/
button?: (props: BottomTabBarButtonProps) => React.ReactNode;
/**
* The accessibility label for the tab.
*/
accessibilityLabel?: string;
/**
* An unique ID for testing for the tab.
*/
testID?: string;
/**
* Function to execute on press in React Native.
* On the web, this will use onClick.
*/
onPress: (e: React.MouseEvent<HTMLElement, MouseEvent> | GestureResponderEvent) => void;
/**
* Function to execute on long press.
*/
onLongPress: (e: GestureResponderEvent) => void;
/**
* Whether the label should be aligned with the icon horizontally.
*/
horizontal: boolean;
/**
* Color for the icon and label when the item is active.
*/
activeTintColor?: string;
/**
* Color for the icon and label when the item is inactive.
*/
inactiveTintColor?: string;
/**
* Background color for item when its active.
*/
activeBackgroundColor?: string;
/**
* Background color for item when its inactive.
*/
inactiveBackgroundColor?: string;
/**
* Whether to show the label text for the tab.
*/
showLabel?: boolean;
/**
* Whether to allow scaling the font for the label for accessibility purposes.
*/
allowFontScaling?: boolean;
/**
* Style object for the label element.
*/
labelStyle?: StyleProp<TextStyle>;
/**
* Style object for the icon element.
*/
iconStyle?: StyleProp<ViewStyle>;
/**
* Style object for the wrapper element.
*/
style?: StyleProp<ViewStyle>;
};
export default function BottomTabBarItem({ focused, route, descriptor, label, icon, badge, badgeStyle, to, button, accessibilityLabel, testID, onPress, onLongPress, horizontal, activeTintColor: customActiveTintColor, inactiveTintColor: customInactiveTintColor, activeBackgroundColor, inactiveBackgroundColor, showLabel, allowFontScaling, labelStyle, iconStyle, style, }: Props): React.ReactElement<any, string | React.JSXElementConstructor<any>>;
export {};
//# sourceMappingURL=BottomTabItem.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"BottomTabItem.d.ts","sourceRoot":"","sources":["../../../../src/views/BottomTabItem.tsx"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,10 @@
import type { ParamListBase, TabNavigationState } from '@react-navigation/native';
import type { BottomTabDescriptorMap, BottomTabNavigationConfig, BottomTabNavigationHelpers } from '../types';
type Props = BottomTabNavigationConfig & {
state: TabNavigationState<ParamListBase>;
navigation: BottomTabNavigationHelpers;
descriptors: BottomTabDescriptorMap;
};
export default function BottomTabView(props: Props): JSX.Element;
export {};
//# sourceMappingURL=BottomTabView.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"BottomTabView.d.ts","sourceRoot":"","sources":["../../../../src/views/BottomTabView.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,aAAa,EACb,kBAAkB,EACnB,MAAM,0BAA0B,CAAC;AAKlC,OAAO,KAAK,EAEV,sBAAsB,EAEtB,yBAAyB,EACzB,0BAA0B,EAE3B,MAAM,UAAU,CAAC;AAMlB,KAAK,KAAK,GAAG,yBAAyB,GAAG;IACvC,KAAK,EAAE,kBAAkB,CAAC,aAAa,CAAC,CAAC;IACzC,UAAU,EAAE,0BAA0B,CAAC;IACvC,WAAW,EAAE,sBAAsB,CAAC;CACrC,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,KAAK,EAAE,KAAK,eAiIjD"}

View File

@@ -0,0 +1,17 @@
import * as React from 'react';
import { StyleProp, ViewProps, ViewStyle } from 'react-native';
type Props = {
visible: boolean;
children: React.ReactNode;
enabled: boolean;
freezeOnBlur?: boolean;
style?: StyleProp<ViewStyle>;
};
export declare const MaybeScreenContainer: ({ enabled, ...rest }: ViewProps & {
enabled: boolean;
hasTwoStates: boolean;
children: React.ReactNode;
}) => JSX.Element;
export declare function MaybeScreen({ visible, children, ...rest }: Props): JSX.Element;
export {};
//# sourceMappingURL=ScreenFallback.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ScreenFallback.d.ts","sourceRoot":"","sources":["../../../../src/views/ScreenFallback.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,SAAS,EAAQ,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAErE,KAAK,KAAK,GAAG;IACX,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC9B,CAAC;AAUF,eAAO,MAAM,oBAAoB;aAItB,OAAO;kBACF,OAAO;cACX,MAAM,SAAS;iBAO1B,CAAC;AAEF,wBAAgB,WAAW,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,EAAE,KAAK,eAchE"}

View File

@@ -0,0 +1,22 @@
import type { Route } from '@react-navigation/native';
import React from 'react';
import { StyleProp, TextStyle, ViewStyle } from 'react-native';
type Props = {
route: Route<string>;
horizontal: boolean;
badge?: string | number;
badgeStyle?: StyleProp<TextStyle>;
activeOpacity: number;
inactiveOpacity: number;
activeTintColor: string;
inactiveTintColor: string;
renderIcon: (props: {
focused: boolean;
color: string;
size: number;
}) => React.ReactNode;
style: StyleProp<ViewStyle>;
};
export default function TabBarIcon({ route, horizontal, badge, badgeStyle, activeOpacity, inactiveOpacity, activeTintColor, inactiveTintColor, renderIcon, style, }: Props): JSX.Element;
export {};
//# sourceMappingURL=TabBarIcon.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"TabBarIcon.d.ts","sourceRoot":"","sources":["../../../../src/views/TabBarIcon.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EACL,SAAS,EAET,SAAS,EAET,SAAS,EACV,MAAM,cAAc,CAAC;AAItB,KAAK,KAAK,GAAG;IACX,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,CAAC,KAAK,EAAE;QAClB,OAAO,EAAE,OAAO,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;KACd,KAAK,KAAK,CAAC,SAAS,CAAC;IACtB,KAAK,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC7B,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,EACjC,KAAQ,EACR,UAAU,EACV,KAAK,EACL,UAAU,EACV,aAAa,EACb,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,UAAU,EACV,KAAK,GACN,EAAE,KAAK,eAoCP"}

View File

@@ -0,0 +1,79 @@
{
"name": "@react-navigation/bottom-tabs",
"description": "Bottom tab navigator following iOS design guidelines",
"version": "6.6.1",
"keywords": [
"react-native-component",
"react-component",
"react-native",
"react-navigation",
"ios",
"android",
"tab"
],
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/react-navigation/react-navigation.git",
"directory": "packages/bottom-tabs"
},
"main": "lib/commonjs/index.js",
"react-native": "src/index.tsx",
"source": "src/index.tsx",
"module": "lib/module/index.js",
"types": "lib/typescript/src/index.d.ts",
"files": [
"src",
"lib",
"!**/__tests__"
],
"sideEffects": false,
"publishConfig": {
"access": "public"
},
"scripts": {
"prepack": "bob build",
"clean": "del lib"
},
"dependencies": {
"@react-navigation/elements": "^1.3.31",
"color": "^4.2.3",
"warn-once": "^0.1.0"
},
"devDependencies": {
"@react-navigation/native": "^6.1.18",
"@testing-library/react-native": "^11.5.0",
"@types/color": "^3.0.1",
"@types/react": "~18.0.27",
"@types/react-native": "~0.71.3",
"del-cli": "^5.0.0",
"react": "18.2.0",
"react-native": "0.71.8",
"react-native-builder-bob": "^0.20.4",
"react-native-safe-area-context": "4.5.0",
"react-native-screens": "~3.29.0",
"typescript": "^4.9.4"
},
"peerDependencies": {
"@react-navigation/native": "^6.0.0",
"react": "*",
"react-native": "*",
"react-native-safe-area-context": ">= 3.0.0",
"react-native-screens": ">= 3.0.0"
},
"react-native-builder-bob": {
"source": "src",
"output": "lib",
"targets": [
"commonjs",
"module",
[
"typescript",
{
"project": "tsconfig.build.json"
}
]
]
},
"gitHead": "a2269aa24bc0c2ceec227dbdcc4fa4c38902396a"
}

View File

@@ -0,0 +1,30 @@
/**
* Navigators
*/
export { default as createBottomTabNavigator } from './navigators/createBottomTabNavigator';
/**
* Views
*/
export { default as BottomTabBar } from './views/BottomTabBar';
export { default as BottomTabView } from './views/BottomTabView';
/**
* Utilities
*/
export { default as BottomTabBarHeightCallbackContext } from './utils/BottomTabBarHeightCallbackContext';
export { default as BottomTabBarHeightContext } from './utils/BottomTabBarHeightContext';
export { default as useBottomTabBarHeight } from './utils/useBottomTabBarHeight';
/**
* Types
*/
export type {
BottomTabBarButtonProps,
BottomTabBarProps,
BottomTabHeaderProps,
BottomTabNavigationEventMap,
BottomTabNavigationOptions,
BottomTabNavigationProp,
BottomTabScreenProps,
} from './types';

View File

@@ -0,0 +1,134 @@
import {
createNavigatorFactory,
DefaultNavigatorOptions,
ParamListBase,
TabActionHelpers,
TabNavigationState,
TabRouter,
TabRouterOptions,
useNavigationBuilder,
} from '@react-navigation/native';
import * as React from 'react';
import warnOnce from 'warn-once';
import type {
BottomTabNavigationConfig,
BottomTabNavigationEventMap,
BottomTabNavigationOptions,
} from '../types';
import BottomTabView from '../views/BottomTabView';
type Props = DefaultNavigatorOptions<
ParamListBase,
TabNavigationState<ParamListBase>,
BottomTabNavigationOptions,
BottomTabNavigationEventMap
> &
TabRouterOptions &
BottomTabNavigationConfig;
function BottomTabNavigator({
id,
initialRouteName,
backBehavior,
children,
screenListeners,
screenOptions,
sceneContainerStyle,
...restWithDeprecated
}: Props) {
const {
// @ts-expect-error: lazy is deprecated
lazy,
// @ts-expect-error: tabBarOptions is deprecated
tabBarOptions,
...rest
} = restWithDeprecated;
let defaultScreenOptions: BottomTabNavigationOptions = {};
if (tabBarOptions) {
Object.assign(defaultScreenOptions, {
tabBarHideOnKeyboard: tabBarOptions.keyboardHidesTabBar,
tabBarActiveTintColor: tabBarOptions.activeTintColor,
tabBarInactiveTintColor: tabBarOptions.inactiveTintColor,
tabBarActiveBackgroundColor: tabBarOptions.activeBackgroundColor,
tabBarInactiveBackgroundColor: tabBarOptions.inactiveBackgroundColor,
tabBarAllowFontScaling: tabBarOptions.allowFontScaling,
tabBarShowLabel: tabBarOptions.showLabel,
tabBarLabelStyle: tabBarOptions.labelStyle,
tabBarIconStyle: tabBarOptions.iconStyle,
tabBarItemStyle: tabBarOptions.tabStyle,
tabBarLabelPosition:
tabBarOptions.labelPosition ??
(tabBarOptions.adaptive === false ? 'below-icon' : undefined),
tabBarStyle: [
{ display: tabBarOptions.tabBarVisible ? 'none' : 'flex' },
defaultScreenOptions.tabBarStyle,
],
});
(
Object.keys(defaultScreenOptions) as (keyof BottomTabNavigationOptions)[]
).forEach((key) => {
if (defaultScreenOptions[key] === undefined) {
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete defaultScreenOptions[key];
}
});
warnOnce(
tabBarOptions,
`Bottom Tab Navigator: 'tabBarOptions' is deprecated. Migrate the options to 'screenOptions' instead.\n\nPlace the following in 'screenOptions' in your code to keep current behavior:\n\n${JSON.stringify(
defaultScreenOptions,
null,
2
)}\n\nSee https://reactnavigation.org/docs/bottom-tab-navigator#options for more details.`
);
}
if (typeof lazy === 'boolean') {
defaultScreenOptions.lazy = lazy;
warnOnce(
true,
`Bottom Tab Navigator: 'lazy' in props is deprecated. Move it to 'screenOptions' instead.\n\nSee https://reactnavigation.org/docs/bottom-tab-navigator/#lazy for more details.`
);
}
const { state, descriptors, navigation, NavigationContent } =
useNavigationBuilder<
TabNavigationState<ParamListBase>,
TabRouterOptions,
TabActionHelpers<ParamListBase>,
BottomTabNavigationOptions,
BottomTabNavigationEventMap
>(TabRouter, {
id,
initialRouteName,
backBehavior,
children,
screenListeners,
screenOptions,
defaultScreenOptions,
});
return (
<NavigationContent>
<BottomTabView
{...rest}
state={state}
navigation={navigation}
descriptors={descriptors}
sceneContainerStyle={sceneContainerStyle}
/>
</NavigationContent>
);
}
export default createNavigatorFactory<
TabNavigationState<ParamListBase>,
BottomTabNavigationOptions,
BottomTabNavigationEventMap,
typeof BottomTabNavigator
>(BottomTabNavigator);

View File

@@ -0,0 +1,329 @@
import type { HeaderOptions } from '@react-navigation/elements';
import type {
Descriptor,
NavigationHelpers,
NavigationProp,
ParamListBase,
RouteProp,
TabActionHelpers,
TabNavigationState,
} from '@react-navigation/native';
import type * as React from 'react';
import type {
Animated,
GestureResponderEvent,
StyleProp,
TextStyle,
TouchableWithoutFeedbackProps,
ViewStyle,
} from 'react-native';
import type { EdgeInsets } from 'react-native-safe-area-context';
export type Layout = { width: number; height: number };
export type BottomTabNavigationEventMap = {
/**
* Event which fires on tapping on the tab in the tab bar.
*/
tabPress: { data: undefined; canPreventDefault: true };
/**
* Event which fires on long press on the tab in the tab bar.
*/
tabLongPress: { data: undefined };
};
export type LabelPosition = 'beside-icon' | 'below-icon';
export type BottomTabNavigationHelpers = NavigationHelpers<
ParamListBase,
BottomTabNavigationEventMap
> &
TabActionHelpers<ParamListBase>;
export type BottomTabNavigationProp<
ParamList extends ParamListBase,
RouteName extends keyof ParamList = keyof ParamList,
NavigatorID extends string | undefined = undefined
> = NavigationProp<
ParamList,
RouteName,
NavigatorID,
TabNavigationState<ParamList>,
BottomTabNavigationOptions,
BottomTabNavigationEventMap
> &
TabActionHelpers<ParamList>;
export type BottomTabScreenProps<
ParamList extends ParamListBase,
RouteName extends keyof ParamList = keyof ParamList,
NavigatorID extends string | undefined = undefined
> = {
navigation: BottomTabNavigationProp<ParamList, RouteName, NavigatorID>;
route: RouteProp<ParamList, RouteName>;
};
export type TimingKeyboardAnimationConfig = {
animation: 'timing';
config?: Omit<
Partial<Animated.TimingAnimationConfig>,
'toValue' | 'useNativeDriver'
>;
};
export type SpringKeyboardAnimationConfig = {
animation: 'spring';
config?: Omit<
Partial<Animated.SpringAnimationConfig>,
'toValue' | 'useNativeDriver'
>;
};
export type TabBarVisibilityAnimationConfig =
| TimingKeyboardAnimationConfig
| SpringKeyboardAnimationConfig;
export type BottomTabNavigationOptions = HeaderOptions & {
/**
* Title text for the screen.
*/
title?: string;
/**
* Title string of a tab displayed in the tab bar
* or a function that given { focused: boolean, color: string, position: 'below-icon' | 'beside-icon', children: string } returns a React.Node to display in tab bar.
*
* When undefined, scene title is used. Use `tabBarShowLabel` to hide the label.
*/
tabBarLabel?:
| string
| ((props: {
focused: boolean;
color: string;
position: LabelPosition;
children: string;
}) => React.ReactNode);
/**
* Whether the tab label should be visible. Defaults to `true`.
*/
tabBarShowLabel?: boolean;
/**
* Whether the label is shown below the icon or beside the icon.
*
* - `below-icon`: the label is shown below the icon (typical for iPhones)
* - `beside-icon` the label is shown next to the icon (typical for iPad)
*
* By default, the position is chosen automatically based on device width.
*/
tabBarLabelPosition?: LabelPosition;
/**
* Style object for the tab label.
*/
tabBarLabelStyle?: StyleProp<TextStyle>;
/**
* Whether label font should scale to respect Text Size accessibility settings.
*/
tabBarAllowFontScaling?: boolean;
/**
* A function that given { focused: boolean, color: string } returns a React.Node to display in the tab bar.
*/
tabBarIcon?: (props: {
focused: boolean;
color: string;
size: number;
}) => React.ReactNode;
/**
* Style object for the tab icon.
*/
tabBarIconStyle?: StyleProp<TextStyle>;
/**
* Text to show in a badge on the tab icon.
*/
tabBarBadge?: number | string;
/**
* Custom style for the tab bar badge.
* You can specify a background color or text color here.
*/
tabBarBadgeStyle?: StyleProp<TextStyle>;
/**
* Accessibility label for the tab button. This is read by the screen reader when the user taps the tab.
* It's recommended to set this if you don't have a label for the tab.
*/
tabBarAccessibilityLabel?: string;
/**
* ID to locate this tab button in tests.
*/
tabBarTestID?: string;
/**
* Function which returns a React element to render as the tab bar button.
* Renders `Pressable` by default.
*/
tabBarButton?: (props: BottomTabBarButtonProps) => React.ReactNode;
/**
* Color for the icon and label in the active tab.
*/
tabBarActiveTintColor?: string;
/**
* Color for the icon and label in the inactive tabs.
*/
tabBarInactiveTintColor?: string;
/**
* Background color for the active tab.
*/
tabBarActiveBackgroundColor?: string;
/**
* Background color for the inactive tabs.
*/
tabBarInactiveBackgroundColor?: string;
/**
* Style object for the tab item container.
*/
tabBarItemStyle?: StyleProp<ViewStyle>;
/**
* Whether the tab bar gets hidden when the keyboard is shown. Defaults to `false`.
*/
tabBarHideOnKeyboard?: boolean;
/**
* Animation config for showing and hiding the tab bar when the keyboard is shown/hidden.
*/
tabBarVisibilityAnimationConfig?: {
show?: TabBarVisibilityAnimationConfig;
hide?: TabBarVisibilityAnimationConfig;
};
/**
* Style object for the tab bar container.
*/
tabBarStyle?: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
/**
* Function which returns a React Element to use as background for the tab bar.
* You could render an image, a gradient, blur view etc.
*
* When using `BlurView`, make sure to set `position: 'absolute'` in `tabBarStyle` as well.
* You'd also need to use `useBottomTabBarHeight()` to add a bottom padding to your content.
*/
tabBarBackground?: () => React.ReactNode;
/**
* Whether this screens should render the first time it's accessed. Defaults to `true`.
* Set it to `false` if you want to render the screen on initial render.
*/
lazy?: boolean;
/**
* Function that given returns a React Element to display as a header.
*/
header?: (props: BottomTabHeaderProps) => React.ReactNode;
/**
* Whether to show the header. Setting this to `false` hides the header.
* Defaults to `true`.
*/
headerShown?: boolean;
/**
* Whether this screen should be unmounted when navigating away from it.
* Defaults to `false`.
*/
unmountOnBlur?: boolean;
/**
* Whether inactive screens should be suspended from re-rendering. Defaults to `false`.
* Defaults to `true` when `enableFreeze()` is run at the top of the application.
* Requires `react-native-screens` version >=3.16.0.
*
* Only supported on iOS and Android.
*/
freezeOnBlur?: boolean;
};
export type BottomTabDescriptor = Descriptor<
BottomTabNavigationOptions,
BottomTabNavigationProp<ParamListBase>,
RouteProp<ParamListBase>
>;
export type BottomTabDescriptorMap = Record<string, BottomTabDescriptor>;
export type BottomTabNavigationConfig = {
/**
* Function that returns a React element to display as the tab bar.
*/
tabBar?: (props: BottomTabBarProps) => React.ReactNode;
/**
* Safe area insets for the tab bar. This is used to avoid elements like the navigation bar on Android and bottom safe area on iOS.
* By default, the device's safe area insets are automatically detected. You can override the behavior with this option.
*/
safeAreaInsets?: {
top?: number;
right?: number;
bottom?: number;
left?: number;
};
/**
* Whether inactive screens should be detached from the view hierarchy to save memory.
* Make sure to call `enableScreens` from `react-native-screens` to make it work.
* Defaults to `true` on Android.
*/
detachInactiveScreens?: boolean;
/**
* Style object for the component wrapping the screen content.
*/
sceneContainerStyle?: StyleProp<ViewStyle>;
};
export type BottomTabHeaderProps = {
/**
* Layout of the screen.
*/
layout: Layout;
/**
* Options for the current screen.
*/
options: BottomTabNavigationOptions;
/**
* Route object for the current screen.
*/
route: RouteProp<ParamListBase>;
/**
* Navigation prop for the header.
*/
navigation: BottomTabNavigationProp<ParamListBase>;
};
export type BottomTabBarProps = {
state: TabNavigationState<ParamListBase>;
descriptors: BottomTabDescriptorMap;
navigation: NavigationHelpers<ParamListBase, BottomTabNavigationEventMap>;
insets: EdgeInsets;
};
export type BottomTabBarButtonProps = Omit<
TouchableWithoutFeedbackProps,
'onPress'
> & {
to?: string;
children: React.ReactNode;
onPress?: (
e: React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent
) => void;
};

View File

@@ -0,0 +1,5 @@
import * as React from 'react';
export default React.createContext<((height: number) => void) | undefined>(
undefined
);

View File

@@ -0,0 +1,3 @@
import * as React from 'react';
export default React.createContext<number | undefined>(undefined);

View File

@@ -0,0 +1,15 @@
import * as React from 'react';
import BottomTabBarHeightContext from './BottomTabBarHeightContext';
export default function useBottomTabBarHeight() {
const height = React.useContext(BottomTabBarHeightContext);
if (height === undefined) {
throw new Error(
"Couldn't find the bottom tab bar height. Are you inside a screen in Bottom Tab Navigator?"
);
}
return height;
}

View File

@@ -0,0 +1,31 @@
import * as React from 'react';
import { EmitterSubscription, Keyboard, Platform } from 'react-native';
export default function useIsKeyboardShown() {
const [isKeyboardShown, setIsKeyboardShown] = React.useState(false);
React.useEffect(() => {
const handleKeyboardShow = () => setIsKeyboardShown(true);
const handleKeyboardHide = () => setIsKeyboardShown(false);
let subscriptions: EmitterSubscription[];
if (Platform.OS === 'ios') {
subscriptions = [
Keyboard.addListener('keyboardWillShow', handleKeyboardShow),
Keyboard.addListener('keyboardWillHide', handleKeyboardHide),
];
} else {
subscriptions = [
Keyboard.addListener('keyboardDidShow', handleKeyboardShow),
Keyboard.addListener('keyboardDidHide', handleKeyboardHide),
];
}
return () => {
subscriptions.forEach((s) => s.remove());
};
}, []);
return isKeyboardShown;
}

View File

@@ -0,0 +1,110 @@
import { useTheme } from '@react-navigation/native';
import color from 'color';
import * as React from 'react';
import { Animated, StyleProp, StyleSheet, TextStyle } from 'react-native';
type Props = {
/**
* Whether the badge is visible
*/
visible: boolean;
/**
* Content of the `Badge`.
*/
children?: string | number;
/**
* Size of the `Badge`.
*/
size?: number;
/**
* Style object for the tab bar container.
*/
style?: Animated.WithAnimatedValue<StyleProp<TextStyle>>;
};
export default function Badge({
children,
style,
visible = true,
size = 18,
...rest
}: Props) {
const [opacity] = React.useState(() => new Animated.Value(visible ? 1 : 0));
const [rendered, setRendered] = React.useState(visible);
const theme = useTheme();
React.useEffect(() => {
if (!rendered) {
return;
}
Animated.timing(opacity, {
toValue: visible ? 1 : 0,
duration: 150,
useNativeDriver: true,
}).start(({ finished }) => {
if (finished && !visible) {
setRendered(false);
}
});
return () => opacity.stopAnimation();
}, [opacity, rendered, visible]);
if (!rendered) {
if (visible) {
setRendered(true);
} else {
return null;
}
}
// @ts-expect-error: backgroundColor definitely exists
const { backgroundColor = theme.colors.notification, ...restStyle } =
StyleSheet.flatten(style) || {};
const textColor = color(backgroundColor).isLight() ? 'black' : 'white';
const borderRadius = size / 2;
const fontSize = Math.floor((size * 3) / 4);
return (
<Animated.Text
numberOfLines={1}
style={[
{
transform: [
{
scale: opacity.interpolate({
inputRange: [0, 1],
outputRange: [0.5, 1],
}),
},
],
color: textColor,
lineHeight: size - 1,
height: size,
minWidth: size,
opacity,
backgroundColor,
fontSize,
borderRadius,
},
styles.container,
restStyle,
]}
{...rest}
>
{children}
</Animated.Text>
);
}
const styles = StyleSheet.create({
container: {
alignSelf: 'flex-end',
textAlign: 'center',
paddingHorizontal: 4,
overflow: 'hidden',
},
});

View File

@@ -0,0 +1,392 @@
import { MissingIcon } from '@react-navigation/elements';
import {
CommonActions,
NavigationContext,
NavigationRouteContext,
ParamListBase,
TabNavigationState,
useLinkBuilder,
useTheme,
} from '@react-navigation/native';
import React from 'react';
import {
Animated,
LayoutChangeEvent,
Platform,
StyleProp,
StyleSheet,
View,
ViewStyle,
} from 'react-native';
import { EdgeInsets, useSafeAreaFrame } from 'react-native-safe-area-context';
import type { BottomTabBarProps, BottomTabDescriptorMap } from '../types';
import BottomTabBarHeightCallbackContext from '../utils/BottomTabBarHeightCallbackContext';
import useIsKeyboardShown from '../utils/useIsKeyboardShown';
import BottomTabItem from './BottomTabItem';
type Props = BottomTabBarProps & {
style?: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
};
const DEFAULT_TABBAR_HEIGHT = 49;
const COMPACT_TABBAR_HEIGHT = 32;
const DEFAULT_MAX_TAB_ITEM_WIDTH = 125;
const useNativeDriver = Platform.OS !== 'web';
type Options = {
state: TabNavigationState<ParamListBase>;
descriptors: BottomTabDescriptorMap;
layout: { height: number; width: number };
dimensions: { height: number; width: number };
};
const shouldUseHorizontalLabels = ({
state,
descriptors,
layout,
dimensions,
}: Options) => {
const { tabBarLabelPosition } =
descriptors[state.routes[state.index].key].options;
if (tabBarLabelPosition) {
switch (tabBarLabelPosition) {
case 'beside-icon':
return true;
case 'below-icon':
return false;
}
}
if (layout.width >= 768) {
// Screen size matches a tablet
const maxTabWidth = state.routes.reduce((acc, route) => {
const { tabBarItemStyle } = descriptors[route.key].options;
const flattenedStyle = StyleSheet.flatten(tabBarItemStyle);
if (flattenedStyle) {
if (typeof flattenedStyle.width === 'number') {
return acc + flattenedStyle.width;
} else if (typeof flattenedStyle.maxWidth === 'number') {
return acc + flattenedStyle.maxWidth;
}
}
return acc + DEFAULT_MAX_TAB_ITEM_WIDTH;
}, 0);
return maxTabWidth <= layout.width;
} else {
return dimensions.width > dimensions.height;
}
};
const getPaddingBottom = (insets: EdgeInsets) =>
Math.max(insets.bottom - Platform.select({ ios: 4, default: 0 }), 0);
export const getTabBarHeight = ({
state,
descriptors,
dimensions,
insets,
style,
...rest
}: Options & {
insets: EdgeInsets;
style: Animated.WithAnimatedValue<StyleProp<ViewStyle>> | undefined;
}) => {
// @ts-ignore
const customHeight = StyleSheet.flatten(style)?.height;
if (typeof customHeight === 'number') {
return customHeight;
}
const isLandscape = dimensions.width > dimensions.height;
const horizontalLabels = shouldUseHorizontalLabels({
state,
descriptors,
dimensions,
...rest,
});
const paddingBottom = getPaddingBottom(insets);
if (
Platform.OS === 'ios' &&
!Platform.isPad &&
isLandscape &&
horizontalLabels
) {
return COMPACT_TABBAR_HEIGHT + paddingBottom;
}
return DEFAULT_TABBAR_HEIGHT + paddingBottom;
};
export default function BottomTabBar({
state,
navigation,
descriptors,
insets,
style,
}: Props) {
const { colors } = useTheme();
const buildLink = useLinkBuilder();
const focusedRoute = state.routes[state.index];
const focusedDescriptor = descriptors[focusedRoute.key];
const focusedOptions = focusedDescriptor.options;
const {
tabBarShowLabel,
tabBarHideOnKeyboard = false,
tabBarVisibilityAnimationConfig,
tabBarStyle,
tabBarBackground,
tabBarActiveTintColor,
tabBarInactiveTintColor,
tabBarActiveBackgroundColor,
tabBarInactiveBackgroundColor,
} = focusedOptions;
const dimensions = useSafeAreaFrame();
const isKeyboardShown = useIsKeyboardShown();
const onHeightChange = React.useContext(BottomTabBarHeightCallbackContext);
const shouldShowTabBar = !(tabBarHideOnKeyboard && isKeyboardShown);
const visibilityAnimationConfigRef = React.useRef(
tabBarVisibilityAnimationConfig
);
React.useEffect(() => {
visibilityAnimationConfigRef.current = tabBarVisibilityAnimationConfig;
});
const [isTabBarHidden, setIsTabBarHidden] = React.useState(!shouldShowTabBar);
const [visible] = React.useState(
() => new Animated.Value(shouldShowTabBar ? 1 : 0)
);
React.useEffect(() => {
const visibilityAnimationConfig = visibilityAnimationConfigRef.current;
if (shouldShowTabBar) {
const animation =
visibilityAnimationConfig?.show?.animation === 'spring'
? Animated.spring
: Animated.timing;
animation(visible, {
toValue: 1,
useNativeDriver,
duration: 250,
...visibilityAnimationConfig?.show?.config,
}).start(({ finished }) => {
if (finished) {
setIsTabBarHidden(false);
}
});
} else {
setIsTabBarHidden(true);
const animation =
visibilityAnimationConfig?.hide?.animation === 'spring'
? Animated.spring
: Animated.timing;
animation(visible, {
toValue: 0,
useNativeDriver,
duration: 200,
...visibilityAnimationConfig?.hide?.config,
}).start();
}
return () => visible.stopAnimation();
}, [visible, shouldShowTabBar]);
const [layout, setLayout] = React.useState({
height: 0,
width: dimensions.width,
});
const handleLayout = (e: LayoutChangeEvent) => {
const { height, width } = e.nativeEvent.layout;
onHeightChange?.(height);
setLayout((layout) => {
if (height === layout.height && width === layout.width) {
return layout;
} else {
return {
height,
width,
};
}
});
};
const { routes } = state;
const paddingBottom = getPaddingBottom(insets);
const tabBarHeight = getTabBarHeight({
state,
descriptors,
insets,
dimensions,
layout,
style: [tabBarStyle, style],
});
const hasHorizontalLabels = shouldUseHorizontalLabels({
state,
descriptors,
dimensions,
layout,
});
const tabBarBackgroundElement = tabBarBackground?.();
return (
<Animated.View
style={[
styles.tabBar,
{
backgroundColor:
tabBarBackgroundElement != null ? 'transparent' : colors.card,
borderTopColor: colors.border,
},
{
transform: [
{
translateY: visible.interpolate({
inputRange: [0, 1],
outputRange: [
layout.height + paddingBottom + StyleSheet.hairlineWidth,
0,
],
}),
},
],
// Absolutely position the tab bar so that the content is below it
// This is needed to avoid gap at bottom when the tab bar is hidden
position: isTabBarHidden ? 'absolute' : (null as any),
},
{
height: tabBarHeight,
paddingBottom,
paddingHorizontal: Math.max(insets.left, insets.right),
},
tabBarStyle,
]}
pointerEvents={isTabBarHidden ? 'none' : 'auto'}
onLayout={handleLayout}
>
<View pointerEvents="none" style={StyleSheet.absoluteFill}>
{tabBarBackgroundElement}
</View>
<View accessibilityRole="tablist" style={styles.content}>
{routes.map((route, index) => {
const focused = index === state.index;
const { options } = descriptors[route.key];
const onPress = () => {
const event = navigation.emit({
type: 'tabPress',
target: route.key,
canPreventDefault: true,
});
if (!focused && !event.defaultPrevented) {
navigation.dispatch({
...CommonActions.navigate({ name: route.name, merge: true }),
target: state.key,
});
}
};
const onLongPress = () => {
navigation.emit({
type: 'tabLongPress',
target: route.key,
});
};
const label =
options.tabBarLabel !== undefined
? options.tabBarLabel
: options.title !== undefined
? options.title
: route.name;
const accessibilityLabel =
options.tabBarAccessibilityLabel !== undefined
? options.tabBarAccessibilityLabel
: typeof label === 'string' && Platform.OS === 'ios'
? `${label}, tab, ${index + 1} of ${routes.length}`
: undefined;
return (
<NavigationContext.Provider
key={route.key}
value={descriptors[route.key].navigation}
>
<NavigationRouteContext.Provider value={route}>
<BottomTabItem
route={route}
descriptor={descriptors[route.key]}
focused={focused}
horizontal={hasHorizontalLabels}
onPress={onPress}
onLongPress={onLongPress}
accessibilityLabel={accessibilityLabel}
to={buildLink(route.name, route.params)}
testID={options.tabBarTestID}
allowFontScaling={options.tabBarAllowFontScaling}
activeTintColor={tabBarActiveTintColor}
inactiveTintColor={tabBarInactiveTintColor}
activeBackgroundColor={tabBarActiveBackgroundColor}
inactiveBackgroundColor={tabBarInactiveBackgroundColor}
button={options.tabBarButton}
icon={
options.tabBarIcon ??
(({ color, size }) => (
<MissingIcon color={color} size={size} />
))
}
badge={options.tabBarBadge}
badgeStyle={options.tabBarBadgeStyle}
label={label}
showLabel={tabBarShowLabel}
labelStyle={options.tabBarLabelStyle}
iconStyle={options.tabBarIconStyle}
style={options.tabBarItemStyle}
/>
</NavigationRouteContext.Provider>
</NavigationContext.Provider>
);
})}
</View>
</Animated.View>
);
}
const styles = StyleSheet.create({
tabBar: {
left: 0,
right: 0,
bottom: 0,
borderTopWidth: StyleSheet.hairlineWidth,
elevation: 8,
},
content: {
flex: 1,
flexDirection: 'row',
},
});

View File

@@ -0,0 +1,333 @@
import { Link, Route, useTheme } from '@react-navigation/native';
import Color from 'color';
import React from 'react';
import {
GestureResponderEvent,
Platform,
Pressable,
StyleProp,
StyleSheet,
Text,
TextStyle,
ViewStyle,
} from 'react-native';
import type {
BottomTabBarButtonProps,
BottomTabDescriptor,
LabelPosition,
} from '../types';
import TabBarIcon from './TabBarIcon';
type Props = {
/**
* Whether the tab is focused.
*/
focused: boolean;
/**
* The route object which should be specified by the tab.
*/
route: Route<string>;
/**
* The descriptor object for the route.
*/
descriptor: BottomTabDescriptor;
/**
* The label text of the tab.
*/
label:
| string
| ((props: {
focused: boolean;
color: string;
position: LabelPosition;
children: string;
}) => React.ReactNode);
/**
* Icon to display for the tab.
*/
icon: (props: {
focused: boolean;
size: number;
color: string;
}) => React.ReactNode;
/**
* Text to show in a badge on the tab icon.
*/
badge?: number | string;
/**
* Custom style for the badge.
*/
badgeStyle?: StyleProp<TextStyle>;
/**
* URL to use for the link to the tab.
*/
to?: string;
/**
* The button for the tab. Uses a `TouchableWithoutFeedback` by default.
*/
button?: (props: BottomTabBarButtonProps) => React.ReactNode;
/**
* The accessibility label for the tab.
*/
accessibilityLabel?: string;
/**
* An unique ID for testing for the tab.
*/
testID?: string;
/**
* Function to execute on press in React Native.
* On the web, this will use onClick.
*/
onPress: (
e: React.MouseEvent<HTMLElement, MouseEvent> | GestureResponderEvent
) => void;
/**
* Function to execute on long press.
*/
onLongPress: (e: GestureResponderEvent) => void;
/**
* Whether the label should be aligned with the icon horizontally.
*/
horizontal: boolean;
/**
* Color for the icon and label when the item is active.
*/
activeTintColor?: string;
/**
* Color for the icon and label when the item is inactive.
*/
inactiveTintColor?: string;
/**
* Background color for item when its active.
*/
activeBackgroundColor?: string;
/**
* Background color for item when its inactive.
*/
inactiveBackgroundColor?: string;
/**
* Whether to show the label text for the tab.
*/
showLabel?: boolean;
/**
* Whether to allow scaling the font for the label for accessibility purposes.
*/
allowFontScaling?: boolean;
/**
* Style object for the label element.
*/
labelStyle?: StyleProp<TextStyle>;
/**
* Style object for the icon element.
*/
iconStyle?: StyleProp<ViewStyle>;
/**
* Style object for the wrapper element.
*/
style?: StyleProp<ViewStyle>;
};
export default function BottomTabBarItem({
focused,
route,
descriptor,
label,
icon,
badge,
badgeStyle,
to,
button = ({
children,
style,
onPress,
to,
accessibilityRole,
...rest
}: BottomTabBarButtonProps) => {
if (Platform.OS === 'web' && to) {
// React Native Web doesn't forward `onClick` if we use `TouchableWithoutFeedback`.
// We need to use `onClick` to be able to prevent default browser handling of links.
return (
<Link
{...rest}
to={to}
style={[styles.button, style]}
onPress={(e: any) => {
if (
!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey) && // ignore clicks with modifier keys
(e.button == null || e.button === 0) // ignore everything but left clicks
) {
e.preventDefault();
onPress?.(e);
}
}}
>
{children}
</Link>
);
} else {
return (
<Pressable
{...rest}
accessibilityRole={accessibilityRole}
onPress={onPress}
style={style}
>
{children}
</Pressable>
);
}
},
accessibilityLabel,
testID,
onPress,
onLongPress,
horizontal,
activeTintColor: customActiveTintColor,
inactiveTintColor: customInactiveTintColor,
activeBackgroundColor = 'transparent',
inactiveBackgroundColor = 'transparent',
showLabel = true,
allowFontScaling,
labelStyle,
iconStyle,
style,
}: Props) {
const { colors } = useTheme();
const activeTintColor =
customActiveTintColor === undefined
? colors.primary
: customActiveTintColor;
const inactiveTintColor =
customInactiveTintColor === undefined
? Color(colors.text).mix(Color(colors.card), 0.5).hex()
: customInactiveTintColor;
const renderLabel = ({ focused }: { focused: boolean }) => {
if (showLabel === false) {
return null;
}
const color = focused ? activeTintColor : inactiveTintColor;
if (typeof label === 'string') {
return (
<Text
numberOfLines={1}
style={[
styles.label,
{ color },
horizontal ? styles.labelBeside : styles.labelBeneath,
labelStyle,
]}
allowFontScaling={allowFontScaling}
>
{label}
</Text>
);
}
const { options } = descriptor;
const children =
typeof options.tabBarLabel === 'string'
? options.tabBarLabel
: options.title !== undefined
? options.title
: route.name;
return label({
focused,
color,
position: horizontal ? 'beside-icon' : 'below-icon',
children,
});
};
const renderIcon = ({ focused }: { focused: boolean }) => {
if (icon === undefined) {
return null;
}
const activeOpacity = focused ? 1 : 0;
const inactiveOpacity = focused ? 0 : 1;
return (
<TabBarIcon
route={route}
horizontal={horizontal}
badge={badge}
badgeStyle={badgeStyle}
activeOpacity={activeOpacity}
inactiveOpacity={inactiveOpacity}
activeTintColor={activeTintColor}
inactiveTintColor={inactiveTintColor}
renderIcon={icon}
style={iconStyle}
/>
);
};
const scene = { route, focused };
const backgroundColor = focused
? activeBackgroundColor
: inactiveBackgroundColor;
return button({
to,
onPress,
onLongPress,
testID,
accessibilityLabel,
// FIXME: accessibilityRole: 'tab' doesn't seem to work as expected on iOS
accessibilityRole: Platform.select({ ios: 'button', default: 'tab' }),
accessibilityState: { selected: focused },
// @ts-expect-error: keep for compatibility with older React Native versions
accessibilityStates: focused ? ['selected'] : [],
style: [
styles.tab,
{ backgroundColor },
horizontal ? styles.tabLandscape : styles.tabPortrait,
style,
],
children: (
<React.Fragment>
{renderIcon(scene)}
{renderLabel(scene)}
</React.Fragment>
),
}) as React.ReactElement;
}
const styles = StyleSheet.create({
tab: {
flex: 1,
alignItems: 'center',
},
tabPortrait: {
justifyContent: 'flex-end',
flexDirection: 'column',
},
tabLandscape: {
justifyContent: 'center',
flexDirection: 'row',
},
label: {
textAlign: 'center',
backgroundColor: 'transparent',
},
labelBeneath: {
fontSize: 10,
},
labelBeside: {
fontSize: 13,
marginLeft: 20,
marginTop: 3,
},
button: {
display: 'flex',
},
});

View File

@@ -0,0 +1,170 @@
import {
getHeaderTitle,
Header,
SafeAreaProviderCompat,
Screen,
} from '@react-navigation/elements';
import type {
ParamListBase,
TabNavigationState,
} from '@react-navigation/native';
import * as React from 'react';
import { Platform, StyleSheet } from 'react-native';
import { SafeAreaInsetsContext } from 'react-native-safe-area-context';
import type {
BottomTabBarProps,
BottomTabDescriptorMap,
BottomTabHeaderProps,
BottomTabNavigationConfig,
BottomTabNavigationHelpers,
BottomTabNavigationProp,
} from '../types';
import BottomTabBarHeightCallbackContext from '../utils/BottomTabBarHeightCallbackContext';
import BottomTabBarHeightContext from '../utils/BottomTabBarHeightContext';
import BottomTabBar, { getTabBarHeight } from './BottomTabBar';
import { MaybeScreen, MaybeScreenContainer } from './ScreenFallback';
type Props = BottomTabNavigationConfig & {
state: TabNavigationState<ParamListBase>;
navigation: BottomTabNavigationHelpers;
descriptors: BottomTabDescriptorMap;
};
export default function BottomTabView(props: Props) {
const {
tabBar = (props: BottomTabBarProps) => <BottomTabBar {...props} />,
state,
navigation,
descriptors,
safeAreaInsets,
detachInactiveScreens = Platform.OS === 'web' ||
Platform.OS === 'android' ||
Platform.OS === 'ios',
sceneContainerStyle,
} = props;
const focusedRouteKey = state.routes[state.index].key;
const [loaded, setLoaded] = React.useState([focusedRouteKey]);
if (!loaded.includes(focusedRouteKey)) {
setLoaded([...loaded, focusedRouteKey]);
}
const dimensions = SafeAreaProviderCompat.initialMetrics.frame;
const [tabBarHeight, setTabBarHeight] = React.useState(() =>
getTabBarHeight({
state,
descriptors,
dimensions,
layout: { width: dimensions.width, height: 0 },
insets: {
...SafeAreaProviderCompat.initialMetrics.insets,
...props.safeAreaInsets,
},
style: descriptors[state.routes[state.index].key].options.tabBarStyle,
})
);
const renderTabBar = () => {
return (
<SafeAreaInsetsContext.Consumer>
{(insets) =>
tabBar({
state: state,
descriptors: descriptors,
navigation: navigation,
insets: {
top: safeAreaInsets?.top ?? insets?.top ?? 0,
right: safeAreaInsets?.right ?? insets?.right ?? 0,
bottom: safeAreaInsets?.bottom ?? insets?.bottom ?? 0,
left: safeAreaInsets?.left ?? insets?.left ?? 0,
},
})
}
</SafeAreaInsetsContext.Consumer>
);
};
const { routes } = state;
return (
<SafeAreaProviderCompat>
<MaybeScreenContainer
enabled={detachInactiveScreens}
hasTwoStates
style={styles.container}
>
{routes.map((route, index) => {
const descriptor = descriptors[route.key];
const { lazy = true, unmountOnBlur } = descriptor.options;
const isFocused = state.index === index;
if (unmountOnBlur && !isFocused) {
return null;
}
if (lazy && !loaded.includes(route.key) && !isFocused) {
// Don't render a lazy screen if we've never navigated to it
return null;
}
const {
freezeOnBlur,
header = ({ layout, options }: BottomTabHeaderProps) => (
<Header
{...options}
layout={layout}
title={getHeaderTitle(options, route.name)}
/>
),
headerShown,
headerStatusBarHeight,
headerTransparent,
} = descriptor.options;
return (
<MaybeScreen
key={route.key}
style={[StyleSheet.absoluteFill, { zIndex: isFocused ? 0 : -1 }]}
visible={isFocused}
enabled={detachInactiveScreens}
freezeOnBlur={freezeOnBlur}
>
<BottomTabBarHeightContext.Provider value={tabBarHeight}>
<Screen
focused={isFocused}
route={descriptor.route}
navigation={descriptor.navigation}
headerShown={headerShown}
headerStatusBarHeight={headerStatusBarHeight}
headerTransparent={headerTransparent}
header={header({
layout: dimensions,
route: descriptor.route,
navigation:
descriptor.navigation as BottomTabNavigationProp<ParamListBase>,
options: descriptor.options,
})}
style={sceneContainerStyle}
>
{descriptor.render()}
</Screen>
</BottomTabBarHeightContext.Provider>
</MaybeScreen>
);
})}
</MaybeScreenContainer>
<BottomTabBarHeightCallbackContext.Provider value={setTabBarHeight}>
{renderTabBar()}
</BottomTabBarHeightCallbackContext.Provider>
</SafeAreaProviderCompat>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
overflow: 'hidden',
},
});

View File

@@ -0,0 +1,50 @@
import { ResourceSavingView } from '@react-navigation/elements';
import * as React from 'react';
import { StyleProp, View, ViewProps, ViewStyle } from 'react-native';
type Props = {
visible: boolean;
children: React.ReactNode;
enabled: boolean;
freezeOnBlur?: boolean;
style?: StyleProp<ViewStyle>;
};
let Screens: typeof import('react-native-screens') | undefined;
try {
Screens = require('react-native-screens');
} catch (e) {
// Ignore
}
export const MaybeScreenContainer = ({
enabled,
...rest
}: ViewProps & {
enabled: boolean;
hasTwoStates: boolean;
children: React.ReactNode;
}) => {
if (Screens?.screensEnabled?.()) {
return <Screens.ScreenContainer enabled={enabled} {...rest} />;
}
return <View {...rest} />;
};
export function MaybeScreen({ visible, children, ...rest }: Props) {
if (Screens?.screensEnabled?.()) {
return (
<Screens.Screen activityState={visible ? 2 : 0} {...rest}>
{children}
</Screens.Screen>
);
}
return (
<ResourceSavingView visible={visible} {...rest}>
{children}
</ResourceSavingView>
);
}

View File

@@ -0,0 +1,110 @@
import type { Route } from '@react-navigation/native';
import React from 'react';
import {
StyleProp,
StyleSheet,
TextStyle,
View,
ViewStyle,
} from 'react-native';
import Badge from './Badge';
type Props = {
route: Route<string>;
horizontal: boolean;
badge?: string | number;
badgeStyle?: StyleProp<TextStyle>;
activeOpacity: number;
inactiveOpacity: number;
activeTintColor: string;
inactiveTintColor: string;
renderIcon: (props: {
focused: boolean;
color: string;
size: number;
}) => React.ReactNode;
style: StyleProp<ViewStyle>;
};
export default function TabBarIcon({
route: _,
horizontal,
badge,
badgeStyle,
activeOpacity,
inactiveOpacity,
activeTintColor,
inactiveTintColor,
renderIcon,
style,
}: Props) {
const size = 25;
// We render the icon twice at the same position on top of each other:
// active and inactive one, so we can fade between them.
return (
<View
style={[horizontal ? styles.iconHorizontal : styles.iconVertical, style]}
>
<View style={[styles.icon, { opacity: activeOpacity }]}>
{renderIcon({
focused: true,
size,
color: activeTintColor,
})}
</View>
<View style={[styles.icon, { opacity: inactiveOpacity }]}>
{renderIcon({
focused: false,
size,
color: inactiveTintColor,
})}
</View>
<Badge
visible={badge != null}
style={[
styles.badge,
horizontal ? styles.badgeHorizontal : styles.badgeVertical,
badgeStyle,
]}
size={(size * 3) / 4}
>
{badge}
</Badge>
</View>
);
}
const styles = StyleSheet.create({
icon: {
// We render the icon twice at the same position on top of each other:
// active and inactive one, so we can fade between them:
// Cover the whole iconContainer:
position: 'absolute',
alignSelf: 'center',
alignItems: 'center',
justifyContent: 'center',
height: '100%',
width: '100%',
// Workaround for react-native >= 0.54 layout bug
minWidth: 25,
},
iconVertical: {
flex: 1,
},
iconHorizontal: {
height: '100%',
marginTop: 3,
},
badge: {
position: 'absolute',
left: 3,
},
badgeVertical: {
top: 3,
},
badgeHorizontal: {
top: 7,
},
});

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017 React Navigation Contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,44 @@
# `@react-navigation/core`
Core utilities for building navigators independent of the platform.
## Installation
Open a Terminal in your project's folder and run,
```sh
yarn add @react-navigation/core
```
## Usage
A basic custom navigator bundling a router and a view looks like this:
```js
import {
createNavigatorFactory,
useNavigationBuilder,
} from '@react-navigation/core';
import { StackRouter } from '@react-navigation/routers';
function StackNavigator({ initialRouteName, children, ...rest }) {
const { state, navigation, descriptors, NavigationContent } =
useNavigationBuilder(StackRouter, {
initialRouteName,
children,
});
return (
<NavigationContent>
<StackView
state={state}
navigation={navigation}
descriptors={descriptors}
{...rest}
/>
</NavigationContent>
);
}
export default createNavigatorFactory(StackNavigator);
```

View File

@@ -0,0 +1,348 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _routers = require("@react-navigation/routers");
var React = _interopRequireWildcard(require("react"));
var _checkDuplicateRouteNames = _interopRequireDefault(require("./checkDuplicateRouteNames"));
var _checkSerializable = _interopRequireDefault(require("./checkSerializable"));
var _createNavigationContainerRef = require("./createNavigationContainerRef");
var _EnsureSingleNavigator = _interopRequireDefault(require("./EnsureSingleNavigator"));
var _findFocusedRoute = _interopRequireDefault(require("./findFocusedRoute"));
var _NavigationBuilderContext = _interopRequireDefault(require("./NavigationBuilderContext"));
var _NavigationContainerRefContext = _interopRequireDefault(require("./NavigationContainerRefContext"));
var _NavigationContext = _interopRequireDefault(require("./NavigationContext"));
var _NavigationRouteContext = _interopRequireDefault(require("./NavigationRouteContext"));
var _NavigationStateContext = _interopRequireDefault(require("./NavigationStateContext"));
var _UnhandledActionContext = _interopRequireDefault(require("./UnhandledActionContext"));
var _useChildListeners = _interopRequireDefault(require("./useChildListeners"));
var _useEventEmitter = _interopRequireDefault(require("./useEventEmitter"));
var _useKeyedChildListeners = _interopRequireDefault(require("./useKeyedChildListeners"));
var _useOptionsGetters = _interopRequireDefault(require("./useOptionsGetters"));
var _useScheduleUpdate = require("./useScheduleUpdate");
var _useSyncState = _interopRequireDefault(require("./useSyncState"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
const serializableWarnings = [];
const duplicateNameWarnings = [];
/**
* Remove `key` and `routeNames` from the state objects recursively to get partial state.
*
* @param state Initial state object.
*/
const getPartialState = state => {
if (state === undefined) {
return;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const {
key,
routeNames,
...partialState
} = state;
return {
...partialState,
stale: true,
routes: state.routes.map(route => {
if (route.state === undefined) {
return route;
}
return {
...route,
state: getPartialState(route.state)
};
})
};
};
/**
* Container component which holds the navigation state.
* This should be rendered at the root wrapping the whole app.
*
* @param props.initialState Initial state object for the navigation tree.
* @param props.onStateChange Callback which is called with the latest navigation state when it changes.
* @param props.children Child elements to render the content.
* @param props.ref Ref object which refers to the navigation object containing helper methods.
*/
const BaseNavigationContainer = /*#__PURE__*/React.forwardRef(function BaseNavigationContainer(_ref, ref) {
let {
initialState,
onStateChange,
onUnhandledAction,
independent,
children
} = _ref;
const parent = React.useContext(_NavigationStateContext.default);
if (!parent.isDefault && !independent) {
throw new Error("Looks like you have nested a 'NavigationContainer' inside another. Normally you need only one container at the root of the app, so this was probably an error. If this was intentional, pass 'independent={true}' explicitly. Note that this will make the child navigators disconnected from the parent and you won't be able to navigate between them.");
}
const [state, getState, setState, scheduleUpdate, flushUpdates] = (0, _useSyncState.default)(() => getPartialState(initialState == null ? undefined : initialState));
const isFirstMountRef = React.useRef(true);
const navigatorKeyRef = React.useRef();
const getKey = React.useCallback(() => navigatorKeyRef.current, []);
const setKey = React.useCallback(key => {
navigatorKeyRef.current = key;
}, []);
const {
listeners,
addListener
} = (0, _useChildListeners.default)();
const {
keyedListeners,
addKeyedListener
} = (0, _useKeyedChildListeners.default)();
const dispatch = React.useCallback(action => {
if (listeners.focus[0] == null) {
console.error(_createNavigationContainerRef.NOT_INITIALIZED_ERROR);
} else {
listeners.focus[0](navigation => navigation.dispatch(action));
}
}, [listeners.focus]);
const canGoBack = React.useCallback(() => {
if (listeners.focus[0] == null) {
return false;
}
const {
result,
handled
} = listeners.focus[0](navigation => navigation.canGoBack());
if (handled) {
return result;
} else {
return false;
}
}, [listeners.focus]);
const resetRoot = React.useCallback(state => {
var _keyedListeners$getSt, _keyedListeners$getSt2;
const target = (state === null || state === void 0 ? void 0 : state.key) ?? ((_keyedListeners$getSt = (_keyedListeners$getSt2 = keyedListeners.getState).root) === null || _keyedListeners$getSt === void 0 ? void 0 : _keyedListeners$getSt.call(_keyedListeners$getSt2).key);
if (target == null) {
console.error(_createNavigationContainerRef.NOT_INITIALIZED_ERROR);
} else {
listeners.focus[0](navigation => navigation.dispatch({
..._routers.CommonActions.reset(state),
target
}));
}
}, [keyedListeners.getState, listeners.focus]);
const getRootState = React.useCallback(() => {
var _keyedListeners$getSt3, _keyedListeners$getSt4;
return (_keyedListeners$getSt3 = (_keyedListeners$getSt4 = keyedListeners.getState).root) === null || _keyedListeners$getSt3 === void 0 ? void 0 : _keyedListeners$getSt3.call(_keyedListeners$getSt4);
}, [keyedListeners.getState]);
const getCurrentRoute = React.useCallback(() => {
const state = getRootState();
if (state == null) {
return undefined;
}
const route = (0, _findFocusedRoute.default)(state);
return route;
}, [getRootState]);
const emitter = (0, _useEventEmitter.default)();
const {
addOptionsGetter,
getCurrentOptions
} = (0, _useOptionsGetters.default)({});
const navigation = React.useMemo(() => ({
...Object.keys(_routers.CommonActions).reduce((acc, name) => {
acc[name] = function () {
return (
// @ts-expect-error: this is ok
dispatch(_routers.CommonActions[name](...arguments))
);
};
return acc;
}, {}),
...emitter.create('root'),
dispatch,
resetRoot,
isFocused: () => true,
canGoBack,
getParent: () => undefined,
getState: () => stateRef.current,
getRootState,
getCurrentRoute,
getCurrentOptions,
isReady: () => listeners.focus[0] != null,
setOptions: () => {
throw new Error('Cannot call setOptions outside a screen');
}
}), [canGoBack, dispatch, emitter, getCurrentOptions, getCurrentRoute, getRootState, listeners.focus, resetRoot]);
React.useImperativeHandle(ref, () => navigation, [navigation]);
const onDispatchAction = React.useCallback((action, noop) => {
emitter.emit({
type: '__unsafe_action__',
data: {
action,
noop,
stack: stackRef.current
}
});
}, [emitter]);
const lastEmittedOptionsRef = React.useRef();
const onOptionsChange = React.useCallback(options => {
if (lastEmittedOptionsRef.current === options) {
return;
}
lastEmittedOptionsRef.current = options;
emitter.emit({
type: 'options',
data: {
options
}
});
}, [emitter]);
const stackRef = React.useRef();
const builderContext = React.useMemo(() => ({
addListener,
addKeyedListener,
onDispatchAction,
onOptionsChange,
stackRef
}), [addListener, addKeyedListener, onDispatchAction, onOptionsChange]);
const scheduleContext = React.useMemo(() => ({
scheduleUpdate,
flushUpdates
}), [scheduleUpdate, flushUpdates]);
const isInitialRef = React.useRef(true);
const getIsInitial = React.useCallback(() => isInitialRef.current, []);
const context = React.useMemo(() => ({
state,
getState,
setState,
getKey,
setKey,
getIsInitial,
addOptionsGetter
}), [state, getState, setState, getKey, setKey, getIsInitial, addOptionsGetter]);
const onStateChangeRef = React.useRef(onStateChange);
const stateRef = React.useRef(state);
React.useEffect(() => {
isInitialRef.current = false;
onStateChangeRef.current = onStateChange;
stateRef.current = state;
});
React.useEffect(() => {
const hydratedState = getRootState();
if (process.env.NODE_ENV !== 'production') {
if (hydratedState !== undefined) {
const serializableResult = (0, _checkSerializable.default)(hydratedState);
if (!serializableResult.serializable) {
const {
location,
reason
} = serializableResult;
let path = '';
let pointer = hydratedState;
let params = false;
for (let i = 0; i < location.length; i++) {
const curr = location[i];
const prev = location[i - 1];
pointer = pointer[curr];
if (!params && curr === 'state') {
continue;
} else if (!params && curr === 'routes') {
if (path) {
path += ' > ';
}
} else if (!params && typeof curr === 'number' && prev === 'routes') {
var _pointer;
path += (_pointer = pointer) === null || _pointer === void 0 ? void 0 : _pointer.name;
} else if (!params) {
path += ` > ${curr}`;
params = true;
} else {
if (typeof curr === 'number' || /^[0-9]+$/.test(curr)) {
path += `[${curr}]`;
} else if (/^[a-z$_]+$/i.test(curr)) {
path += `.${curr}`;
} else {
path += `[${JSON.stringify(curr)}]`;
}
}
}
const message = `Non-serializable values were found in the navigation state. Check:\n\n${path} (${reason})\n\nThis can break usage such as persisting and restoring state. This might happen if you passed non-serializable values such as function, class instances etc. in params. If you need to use components with callbacks in your options, you can use 'navigation.setOptions' instead. See https://reactnavigation.org/docs/troubleshooting#i-get-the-warning-non-serializable-values-were-found-in-the-navigation-state for more details.`;
if (!serializableWarnings.includes(message)) {
serializableWarnings.push(message);
console.warn(message);
}
}
const duplicateRouteNamesResult = (0, _checkDuplicateRouteNames.default)(hydratedState);
if (duplicateRouteNamesResult.length) {
const message = `Found screens with the same name nested inside one another. Check:\n${duplicateRouteNamesResult.map(locations => `\n${locations.join(', ')}`)}\n\nThis can cause confusing behavior during navigation. Consider using unique names for each screen instead.`;
if (!duplicateNameWarnings.includes(message)) {
duplicateNameWarnings.push(message);
console.warn(message);
}
}
}
}
emitter.emit({
type: 'state',
data: {
state
}
});
if (!isFirstMountRef.current && onStateChangeRef.current) {
onStateChangeRef.current(hydratedState);
}
isFirstMountRef.current = false;
}, [getRootState, emitter, state]);
const defaultOnUnhandledAction = React.useCallback(action => {
if (process.env.NODE_ENV === 'production') {
return;
}
const payload = action.payload;
let message = `The action '${action.type}'${payload ? ` with payload ${JSON.stringify(action.payload)}` : ''} was not handled by any navigator.`;
switch (action.type) {
case 'NAVIGATE':
case 'PUSH':
case 'REPLACE':
case 'JUMP_TO':
if (payload !== null && payload !== void 0 && payload.name) {
message += `\n\nDo you have a screen named '${payload.name}'?\n\nIf you're trying to navigate to a screen in a nested navigator, see https://reactnavigation.org/docs/nesting-navigators#navigating-to-a-screen-in-a-nested-navigator.`;
} else {
message += `\n\nYou need to pass the name of the screen to navigate to.\n\nSee https://reactnavigation.org/docs/navigation-actions for usage.`;
}
break;
case 'GO_BACK':
case 'POP':
case 'POP_TO_TOP':
message += `\n\nIs there any screen to go back to?`;
break;
case 'OPEN_DRAWER':
case 'CLOSE_DRAWER':
case 'TOGGLE_DRAWER':
message += `\n\nIs your screen inside a Drawer navigator?`;
break;
}
message += `\n\nThis is a development-only warning and won't be shown in production.`;
console.error(message);
}, []);
let element = /*#__PURE__*/React.createElement(_NavigationContainerRefContext.default.Provider, {
value: navigation
}, /*#__PURE__*/React.createElement(_useScheduleUpdate.ScheduleUpdateContext.Provider, {
value: scheduleContext
}, /*#__PURE__*/React.createElement(_NavigationBuilderContext.default.Provider, {
value: builderContext
}, /*#__PURE__*/React.createElement(_NavigationStateContext.default.Provider, {
value: context
}, /*#__PURE__*/React.createElement(_UnhandledActionContext.default.Provider, {
value: onUnhandledAction ?? defaultOnUnhandledAction
}, /*#__PURE__*/React.createElement(_EnsureSingleNavigator.default, null, children))))));
if (independent) {
// We need to clear any existing contexts for nested independent container to work correctly
element = /*#__PURE__*/React.createElement(_NavigationRouteContext.default.Provider, {
value: undefined
}, /*#__PURE__*/React.createElement(_NavigationContext.default.Provider, {
value: undefined
}, element));
}
return element;
});
var _default = BaseNavigationContainer;
exports.default = _default;
//# sourceMappingURL=BaseNavigationContainer.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,17 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var React = _interopRequireWildcard(require("react"));
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
/**
* Context which holds the values for the current navigation tree.
* Intended for use in SSR. This is not safe to use on the client.
*/
const CurrentRenderContext = /*#__PURE__*/React.createContext(undefined);
var _default = CurrentRenderContext;
exports.default = _default;
//# sourceMappingURL=CurrentRenderContext.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["CurrentRenderContext","React","createContext","undefined"],"sourceRoot":"../../src","sources":["CurrentRenderContext.tsx"],"mappings":";;;;;;AAAA;AAA+B;AAAA;AAE/B;AACA;AACA;AACA;AACA,MAAMA,oBAAoB,gBAAGC,KAAK,CAACC,aAAa,CAE9CC,SAAS,CAAC;AAAC,eAEEH,oBAAoB;AAAA"}

Some files were not shown because too many files have changed in this diff Show More