From e35bc99a3b12ba95fe289688073bda988683df95 Mon Sep 17 00:00:00 2001 From: Gustavo Parreira Date: Thu, 5 May 2022 15:41:05 +0100 Subject: [PATCH 1/3] feat: added `renderTile` prop --- src/index.tsx | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/index.tsx b/src/index.tsx index 39abb17a..8dc43b28 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -14,6 +14,15 @@ import Animated, { } from 'react-native-reanimated'; import { widthPercentageToDP } from 'react-native-responsive-screen'; +export interface TileProps { + /** Styles of the default tile */ + style: ViewStyle; + /** The React Native Reanimated transform style with translateX */ + transform: ViewStyle['transform']; + /** The full width of tile */ + width: number; +} + interface SegmentedControlProps { /** * The Segments Text Array @@ -72,6 +81,10 @@ interface SegmentedControlProps { * Badge Text Styles */ badgeTextStyle?: TextStyle; + /** + * Render a custom tile component + */ + renderTile?: (props: TileProps) => React.ReactNode; } const defaultShadowStyle = { From df6512403183c6823394796f26d1e5a966e125eb Mon Sep 17 00:00:00 2001 From: Gustavo Parreira Date: Thu, 5 May 2022 15:42:07 +0100 Subject: [PATCH 2/3] feat: rendering and memoizing custom tile if `renderTile` is supplied --- src/index.tsx | 43 +++++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/src/index.tsx b/src/index.tsx index 8dc43b28..24396e35 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -123,6 +123,7 @@ const SegmentedControl: React.FC = ({ activeBadgeStyle, inactiveBadgeStyle, badgeTextStyle, + renderTile, }: SegmentedControlProps) => { const width = widthPercentageToDP('100%') - containerMargin * 2; const translateValue = width / segments.length; @@ -190,22 +191,40 @@ const SegmentedControl: React.FC = ({ ...badgeTextStyle, }; + const flattenedTileStyle: ViewStyle = StyleSheet.flatten([ + styles.movingSegmentStyle, + defaultShadowStyle, + StyleSheet.absoluteFill, + { + width: width / segments.length - 4, + }, + tileStyle, + ]); + + const memoizedTile = React.useMemo(() => { + if (renderTile) { + return renderTile({ + style: flattenedTileStyle, + transform: tabTranslateAnimatedStyles.transform, + width: translateValue, + }); + } + + return ( + + ); + }, [ + flattenedTileStyle, + renderTile, + tabTranslateAnimatedStyles, + translateValue, + ]); + return ( - + {memoizedTile} {segments.map((segment, index) => { return ( Date: Thu, 5 May 2022 15:42:58 +0100 Subject: [PATCH 3/3] chore: updated README with `renderTile` prop --- README.md | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index eb5874be..2faabaae 100644 --- a/README.md +++ b/README.md @@ -27,27 +27,30 @@ Make sure you have [React Native Reanimated](https://docs.swmansion.com/react-na ## :wrench: Props -| Name | Description | Required | Type | Default | -| ----------------------- | ---------------------------------------------- | -------- | --------- | -------- | -| segments | An array of labels for segments | YES | Array | [] | -| currentIndex | Index for the currently active segment | YES | Number | 0 | -| onChange | A callback Function with pressed segment index | YES | Function | () => {} | -| badgeValues | An array of badge value for segments. | NO | Array | [] | -| isRTL | Controls the toggle animation direction | NO | Boolean | false | -| containerMargin | The value used to determine the width | NO | Number | 16 | -| activeTextStyle | active text styles | NO | TextStyle | {} | -| inactiveTextStyle | inactive text styles. | NO | TextStyle | {} | -| segmentedControlWrapper | Style object for the Segmented Control. | NO | ViewStyle | {} | -| pressableWrapper | Style object for the Pressable Container | NO | ViewStyle | {} | -| tileStyle | Style object for the Absolute positioned tile | NO | ViewStyle | {} | -| activeBadgeStyle | Active Badge Style | NO | ViewStyle | {} | -| inactiveBadgeStyle | Inactive Badge Style | NO | ViewStyle | {} | -| badgeTextStyle | Badge text styles | NO | TextStyle | {} | +| Name | Description | Required | Type | Default | +| ----------------------- | ---------------------------------------------- | -------- | --------- | -------- | +| segments | An array of labels for segments | YES | Array | [] | +| currentIndex | Index for the currently active segment | YES | Number | 0 | +| onChange | A callback Function with pressed segment index | YES | Function | () => {} | +| badgeValues | An array of badge value for segments. | NO | Array | [] | +| isRTL | Controls the toggle animation direction | NO | Boolean | false | +| containerMargin | The value used to determine the width | NO | Number | 16 | +| activeTextStyle | active text styles | NO | TextStyle | {} | +| inactiveTextStyle | inactive text styles. | NO | TextStyle | {} | +| segmentedControlWrapper | Style object for the Segmented Control. | NO | ViewStyle | {} | +| pressableWrapper | Style object for the Pressable Container | NO | ViewStyle | {} | +| tileStyle | Style object for the Absolute positioned tile | NO | ViewStyle | {} | +| activeBadgeStyle | Active Badge Style | NO | ViewStyle | {} | +| inactiveBadgeStyle | Inactive Badge Style | NO | ViewStyle | {} | +| badgeTextStyle | Badge text styles | NO | TextStyle | {} | +| renderTile | Render a custom tile component | NO | Function | undefined | > :warning: all View styles or Text Styles passed as props overrides some default styles provided by the package. Make sure you use it properly :) > :information_source: To apply your own `shadowStyles` use the tileStyle prop +> :information_source: `renderTile` takes a function with `style`, `transform` and `width`. You can use these to style your custom tile to look the same as the default style (e.g. if you just wanted to change the animation) + ## :mag: Usage ```tsx