Skip to content

PedroBern/react-native-collapsible-segmented-view

Repository files navigation

react-native-collapsible-segmented-view

Build Status Version MIT License runs with expo

Expo app

Collapsible Segmented View for React Native.

Credits

The react-native-tab-view example app was used as template for the demos.

Demo

ios android

Features

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