diff --git a/README.md b/README.md index b97b063..2c89aa6 100644 --- a/README.md +++ b/README.md @@ -97,20 +97,20 @@ export default App ## Props -| name | description | required | type | default | -| ---------------------------- | ------------------------------------------------------------------------------------------------- | -------- | --------------------------------------------------- | ------- | -| `itemWidth` | Item's width. | YES | number | | -| `itemHeight` | Item's height. | YES | number | | -| `separatorSize` | FlatList's separator width. | NO | number | 10 | -| `borderRadius` | Item & sticky border radius. | NO | number | 15 | -| `stickyItemActiveOpacity` | Sticky item's active opacity. | YES | number | 0.25 | -| `stickyItemWidth` | Sticky item's width. | YES | number | | -| `stickyItemHeight` | Sticky item's height. | YES | number | | -| `stickyItemBackgroundColors` | Sticky item's two background colors, one when sticky item is extended another when it's minimize. | YES | string[] | | -| `stickyItemContent` | Sticky item's content component. | YES | [`ReactNode`](./src/types.ts#L30) | | -| `isRTL` | FlatList' layout direction. | NO | boolean | false | -| `onStickyItemPress` | Callback when sticky item gets pressed. | NO | function | | -| `...FlatList Props` | React Native FlatList props. | NO | [`FlatList`](https://reactnative.dev/docs/flatlist) | | +| name | description | required | type | default | +| ---------------------------- | ------------------------------------------------------------------------------------------------------------- | -------- | --------------------------------------------------- | ------- | +| `itemWidth` | Item's width. | YES | number | | +| `itemHeight` | Item's height. | YES | number | | +| `separatorSize` | FlatList's separator width, \* if you provide `ItemSeparatorComponent`, you will need to set `separatorSize`. | NO\* | number | 10 | +| `borderRadius` | Item & sticky border radius. | NO | number | 15 | +| `stickyItemActiveOpacity` | Sticky item's active opacity. | YES | number | 0.25 | +| `stickyItemWidth` | Sticky item's width. | YES | number | | +| `stickyItemHeight` | Sticky item's height. | YES | number | | +| `stickyItemBackgroundColors` | Sticky item's two background colors, one when sticky item is extended another when it's minimize. | YES | string[] | | +| `stickyItemContent` | Sticky item's content component. | YES | [`ReactNode`](./src/types.ts#L30) | | +| `isRTL` | FlatList' layout direction. | NO | boolean | false | +| `onStickyItemPress` | Callback when sticky item gets pressed. | NO | function | | +| `...FlatList Props` | React Native FlatList props. | NO | [`FlatList`](https://reactnative.dev/docs/flatlist) | | ## To Do diff --git a/example/src/App.tsx b/example/src/App.tsx index 3744c08..0f1b021 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -4,6 +4,7 @@ import { createStackNavigator } from '@react-navigation/stack'; import RootScreen from './screens/Root'; import BasicScreen from './screens/Basic'; import BasicRTLScreen from './screens/BasicRTL'; +import BasicCustomSeparatorScreen from './screens/BasicCustomSeparator'; import FacebookStoriesScreen from './screens/FacebookStories'; import FacebookStoriesStyledScreen from './screens/FacebookStoriesStyled'; import FacebookStoriesRTLScreen from './screens/FacebookStoriesRTL'; @@ -29,6 +30,13 @@ export default function App() { }} component={BasicRTLScreen} /> + ({ id: `item-${index}` })); + +export const STORY_WIDTH = 200; +export const STORY_HEIGHT = 100; +const SEPARATOR_SIZE = 10; +const BORDER_RADIUS = 0; + +const BasicCustomSeparator = () => { + const { params } = useRoute(); + // @ts-ignore + const { title } = params; + + // styles + const containerStyle = { + paddingVertical: SEPARATOR_SIZE * 2, + backgroundColor: 'white', + }; + + // methods + const handleStickyItemPress = () => Alert.alert('Sticky Item Pressed'); + + // render + const renderItem = ({ index }: ListRenderItemInfo<{}>) => ( + Alert.alert(`Item ${index} Pressed`)}> + + + ); + + const renderSeparator = ({ size }: { size: number }) => { + return ( + + + + ); + }; + return ( + + + {title} + + + + + ); +}; + +const styles = StyleSheet.create({ + root: { + flex: 1, + flexDirection: 'column', + justifyContent: 'flex-start', + backgroundColor: '#CACACD', + }, + text: { + marginHorizontal: SEPARATOR_SIZE * 2, + marginBottom: SEPARATOR_SIZE, + fontSize: 43, + fontWeight: Platform.OS === 'ios' ? '900' : 'bold', + textTransform: 'uppercase', + color: '#2d88ff', + }, + buttons: { + marginTop: SEPARATOR_SIZE, + marginHorizontal: SEPARATOR_SIZE * 2, + flexDirection: 'row', + justifyContent: 'space-between', + alignContent: 'space-between', + }, + separatorLine: { + position: 'absolute', + left: '50%', + top: '25%', + height: '50%', + width: 1, + opacity: 0.5, + backgroundColor: '#CACACD', + }, +}); + +export default BasicCustomSeparator; diff --git a/example/src/screens/Root.tsx b/example/src/screens/Root.tsx index da5368a..b22362e 100644 --- a/example/src/screens/Root.tsx +++ b/example/src/screens/Root.tsx @@ -15,6 +15,10 @@ const examples = [ name: 'RTL', slug: 'BasicRTL', }, + { + name: 'Custom Separator', + slug: 'BasicCustomSeparator', + }, ], }, { diff --git a/src/StickyItemFlatList.tsx b/src/StickyItemFlatList.tsx index d3ca50c..8211a0c 100644 --- a/src/StickyItemFlatList.tsx +++ b/src/StickyItemFlatList.tsx @@ -7,7 +7,7 @@ import React, { Ref, useImperativeHandle, } from 'react'; -import { View, Dimensions } from 'react-native'; +import { Dimensions } from 'react-native'; import Animated, { event, useCode, @@ -24,6 +24,7 @@ import { } from 'react-native-gesture-handler'; import { useValues, useGestureHandler } from 'react-native-redash'; import StickyItem from './components/sticky-item'; +import Separator from './components/separator'; import { DEFAULT_SEPARATOR_SIZE, DEFAULT_BORDER_RADIUS, @@ -55,6 +56,7 @@ const StickyItemFlatList = forwardRef( stickyItemContent, onStickyItemPress, isRTL = DEFAULT_IS_RTL, + ItemSeparatorComponent = Separator, ...rest } = props; @@ -67,6 +69,12 @@ const StickyItemFlatList = forwardRef( itemWidth, separatorSize, ]); + const separatorProps = useMemo( + () => ({ + size: separatorSize, + }), + [separatorSize] + ); //#endregion //#region styles @@ -195,7 +203,16 @@ const StickyItemFlatList = forwardRef( //#endregion // render - const renderSeparator = () => ; + const renderSeparator = useCallback(() => { + if (typeof ItemSeparatorComponent === 'function') { + // @ts-ignore + return ItemSeparatorComponent(separatorProps); + } else { + // @ts-ignore + return ; + } + }, [ItemSeparatorComponent, separatorProps]); + return ( { + return ; +}; + +const Separator = memo(SeparatorComponent); + +export default Separator; diff --git a/src/components/separator/index.ts b/src/components/separator/index.ts new file mode 100644 index 0000000..3223b4d --- /dev/null +++ b/src/components/separator/index.ts @@ -0,0 +1 @@ +export { default } from './Separator'; diff --git a/src/types.ts b/src/types.ts index 3b4918e..bb7b4c7 100644 --- a/src/types.ts +++ b/src/types.ts @@ -91,6 +91,15 @@ export interface StickyItemConfig { isRTL?: boolean; } +export interface SeparatorConfig { + /** + * FlatList's separator width + * @type {number} + * @default 10 + */ + size: number; +} + export interface StickyItemFlatListProps extends FlatListProps, StickyItemConfig { @@ -99,4 +108,10 @@ export interface StickyItemFlatListProps * @type {() => void} */ onStickyItemPress?: () => void; + + /** + * Override `FlatList` prop, to add + * `SeparatorConfig` to `ItemSeparatorComponent` + */ + ItemSeparatorComponent?: React.ComponentType; }