Skip to content

Commit 51bc68a

Browse files
committed
TabController - support react-native-safe-area-context (#3928)
* TabController - support react-native-safe-area-context * SafeAre - support Android
1 parent 83d74c1 commit 51bc68a

File tree

3 files changed

+68
-61
lines changed
  • demo/src/screens/componentScreens/TabControllerScreen
  • docs/getting-started
  • packages/react-native-ui-lib/src/components/tabController

3 files changed

+68
-61
lines changed

demo/src/screens/componentScreens/TabControllerScreen/index.tsx

Lines changed: 58 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import _ from 'lodash';
22
import React, {Component} from 'react';
33
import {ActivityIndicator, StyleSheet} from 'react-native';
4+
import {SafeAreaProvider} from 'react-native-safe-area-context';
45
import {
56
Assets,
67
TabController,
@@ -162,63 +163,65 @@ class TabControllerScreen extends Component<{}, State> {
162163
render() {
163164
const {key, initialIndex, asCarousel, centerSelected, fewItems, items} = this.state;
164165
return (
165-
<View flex bg-$backgroundDefault>
166-
<TabController
167-
key={key}
168-
ref={this.tabController}
169-
asCarousel={asCarousel}
170-
initialIndex={initialIndex}
171-
onChangeIndex={this.onChangeIndex}
172-
items={items}
173-
>
174-
<TabController.TabBar
175-
// items={items}
166+
<SafeAreaProvider style={{flex: 1}}>
167+
<View flex bg-$backgroundDefault>
168+
<TabController
176169
key={key}
177-
// uppercase
178-
// indicatorStyle={{backgroundColor: 'green', height: 3}}
179-
// indicatorInsets={0}
180-
spreadItems={!fewItems}
181-
backgroundColor={fewItems ? 'transparent' : undefined}
182-
// labelColor={'green'}
183-
// selectedLabelColor={'red'}
184-
labelStyle={styles.labelStyle}
185-
selectedLabelStyle={styles.selectedLabelStyle}
186-
// iconColor={'green'}
187-
// selectedIconColor={'blue'}
188-
enableShadow
189-
activeBackgroundColor={Colors.$backgroundPrimaryMedium}
190-
centerSelected={centerSelected}
191-
/>
192-
{this.renderTabPages()}
193-
</TabController>
194-
<View absB left margin-20 marginB-100 style={{zIndex: 1}}>
195-
<Button
196-
bg-green10={!fewItems}
197-
bg-green30={fewItems}
198-
label={fewItems ? 'Show Many Items' : 'Show Few Items'}
199-
marginB-12
200-
size={Button.sizes.small}
201-
onPress={this.toggleItemsCount}
202-
/>
203-
<Button
204-
bg-grey20={!asCarousel}
205-
bg-green30={asCarousel}
206-
label={`Carousel : ${asCarousel ? 'ON' : 'OFF'}`}
207-
marginB-12
208-
size={Button.sizes.small}
209-
onPress={this.toggleCarouselMode}
210-
/>
211-
<Button
212-
bg-grey20={!centerSelected}
213-
bg-green30={centerSelected}
214-
label={`centerSelected : ${centerSelected ? 'ON' : 'OFF'}`}
215-
size={Button.sizes.small}
216-
marginB-12
217-
onPress={this.toggleCenterSelected}
218-
/>
219-
<Button label="setTab (Imperative)" bg-green10 onPress={this.setTab} size={Button.sizes.small}/>
170+
ref={this.tabController}
171+
asCarousel={asCarousel}
172+
initialIndex={initialIndex}
173+
onChangeIndex={this.onChangeIndex}
174+
items={items}
175+
>
176+
<TabController.TabBar
177+
// items={items}
178+
key={key}
179+
// uppercase
180+
// indicatorStyle={{backgroundColor: 'green', height: 3}}
181+
// indicatorInsets={0}
182+
spreadItems={!fewItems}
183+
backgroundColor={fewItems ? 'transparent' : undefined}
184+
// labelColor={'green'}
185+
// selectedLabelColor={'red'}
186+
labelStyle={styles.labelStyle}
187+
selectedLabelStyle={styles.selectedLabelStyle}
188+
// iconColor={'green'}
189+
// selectedIconColor={'blue'}
190+
enableShadow
191+
activeBackgroundColor={Colors.$backgroundPrimaryMedium}
192+
centerSelected={centerSelected}
193+
/>
194+
{this.renderTabPages()}
195+
</TabController>
196+
<View absB left margin-20 marginB-100 style={{zIndex: 1}}>
197+
<Button
198+
bg-green10={!fewItems}
199+
bg-green30={fewItems}
200+
label={fewItems ? 'Show Many Items' : 'Show Few Items'}
201+
marginB-12
202+
size={Button.sizes.small}
203+
onPress={this.toggleItemsCount}
204+
/>
205+
<Button
206+
bg-grey20={!asCarousel}
207+
bg-green30={asCarousel}
208+
label={`Carousel : ${asCarousel ? 'ON' : 'OFF'}`}
209+
marginB-12
210+
size={Button.sizes.small}
211+
onPress={this.toggleCarouselMode}
212+
/>
213+
<Button
214+
bg-grey20={!centerSelected}
215+
bg-green30={centerSelected}
216+
label={`centerSelected : ${centerSelected ? 'ON' : 'OFF'}`}
217+
size={Button.sizes.small}
218+
marginB-12
219+
onPress={this.toggleCenterSelected}
220+
/>
221+
<Button label="setTab (Imperative)" bg-green10 onPress={this.setTab} size={Button.sizes.small}/>
222+
</View>
220223
</View>
221-
</View>
224+
</SafeAreaProvider>
222225
);
223226
}
224227
}

docs/getting-started/setup.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ UILib supports additional features through optional dependencies. These packages
4242
| @react-native-community/blur | Card component's blur effects |
4343
| @react-native-community/datetimepicker | Date/time picker components |
4444
| @react-native-community/netinfo | Network connectivity features |
45-
| react-native-safe-area-context | support useSafeAreaInsets inside and usages of Modal |
45+
| react-native-safe-area-context | support useSafeAreaInsets inside Modal, usages of Modal and TabController |
4646
| react-native-haptic-feedback | Haptic feedback functionality |
4747
| react-native-svg | SVG-based components |
4848
| react-native-shimmer-placeholder | Shimmer loading effects |

packages/react-native-ui-lib/src/components/tabController/index.tsx

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import _ from 'lodash';
33
import React, {PropsWithChildren, useMemo, useEffect, useState, useCallback} from 'react';
44
import {useAnimatedReaction, useSharedValue, withTiming, runOnJS} from 'react-native-reanimated';
5+
import {SafeAreaContextPackage} from '../../optionalDependencies';
56
import {useOrientation, useThemeProps} from '../../hooks';
67
import {Constants} from '../../commons/new';
78
import TabBarContext from './TabBarContext';
@@ -52,9 +53,11 @@ export interface TabControllerProps {
5253
children?: React.ReactNode;
5354
}
5455

55-
const getScreenWidth = (useSafeArea: boolean) => {
56-
const {left, right} = Constants.getSafeAreaInsets();
57-
return Constants.windowWidth - (useSafeArea && Constants.isIphoneX ? left + right : 0);
56+
const useSafeAreaInsets = SafeAreaContextPackage?.useSafeAreaInsets ?? (() => Constants.getSafeAreaInsets());
57+
58+
59+
const getScreenWidth = (useSafeArea: boolean, left: number, right: number) => {
60+
return Constants.windowWidth - (useSafeArea ? left + right : 0);
5861
};
5962

6063
/**
@@ -75,15 +78,16 @@ const TabController = React.forwardRef((props: PropsWithChildren<TabControllerPr
7578
useSafeArea = false,
7679
children
7780
} = themeProps;
78-
const [screenWidth, setScreenWidth] = useState<number>(getScreenWidth(useSafeArea));
81+
const {left, right} = useSafeAreaInsets();
82+
const [screenWidth, setScreenWidth] = useState<number>(getScreenWidth(useSafeArea, left, right));
7983

8084
if (items?.length < 2) {
8185
console.warn('TabController component expect a minimum of 2 items');
8286
}
8387

8488
useOrientation({
8589
onOrientationChange: () => {
86-
setScreenWidth(getScreenWidth(useSafeArea));
90+
setScreenWidth(getScreenWidth(useSafeArea, left, right));
8791
}
8892
});
8993

0 commit comments

Comments
 (0)