@bigbinary/neetoui-rn 0.0.255 → 0.0.256

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts CHANGED
@@ -326,27 +326,27 @@ type ChatInputProps = {
326
326
  onOptionChange?: (option: string) => void;
327
327
  onChangeText: (text: string) => void;
328
328
  onForward?: () => void;
329
- onCannedResponse?: () => void;
329
+ onCannedResponse?: () => void;
330
330
  toEmails?: string;
331
331
  onReply?: () => void;
332
332
  onAddNote?: () => void;
333
333
  onAttachment?: () => void;
334
334
  attachmentsCount?: number;
335
- Attachments?: React.FC;
335
+ Attachments?: React.FC;
336
336
  showCannedResponsesFor?: Array<"REPLY" | "NOTE" | "FORWARD">;
337
337
  showSuggestionsFor?: Array<"REPLY" | "NOTE" | "FORWARD">;
338
338
  disabled?: boolean;
339
339
  suggestions: Array<{
340
- name: string
341
- imageUrl: string
342
- id: string
340
+ name: string;
341
+ imageUrl: string;
342
+ id: string;
343
343
  }>;
344
344
  };
345
345
 
346
346
  type LineLoaderProps = {
347
- backgroundColor?: string,
348
- foregroundColor?: string,
349
- height?: number,
347
+ backgroundColor?: string;
348
+ foregroundColor?: string;
349
+ height?: number;
350
350
  isLoading?: boolean;
351
351
  };
352
352
 
@@ -526,10 +526,6 @@ interface NavigationProps {
526
526
  }
