Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add pager view + use rntb tabbar #5

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ version: 2

defaults: &defaults
docker:
- image: circleci/node:10
- image: circleci/node:12
working_directory: ~/project

jobs:
Expand Down
101 changes: 73 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

# Expo app

Collapsible Segmented View for React Native.
Collapsible Segmented View for React Native

- [View it with Expo](https://expo.io/@pedrobern/react-native-collapsible-segmented-view-demos).
- Checkout the [examples](https://github.com/PedroBern/react-native-collapsible-segmented-view/tree/main/example) for the source code of the Expo app.
Expand All @@ -48,7 +48,8 @@ The [react-native-tab-view](https://github.com/satya164/react-native-tab-view) e

# Features

- Implements [SegmentedControl](https://developer.apple.com/design/human-interface-guidelines/ios/controls/segmented-controls/) and [Fixed Material Tab Bar](https://material.io/components/tabs)
- [Material Tab Bar](https://github.com/satya164/react-native-tab-view#tabbar) for Android
- [SegmentedControl](https://github.com/react-native-segmented-control/segmented-control#react-native-segmented-controlsegmented-control) for iOS
- Lazy support
- Highly customizable
- Fully typed with [TypeScript](https://typescriptlang.org)
Expand All @@ -61,6 +62,8 @@ Open a Terminal in the project root and run:
yarn add react-native-collapsible-segmented-view

expo install @react-native-community/segmented-control

yarn add react-native-tab-view react-native-pager-view
```

# Quick Start
Expand All @@ -80,10 +83,10 @@ const Header = () => {

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 renderHeader={Header}>
<Segmented.Segment id="A" title="A" component={SegmentA} />
<Segmented.Segment id="B" title="B" component={SegmentB} />
<Segmented.Segment id="C" title="C" component={SegmentC} />
</Segmented.View>
)
}
Expand Down Expand Up @@ -151,9 +154,9 @@ 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} />
<Segmented.Segment id="A" component={ScreenA} />
<Segmented.Segment id="B" component={ScreenB} />
<Segmented.Segment id="C" component={ScreenC} />
</Tabs.Container>
)
}
Expand All @@ -163,16 +166,17 @@ const Example = () => {

|name|type|default|
|:----:|:----:|:----:|
|animatedValue|`Value \| undefined`|`new Animated.Value(0)`|
|animatedValue|`Value \| undefined`||
|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`|
|keyboardDismissMode|`"none" \| "on-drag" \| "auto" \| undefined`||
|lazy|`boolean \| undefined`|`false`|
|renderControl|`FC<ControlProps> \| ((props: ControlProps) => ReactElement<any, string \| ((props: any) => ReactElement<any, string \| ... \| (new (props: any) => Component<any, any, any>)> \| null) \| (new (props: any) => Component<...>)>) \| undefined`||
|renderHeader|`FC<{}> \| (() => ReactElement<any, string \| ((props: any) => ReactElement<any, string \| ... \| (new (props: any) => Component<any, any, any>)> \| null) \| (new (props: any) => Component<...>)>) \| undefined`||
|swipeEnabled|`boolean \| undefined`|`true`|
|topStyle|`ViewStyle \| undefined`||

### Segmented.Segment
Expand All @@ -181,18 +185,23 @@ Wrap your screens with `Segmented.Segment`. Basic usage looks like this:

```tsx
<Segmented.View ...>
<Segmented.Segment label="A" component={ScreenA} />
<Segmented.Segment label="B" component={ScreenB} />
<Segmented.Segment label="C" component={ScreenC} />
<Segmented.Segment id="A" component={ScreenA} />
<Segmented.Segment id="B" component={ScreenB} />
<Segmented.Segment id="C" component={ScreenC} />
</Segmented.Container>
```

#### Props

|name|type|
|:----:|:----:|
|accessibilityLabel|`string \| undefined`|
|accessible|`boolean \| undefined`|
|component|`() => React.ReactElement`|
|label|`string`|
|icon|`string \| undefined`|
|id|`string`|
|testID|`string \| undefined`|
|title|`string \| undefined`|

### Segmented.FlatList

Expand Down Expand Up @@ -236,7 +245,7 @@ import {

### MaterialTabBar

Default android control.
Default android control. Props are passed to the original [TabBar](https://github.com/satya164/react-native-tab-view#tabbar).

Example usage:

Expand All @@ -249,22 +258,58 @@ import {
...

<Segmented.View
control={(props) => <MaterialTabBar {...props} indicatorStyle='red' />}
control={(props) => <MaterialTabBar {...props} />}
>
...
```

Rendering icons:

```tsx
const renderIcon={({ route, focused, color }) => (
<Icon
name={route.icon}
color={color}
/>
)}


<Segmented.View
control={(props) => (
<MaterialTabBar renderIcon={renderIcon} {...props} />
)}
...
>
<Segmented.Segment key='article' title='Article' icon='home' component={Article} />
...
```

#### 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`||
|name|type|
|:----:|:----:|
|activeColor|`string \| undefined`|
|bounces|`boolean \| undefined`|
|contentContainerStyle|`StyleProp<ViewStyle>`|
|getAccessibilityLabel|`((scene: Scene<any>) => string \| undefined) \| undefined`|
|getAccessible|`((scene: Scene<any>) => boolean \| undefined) \| undefined`|
|getLabelText|`((scene: Scene<any>) => string \| undefined) \| undefined`|
|getTestID|`((scene: Scene<any>) => string \| undefined) \| undefined`|
|inactiveColor|`string \| undefined`|
|indicatorContainerStyle|`StyleProp<ViewStyle>`|
|indicatorStyle|`StyleProp<ViewStyle>`|
|labelStyle|`StyleProp<TextStyle>`|
|onTabLongPress|`((scene: Scene<any>) => void) \| undefined`|
|pressColor|`string \| undefined`|
|pressOpacity|`number \| undefined`|
|renderBadge|`((scene: Scene<any>) => ReactNode) \| undefined`|
|renderIcon|`((scene: Scene<any> & { focused: boolean; color: string; }) => ReactNode) \| undefined`|
|renderIndicator|`((props: Props<any>) => ReactNode) \| undefined`|
|renderLabel|`((scene: Scene<any> & { focused: boolean; color: string; }) => ReactNode) \| undefined`|
|renderTabBarItem|`((props: Props<any> & { key: string; }) => ReactElement<any, string \| ((props: any) => ReactElement<any, string \| ... \| (new (props: any) => Component<any, any, any>)> \| null) \| (new (props: any) => Component<...>)>) \| undefined`|
|scrollEnabled|`boolean \| undefined`|
|style|`StyleProp<ViewStyle>`|
|tabStyle|`StyleProp<ViewStyle>`|



Expand Down
Binary file modified demo/android.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified demo/ios.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 5 additions & 2 deletions documentation/README_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

# Expo app

Collapsible Segmented View for React Native.
Collapsible Segmented View for React Native

- [View it with Expo](https://expo.io/@pedrobern/react-native-collapsible-segmented-view-demos).
- Checkout the [examples](https://github.com/PedroBern/react-native-collapsible-segmented-view/tree/main/example) for the source code of the Expo app.
Expand All @@ -48,7 +48,8 @@ The [react-native-tab-view](https://github.com/satya164/react-native-tab-view) e

# Features

- Implements [SegmentedControl](https://developer.apple.com/design/human-interface-guidelines/ios/controls/segmented-controls/) and [Fixed Material Tab Bar](https://material.io/components/tabs)
- [Material Tab Bar](https://github.com/satya164/react-native-tab-view#tabbar) for Android
- [SegmentedControl](https://github.com/react-native-segmented-control/segmented-control#react-native-segmented-controlsegmented-control) for iOS
- Lazy support
- Highly customizable
- Fully typed with [TypeScript](https://typescriptlang.org)
Expand All @@ -61,6 +62,8 @@ Open a Terminal in the project root and run:
yarn add react-native-collapsible-segmented-view

expo install @react-native-community/segmented-control

yarn add react-native-tab-view react-native-pager-view
```

# Quick Start
Expand Down
12 changes: 7 additions & 5 deletions documentation/buildDocs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ const coreComponents = getComponentPaths([
'ScrollComponents/ScrollView',
])

const segmentedControlComponents = getComponentPaths(['SegmentedControl'])
const segmentedControlComponents = getComponentPaths([
'ControlComponents/SegmentedControl',
])

const tabBarComponents = getComponentPaths(['MaterialTabBar'])
const tabBarComponents = getComponentPaths(['ControlComponents/MaterialTabBar'])

const docs = docgen.withCustomConfig(tsconfig, {
savePropValueAsString: true,
Expand All @@ -41,11 +43,11 @@ const docs = docgen.withCustomConfig(tsconfig, {
component.name === 'MaterialTabBar'
) {
const blackList = [
'floatIndex',
'position',
'onTabPress',
'index',
'initialIndex',
'labels',
'setIndex',
'routes',
]
if (blackList.includes(prop.name)) {
return false
Expand Down
31 changes: 16 additions & 15 deletions example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,26 @@
"dependencies": {
"@expo/vector-icons": "^12.0.0",
"@react-native-community/segmented-control": "2.2.1",
"expo": "^40.0.1",
"expo-constants": "~9.3.3",
"expo-status-bar": "~1.0.3",
"react": "16.13.1",
"react-dom": "16.13.1",
"react-native": "https://github.com/expo/react-native/archive/sdk-40.0.1.tar.gz",
"react-native-gesture-handler": "^1.9.0",
"react-native-reanimated": "2.0.0-rc.0",
"react-native-web": "~0.13.12",
"expo": "^43.0.0",
"expo-constants": "~12.1.3",
"expo-status-bar": "~1.1.0",
"react": "17.0.1",
"react-dom": "17.0.1",
"react-native": "0.64.3",
"react-native-gesture-handler": "~1.10.2",
"react-native-pager-view": "5.4.6",
"react-native-tab-view": "^3.1.1",
"react-native-web": "0.17.1",
"use-debounce": "^5.2.0",
"use-deep-compare": "^1.1.0"
},
"devDependencies": {
"@babel/core": "~7.9.0",
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"@types/react-native": "^0.63.46",
"babel-preset-expo": "8.3.0",
"typescript": "^4.1.3"
"@babel/core": "^7.12.9",
"@types/react": "~17.0.21",
"@types/react-dom": "~17.0.9",
"@types/react-native": "~0.64.12",
"babel-preset-expo": "8.5.1",
"typescript": "~4.3.5"
},
"scripts": {
"start": "expo start",
Expand Down
2 changes: 1 addition & 1 deletion example/src/AnimatedHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export const Header = () => {
}

const Example: ExampleComponentType = () => {
return <ExampleComponent header={Header} />
return <ExampleComponent renderHeader={Header} />
}

const styles = StyleSheet.create({
Expand Down
4 changes: 2 additions & 2 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import {
import AnimatedHeader from './AnimatedHeader'
import Default from './Default'
import Lazy from './Lazy'
import NoFadeIn from './NoFadeIn'
import QuickStartDemo from './QuickStartDemo'
import ScrollableTabBar from './ScrollableTabBar'
import UndefinedHeaderHeight from './UndefinedHeaderHeight'
import { ExampleComponentType } from './types'

Expand All @@ -25,8 +25,8 @@ const EXAMPLE_COMPONENTS: ExampleComponentType[] = [
QuickStartDemo,
Lazy,
AnimatedHeader,
NoFadeIn,
UndefinedHeaderHeight,
ScrollableTabBar,
]

const ExampleList: React.FC<object> = () => {
Expand Down
2 changes: 1 addition & 1 deletion example/src/Default.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const title = 'Default'
const Header = buildHeader(title)

const Example: ExampleComponentType = () => {
return <ExampleComponent header={Header} />
return <ExampleComponent renderHeader={Header} />
}

Example.title = title
Expand Down
2 changes: 1 addition & 1 deletion example/src/Lazy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const title = 'Lazy'
const Header = buildHeader(title)

const Example: ExampleComponentType = () => {
return <ExampleComponent header={Header} lazy />
return <ExampleComponent renderHeader={Header} lazy />
}

Example.title = title
Expand Down
17 changes: 0 additions & 17 deletions example/src/NoFadeIn.tsx

This file was deleted.

27 changes: 27 additions & 0 deletions example/src/ScrollableTabBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react'
import {
ControlProps,
MaterialTabBar,
} from 'react-native-collapsible-segmented-view'

import { ExampleComponent } from './Shared/ExampleComponent'
import { buildHeader } from './Shared/Header'
import { ExampleComponentType } from './types'

const title = 'Scrollable Tab Bar'

const Header = buildHeader(title)

const renderTab = (props: ControlProps) => {
return (
<MaterialTabBar scrollEnabled {...props} tabStyle={{ width: 'auto' }} />
)
}

const Example: ExampleComponentType = () => {
return <ExampleComponent renderHeader={Header} renderControl={renderTab} />
}

Example.title = title

export default Example
6 changes: 3 additions & 3 deletions example/src/Shared/ExampleComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ type Props = Partial<SegmentedViewProps>
export const ExampleComponent: React.FC<Props> = (props) => {
return (
<Segmented.View headerHeight={HEADER_HEIGHT} {...props}>
<Segmented.Segment label="Article" component={Article} />
<Segmented.Segment label="Albums" component={Albums} />
<Segmented.Segment label="Contacts" component={Contacts} />
<Segmented.Segment id="article" title="Article" component={Article} />
<Segmented.Segment id="albums" title="Albums" component={Albums} />
<Segmented.Segment id="contacts" title="Contacts" component={Contacts} />
</Segmented.View>
)
}
Loading