From e34a34b8ef2fb498be1afbbfb292154265ee7ece Mon Sep 17 00:00:00 2001 From: Andrei Alecu Date: Mon, 30 Nov 2020 16:24:58 +0200 Subject: [PATCH] feat: createMaterialCollapsibleTopTabNavigator --- package.json | 12 +++ src/MaterialTopTabsCollapsibleTabView.tsx | 74 ++++++++++++++ ...eateMaterialCollapsibleTopTabNavigator.tsx | 79 +++++++++++++++ src/index.tsx | 3 + yarn.lock | 97 ++++++++++++++++++- 5 files changed, 262 insertions(+), 3 deletions(-) create mode 100644 src/MaterialTopTabsCollapsibleTabView.tsx create mode 100644 src/createMaterialCollapsibleTopTabNavigator.tsx diff --git a/package.json b/package.json index 906c3fdb..c9f17146 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,8 @@ "@commitlint/config-conventional": "^9.1.1", "@expo/vector-icons": "^10.2.0", "@react-native-community/bob": "^0.16.2", + "@react-navigation/material-top-tabs": "^5.3.10", + "@react-navigation/native": "^5.8.10", "@release-it/conventional-changelog": "^1.1.4", "@types/react": "^16.9.44", "@types/react-native": "0.63.4", @@ -68,10 +70,20 @@ "typescript": "^3.9.7" }, "peerDependencies": { + "@react-navigation/material-top-tabs": "^5", + "@react-navigation/native": "^5", "react": "*", "react-native": "*", "react-native-tab-view": "*" }, + "peerDependenciesMeta": { + "@react-navigation/material-top-tabs": { + "optional": true + }, + "@react-navigation/native": { + "optional": true + } + }, "husky": { "hooks": { "commit-msg": "commitlint -E HUSKY_GIT_PARAMS", diff --git a/src/MaterialTopTabsCollapsibleTabView.tsx b/src/MaterialTopTabsCollapsibleTabView.tsx new file mode 100644 index 00000000..29ab39be --- /dev/null +++ b/src/MaterialTopTabsCollapsibleTabView.tsx @@ -0,0 +1,74 @@ +import * as React from 'react'; +import { SceneRendererProps } from 'react-native-tab-view'; +import { + NavigationHelpersContext, + TabActions, + useTheme, +} from '@react-navigation/native'; + +import CollapsibleTabView, { + Props as CollapsibleTabViewProps, +} from './CollapsibleTabView'; +import { + MaterialTopTabBarProps, + MaterialTopTabBar, + MaterialTopTabView, +} from '@react-navigation/material-top-tabs'; + +export type MaterialTopTabsCollapsibleTabViewProps = Parameters< + typeof MaterialTopTabView +>[0] & { + collapsibleOptions?: Partial>; +}; + +export default function MaterialTopTabsCollapsibleTabView({ + pager, + lazyPlaceholder, + tabBar = (props: MaterialTopTabBarProps) => , + tabBarOptions, + state, + navigation, + descriptors, + sceneContainerStyle, + collapsibleOptions, + ...rest +}: MaterialTopTabsCollapsibleTabViewProps) { + const { colors } = useTheme(); + + const renderTabBar = (props: SceneRendererProps) => { + return tabBar({ + ...tabBarOptions, + ...props, + state: state, + navigation: navigation, + descriptors: descriptors, + }); + }; + + return ( + + + navigation.dispatch({ + ...TabActions.jumpTo(state.routes[index].name), + target: state.key, + }) + } + renderScene={({ route }) => descriptors[route.key].render()} + navigationState={state} + renderTabBar={renderTabBar} + renderPager={pager} + renderLazyPlaceholder={lazyPlaceholder} + onSwipeStart={() => navigation.emit({ type: 'swipeStart' })} + onSwipeEnd={() => navigation.emit({ type: 'swipeEnd' })} + sceneContainerStyle={[ + { backgroundColor: colors.background }, + sceneContainerStyle, + ]} + /> + + ); +} diff --git a/src/createMaterialCollapsibleTopTabNavigator.tsx b/src/createMaterialCollapsibleTopTabNavigator.tsx new file mode 100644 index 00000000..9de44eb1 --- /dev/null +++ b/src/createMaterialCollapsibleTopTabNavigator.tsx @@ -0,0 +1,79 @@ +import * as React from 'react'; +import { + useNavigationBuilder, + createNavigatorFactory, + TabRouter, + TabRouterOptions, + TabNavigationState, + TabActionHelpers, + ParamListBase, +} from '@react-navigation/native'; +import MaterialTopTabsCollapsibleTabView from './MaterialTopTabsCollapsibleTabView'; +import { + createMaterialTopTabNavigator, + MaterialTopTabNavigationOptions, +} from '@react-navigation/material-top-tabs'; + +type MaterialTopTabNavigationEventMap = { + /** + * Event which fires on tapping on the tab in the tab bar. + */ + tabPress: { data: undefined; canPreventDefault: true }; + /** + * Event which fires on long press on the tab in the tab bar. + */ + tabLongPress: { data: undefined }; + /** + * Event which fires when a swipe gesture starts, i.e. finger touches the screen. + */ + swipeStart: { data: undefined }; + /** + * Event which fires when a swipe gesture ends, i.e. finger leaves the screen. + */ + swipeEnd: { data: undefined }; +}; + +type BaseNavigator = ReturnType< + typeof createMaterialTopTabNavigator +>['Navigator']; + +type Props = Parameters< + Extract> +>[0]; + +function MaterialTopTabNavigator({ + initialRouteName, + backBehavior, + children, + screenOptions, + ...rest +}: Props) { + const { state, descriptors, navigation } = useNavigationBuilder< + TabNavigationState, + TabRouterOptions, + TabActionHelpers, + MaterialTopTabNavigationOptions, + MaterialTopTabNavigationEventMap + >(TabRouter, { + initialRouteName, + backBehavior, + children, + screenOptions, + }); + + return ( + + ); +} + +export default createNavigatorFactory< + TabNavigationState, + MaterialTopTabNavigationOptions, + MaterialTopTabNavigationEventMap, + typeof MaterialTopTabNavigator +>(MaterialTopTabNavigator); diff --git a/src/index.tsx b/src/index.tsx index 67d4701b..a91ddf50 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -3,3 +3,6 @@ export type { Props as CollapsibleTabViewProps } from './CollapsibleTabView'; export { default as useCollapsibleScene } from './useCollapsibleScene'; export type { CollapsibleScenePropsAndRef } from './types'; + +export { default as MaterialTopTabsCollapsibleTabView } from './MaterialTopTabsCollapsibleTabView'; +export { default as createMaterialCollapsibleTopTabNavigator } from './createMaterialCollapsibleTopTabNavigator'; diff --git a/yarn.lock b/yarn.lock index 5fcbeb7a..36f5b2ac 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1738,6 +1738,40 @@ sudo-prompt "^9.0.0" wcwidth "^1.0.1" +"@react-navigation/core@^5.14.4": + version "5.14.4" + resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-5.14.4.tgz#f63a2cd214bddbd25e1181f9335c32dfc3b6460f" + integrity sha512-MzZU9PO1a/6f9KdN04dC/E4BNl6M1Ba0Tb4sQdl/32y0hM2ToxlrKcERnTLWGFIbQV+9ZV1GTrp3mlGS6U9Jpw== + dependencies: + "@react-navigation/routers" "^5.6.2" + escape-string-regexp "^4.0.0" + nanoid "^3.1.15" + query-string "^6.13.6" + react-is "^16.13.0" + +"@react-navigation/material-top-tabs@^5.3.10": + version "5.3.10" + resolved "https://registry.yarnpkg.com/@react-navigation/material-top-tabs/-/material-top-tabs-5.3.10.tgz#158b694e87bff2eb9577e8142415de8ac3547412" + integrity sha512-mmQYEBhcLp1DwvuD8+HiFtYPk5zP43272C/38iX2T8AblcwRdoJejuO/GUzQcEPrmZHjeAnA5GDaMiXQM4EXLQ== + dependencies: + color "^3.1.3" + +"@react-navigation/native@^5.8.10": + version "5.8.10" + resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-5.8.10.tgz#3fe806abff9efb085bcf595212803dd05a1347ca" + integrity sha512-OUgD1o+y7PwmhRIRqQxN0SQvVU/SHic/ek/qMvBZX8nu5/WlBNxmNRMHVxONgHlG3AQZh27NUs9ynntL7ek1zQ== + dependencies: + "@react-navigation/core" "^5.14.4" + escape-string-regexp "^4.0.0" + nanoid "^3.1.15" + +"@react-navigation/routers@^5.6.2": + version "5.6.2" + resolved "https://registry.yarnpkg.com/@react-navigation/routers/-/routers-5.6.2.tgz#accc008c3b777f74d998e16cb2ea8e4c1fe8d9aa" + integrity sha512-XBcDKXS5s4MaHFufN44LtbXqFDH/nUHfHjbwG85fP3k772oRyPRgbnUb2mbw5MFGqORla9T7uymR6Gh6uwIwVw== + dependencies: + nanoid "^3.1.15" + "@release-it/conventional-changelog@^1.1.4": version "1.1.4" resolved "https://registry.yarnpkg.com/@release-it/conventional-changelog/-/conventional-changelog-1.1.4.tgz#28ad5a49e096fec7d874f06041b5cc0ddffa7daa" @@ -3467,7 +3501,7 @@ collection-visit@^1.0.0: map-visit "^1.0.0" object-visit "^1.0.0" -color-convert@^1.9.0: +color-convert@^1.9.0, color-convert@^1.9.1: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== @@ -3486,16 +3520,32 @@ color-name@1.1.3: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= -color-name@~1.1.4: +color-name@^1.0.0, color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +color-string@^1.5.4: + version "1.5.4" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.4.tgz#dd51cd25cfee953d138fe4002372cc3d0e504cb6" + integrity sha512-57yF5yt8Xa3czSEW1jfQDE79Idk0+AkN/4KWad6tbdxUmAs3MvjxlWSWD4deYytcRfoZ9nhKyFl1kj5tBvidbw== + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + color-support@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== +color@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/color/-/color-3.1.3.tgz#ca67fb4e7b97d611dcde39eceed422067d91596e" + integrity sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ== + dependencies: + color-convert "^1.9.1" + color-string "^1.5.4" + colorette@^1.0.7, colorette@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.1.tgz#4d0b921325c14faf92633086a536db6e89564b1b" @@ -4390,6 +4440,11 @@ escape-string-regexp@^2.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + escodegen@^1.14.1: version "1.14.3" resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" @@ -5850,6 +5905,11 @@ is-arrayish@^0.2.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= +is-arrayish@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" + integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== + is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" @@ -7651,6 +7711,11 @@ nan@^2.12.1: resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== +nanoid@^3.1.15: + version "3.1.18" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.18.tgz#0680db22ab01c372e89209f5d18283d98de3e96d" + integrity sha512-rndlDjbbHbcV3xi+R2fpJ+PbGMdfBxz5v1fATIQFq0DP64FsicQdwnKLy47K4kZHdRpmQXtz24eGsxQqamzYTA== + nanomatch@^1.2.9: version "1.2.13" resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" @@ -8496,6 +8561,15 @@ qs@~6.5.2: resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== +query-string@^6.13.6: + version "6.13.7" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.13.7.tgz#af53802ff6ed56f3345f92d40a056f93681026ee" + integrity sha512-CsGs8ZYb39zu0WLkeOhe0NMePqgYdAuCqxOYKDR5LVCytDZYMGx3Bb+xypvQvPHVPijRXB0HZNFllCzHRe4gEA== + dependencies: + decode-uri-component "^0.2.0" + split-on-first "^1.0.0" + strict-uri-encode "^2.0.0" + quick-lru@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8" @@ -8539,7 +8613,7 @@ react-devtools-core@^4.0.6: shell-quote "^1.6.1" ws "^7" -react-is@^16.12.0, react-is@^16.8.1, react-is@^16.8.4: +react-is@^16.12.0, react-is@^16.13.0, react-is@^16.8.1, react-is@^16.8.4: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -9356,6 +9430,13 @@ simple-plist@^1.0.0: bplist-parser "0.2.0" plist "^3.0.1" +simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" + integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= + dependencies: + is-arrayish "^0.3.1" + sisteransi@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" @@ -9480,6 +9561,11 @@ spdx-license-ids@^3.0.0: resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz#e9c18a410e5ed7e12442a549fbd8afa767038d65" integrity sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ== +split-on-first@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" + integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw== + split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" @@ -9565,6 +9651,11 @@ stream-buffers@~2.2.0: resolved "https://registry.yarnpkg.com/stream-buffers/-/stream-buffers-2.2.0.tgz#91d5f5130d1cef96dcfa7f726945188741d09ee4" integrity sha1-kdX1Ew0c75bc+n9yaUUYh0HQnuQ= +strict-uri-encode@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" + integrity sha1-ucczDHBChi9rFC3CdLvMWGbONUY= + string-length@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.1.tgz#4a973bf31ef77c4edbceadd6af2611996985f8a1"