527
527
  interface SegmentedTopBarProps extends MaterialTopTabBarProps {
528
528
  state?: SegmentedTopBarStateProps;
529
- inactiveSegmentStyle?: ViewStyle;
530
- activeSegmentStyle?: ViewStyle;
531
- activeTextStyle?: TouchableProps;
532
- inactiveTextStyle?: TouchableProps;
533
529
  navigation?: NavigationProps;
534
530
  height?: number;
535
531
  descriptors?: object;
@@ -0,0 +1 @@
1
+ var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:true});exports.Indicator=void 0;var _react=_interopRequireWildcard(require("react"));var _reactNative=require("react-native");var _propTypes=_interopRequireDefault(require("prop-types"));var _reactNativeReanimated=_interopRequireWildcard(require("react-native-reanimated"));var _reactNativeSizeMatters=require("react-native-size-matters");var _theme=require("../../theme");var _this=this,_jsxFileName="/home/runner/work/neeto-ui-rn/neeto-ui-rn/src/components/SegmentedTopBar/Indicator.jsx";function _getRequireWildcardCache(nodeInterop){if(typeof WeakMap!=="function")return null;var cacheBabelInterop=new WeakMap();var cacheNodeInterop=new WeakMap();return(_getRequireWildcardCache=function _getRequireWildcardCache(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 springConfig={mass:1,overshootClamping:true,restSpeedThreshold:0.5,restDisplacementThreshold:0.5};var spacing=(0,_reactNativeSizeMatters.moderateScale)(6);var Indicator=function Indicator(_ref){var measure=_ref.measure;var x=measure.x,width=measure.width,height=measure.height;var translateX=(0,_reactNativeReanimated.useSharedValue)(0);var animatedWidth=(0,_reactNativeReanimated.useSharedValue)(0);(0,_react.useEffect)(function(){(0,_reactNativeReanimated.cancelAnimation)(translateX);(0,_reactNativeReanimated.cancelAnimation)(animatedWidth);translateX.value=(0,_reactNativeReanimated.withSpring)(x+spacing/2,springConfig);animatedWidth.value=(0,_reactNativeReanimated.withSpring)(width-spacing,springConfig);},[animatedWidth,translateX,width,x]);var tabTranslateAnimatedStyles=(0,_reactNativeReanimated.useAnimatedStyle)(function(){var _f=function _f(){return{transform:[{translateX:translateX.value}],width:animatedWidth.value};};_f._closure={translateX:translateX,animatedWidth:animatedWidth};_f.asString="function _f(){const{translateX,animatedWidth}=jsThis._closure;{return{transform:[{translateX:translateX.value}],width:animatedWidth.value};}}";_f.__workletHash=12388547266078;_f.__location="/home/runner/work/neeto-ui-rn/neeto-ui-rn/src/components/SegmentedTopBar/Indicator.jsx (38:54)";_f.__optimalization=3;return _f;}());return _react.default.createElement(_reactNativeReanimated.default.View,{style:[styles.movingSegmentStyle,{height:height-spacing},tabTranslateAnimatedStyles],__self:_this,__source:{fileName:_jsxFileName,lineNumber:44,columnNumber:5}});};exports.Indicator=Indicator;var styles=_reactNative.StyleSheet.create({movingSegmentStyle:{position:"absolute",top:spacing/2,borderRadius:(0,_reactNativeSizeMatters.moderateScale)(6),backgroundColor:_theme.theme.colors.background.primary,shadowColor:_theme.theme.colors.background.grey,shadowOffset:{width:0,height:5},shadowOpacity:0.34,shadowRadius:6.27,elevation:10}});Indicator.propTypes={measure:_propTypes.default.shape({x:_propTypes.default.number.isRequired,width:_propTypes.default.number.isRequired,height:_propTypes.default.number.isRequired}).isRequired};
@@ -0,0 +1 @@
1
+ var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:true});exports.Tab=void 0;var _react=_interopRequireWildcard(require("react"));var _reactNative=require("react-native");var _propTypes=_interopRequireDefault(require("prop-types"));var _=require("./..");var _this=this,_jsxFileName="/home/runner/work/neeto-ui-rn/neeto-ui-rn/src/components/SegmentedTopBar/Tab.jsx";function _getRequireWildcardCache(nodeInterop){if(typeof WeakMap!=="function")return null;var cacheBabelInterop=new WeakMap();var cacheNodeInterop=new WeakMap();return(_getRequireWildcardCache=function _getRequireWildcardCache(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 Tab=(0,_react.forwardRef)(function(_ref,ref){var label=_ref.label,value=_ref.value,navigation=_ref.navigation,flex=_ref.flex;var handleOnPress=(0,_react.useCallback)(function(){return navigation.navigate(value);},[navigation,value]);return _react.default.createElement(_reactNative.View,{ref:ref,style:{flex:flex},__self:_this,__source:{fileName:_jsxFileName,lineNumber:15,columnNumber:5}},_react.default.createElement(_.Touchable,{flex:1,justifyContent:"center",onPress:handleOnPress,__self:_this,__source:{fileName:_jsxFileName,lineNumber:16,columnNumber:7}},_react.default.createElement(_.Typography,{fontFamily:"sf500",fontSize:"xs",numberOfLines:1,textAlign:"center",__self:_this,__source:{fileName:_jsxFileName,lineNumber:17,columnNumber:9}},label)));});exports.Tab=Tab;Tab.displayName="Tab";Tab.propTypes={flex:_propTypes.default.number,label:_propTypes.default.string.isRequired,value:_propTypes.default.string.isRequired,navigation:_propTypes.default.object};
@@ -0,0 +1 @@
1
+ var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:true});exports.SegmentedTopBar=void 0;var _slicedToArray2=_interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));var _react=_interopRequireWildcard(require("react"));var _reactNative=require("react-native");var _propTypes=_interopRequireDefault(require("prop-types"));var _reactNativeSizeMatters=require("react-native-size-matters");var _theme=require("../../theme");var _Indicator=require("./Indicator");var _Tab=require("./Tab");var _this=this,_jsxFileName="/home/runner/work/neeto-ui-rn/neeto-ui-rn/src/components/SegmentedTopBar/index.jsx";function _getRequireWildcardCache(nodeInterop){if(typeof WeakMap!=="function")return null;var cacheBabelInterop=new WeakMap();var cacheNodeInterop=new WeakMap();return(_getRequireWildcardCache=function _getRequireWildcardCache(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 SegmentedTopBar=function SegmentedTopBar(_ref){var _ref$state=_ref.state,routes=_ref$state.routes,index=_ref$state.index,navigation=_ref.navigation,height=_ref.height,descriptors=_ref.descriptors;var containerRef=(0,_react.useRef)();var _useState=(0,_react.useState)([]),_useState2=(0,_slicedToArray2.default)(_useState,2),measures=_useState2[0],setMeasures=_useState2[1];var tabsData=(0,_react.useMemo)(function(){return routes.map(function(_ref2){var _ref3,_options$tabBarLabel;var key=_ref2.key,name=_ref2.name;var options=descriptors[key].options;var label=(_ref3=(_options$tabBarLabel=options.tabBarLabel)!=null?_options$tabBarLabel:options.title)!=null?_ref3:name;return{label:label,value:name,ref:(0,_react.createRef)()};});},[]);(0,_react.useLayoutEffect)(function(){var _measures=[];tabsData.forEach(function(_ref4){var ref=_ref4.ref;ref.current.measureLayout(containerRef.current,function(x,y,width,height){_measures.push({x:x,y:y,width:width,height:height});if(_measures.length===tabsData.length){setMeasures(_measures);}});});},[measures.length]);return _react.default.createElement(_reactNative.View,{height:height,ref:containerRef,style:styles.container,__self:_this,__source:{fileName:_jsxFileName,lineNumber:94,columnNumber:5}},measures.length>0&&_react.default.createElement(_Indicator.Indicator,{measure:measures[index],__self:_this,__source:{fileName:_jsxFileName,lineNumber:95,columnNumber:31}}),tabsData.map(function(_ref5){var label=_ref5.label,value=_ref5.value,ref=_ref5.ref;return _react.default.createElement(_Tab.Tab,{flex:tabsData.length>3?label.length:1,key:value,label:label,navigation:navigation,ref:ref,value:value,__self:_this,__source:{fileName:_jsxFileName,lineNumber:97,columnNumber:9}});}));};exports.SegmentedTopBar=SegmentedTopBar;var styles=_reactNative.StyleSheet.create({container:{flexDirection:"row",borderRadius:(0,_reactNativeSizeMatters.moderateScale)(6),backgroundColor:_theme.theme.colors.background.secondary}});SegmentedTopBar.propTypes={state:_propTypes.default.object,height:_propTypes.default.number,navigation:_propTypes.default.object,descriptors:_propTypes.default.object};SegmentedTopBar.defaultProps={tabs:[],height:(0,_reactNativeSizeMatters.moderateScale)(36)};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bigbinary/neetoui-rn",
3
- "version": "0.0.255",
3
+ "version": "0.0.256",
4
4
  "main": "lib/index.js",
5
5
  "author": "BigBinary",
6
6
  "license": "MIT",
@@ -0,0 +1,77 @@
1
+ import React, { useEffect } from "react";
2
+ import { StyleSheet } from "react-native";
3
+
4
+ import PropTypes from "prop-types";
5
+ import Animated, {
6
+ cancelAnimation,
7
+ useAnimatedStyle,
8
+ useSharedValue,
9
+ withSpring,
10
+ } from "react-native-reanimated";
11
+ import { moderateScale } from "react-native-size-matters";
12
+
13
+ import { theme } from "@theme";
14
+
15
+ const springConfig = {
16
+ mass: 1,
17
+ overshootClamping: true,
18
+ restSpeedThreshold: 0.5,
19
+ restDisplacementThreshold: 0.5,
20
+ };
21
+
22
+ const spacing = moderateScale(6);
23
+
24
+ export const Indicator = ({ measure }) => {
25
+ const { x, width, height } = measure;
26
+
27
+ const translateX = useSharedValue(0);
28
+ const animatedWidth = useSharedValue(0);
29
+
30
+ useEffect(() => {
31
+ cancelAnimation(translateX);
32
+ cancelAnimation(animatedWidth);
33
+
34
+ translateX.value = withSpring(x + spacing / 2, springConfig);
35
+ animatedWidth.value = withSpring(width - spacing, springConfig);
36
+ }, [animatedWidth, translateX, width, x]);
37
+
38
+ const tabTranslateAnimatedStyles = useAnimatedStyle(() => ({
39
+ transform: [{ translateX: translateX.value }],
40
+ width: animatedWidth.value,
41
+ }));
42
+
43
+ return (
44
+ <Animated.View
45
+ style={[
46
+ styles.movingSegmentStyle,
47
+ { height: height - spacing },
48
+ tabTranslateAnimatedStyles,
49
+ ]}
50
+ />
51
+ );
52
+ };
53
+
54
+ const styles = StyleSheet.create({
55
+ movingSegmentStyle: {
56
+ position: "absolute",
57
+ top: spacing / 2,
58
+ borderRadius: moderateScale(6),
59
+ backgroundColor: theme.colors.background.primary,
60
+ shadowColor: theme.colors.background.grey,
61
+ shadowOffset: {
62
+ width: 0,
63
+ height: 5,
64
+ },
65
+ shadowOpacity: 0.34,
66
+ shadowRadius: 6.27,
67
+ elevation: 10,
68
+ },
69
+ });
70
+
71
+ Indicator.propTypes = {
72
+ measure: PropTypes.shape({
73
+ x: PropTypes.number.isRequired,
74
+ width: PropTypes.number.isRequired,
75
+ height: PropTypes.number.isRequired,
76
+ }).isRequired,
77
+ };
@@ -0,0 +1,37 @@
1
+ import React, { forwardRef, useCallback } from "react";
2
+ import { View } from "react-native";
3
+
4
+ import PropTypes from "prop-types";
5
+
6
+ import { Typography, Touchable } from "@components";
7
+
8
+ export const Tab = forwardRef(({ label, value, navigation, flex }, ref) => {
9
+ const handleOnPress = useCallback(
10
+ () => navigation.navigate(value),
11
+ [navigation, value]
12
+ );
13
+
14
+ return (
15
+ <View ref={ref} style={{ flex }}>
16
+ <Touchable flex={1} justifyContent="center" onPress={handleOnPress}>
17
+ <Typography
18
+ fontFamily="sf500"
19
+ fontSize="xs"
20
+ numberOfLines={1}
21
+ textAlign="center"
22
+ >
23
+ {label}
24
+ </Typography>
25
+ </Touchable>
26
+ </View>
27
+ );
28
+ });
29
+
30
+ Tab.displayName = "Tab";
31
+
32
+ Tab.propTypes = {
33
+ flex: PropTypes.number,
34
+ label: PropTypes.string.isRequired,
35
+ value: PropTypes.string.isRequired,
36
+ navigation: PropTypes.object,
37
+ };
@@ -0,0 +1,128 @@
1
+ import React, {
2
+ createRef,
3
+ useState,
4
+ useMemo,
5
+ useRef,
6
+ useLayoutEffect,
7
+ } from "react";
8
+ import { StyleSheet, View } from "react-native";
9
+
10
+ import PropTypes from "prop-types";
11
+ import { moderateScale } from "react-native-size-matters";
12
+
13
+ import { theme } from "@theme";
14
+
15
+ import { Indicator } from "./Indicator";
16
+ import { Tab } from "./Tab";
17
+
18
+ /**
19
+ *
20
+ * A Segment Picker component that provides toggling between two or more views.
21
+ *
22
+ * <div class="screenshots">
23
+ * <img src="screenshots/toptabbar/toptabbar-1.png" />
24
+ * <img src="screenshots/toptabbar/toptabbar-2.png" />
25
+ * </div>
26
+ *
27
+ * ## Usage
28
+ * ```js
29
+ * import * as React from 'react';
30
+ * import { createMaterialTopTabNavigator } from "@react-navigation/material-top-tabs";
31
+ * import { NavigationContainer } from "@react-navigation/native";
32
+ *
33
+ * import { SegmentedTopBar } from '@bigbinary/neetoui-rn';
34
+ *
35
+ * const Tab = createMaterialTopTabNavigator();
36
+ *
37
+ * export default function Main(){
38
+ *
39
+ * return (
40
+ * <NavigationContainer>
41
+ * <Tab.Navigator tabBar={props => <SegmentedTopBar {...props} />} >
42
+ * <Tab.Screen
43
+ * name="Home"
44
+ * component={HomeScreen}
45
+ * />
46
+ *
47
+ * <Tab.Screen
48
+ * name="Settings"
49
+ * component={SettingsScreen}
50
+ * />
51
+ * </Tab.Navigator>
52
+ * </NavigationContainer>
53
+ * );
54
+ * }
55
+ * ```
56
+ */
57
+
58
+ export const SegmentedTopBar = ({
59
+ state: { routes, index },
60
+ navigation,
61
+ height,
62
+ descriptors,
63
+ }) => {
64
+ const containerRef = useRef();
65
+
66
+ const [measures, setMeasures] = useState([]);
67
+
68
+ const tabsData = useMemo(
69
+ () =>
70
+ routes.map(({ key, name }) => {
71
+ const { options } = descriptors[key];
72
+ const label = options.tabBarLabel ?? options.title ?? name;
73
+
74
+ return { label, value: name, ref: createRef() };
75
+ }),
76
+ []
77
+ );
78
+
79
+ useLayoutEffect(() => {
80
+ const _measures = [];
81
+
82
+ tabsData.forEach(({ ref }) => {
83
+ ref.current.measureLayout(containerRef.current, (x, y, width, height) => {
84
+ _measures.push({ x, y, width, height });
85
+
86
+ if (_measures.length === tabsData.length) {
87
+ setMeasures(_measures);
88
+ }
89
+ });
90
+ });
91
+ }, [measures.length]);
92
+
93
+ return (
94
+ <View height={height} ref={containerRef} style={styles.container}>
95
+ {measures.length > 0 && <Indicator measure={measures[index]} />}
96
+ {tabsData.map(({ label, value, ref }) => (
97
+ <Tab
98
+ flex={tabsData.length > 3 ? label.length : 1}
99
+ key={value}
100
+ label={label}
101
+ navigation={navigation}
102
+ ref={ref}
103
+ value={value}
104
+ />
105
+ ))}
106
+ </View>
107
+ );
108
+ };
109
+
110
+ const styles = StyleSheet.create({
111
+ container: {
112
+ flexDirection: "row",
113
+ borderRadius: moderateScale(6),
114
+ backgroundColor: theme.colors.background.secondary,
115
+ },
116
+ });
117
+
118
+ SegmentedTopBar.propTypes = {
119
+ state: PropTypes.object,
120
+ height: PropTypes.number,
121
+ navigation: PropTypes.object,
122
+ descriptors: PropTypes.object,
123
+ };
124
+
125
+ SegmentedTopBar.defaultProps = {
126
+ tabs: [],
127
+ height: moderateScale(36),
128
+ };
@@ -1,211 +0,0 @@
1
- import React, { useEffect } from "react";
2
- import { Dimensions, Platform, StyleSheet } from "react-native";
3
-
4
- import PropTypes from "prop-types";
5
- import Animated, {
6
- useAnimatedStyle,
7
- useSharedValue,
8
- withSpring,
9
- } from "react-native-reanimated";
10
- import { moderateScale } from "react-native-size-matters";
11
-
12
- import { Typography, Touchable } from "@components";
13
- import { theme } from "@theme";
14
-
15
- const defaultShadowStyle = {
16
- shadowColor: theme.colors.background.grey800,
17
- shadowOffset: {
18
- width: 0,
19
- height: moderateScale(2),
20
- },
21
- shadowOpacity: 0.23,
22
- shadowRadius: moderateScale(2.62),
23
- elevation: 4,
24
- };
25
-
26
- // eslint-disable-next-line @bigbinary/neeto/no-dangling-constants
27
- const DEFAULT_SPRING_CONFIG = {
28
- stiffness: 150,
29
- damping: 20,
30
- mass: 1,
31
- overshootClamping: false,
32
- restSpeedThreshold: 0.001,
33
- restDisplacementThreshold: 0.001,
34
- };
35
-
36
- // So that it stretches in landscape mode.
37
- const width = Dimensions.get("screen").width - moderateScale(32);
38
-
39
- /**
40
- *
41
- * A Segment Picker component that provides toggling between two or more views.
42
- *
43
- * <div class="screenshots">
44
- * <img src="screenshots/toptabbar/toptabbar-1.png" />
45
- * <img src="screenshots/toptabbar/toptabbar-2.png" />
46
- * </div>
47
- *
48
- * ## Usage
49
- * ```js
50
- * import * as React from 'react';
51
- * import { createMaterialTopTabNavigator } from "@react-navigation/material-top-tabs";
52
- * import { NavigationContainer } from "@react-navigation/native";
53
- *
54
- * import { SegmentedTopBar } from '@bigbinary/neetoui-rn';
55
- *
56
- * const Tab = createMaterialTopTabNavigator();
57
- *
58
- * export default function Main(){
59
- *
60
- * return (
61
- * <NavigationContainer>
62
- * <Tab.Navigator tabBar={props => <SegmentedTopBar {...props} />} >
63
- * <Tab.Screen
64
- * name="Home"
65
- * component={HomeScreen}
66
- * />
67
- *
68
- * <Tab.Screen
69
- * name="Settings"
70
- * component={SettingsScreen}
71
- * />
72
- * </Tab.Navigator>
73
- * </NavigationContainer>
74
- * );
75
- * }
76
- * ```
77
- */
78
-
79
- export const SegmentedTopBar = ({
80
- state: { routes, index },
81
- inactiveSegmentStyle,
82
- activeSegmentStyle,
83
- activeTextStyle,
84
- inactiveTextStyle,
85
- navigation,
86
- height,
87
- descriptors,
88
- }) => {
89
- const translateValue = (width - 4) / routes?.length;
90
- const tabTranslateValue = useSharedValue(0);
91
- useEffect(() => {
92
- tabTranslateValue.value = withSpring(
93
- index * Number(translateValue),
94
- DEFAULT_SPRING_CONFIG
95
- );
96
- }, [index]);
97
-
98
- const tabTranslateAnimatedStyles = useAnimatedStyle(() => ({
99
- transform: [{ translateX: tabTranslateValue.value }],
100
- }));
101
-
102
- return (
103
- <Animated.View
104
- style={[styles.defaultSegmentedControlWrapper, inactiveSegmentStyle]}
105
- >
106
- <Animated.View
107
- style={[
108
- styles.movingSegmentStyle,
109
- activeSegmentStyle,
110
- defaultShadowStyle,
111
- StyleSheet.absoluteFill,
112
- {
113
- width: (width - moderateScale(4)) / routes?.length,
114
- },
115
- tabTranslateAnimatedStyles,
116
- ]}
117
- />
118
- {routes.map((route, i) => {
119
- const currentIndexTextStyle =
120
- index === index + 1 ? activeTextStyle : inactiveTextStyle;
121
- const { options } = descriptors[route.key];
122
- const label =
123
- options.tabBarLabel !== undefined
124
- ? options.tabBarLabel
125
- : options.title !== undefined
126
- ? options.title
127
- : route.name;
128
-
129
- return (
130
- <Touchable
131
- alignItems="center"
132
- elevation={Platform.OS === "android" ? 9 : null}
133
- flex={1}
134
- height={height}
135
- justifyContent="center"
136
- key={i}
137
- onPress={() => navigation.navigate(route.name)}
138
- {...currentIndexTextStyle}
139
- >
140
- <Typography
141
- color="font.grey800"
142
- fontFamily="sf500"
143
- fontSize="xs"
144
- textAlign="center"
145
- >
146
- {label}
147
- </Typography>
148
- </Touchable>
149
- );
150
- })}
151
- </Animated.View>
152
- );
153
- };
154
-
155
- const styles = StyleSheet.create({
156
- segmentedControlWrapper: {
157
- display: "flex",
158
- flexDirection: "row",
159
- alignItems: "center",
160
- borderRadius: moderateScale(8),
161
- width,
162
- },
163
- defaultSegmentedControlWrapper: {
164
- position: "relative",
165
- display: "flex",
166
- flexDirection: "row",
167
- alignItems: "center",
168
- borderRadius: moderateScale(8),
169
- backgroundColor: "#F6F6FA",
170
- width,
171
- marginBottom: moderateScale(5),
172
- },
173
- movingSegmentStyle: {
174
- top: 0,
175
- marginVertical: moderateScale(2),
176
- marginHorizontal: moderateScale(2),
177
- borderRadius: moderateScale(6),
178
- backgroundColor: "#FFFFFF",
179
- },
180
- });
181
-
182
- SegmentedTopBar.propTypes = {
183
- /**
184
- * Navigation routes and additional data.
185
- */
186
- state: PropTypes.object,
187
- /**
188
- * To change the inactive segment container style.
189
- */
190
- inactiveSegmentStyle: PropTypes.object,
191
- /**
192
- * To change the active segment container style.
193
- */
194
- activeSegmentStyle: PropTypes.object,
195
- /**
196
- * To change the inactive segment font style.
197
- */
198
- inactiveTextStyle: PropTypes.object,
199
- /**
200
- * To change the active segment font style.
201
- */
202
- activeTextStyle: PropTypes.object,
203
- height: PropTypes.number,
204
- navigation: PropTypes.object,
205
- descriptors: PropTypes.object,
206
- };
207
-
208
- SegmentedTopBar.defaultProps = {
209
- tabs: [],
210
- height: moderateScale(32),
211
- };