Skip to content

Commit

Permalink
Merge pull request #265 from PedroBern/feat-usecurrenttabscrolly
Browse files Browse the repository at this point in the history
  • Loading branch information
andreialecu authored Jun 14, 2022
2 parents 90de549 + 7a81951 commit 9671587
Show file tree
Hide file tree
Showing 11 changed files with 107 additions and 12 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# [5.0.0](https://github.com/PedroBern/react-native-collapsible-tab-view/compare/v5.0.0-rc.1...v5.0.0-rc.10) (2022-05-25)
# [5.0.0](https://github.com/PedroBern/react-native-collapsible-tab-view/compare/v5.0.0-rc.1...v5.0.0-rc.10) (2022-06-29)

### Performance Improvements

Expand All @@ -16,6 +16,8 @@

* custom label component ([51a7234](https://github.com/PedroBern/react-native-collapsible-tab-view/commit/51a7234fec8f19f384ed771789d883aee247260f))
* `keepActiveTabCentered` property on scrollable MaterialTabBar to keep tab in the center ([6d35e31](https://github.com/PedroBern/react-native-collapsible-tab-view/commit/6d35e3151355d35830a8387af642c5af5a13c54d))
* `useCurrentTabScrollY` ([73ee5d7](https://github.com/PedroBern/react-native-collapsible-tab-view/commit/73ee5d7c5e2b470551a5ad1dedae68413d3d5da0))

### Code Refactoring

* remove obsolete HeaderComponent and FooterComponent ([cb2cb04](https://github.com/PedroBern/react-native-collapsible-tab-view/commit/cb2cb04bbcf1dd86484c2a77f273e10ee6ceabbe))
Expand All @@ -25,6 +27,7 @@

* use `renderHeader` and `renderTabBar` instead of HeaderComponent and FooterComponent
* a peer dependency on `react-native-pager-view@5` is now required
* `useHeaderMeasurements` now returns the `height` as an `Animated.SharedValue`

## [4.5.2](https://github.com/PedroBern/react-native-collapsible-tab-view/compare/v4.5.1...v4.5.2) (2022-01-15)

Expand Down
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,17 @@ Returns the top distance and the header height. See the animated header example
const { top, height } = useHeaderMeasurements()
```

### useCurrentTabScrollY

Returns the vertical scroll position of the current tab as an Animated SharedValue.

Because this library requires handling `onScroll` for its functionality, this is the only way to react to changes to the scroll position of the underlying scrollable component.

```tsx
const scrollY = useCurrentTabScrollY()
```


## Default Tab Bar

### MaterialTabItem
Expand Down
11 changes: 11 additions & 0 deletions documentation/README_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,17 @@ Returns the top distance and the header height. See the animated header example
const { top, height } = useHeaderMeasurements()
```

### useCurrentTabScrollY

Returns the vertical scroll position of the current tab as an Animated SharedValue.

Because this library requires handling `onScroll` for its functionality, this is the only way to react to changes to the scroll position of the underlying scrollable component.

```tsx
const scrollY = useCurrentTabScrollY()
```


## Default Tab Bar

$TAB_BAR_API
Expand Down
16 changes: 12 additions & 4 deletions example/src/AnimatedHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import React from 'react'
import { Text, StyleSheet, View } from 'react-native'
import { StyleSheet, View } from 'react-native'
import { useHeaderMeasurements } from 'react-native-collapsible-tab-view'
import Animated, {
interpolate,
useAnimatedStyle,
useDerivedValue,
} from 'react-native-reanimated'

import { useCurrentTabScrollY } from '../../src/hooks'
import ExampleComponent from './Shared/ExampleComponent'
import ReText from './Shared/ReText'
import { ExampleComponentType } from './types'

const title = 'Animated Header'
Expand All @@ -15,15 +18,20 @@ const MIN_HEADER_HEIGHT = 48

export const Header = () => {
const { top, height } = useHeaderMeasurements()
const scrollY = useCurrentTabScrollY()

const scrollYText = useDerivedValue(
() => `Scroll Y is: ${scrollY.value.toFixed(2)}`
)

const stylez = useAnimatedStyle(() => {
return {
transform: [
{
translateY: interpolate(
top.value,
[0, -(height - MIN_HEADER_HEIGHT)],
[0, (height - MIN_HEADER_HEIGHT) / 2]
[0, -(height.value || 0 - MIN_HEADER_HEIGHT)],
[0, (height.value || 0 - MIN_HEADER_HEIGHT) / 2]
),
},
],
Expand All @@ -33,7 +41,7 @@ export const Header = () => {
return (
<View style={[styles.root]}>
<Animated.View style={[styles.container, stylez]}>
<Text style={styles.text}>{title}</Text>
<ReText style={styles.text} text={scrollYText} />
</Animated.View>
</View>
)
Expand Down
6 changes: 5 additions & 1 deletion example/src/Shared/Contacts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,11 @@ const renderItem = ({ item }: { item: Item }) => <ContactItem item={item} />
const ListEmptyComponent = () => {
const { top, height } = Tabs.useHeaderMeasurements()
const translateY = useDerivedValue(() => {
return interpolate(-top.value, [0, height], [-height / 2, 0])
return interpolate(
-top.value,
[0, height.value || 0],
[-(height.value || 0) / 2, 0]
)
}, [height])

const stylez = useAnimatedStyle(() => {
Expand Down
42 changes: 42 additions & 0 deletions example/src/Shared/ReText.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// courtesy of https://github.com/wcandillon/react-native-redash/blob/fd0b0ddb3b4c10ae88cf1f8a95890c7c5eb3c475/src/ReText.tsx

import React from 'react'
import type { TextProps as RNTextProps } from 'react-native'
import { StyleSheet, TextInput } from 'react-native'
import Animated, { useAnimatedProps } from 'react-native-reanimated'

const styles = StyleSheet.create({
baseStyle: {
color: 'black',
},
})
Animated.addWhitelistedNativeProps({ text: true })

interface TextProps {
text: Animated.SharedValue<string>
style?: Animated.AnimateProps<RNTextProps>['style']
}

const AnimatedTextInput = Animated.createAnimatedComponent(TextInput)

const ReText = (props: TextProps) => {
const { text, style } = { style: {}, ...props }
const animatedProps = useAnimatedProps(() => {
return {
text: text.value,
// Here we use any because the text prop is not available in the type
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} as any
})
return (
<AnimatedTextInput
underlineColorAndroid="transparent"
editable={false}
value={text.value}
style={[styles.baseStyle, style]}
{...{ animatedProps }}
/>
)
}

export default ReText
6 changes: 5 additions & 1 deletion example/src/Shared/SectionContacts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,11 @@ const renderItem = ({ item }: { item: Item }) => <ContactItem item={item} />
const ListEmptyComponent = () => {
const { top, height } = Tabs.useHeaderMeasurements()
const translateY = useDerivedValue(() => {
return interpolate(-top.value, [0, height], [-height / 2, 0])
return interpolate(
-top.value,
[0, height.value || 0],
[-(height.value || 0) / 2, 0]
)
}, [height])

const stylez = useAnimatedStyle(() => {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-native-collapsible-tab-view",
"version": "5.0.0-rc.10",
"version": "5.0.0-rc.13",
"description": "Collapsible tab view component for React Native",
"main": "lib/commonjs/index.js",
"react-native": "src/index.tsx",
Expand Down
1 change: 1 addition & 0 deletions src/Container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ export const Container = React.memo(
tabName: tabNames.value[i],
})
index.value = i
scrollYCurrent.value = scrollY.value[index.value] || 0
}
},
[]
Expand Down
16 changes: 12 additions & 4 deletions src/hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -568,25 +568,33 @@ export function useConvertAnimatedToValue<T>(
return value
}

interface HeaderMeasurements {
export interface HeaderMeasurements {
/**
* Animated value that represents the current Y translation of the header
*/
top: Animated.SharedValue<number>
/**
* The height of the header
* Animated value that represents the height of the header
*/
height: number
height: Animated.SharedValue<number | undefined>
}

export function useHeaderMeasurements(): HeaderMeasurements {
const { headerTranslateY, headerHeight } = useTabsContext()
return {
top: headerTranslateY,
height: headerHeight.value || 0,
height: headerHeight,
}
}

/**
* Returns the vertical scroll position of the current tab as an Animated SharedValue
*/
export function useCurrentTabScrollY(): Animated.SharedValue<number> {
const { scrollYCurrent } = useTabsContext()
return scrollYCurrent
}

/**
* Returns the currently focused tab name
*/
Expand Down
3 changes: 3 additions & 0 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,13 @@ export const Tabs = {

export { Container, Tab, Lazy, FlatList, ScrollView, SectionList }
export {
useCurrentTabScrollY,
useHeaderMeasurements,
useFocusedTab,
useAnimatedTabIndex,
useCollapsibleStyle,
} from './hooks'
export type { HeaderMeasurements } from './hooks'

export { MaterialTabBar } from './MaterialTabBar/TabBar'
export { MaterialTabItem } from './MaterialTabBar/TabItem'

0 comments on commit 9671587

Please sign in to comment.