react-native-collapsible-segmented-view
Expo app
Collapsible Segmented View for React Native.
- View it with Expo.
- Checkout the examples for the source code of the Expo app.
Credits
The react-native-tab-view example app was used as template for the demos.
Demo
ios | android |
---|---|
Features
- Implements SegmentedControl and Fixed Material Tab Bar
- Lazy support
- Highly customizable
- Fully typed with TypeScript
Installation
Open a Terminal in the project root and run:
yarn add react-native-collapsible-segmented-view
expo install @react-native-community/segmented-control
Quick Start
import React from 'react'
import { View, StyleSheet, ListRenderItem, Text } from 'react-native'
import { Segmented } from 'react-native-collapsible-segmented-view'
const Header = () => {
return (
<View style={styles.box} pointerEvents="box-none">
<Text style={styles.text}>Collapsible Header</Text>
</View>
)
}
const Example: React.FC = () => {
return (
<Segmented.View header={Header}>
<Segmented.Segment label="A" component={SegmentA} />
<Segmented.Segment label="B" component={SegmentB} />
<Segmented.Segment label="C" component={SegmentC} />
</Segmented.View>
)
}
const buildRenderItem = (color0: string, color1: string) => {
const renderItem: ListRenderItem<number> = (data) => {
const backgroundColor = data.index % 2 === 0 ? color0 : color1
const color = data.index % 2 === 0 ? color1 : color0
return (
<View style={[styles.box, { backgroundColor }]}>
<Text style={[{ color }, styles.text]}>{data.index}</Text>
</View>
)
}
return renderItem
}
const buildSegment = (data: number[], color0: string, color1: string) => {
const Segment = () => {
return (
<Segmented.FlatList
data={data}
renderItem={buildRenderItem(color0, color1)}
keyExtractor={(v) => v + ''}
/>
)
}
return Segment
}
const data0 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
const data1 = [0, 1]
const SegmentA = buildSegment(data0, '#FBC02D', '#FFF9C4')
const SegmentB = buildSegment(data0, '#0097A7', '#B2EBF2')
const SegmentC = buildSegment(data1, '#D32F2F', '#FFCDD2')
const styles = StyleSheet.create({
box: {
justifyContent: 'center',
alignItems: 'center',
height: 250,
width: '100%',
},
text: {
fontSize: 32,
},
})
export default Example
API reference
Core
Segmented.View
Basic usage looks like this:
import { Segmented } from 'react-native-collapsible-segmented-view'
const Example = () => {
return (
<Segmented.View hader={MyHeader}>
<Segmented.Segment label="A" component={ScreenA} />
<Segmented.Segment label="B" component={ScreenB} />
<Segmented.Segment label="C" component={ScreenC} />
</Tabs.Container>
)
}
Props
name | type | default |
---|---|---|
animatedValue | Value | undefined |
new Animated.Value(0) |
containerHeight | number | undefined |
0 |
containerStyle | ViewStyle | undefined |
|
control | (props: ControlProps) => React.ReactElement |
IS_IOS ? SegmentedControl : MaterialTabBar |
controlHeight | number | undefined |
48 |
disableFadeIn | boolean | undefined |
false |
header | () => React.ReactElement |
|
headerHeight | number | undefined |
|
initialIndex | number | undefined |
0 |
lazy | boolean | undefined |
false |
topStyle | ViewStyle | undefined |
Segmented.Segment
Wrap your screens with Segmented.Segment
. Basic usage looks like this:
<Segmented.View ...>
<Segmented.Segment label="A" component={ScreenA} />
<Segmented.Segment label="B" component={ScreenB} />
<Segmented.Segment label="C" component={ScreenC} />
</Segmented.Container>
Props
name | type |
---|---|
component | () => React.ReactElement |
label | string |
Segmented.FlatList
Use like a regular flatlist.
Segmented.ScrollView
Use like a regular ScrollView.
Controls
SegmentedControl
Default iOS control. Props are passed down to the original SegmentedControl.
Example usage:
import {
Segmented,
SegmentedControl
} from 'react-native-collapsible-segmented-view
...
<Segmented.View
control={(props) => <SegmentedControl {...props} appearance='dark' />}
>
...
Props
name | type |
---|---|
containerStyle | ViewStyle | undefined |
MaterialTabBar
Default android control.
Example usage:
import {
Segmented,
MaterialTabBar
} from 'react-native-collapsible-segmented-view
...
<Segmented.View
control={(props) => <MaterialTabBar {...props} indicatorStyle='red' />}
>
...
Props
name | type | default |
---|---|---|
containerStyle | ViewStyle | undefined |
|
inactiveOpacity | number | undefined |
0.7 |
indicatorStyle | ViewStyle | undefined |
|
labelStyle | TextStyle | undefined |
|
pressColor | string | undefined |
DDDDDD |
pressOpacity | number | undefined |
IS_IOS ? 0.2 : 1 |
tabStyle | ViewStyle | undefined |
Hooks
useIsFocused
Returns true if the segment is focused, else returns false.
const isFocused = useIsFocused()
useSelectedIndex
Returns the current segment selected index.
const selectedIndex = useSelectedIndex()
useHeaderMeasurements
Returns translateY
interpolation and the height of the header. See the animated header example.
const { translateY, height } = useHeaderMeasurements()
Alternative libraries
If you are looking for a full-featured tab bar with swiping, scrollable tabs, dynamic rendering, snapping and diffClamp:
Contributing
While developing, you can run the example app to test your changes.
Please follow the angular commit message format.
Make sure your code passes TypeScript and ESLint. Run the following to verify:
yarn typescript
yarn lint
To fix formatting errors, run the following:
yarn lint -- --fix
Remember to add tests for your change if possible.
Documentation changes
Edit the README_TEMPLATE, or update the docstrings inside the src
folder, and run:
yarn docs