From a09f66b2ae357e8ff645a5beecdcf3af0b04a3ff Mon Sep 17 00:00:00 2001 From: gorhom Date: Sat, 10 Sep 2022 12:46:12 +0100 Subject: [PATCH 01/13] chore: updated dependencies --- example/app/package.json | 4 +-- example/bare/ios/Podfile.lock | 8 +++--- example/bare/package.json | 4 +-- example/expo/package.json | 4 +-- package.json | 8 +++--- yarn.lock | 48 ++++++++++------------------------- 6 files changed, 28 insertions(+), 48 deletions(-) diff --git a/example/app/package.json b/example/app/package.json index 0894dc9f4..f30108a27 100644 --- a/example/app/package.json +++ b/example/app/package.json @@ -20,10 +20,10 @@ "nanoid": "^3.3.3", "react": "17.0.2", "react-native": "0.68.1", - "react-native-gesture-handler": "^2.5.0", + "react-native-gesture-handler": "^2.6.0", "react-native-maps": "^0.30.1", "react-native-pager-view": "^5.4.24", - "react-native-reanimated": "^2.9.1", + "react-native-reanimated": "^2.10.0", "react-native-redash": "^16.0.11", "react-native-safe-area-context": "4.2.4", "react-native-screens": "^3.15.0", diff --git a/example/bare/ios/Podfile.lock b/example/bare/ios/Podfile.lock index 05c4758de..77eb7790f 100644 --- a/example/bare/ios/Podfile.lock +++ b/example/bare/ios/Podfile.lock @@ -382,9 +382,9 @@ PODS: - React-perflogger (= 0.69.4) - RNCMaskedView (0.1.11): - React - - RNGestureHandler (2.5.0): + - RNGestureHandler (2.6.0): - React-Core - - RNReanimated (2.9.1): + - RNReanimated (2.10.0): - DoubleConversion - FBLazyVector - FBReactNativeSpec @@ -644,8 +644,8 @@ SPEC CHECKSUMS: React-runtimeexecutor: 61ee22a8cdf8b6bb2a7fb7b4ba2cc763e5285196 ReactCommon: 8f67bd7e0a6afade0f20718f859dc8c2275f2e83 RNCMaskedView: 0e1bc4bfa8365eba5fbbb71e07fbdc0555249489 - RNGestureHandler: bad495418bcbd3ab47017a38d93d290ebd406f50 - RNReanimated: 2cf7451318bb9cc430abeec8d67693f9cf4e039c + RNGestureHandler: 920eb17f5b1e15dae6e5ed1904045f8f90e0b11e + RNReanimated: 7faa787e8d4493fbc95fab2ad331fa7625828cfa RNScreens: 4a1af06327774490d97342c00aee0c2bafb497b7 SocketRocket: fccef3f9c5cedea1353a9ef6ada904fde10d6608 Yoga: ff994563b2fd98c982ca58e8cd9db2cdaf4dda74 diff --git a/example/bare/package.json b/example/bare/package.json index 183945ee2..f281ac9fc 100644 --- a/example/bare/package.json +++ b/example/bare/package.json @@ -24,10 +24,10 @@ "nanoid": "^3.3.3", "react": "18.0.0", "react-native": "0.69.4", - "react-native-gesture-handler": "^2.5.0", + "react-native-gesture-handler": "^2.6.0", "react-native-maps": "^0.30.1", "react-native-pager-view": "^5.4.9", - "react-native-reanimated": "^2.9.1", + "react-native-reanimated": "^2.10.0", "react-native-redash": "^16.0.11", "react-native-safe-area-context": "4.2.4", "react-native-screens": "^3.15.0", diff --git a/example/expo/package.json b/example/expo/package.json index 521b9a090..82ee74566 100644 --- a/example/expo/package.json +++ b/example/expo/package.json @@ -20,7 +20,7 @@ "@react-navigation/native": "^6.0.10", "@react-navigation/native-stack": "^6.6.2", "@react-navigation/stack": "^6.2.1", - "expo": "^46.0.0", + "expo": "^46.0.10", "expo-status-bar": "~1.4.0", "faker": "^4.1.0", "nanoid": "^3.3.3", @@ -41,7 +41,7 @@ "@types/react": "~18.0.0", "@types/react-native": "~0.69.1", "babel-plugin-module-resolver": "^4.1.0", - "expo-cli": "^6.0.2", + "expo-cli": "^6.0.5", "typescript": "^4.6.3" }, "resolutions": { diff --git a/package.json b/package.json index cfa0f4822..6a4008979 100644 --- a/package.json +++ b/package.json @@ -61,16 +61,16 @@ "react": "~16.9.0", "react-native": "^0.62.2", "react-native-builder-bob": "^0.18.1", - "react-native-gesture-handler": "^1.10.3", - "react-native-reanimated": "^2.8.0", + "react-native-gesture-handler": "^2.6.0", + "react-native-reanimated": "^2.10.0", "release-it": "^14.10.1", "typescript": "^4.2.4" }, "peerDependencies": { "react": "*", "react-native": "*", - "react-native-gesture-handler": ">=1.10.1", - "react-native-reanimated": ">=2.2.0" + "react-native-gesture-handler": ">=2.6.0", + "react-native-reanimated": ">=2.10.0" }, "react-native-builder-bob": { "source": "src", diff --git a/yarn.lock b/yarn.lock index 89ac6c242..5a8b91490 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3255,13 +3255,6 @@ create-react-class@^15.6.3: loose-envify "^1.3.1" object-assign "^4.1.1" -cross-fetch@^3.0.4: - version "3.1.4" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.4.tgz#9723f3a3a247bf8b89039f3a380a9244e8fa2f39" - integrity sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ== - dependencies: - node-fetch "2.6.1" - cross-spawn@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" @@ -4073,19 +4066,6 @@ fbjs@^1.0.0: setimmediate "^1.0.5" ua-parser-js "^0.7.18" -fbjs@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-3.0.0.tgz#0907067fb3f57a78f45d95f1eacffcacd623c165" - integrity sha512-dJd4PiDOFuhe7vk4F80Mba83Vr2QuK86FoxtgPmzBqEJahncp+13YCmfoa53KHCo6OnlXLG7eeMWPfB5CrpVKg== - dependencies: - cross-fetch "^3.0.4" - fbjs-css-vars "^1.0.0" - loose-envify "^1.0.0" - object-assign "^4.1.0" - promise "^7.1.1" - setimmediate "^1.0.5" - ua-parser-js "^0.7.18" - figures@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" @@ -6338,11 +6318,6 @@ nocache@^2.1.0: resolved "https://registry.yarnpkg.com/nocache/-/nocache-2.1.0.tgz#120c9ffec43b5729b1d5de88cd71aa75a0ba491f" integrity sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q== -node-fetch@2.6.1, node-fetch@^2.2.0, node-fetch@^2.6.0, node-fetch@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" - integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== - node-fetch@^1.0.1: version "1.7.3" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" @@ -6351,6 +6326,11 @@ node-fetch@^1.0.1: encoding "^0.1.11" is-stream "^1.0.1" +node-fetch@^2.2.0, node-fetch@^2.6.0, node-fetch@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" + integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -7105,21 +7085,21 @@ react-native-builder-bob@^0.18.1: optionalDependencies: jetifier "^1.6.6" -react-native-gesture-handler@^1.10.3: - version "1.10.3" - resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-1.10.3.tgz#942bbf2963bbf49fa79593600ee9d7b5dab3cfc0" - integrity sha512-cBGMi1IEsIVMgoox4RvMx7V2r6bNKw0uR1Mu1o7NbuHS6BRSVLq0dP34l2ecnPlC+jpWd3le6Yg1nrdCjby2Mw== +react-native-gesture-handler@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-2.6.0.tgz#8eeb25a2be9718db2e241084f4a337bec0e30ed1" + integrity sha512-IwdYdt5FKjjbRSrSqh8hoNctlYZl5DFnqSJ6buKtrl4A4gyzkrtW6WcmOFl5LnCa6Bcw+znSD77O6UiZ8qda7g== dependencies: "@egjs/hammerjs" "^2.0.17" - fbjs "^3.0.0" hoist-non-react-statics "^3.3.0" invariant "^2.2.4" + lodash "^4.17.21" prop-types "^15.7.2" -react-native-reanimated@^2.8.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-2.8.0.tgz#93c06ca84d91fb3865110b0857c49a24e316130e" - integrity sha512-kJvf/UWLBMaGCs9X66MKq5zdFMgwx8D0nHnolbHR7s8ZnbLdb7TlQ/yuzIXqn/9wABfnwtNRI3CyaP1aHWMmZg== +react-native-reanimated@^2.10.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-2.10.0.tgz#ed53be66bbb553b5b5e93e93ef4217c87b8c73db" + integrity sha512-jKm3xz5nX7ABtHzzuuLmawP0pFWP77lXNdIC6AWOceBs23OHUaJ29p4prxr/7Sb588GwTbkPsYkDqVFaE3ezNQ== dependencies: "@babel/plugin-transform-object-assign" "^7.16.7" "@babel/preset-typescript" "^7.16.7" From a89ef99fcd9132f1b76ddac10df5a994a3b2dc90 Mon Sep 17 00:00:00 2001 From: Mo Gorhom Date: Tue, 24 May 2022 22:18:31 +0100 Subject: [PATCH 02/13] refactor: updated ReText view for web --- .../bottomSheetDebugView/ReText.web.tsx | 53 +++++++++++++++++++ .../bottomSheetDebugView/styles.web.ts | 20 +++++++ 2 files changed, 73 insertions(+) create mode 100644 src/components/bottomSheetDebugView/ReText.web.tsx create mode 100644 src/components/bottomSheetDebugView/styles.web.ts diff --git a/src/components/bottomSheetDebugView/ReText.web.tsx b/src/components/bottomSheetDebugView/ReText.web.tsx new file mode 100644 index 000000000..94fc67c38 --- /dev/null +++ b/src/components/bottomSheetDebugView/ReText.web.tsx @@ -0,0 +1,53 @@ +import React, { useRef } from 'react'; +import { TextProps as RNTextProps, TextInput } from 'react-native'; +import Animated, { + useAnimatedReaction, + useDerivedValue, +} from 'react-native-reanimated'; + +interface TextProps { + text: string; + value: Animated.SharedValue | number; + style?: Animated.AnimateProps['style']; +} + +const AnimatedTextInput = Animated.createAnimatedComponent(TextInput); + +const ReText = (props: TextProps) => { + const { text, value: _providedValue, style } = { style: {}, ...props }; + const textRef = useRef(null); + + const providedValue = useDerivedValue(() => { + const value = + typeof _providedValue === 'number' + ? _providedValue + : typeof _providedValue.value === 'number' + ? _providedValue.value.toFixed(2) + : _providedValue.value; + + return `${text}: ${value}`; + }); + + //region effects + useAnimatedReaction( + () => providedValue.value, + result => { + textRef.current?.setNativeProps({ + text: result, + }); + } + ); + //endregion + + return ( + + ); +}; + +export default ReText; diff --git a/src/components/bottomSheetDebugView/styles.web.ts b/src/components/bottomSheetDebugView/styles.web.ts new file mode 100644 index 000000000..d77bfdc0b --- /dev/null +++ b/src/components/bottomSheetDebugView/styles.web.ts @@ -0,0 +1,20 @@ +import { StyleSheet } from 'react-native'; + +export const styles = StyleSheet.create({ + container: { + position: 'absolute', + left: 4, + top: 80, + padding: 2, + width: 400, + backgroundColor: 'rgba(0, 0,0,0.5)', + }, + text: { + fontSize: 14, + lineHeight: 16, + textAlignVertical: 'center', + height: 20, + padding: 0, + color: 'white', + }, +}); From 3a7f5e68016a52346e15611078f6b99b755bfae3 Mon Sep 17 00:00:00 2001 From: gorhom Date: Sat, 17 Sep 2022 15:39:39 +0100 Subject: [PATCH 03/13] chore: added cursor for handle container --- .../BottomSheetHandleContainer.tsx | 2 ++ src/components/bottomSheetHandleContainer/styles.ts | 5 +++++ src/components/bottomSheetHandleContainer/styles.web.ts | 8 ++++++++ 3 files changed, 15 insertions(+) create mode 100644 src/components/bottomSheetHandleContainer/styles.ts create mode 100644 src/components/bottomSheetHandleContainer/styles.web.ts diff --git a/src/components/bottomSheetHandleContainer/BottomSheetHandleContainer.tsx b/src/components/bottomSheetHandleContainer/BottomSheetHandleContainer.tsx index 2219e0f1d..15a29b664 100644 --- a/src/components/bottomSheetHandleContainer/BottomSheetHandleContainer.tsx +++ b/src/components/bottomSheetHandleContainer/BottomSheetHandleContainer.tsx @@ -8,6 +8,7 @@ import { useBottomSheetInternal, } from '../../hooks'; import { print } from '../../utilities'; +import { styles } from './styles'; import type { BottomSheetHandleContainerProps } from './types'; function BottomSheetHandleContainerComponent({ @@ -96,6 +97,7 @@ function BottomSheetHandleContainerComponent({ accessibilityRole="adjustable" accessibilityLabel="Bottom Sheet handle" accessibilityHint="Drag up or down to extend or minimize the Bottom Sheet" + style={styles.container} onLayout={handleContainerLayout} > Date: Sat, 17 Sep 2022 15:40:15 +0100 Subject: [PATCH 04/13] chore: updated expo version for example project --- example/expo/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/expo/package.json b/example/expo/package.json index 82ee74566..28327fa75 100644 --- a/example/expo/package.json +++ b/example/expo/package.json @@ -27,7 +27,7 @@ "react": "18.0.0", "react-dom": "18.0.0", "react-native": "0.69.4", - "react-native-gesture-handler": "~2.5.0", + "react-native-gesture-handler": "~2.6.0", "react-native-pager-view": "5.4.24", "react-native-reanimated": "~2.9.1", "react-native-redash": "^16.2.4", From 08ac8702ed4cf5ed33886d564ff4a2ffcd800237 Mon Sep 17 00:00:00 2001 From: gorhom Date: Sat, 17 Sep 2022 15:58:48 +0100 Subject: [PATCH 05/13] feat: added scrollable component for web --- ...eateBottomSheetScrollableComponent.web.tsx | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 src/components/bottomSheetScrollable/createBottomSheetScrollableComponent.web.tsx diff --git a/src/components/bottomSheetScrollable/createBottomSheetScrollableComponent.web.tsx b/src/components/bottomSheetScrollable/createBottomSheetScrollableComponent.web.tsx new file mode 100644 index 000000000..f89ad6d04 --- /dev/null +++ b/src/components/bottomSheetScrollable/createBottomSheetScrollableComponent.web.tsx @@ -0,0 +1,101 @@ +import React, { forwardRef, useImperativeHandle, useMemo } from 'react'; +import { useAnimatedProps, useAnimatedStyle } from 'react-native-reanimated'; +import { + useScrollHandler, + useScrollableSetter, + useBottomSheetInternal, +} from '../../hooks'; +import { + SCROLLABLE_DECELERATION_RATE_MAPPER, + SCROLLABLE_STATE, + SCROLLABLE_TYPE, +} from '../../constants'; + +export function createBottomSheetScrollableComponent( + type: SCROLLABLE_TYPE, + ScrollableComponent: any +) { + return forwardRef((props, ref) => { + // props + const { + // hooks + focusHook, + scrollEventsHandlersHook, + // props + enableFooterMarginAdjustment = false, + overScrollMode = 'never', + keyboardDismissMode = 'interactive', + showsVerticalScrollIndicator = true, + style, + progressViewOffset, + ...rest + }: any = props; + + //#region hooks + const { scrollableRef, scrollableContentOffsetY } = useScrollHandler( + scrollEventsHandlersHook + ); + const { animatedFooterHeight, animatedScrollableState } = + useBottomSheetInternal(); + //#endregion + + //#region variables + const scrollableAnimatedProps = useAnimatedProps( + () => ({ + decelerationRate: + SCROLLABLE_DECELERATION_RATE_MAPPER[animatedScrollableState.value], + showsVerticalScrollIndicator: showsVerticalScrollIndicator + ? animatedScrollableState.value === SCROLLABLE_STATE.UNLOCKED + : showsVerticalScrollIndicator, + }), + [showsVerticalScrollIndicator] + ); + //#endregion + + //#region styles + const containerAnimatedStyle = useAnimatedStyle( + () => ({ + marginBottom: enableFooterMarginAdjustment + ? animatedFooterHeight.value + : 0, + }), + [enableFooterMarginAdjustment] + ); + const containerStyle = useMemo(() => { + return enableFooterMarginAdjustment + ? [ + ...(style ? ('length' in style ? style : [style]) : []), + containerAnimatedStyle, + ] + : style; + }, [enableFooterMarginAdjustment, style, containerAnimatedStyle]); + //#endregion + + //#region effects + // @ts-ignore + useImperativeHandle(ref, () => scrollableRef.current); + useScrollableSetter( + scrollableRef, + type, + scrollableContentOffsetY, + false, + focusHook + ); + //#endregion + + //#region render + return ( + + ); + //#endregion + }); +} From 8025d14aef5b164eaeff53845e8dd6f137c3b014 Mon Sep 17 00:00:00 2001 From: gorhom Date: Sat, 17 Sep 2022 16:02:13 +0100 Subject: [PATCH 06/13] feat: added gesture and scroll handler for web --- .../useGestureEventsHandlersDefault.web.tsx | 378 ++++++++++++++++++ src/hooks/useScrollHandler.web.ts | 178 +++++++++ 2 files changed, 556 insertions(+) create mode 100644 src/hooks/useGestureEventsHandlersDefault.web.tsx create mode 100644 src/hooks/useScrollHandler.web.ts diff --git a/src/hooks/useGestureEventsHandlersDefault.web.tsx b/src/hooks/useGestureEventsHandlersDefault.web.tsx new file mode 100644 index 000000000..740698de6 --- /dev/null +++ b/src/hooks/useGestureEventsHandlersDefault.web.tsx @@ -0,0 +1,378 @@ +import { Keyboard, Platform } from 'react-native'; +import { runOnJS, useWorkletCallback } from 'react-native-reanimated'; +import { useBottomSheetInternal } from './useBottomSheetInternal'; +import { + ANIMATION_SOURCE, + GESTURE_SOURCE, + KEYBOARD_STATE, + SCROLLABLE_TYPE, + WINDOW_HEIGHT, +} from '../constants'; +import type { + GestureEventsHandlersHookType, + GestureEventHandlerCallbackType, +} from '../types'; +import { clamp } from '../utilities/clamp'; +import { snapPoint } from '../utilities/snapPoint'; + +type GestureEventContextType = { + initialPosition: number; + initialKeyboardState: KEYBOARD_STATE; + initialTranslationY: number; + isScrollablePositionLocked: boolean; +}; + +export const useGestureEventsHandlersDefault: GestureEventsHandlersHookType = + () => { + //#region variables + const { + animatedPosition, + animatedSnapPoints, + animatedKeyboardState, + animatedKeyboardHeight, + animatedContainerHeight, + animatedScrollableType, + animatedHighestSnapPoint, + animatedClosedPosition, + animatedScrollableContentOffsetY, + enableOverDrag, + enablePanDownToClose, + overDragResistanceFactor, + isInTemporaryPosition, + isScrollableRefreshable, + animateToPosition, + stopAnimation, + } = useBottomSheetInternal(); + //#endregion + + //#region gesture methods + const handleOnStart: GestureEventHandlerCallbackType = + useWorkletCallback( + function handleOnStart(__, { translationY }, context) { + console.log("handleOnStart"); + // cancel current animation + stopAnimation(); + + // store current animated position + context.initialPosition = animatedPosition.value; + context.initialKeyboardState = animatedKeyboardState.value; + context.initialTranslationY = translationY; + + /** + * if the scrollable content is scrolled, then + * we lock the position. + */ + if (animatedScrollableContentOffsetY.value > 0) { + context.isScrollablePositionLocked = true; + } + }, + [ + stopAnimation, + animatedPosition, + animatedKeyboardState, + animatedScrollableContentOffsetY, + ] + ); + const handleOnActive: GestureEventHandlerCallbackType = + useWorkletCallback( + function handleOnActive(source, { translationY }, context) { + console.log("handleOnActive"); + let highestSnapPoint = animatedHighestSnapPoint.value; + + translationY = translationY - context.initialTranslationY; + /** + * if keyboard is shown, then we set the highest point to the current + * position which includes the keyboard height. + */ + if ( + isInTemporaryPosition.value && + context.initialKeyboardState === KEYBOARD_STATE.SHOWN + ) { + highestSnapPoint = context.initialPosition; + } + + /** + * if current position is out of provided `snapPoints` and smaller then + * highest snap pont, then we set the highest point to the current position. + */ + if ( + isInTemporaryPosition.value && + context.initialPosition < highestSnapPoint + ) { + highestSnapPoint = context.initialPosition; + } + + const lowestSnapPoint = enablePanDownToClose + ? animatedContainerHeight.value + : animatedSnapPoints.value[0]; + + /** + * if scrollable is refreshable and sheet position at the highest + * point, then do not interact with current gesture. + */ + if ( + source === GESTURE_SOURCE.SCROLLABLE && + isScrollableRefreshable.value && + animatedPosition.value === highestSnapPoint + ) { + return; + } + + /** + * a negative scrollable content offset to be subtracted from accumulated + * current position and gesture translation Y to allow user to drag the sheet, + * when scrollable position at the top. + * a negative scrollable content offset when the scrollable is not locked. + */ + const negativeScrollableContentOffset = + (context.initialPosition === highestSnapPoint && + source === GESTURE_SOURCE.SCROLLABLE) || + !context.isScrollablePositionLocked + ? animatedScrollableContentOffsetY.value * -1 + : 0; + + /** + * an accumulated value of starting position with gesture translation y. + */ + const draggedPosition = context.initialPosition + translationY; + + /** + * an accumulated value of dragged position and negative scrollable content offset, + * this will insure locking sheet position when user is scrolling the scrollable until, + * they reach to the top of the scrollable. + */ + const accumulatedDraggedPosition = + draggedPosition + negativeScrollableContentOffset; + + /** + * a clamped value of the accumulated dragged position, to insure keeping the dragged + * position between the highest and lowest snap points. + */ + const clampedPosition = clamp( + accumulatedDraggedPosition, + highestSnapPoint, + lowestSnapPoint + ); + + /** + * if scrollable position is locked and the animated position + * reaches the highest point, then we unlock the scrollable position. + */ + if ( + context.isScrollablePositionLocked && + source === GESTURE_SOURCE.SCROLLABLE && + animatedPosition.value === highestSnapPoint + ) { + context.isScrollablePositionLocked = false; + } + + /** + * over-drag implementation. + */ + if (enableOverDrag) { + if ( + (source === GESTURE_SOURCE.HANDLE || + animatedScrollableType.value === SCROLLABLE_TYPE.VIEW) && + draggedPosition < highestSnapPoint + ) { + const resistedPosition = + highestSnapPoint - + Math.sqrt(1 + (highestSnapPoint - draggedPosition)) * + overDragResistanceFactor; + animatedPosition.value = resistedPosition; + return; + } + + if ( + source === GESTURE_SOURCE.HANDLE && + draggedPosition > lowestSnapPoint + ) { + const resistedPosition = + lowestSnapPoint + + Math.sqrt(1 + (draggedPosition - lowestSnapPoint)) * + overDragResistanceFactor; + animatedPosition.value = resistedPosition; + return; + } + + if ( + source === GESTURE_SOURCE.SCROLLABLE && + draggedPosition + negativeScrollableContentOffset > + lowestSnapPoint + ) { + const resistedPosition = + lowestSnapPoint + + Math.sqrt( + 1 + + (draggedPosition + + negativeScrollableContentOffset - + lowestSnapPoint) + ) * + overDragResistanceFactor; + animatedPosition.value = resistedPosition; + return; + } + } + + animatedPosition.value = clampedPosition; + }, + [ + enableOverDrag, + enablePanDownToClose, + overDragResistanceFactor, + isInTemporaryPosition, + isScrollableRefreshable, + animatedHighestSnapPoint, + animatedContainerHeight, + animatedSnapPoints, + animatedPosition, + animatedScrollableType, + animatedScrollableContentOffsetY, + ] + ); + const handleOnEnd: GestureEventHandlerCallbackType = + useWorkletCallback( + function handleOnEnd( + source, + { translationY, absoluteY, velocityY }, + context + ) { + const highestSnapPoint = animatedHighestSnapPoint.value; + const isSheetAtHighestSnapPoint = + animatedPosition.value === highestSnapPoint; + + /** + * if scrollable is refreshable and sheet position at the highest + * point, then do not interact with current gesture. + */ + if ( + source === GESTURE_SOURCE.SCROLLABLE && + isScrollableRefreshable.value && + isSheetAtHighestSnapPoint + ) { + return; + } + + /** + * if the sheet is in a temporary position and the gesture ended above + * the current position, then we snap back to the temporary position. + */ + if ( + isInTemporaryPosition.value && + context.initialPosition >= animatedPosition.value + ) { + if (context.initialPosition > animatedPosition.value) { + animateToPosition( + context.initialPosition, + ANIMATION_SOURCE.GESTURE, + velocityY / 2 + ); + } + return; + } + + /** + * close keyboard if current position is below the recorded + * start position and keyboard still shown. + */ + const isScrollable = + animatedScrollableType.value !== SCROLLABLE_TYPE.UNDETERMINED && + animatedScrollableType.value !== SCROLLABLE_TYPE.VIEW; + + /** + * if keyboard is shown and the sheet is dragged down, + * then we dismiss the keyboard. + */ + if ( + context.initialKeyboardState === KEYBOARD_STATE.SHOWN && + animatedPosition.value > context.initialPosition + ) { + /** + * if the platform is ios, current content is scrollable and + * the end touch point is below the keyboard position then + * we exit the method. + * + * because the the keyboard dismiss is interactive in iOS. + */ + if ( + !( + Platform.OS === 'ios' && + isScrollable && + absoluteY > WINDOW_HEIGHT - animatedKeyboardHeight.value + ) + ) { + runOnJS(Keyboard.dismiss)(); + } + } + + /** + * reset isInTemporaryPosition value + */ + if (isInTemporaryPosition.value) { + isInTemporaryPosition.value = false; + } + + /** + * clone snap points array, and insert the container height + * if pan down to close is enabled. + */ + const snapPoints = animatedSnapPoints.value.slice(); + if (enablePanDownToClose) { + snapPoints.unshift(animatedClosedPosition.value); + } + + /** + * calculate the destination point, using redash. + */ + const destinationPoint = snapPoint( + translationY + context.initialPosition, + velocityY, + snapPoints + ); + + /** + * if destination point is the same as the current position, + * then no need to perform animation. + */ + if (destinationPoint === animatedPosition.value) { + return; + } + + const wasGestureHandledByScrollView = + source === GESTURE_SOURCE.SCROLLABLE && + animatedScrollableContentOffsetY.value > 0; + /** + * prevents snapping from top to middle / bottom with repeated interrupted scrolls + */ + if (wasGestureHandledByScrollView && isSheetAtHighestSnapPoint) { + return; + } + + animateToPosition( + destinationPoint, + ANIMATION_SOURCE.GESTURE, + velocityY / 2 + ); + }, + [ + enablePanDownToClose, + isInTemporaryPosition, + isScrollableRefreshable, + animatedClosedPosition, + animatedHighestSnapPoint, + animatedKeyboardHeight, + animatedPosition, + animatedScrollableType, + animatedSnapPoints, + animatedScrollableContentOffsetY, + animateToPosition, + ] + ); + //#endregion + + return { + handleOnStart, + handleOnActive, + handleOnEnd, + }; + }; diff --git a/src/hooks/useScrollHandler.web.ts b/src/hooks/useScrollHandler.web.ts new file mode 100644 index 000000000..002568431 --- /dev/null +++ b/src/hooks/useScrollHandler.web.ts @@ -0,0 +1,178 @@ +import { useEffect, useRef, TouchEvent } from 'react'; +import { useSharedValue } from 'react-native-reanimated'; +import { useBottomSheetInternal } from './useBottomSheetInternal'; +import { ANIMATION_STATE, SCROLLABLE_STATE } from '../constants'; +import type { Scrollable } from '../types'; + +export type ScrollEventContextType = { + initialContentOffsetY: number; + shouldLockInitialPosition: boolean; +}; + +export const useScrollHandler = () => { + //#region refs + const scrollableRef = useRef(); + //#endregion + + //#region variables + const scrollableContentOffsetY = useSharedValue(0); + //#endregion + + //#region hooks + const { + animatedScrollableState, + animatedAnimationState, + animatedScrollableContentOffsetY, + } = useBottomSheetInternal(); + //#endregion + + //#region effects + useEffect(() => { + const element = scrollableRef.current as any; + + var scrollOffset = 0; + var supportsPassive = false; + var maybePrevent = false; + var lastTouchY = 0; + + var initialContentOffsetY = 0; + var shouldLockInitialPosition = false; + + function handleOnTouchStart(event: TouchEvent) { + // console.log('handleOnTouchStart'); + if (event.touches.length !== 1) return; + + initialContentOffsetY = element.scrollTop; + lastTouchY = event.touches[0].clientY; + maybePrevent = scrollOffset <= 0; + } + + function handleOnTouchMove(event: TouchEvent) { + // console.log( + // 'handleOnTouchMove', + // animatedScrollableState.value === SCROLLABLE_STATE.LOCKED + // ); + + if (animatedScrollableState.value === SCROLLABLE_STATE.LOCKED) { + return event.preventDefault(); + } + + if (maybePrevent) { + maybePrevent = false; + + const touchY = event.touches[0].clientY; + const touchYDelta = touchY - lastTouchY; + + if (touchYDelta > 0) { + return event.preventDefault(); + } + } + + return true; + } + + function handleOnTouchEnd() { + // console.log('handleOnTouchEnd'); + // console.log(''); + if (animatedScrollableState.value === SCROLLABLE_STATE.LOCKED) { + const lockPosition = shouldLockInitialPosition + ? initialContentOffsetY ?? 0 + : 0; + // @ts-ignore + element.scroll({ + top: 0, + left: 0, + behavior: 'instant', + }); + scrollableContentOffsetY.value = lockPosition; + return; + } + } + + function handleOnScroll(event: TouchEvent) { + scrollOffset = element.scrollTop; + + if (animatedAnimationState.value !== ANIMATION_STATE.RUNNING) { + scrollableContentOffsetY.value = Math.max(0, scrollOffset); + animatedScrollableContentOffsetY.value = Math.max(0, scrollOffset); + } + + if (scrollOffset <= 0) { + event.preventDefault(); + event.stopPropagation(); + return false; + } + return true; + } + + try { + // @ts-ignore + window.addEventListener('test', null, { + // @ts-ignore + get passive() { + supportsPassive = true; + }, + }); + } catch (e) {} + + element.addEventListener( + 'touchstart', + handleOnTouchStart, + supportsPassive + ? { + passive: true, + } + : false + ); + + element.addEventListener( + 'touchmove', + handleOnTouchMove, + supportsPassive + ? { + passive: false, + } + : false + ); + + element.addEventListener( + 'touchend', + handleOnTouchEnd, + supportsPassive + ? { + passive: false, + } + : false + ); + + element.addEventListener( + 'scroll', + handleOnScroll, + supportsPassive + ? { + passive: false, + } + : false + ); + + return () => { + // @ts-ignore + window.removeEventListener('test', null); + element.removeEventListener('touchstart', handleOnTouchStart); + element.removeEventListener('touchmove', handleOnTouchMove); + element.removeEventListener('touchend', handleOnTouchEnd); + element.removeEventListener('scroll', handleOnScroll); + }; + }, [ + animatedAnimationState, + animatedScrollableContentOffsetY, + animatedScrollableState, + scrollableContentOffsetY, + ]); + //#endregion + + return { + scrollableRef, + scrollableContentOffsetY, + }; +}; From 941d1d8be016f2c68ada71c0a192a013da37e423 Mon Sep 17 00:00:00 2001 From: gorhom Date: Mon, 19 Sep 2022 16:39:41 +0100 Subject: [PATCH 07/13] chore: added getRefNativeTag for web --- src/utilities/getRefNativeTag.web.ts | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 src/utilities/getRefNativeTag.web.ts diff --git a/src/utilities/getRefNativeTag.web.ts b/src/utilities/getRefNativeTag.web.ts new file mode 100644 index 000000000..5cece79bd --- /dev/null +++ b/src/utilities/getRefNativeTag.web.ts @@ -0,0 +1,5 @@ +import type { RefObject } from 'react'; + +export function getRefNativeTag(ref: RefObject) { + return ref?.current || null; +} From c173ab9a69d8685d31082ca9387dc49dc77fd0e7 Mon Sep 17 00:00:00 2001 From: gorhom Date: Mon, 3 Oct 2022 22:10:12 +0100 Subject: [PATCH 08/13] feat: rewrite gesture apis with gesture handler 2 (#1126) * chore: updated dependencies * feat: rewrite the gesture api with gh2 --- example/bare/ios/Podfile.lock | 12 +- example/bare/package.json | 2 +- lint-staged.config.js | 2 +- package.json | 16 +- src/components/bottomSheet/BottomSheet.tsx | 12 +- src/components/bottomSheet/types.d.ts | 27 +- .../BottomSheetDraggableView.tsx | 91 +- .../bottomSheetDraggableView/types.d.ts | 16 +- .../BottomSheetGestureHandlersProvider.tsx | 29 +- .../BottomSheetHandleContainer.tsx | 67 +- .../BottomSheetRefreshControl.android.tsx | 44 +- .../bottomSheetRefreshControl/index.ts | 6 +- .../ScrollableContainer.android.tsx | 51 ++ .../ScrollableContainer.tsx | 23 + .../createBottomSheetScrollableComponent.tsx | 122 +-- src/contexts/gesture.ts | 10 +- src/contexts/internal.ts | 16 +- src/hooks/useGestureEventsHandlersDefault.tsx | 593 ++++++------ .../useGestureEventsHandlersDefault.web.tsx | 704 +++++++------- src/hooks/useGestureHandler.ts | 131 ++- src/types.d.ts | 31 +- yarn.lock | 867 ++++++++---------- 22 files changed, 1465 insertions(+), 1407 deletions(-) create mode 100644 src/components/bottomSheetScrollable/ScrollableContainer.android.tsx create mode 100644 src/components/bottomSheetScrollable/ScrollableContainer.tsx diff --git a/example/bare/ios/Podfile.lock b/example/bare/ios/Podfile.lock index 77eb7790f..3d1109926 100644 --- a/example/bare/ios/Podfile.lock +++ b/example/bare/ios/Podfile.lock @@ -306,7 +306,7 @@ PODS: - React - react-native-maps (0.30.2): - React-Core - - react-native-pager-view (5.4.24): + - react-native-pager-view (5.4.25): - React-Core - react-native-safe-area-context (4.2.4): - RCT-Folly @@ -382,7 +382,7 @@ PODS: - React-perflogger (= 0.69.4) - RNCMaskedView (0.1.11): - React - - RNGestureHandler (2.6.0): + - RNGestureHandler (2.7.0): - React-Core - RNReanimated (2.10.0): - DoubleConversion @@ -411,7 +411,7 @@ PODS: - React-RCTText - ReactCommon/turbomodule/core - Yoga - - RNScreens (3.15.0): + - RNScreens (3.17.0): - React-Core - React-RCTImage - SocketRocket (0.6.0) @@ -629,7 +629,7 @@ SPEC CHECKSUMS: React-logger: 1088859f145b8f6dd0d3ed051a647ef0e3e80fad react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-maps: df7b9fca1b1c8d356fadbf5b8a63a5f8cf32fc73 - react-native-pager-view: 95d0418c3c74279840abec6926653d32447bafb6 + react-native-pager-view: da490aa1f902c9a5aeecf0909cc975ad0e92e53e react-native-safe-area-context: f98b0b16d1546d208fc293b4661e3f81a895afd9 React-perflogger: cb386fd44c97ec7f8199c04c12b22066b0f2e1e0 React-RCTActionSheet: f803a85e46cf5b4066c2ac5e122447f918e9c6e5 @@ -644,9 +644,9 @@ SPEC CHECKSUMS: React-runtimeexecutor: 61ee22a8cdf8b6bb2a7fb7b4ba2cc763e5285196 ReactCommon: 8f67bd7e0a6afade0f20718f859dc8c2275f2e83 RNCMaskedView: 0e1bc4bfa8365eba5fbbb71e07fbdc0555249489 - RNGestureHandler: 920eb17f5b1e15dae6e5ed1904045f8f90e0b11e + RNGestureHandler: 7673697e7c0e9391adefae4faa087442bc04af33 RNReanimated: 7faa787e8d4493fbc95fab2ad331fa7625828cfa - RNScreens: 4a1af06327774490d97342c00aee0c2bafb497b7 + RNScreens: 0df01424e9e0ed7827200d6ed1087ddd06c493f9 SocketRocket: fccef3f9c5cedea1353a9ef6ada904fde10d6608 Yoga: ff994563b2fd98c982ca58e8cd9db2cdaf4dda74 YogaKit: f782866e155069a2cca2517aafea43200b01fd5a diff --git a/example/bare/package.json b/example/bare/package.json index f281ac9fc..3f5c31e6c 100644 --- a/example/bare/package.json +++ b/example/bare/package.json @@ -24,7 +24,7 @@ "nanoid": "^3.3.3", "react": "18.0.0", "react-native": "0.69.4", - "react-native-gesture-handler": "^2.6.0", + "react-native-gesture-handler": "^2.6.2", "react-native-maps": "^0.30.1", "react-native-pager-view": "^5.4.9", "react-native-reanimated": "^2.10.0", diff --git a/lint-staged.config.js b/lint-staged.config.js index 8efb35dc5..9a93ff059 100644 --- a/lint-staged.config.js +++ b/lint-staged.config.js @@ -1,4 +1,4 @@ module.exports = { '**/*.js': ['eslint'], - '**/*.{ts,tsx}': [() => 'tsc --skipLibCheck --noEmit', 'eslint'], + '**/*.{ts,tsx}': [() => 'tsc --skipLibCheck --noEmit', 'eslint --fix'], }; diff --git a/package.json b/package.json index 566c958b2..5302630c4 100644 --- a/package.json +++ b/package.json @@ -52,17 +52,17 @@ "@types/react-native": "^0.67.7", "auto-changelog": "^2.4.0", "copyfiles": "^2.4.1", - "eslint": "^7.32.0", - "eslint-config-prettier": "^8.3.0", - "eslint-plugin-prettier": "^3.4.0", + "eslint": "^8.21.0", + "eslint-config-prettier": "^8.5.0", + "eslint-plugin-prettier": "^4.2.1", "husky": "^4.3.8", - "lint-staged": "^11.1.2", - "prettier": "^2.3.2", + "lint-staged": "^13.0.3", + "prettier": "^2.7.1", "react": "~16.9.0", "react-native": "^0.62.2", - "react-native-builder-bob": "^0.18.1", - "react-native-gesture-handler": "^2.6.1", - "react-native-reanimated": "^2.10.0", + "react-native-builder-bob": "^0.18.3", + "react-native-gesture-handler": "^2.5.0", + "react-native-reanimated": "^2.9.1", "release-it": "^15.4.2", "typescript": "^4.2.4" }, diff --git a/src/components/bottomSheet/BottomSheet.tsx b/src/components/bottomSheet/BottomSheet.tsx index b16644070..616a6014a 100644 --- a/src/components/bottomSheet/BottomSheet.tsx +++ b/src/components/bottomSheet/BottomSheet.tsx @@ -1642,14 +1642,16 @@ const BottomSheetComponent = forwardRef( // topInset, // bottomInset, animatedSheetState, - animatedScrollableState, - animatedScrollableOverrideState, + // animatedScrollableState, + // animatedScrollableOverrideState, // isScrollableRefreshable, // animatedScrollableContentOffsetY, // keyboardState, - // animatedIndex, - // animatedCurrentIndex, - // animatedPosition, + animatedIndex, + animatedCurrentIndex, + animatedPosition, + animatedHandleGestureState, + animatedContentGestureState, // animatedContainerHeight, // animatedSheetHeight, // animatedHandleHeight, diff --git a/src/components/bottomSheet/types.d.ts b/src/components/bottomSheet/types.d.ts index c489981e1..9a4295642 100644 --- a/src/components/bottomSheet/types.d.ts +++ b/src/components/bottomSheet/types.d.ts @@ -6,7 +6,7 @@ import type { WithSpringConfig, WithTimingConfig, } from 'react-native-reanimated'; -import type { PanGestureHandlerProps } from 'react-native-gesture-handler'; +import type { PanGesture } from 'react-native-gesture-handler'; import type { BottomSheetHandleProps } from '../bottomSheetHandle'; import type { BottomSheetBackdropProps } from '../bottomSheetBackdrop'; import type { BottomSheetBackgroundProps } from '../bottomSheetBackground'; @@ -21,17 +21,7 @@ import type { GestureEventsHandlersHookType } from '../../types'; export interface BottomSheetProps extends BottomSheetAnimationConfigs, - Partial< - Pick< - PanGestureHandlerProps, - | 'activeOffsetY' - | 'activeOffsetX' - | 'failOffsetY' - | 'failOffsetX' - | 'waitFor' - | 'simultaneousHandlers' - > - > { + Partial { //#region configuration /** * Initial snap point index, provide `-1` to initiate bottom sheet in closed state. @@ -313,3 +303,16 @@ export type AnimateToPositionType = ( velocity?: number, configs?: WithTimingConfig | WithSpringConfig ) => void; + +export type BottomSheetGestureProps = { + activeOffsetX: Parameters[0]; + activeOffsetY: Parameters[0]; + + failOffsetY: Parameters[0]; + failOffsetX: Parameters[0]; + + simultaneousHandlers: Parameters< + PanGesture['simultaneousWithExternalGesture'] + >[0]; + waitFor: Parameters[0]; +}; diff --git a/src/components/bottomSheetDraggableView/BottomSheetDraggableView.tsx b/src/components/bottomSheetDraggableView/BottomSheetDraggableView.tsx index 377b2d5a8..ec137bb5f 100644 --- a/src/components/bottomSheetDraggableView/BottomSheetDraggableView.tsx +++ b/src/components/bottomSheetDraggableView/BottomSheetDraggableView.tsx @@ -1,15 +1,14 @@ -import React, { useMemo, useRef, memo } from 'react'; +import React, { useMemo, memo } from 'react'; import Animated from 'react-native-reanimated'; -import { PanGestureHandler } from 'react-native-gesture-handler'; +import { GestureDetector, Gesture } from 'react-native-gesture-handler'; import { useBottomSheetGestureHandlers, useBottomSheetInternal, } from '../../hooks'; -import { GESTURE_SOURCE } from '../../constants'; import type { BottomSheetDraggableViewProps } from './types'; +import { BottomSheetDraggableContext } from '../../contexts/gesture'; const BottomSheetDraggableViewComponent = ({ - gestureType = GESTURE_SOURCE.CONTENT, nativeGestureRef, refreshControlGestureRef, style, @@ -26,19 +25,10 @@ const BottomSheetDraggableViewComponent = ({ failOffsetX, failOffsetY, } = useBottomSheetInternal(); - const { contentPanGestureHandler, scrollablePanGestureHandler } = - useBottomSheetGestureHandlers(); + const { contentPanGestureHandler } = useBottomSheetGestureHandlers(); //#endregion //#region variables - const panGestureRef = useRef(null); - const gestureHandler = useMemo( - () => - gestureType === GESTURE_SOURCE.CONTENT - ? contentPanGestureHandler - : scrollablePanGestureHandler, - [gestureType, contentPanGestureHandler, scrollablePanGestureHandler] - ); const simultaneousHandlers = useMemo(() => { const refs = []; @@ -64,25 +54,66 @@ const BottomSheetDraggableViewComponent = ({ nativeGestureRef, refreshControlGestureRef, ]); + const draggableGesture = useMemo(() => { + let gesture = Gesture.Pan() + .enabled(enableContentPanningGesture) + .shouldCancelWhenOutside(false) + .runOnJS(false) + .onStart(contentPanGestureHandler.handleOnStart) + .onChange(contentPanGestureHandler.handleOnChange) + .onEnd(contentPanGestureHandler.handleOnEnd) + .onFinalize(contentPanGestureHandler.handleOnFinalize); + + if (waitFor) { + gesture = gesture.requireExternalGestureToFail(waitFor); + } + + if (simultaneousHandlers) { + gesture = gesture.simultaneousWithExternalGesture( + simultaneousHandlers as any + ); + } + + if (activeOffsetX) { + gesture = gesture.activeOffsetX(activeOffsetX); + } + + if (activeOffsetY) { + gesture = gesture.activeOffsetY(activeOffsetY); + } + + if (failOffsetX) { + gesture = gesture.failOffsetX(failOffsetX); + } + + if (failOffsetY) { + gesture = gesture.failOffsetY(failOffsetY); + } + + return gesture; + }, [ + activeOffsetX, + activeOffsetY, + enableContentPanningGesture, + failOffsetX, + failOffsetY, + simultaneousHandlers, + waitFor, + contentPanGestureHandler.handleOnChange, + contentPanGestureHandler.handleOnEnd, + contentPanGestureHandler.handleOnFinalize, + contentPanGestureHandler.handleOnStart, + ]); //#endregion return ( - - - {children} - - + + + + {children} + + + ); }; diff --git a/src/components/bottomSheetDraggableView/types.d.ts b/src/components/bottomSheetDraggableView/types.d.ts index 8d38987e2..5ed61d78c 100644 --- a/src/components/bottomSheetDraggableView/types.d.ts +++ b/src/components/bottomSheetDraggableView/types.d.ts @@ -1,17 +1,9 @@ -import type { ReactNode, Ref } from 'react'; +import type { ReactNode } from 'react'; import type { ViewProps as RNViewProps } from 'react-native'; -import type { NativeViewGestureHandler } from 'react-native-gesture-handler'; -import type { GESTURE_SOURCE } from '../../constants'; +import type { GestureRef } from 'react-native-gesture-handler/lib/typescript/handlers/gestures/gesture'; export type BottomSheetDraggableViewProps = RNViewProps & { - /** - * Defines the gesture type of the draggable view. - * - * @default GESTURE_SOURCE.CONTENT - * @type GESTURE_SOURCE - */ - gestureType?: GESTURE_SOURCE; - nativeGestureRef?: Ref | null; - refreshControlGestureRef?: Ref | null; + nativeGestureRef?: Exclude; + refreshControlGestureRef?: Exclude; children: ReactNode[] | ReactNode; }; diff --git a/src/components/bottomSheetGestureHandlersProvider/BottomSheetGestureHandlersProvider.tsx b/src/components/bottomSheetGestureHandlersProvider/BottomSheetGestureHandlersProvider.tsx index e3314b812..9e2a8ca7b 100644 --- a/src/components/bottomSheetGestureHandlersProvider/BottomSheetGestureHandlersProvider.tsx +++ b/src/components/bottomSheetGestureHandlersProvider/BottomSheetGestureHandlersProvider.tsx @@ -23,7 +23,7 @@ const BottomSheetGestureHandlersProvider = ({ //#region hooks const { animatedContentGestureState, animatedHandleGestureState } = useBottomSheetInternal(); - const { handleOnStart, handleOnActive, handleOnEnd } = + const { handleOnStart, handleOnChange, handleOnEnd, handleOnFinalize } = useGestureEventsHandlers(); //#endregion @@ -33,17 +33,9 @@ const BottomSheetGestureHandlersProvider = ({ animatedContentGestureState, animatedGestureSource, handleOnStart, - handleOnActive, - handleOnEnd - ); - - const scrollablePanGestureHandler = useGestureHandler( - GESTURE_SOURCE.SCROLLABLE, - animatedContentGestureState, - animatedGestureSource, - handleOnStart, - handleOnActive, - handleOnEnd + handleOnChange, + handleOnEnd, + handleOnFinalize ); const handlePanGestureHandler = useGestureHandler( @@ -51,8 +43,9 @@ const BottomSheetGestureHandlersProvider = ({ animatedHandleGestureState, animatedGestureSource, handleOnStart, - handleOnActive, - handleOnEnd + handleOnChange, + handleOnEnd, + handleOnFinalize ); //#endregion @@ -61,15 +54,9 @@ const BottomSheetGestureHandlersProvider = ({ () => ({ contentPanGestureHandler, handlePanGestureHandler, - scrollablePanGestureHandler, animatedGestureSource, }), - [ - contentPanGestureHandler, - handlePanGestureHandler, - scrollablePanGestureHandler, - animatedGestureSource, - ] + [contentPanGestureHandler, handlePanGestureHandler, animatedGestureSource] ); //#endregion return ( diff --git a/src/components/bottomSheetHandleContainer/BottomSheetHandleContainer.tsx b/src/components/bottomSheetHandleContainer/BottomSheetHandleContainer.tsx index 15a29b664..23724d557 100644 --- a/src/components/bottomSheetHandleContainer/BottomSheetHandleContainer.tsx +++ b/src/components/bottomSheetHandleContainer/BottomSheetHandleContainer.tsx @@ -1,6 +1,6 @@ import React, { memo, useCallback, useMemo } from 'react'; import type { LayoutChangeEvent } from 'react-native'; -import { PanGestureHandler } from 'react-native-gesture-handler'; +import { Gesture, GestureDetector } from 'react-native-gesture-handler'; import Animated from 'react-native-reanimated'; import BottomSheetHandle from '../bottomSheetHandle'; import { @@ -51,6 +51,57 @@ function BottomSheetHandleContainerComponent({ return refs; }, [_providedSimultaneousHandlers, _internalSimultaneousHandlers]); + + const panGesture = useMemo(() => { + let gesture = Gesture.Pan() + .enabled(enableHandlePanningGesture!) + .shouldCancelWhenOutside(false) + .runOnJS(false) + .onStart(handlePanGestureHandler.handleOnStart) + .onChange(handlePanGestureHandler.handleOnChange) + .onEnd(handlePanGestureHandler.handleOnEnd) + .onFinalize(handlePanGestureHandler.handleOnFinalize); + + if (waitFor) { + gesture = gesture.requireExternalGestureToFail(waitFor); + } + + if (simultaneousHandlers) { + gesture = gesture.simultaneousWithExternalGesture( + simultaneousHandlers as any + ); + } + + if (activeOffsetX) { + gesture = gesture.activeOffsetX(activeOffsetX); + } + + if (activeOffsetY) { + gesture = gesture.activeOffsetY(activeOffsetY); + } + + if (failOffsetX) { + gesture = gesture.failOffsetX(failOffsetX); + } + + if (failOffsetY) { + gesture = gesture.failOffsetY(failOffsetY); + } + + return gesture; + }, [ + activeOffsetX, + activeOffsetY, + enableHandlePanningGesture, + failOffsetX, + failOffsetY, + simultaneousHandlers, + waitFor, + handlePanGestureHandler.handleOnChange, + handlePanGestureHandler.handleOnEnd, + handlePanGestureHandler.handleOnFinalize, + handlePanGestureHandler.handleOnStart, + ]); //#endregion //#region callbacks @@ -80,17 +131,7 @@ function BottomSheetHandleContainerComponent({ ? BottomSheetHandle : _providedHandleComponent; return HandleComponent !== null ? ( - + - + ) : null; //#endregion } diff --git a/src/components/bottomSheetRefreshControl/BottomSheetRefreshControl.android.tsx b/src/components/bottomSheetRefreshControl/BottomSheetRefreshControl.android.tsx index be502259c..2bce722bf 100644 --- a/src/components/bottomSheetRefreshControl/BottomSheetRefreshControl.android.tsx +++ b/src/components/bottomSheetRefreshControl/BottomSheetRefreshControl.android.tsx @@ -1,35 +1,57 @@ -import React, { forwardRef, memo } from 'react'; +import React, { memo, useContext, useMemo } from 'react'; import { RefreshControl, RefreshControlProps } from 'react-native'; -import { NativeViewGestureHandler } from 'react-native-gesture-handler'; +import { + Gesture, + GestureDetector, + SimultaneousGesture, +} from 'react-native-gesture-handler'; import Animated, { useAnimatedProps } from 'react-native-reanimated'; +import { BottomSheetDraggableContext } from '../../contexts/gesture'; import { SCROLLABLE_STATE } from '../../constants'; import { useBottomSheetInternal } from '../../hooks'; const AnimatedRefreshControl = Animated.createAnimatedComponent(RefreshControl); -const BottomSheetRefreshControlComponent = forwardRef< - NativeViewGestureHandler, - RefreshControlProps ->(({ onRefresh, ...rest }, ref) => { - // hooks +interface BottomSheetRefreshControlProps extends RefreshControlProps { + scrollableGesture: SimultaneousGesture; +} + +function BottomSheetRefreshControlComponent({ + onRefresh, + scrollableGesture, + ...rest +}: BottomSheetRefreshControlProps) { + //#region hooks + const draggableGesture = useContext(BottomSheetDraggableContext); const { animatedScrollableState } = useBottomSheetInternal(); + //#endregion - // variables + //#region variables const animatedProps = useAnimatedProps(() => ({ enabled: animatedScrollableState.value === SCROLLABLE_STATE.UNLOCKED, })); + const gesture = useMemo( + () => + Gesture.Simultaneous( + Gesture.Native().shouldCancelWhenOutside(false), + scrollableGesture, + draggableGesture! + ), + [draggableGesture, scrollableGesture] + ); + //#endregion // render return ( - + - + ); -}); +} const BottomSheetRefreshControl = memo(BottomSheetRefreshControlComponent); BottomSheetRefreshControl.displayName = 'BottomSheetRefreshControl'; diff --git a/src/components/bottomSheetRefreshControl/index.ts b/src/components/bottomSheetRefreshControl/index.ts index ac07963d2..e295515b0 100644 --- a/src/components/bottomSheetRefreshControl/index.ts +++ b/src/components/bottomSheetRefreshControl/index.ts @@ -1,11 +1,15 @@ import type React from 'react'; import type { RefreshControlProps } from 'react-native'; -import type { NativeViewGestureHandlerProps } from 'react-native-gesture-handler'; +import type { + NativeViewGestureHandlerProps, + SimultaneousGesture, +} from 'react-native-gesture-handler'; import BottomSheetRefreshControl from './BottomSheetRefreshControl'; export default BottomSheetRefreshControl as any as React.MemoExoticComponent< React.ForwardRefExoticComponent< RefreshControlProps & { + scrollableGesture: SimultaneousGesture; children: React.ReactNode | React.ReactNode[]; } & React.RefAttributes< React.ComponentType< diff --git a/src/components/bottomSheetScrollable/ScrollableContainer.android.tsx b/src/components/bottomSheetScrollable/ScrollableContainer.android.tsx new file mode 100644 index 000000000..9a152af3b --- /dev/null +++ b/src/components/bottomSheetScrollable/ScrollableContainer.android.tsx @@ -0,0 +1,51 @@ +import React, { forwardRef } from 'react'; +import { + GestureDetector, + SimultaneousGesture, +} from 'react-native-gesture-handler'; +import BottomSheetRefreshControl from '../bottomSheetRefreshControl'; +import { styles } from './styles'; + +interface ScrollableContainerProps { + nativeGesture: SimultaneousGesture; + refreshControl: any; + progressViewOffset: any; + refreshing: any; + onRefresh: any; + ScrollableComponent: any; +} + +export const ScrollableContainer = forwardRef( + function ScrollableContainer( + { + nativeGesture, + refreshControl: _refreshControl, + refreshing, + progressViewOffset, + onRefresh, + ScrollableComponent, + ...rest + }, + ref + ) { + const Scrollable = ( + + + + ); + + return onRefresh ? ( + + {Scrollable} + + ) : ( + Scrollable + ); + } +); diff --git a/src/components/bottomSheetScrollable/ScrollableContainer.tsx b/src/components/bottomSheetScrollable/ScrollableContainer.tsx new file mode 100644 index 000000000..e8aff0de3 --- /dev/null +++ b/src/components/bottomSheetScrollable/ScrollableContainer.tsx @@ -0,0 +1,23 @@ +import React, { forwardRef } from 'react'; +import { + GestureDetector, + SimultaneousGesture, +} from 'react-native-gesture-handler'; + +interface ScrollableContainerProps { + nativeGesture: SimultaneousGesture; + ScrollableComponent: any; +} + +export const ScrollableContainer = forwardRef( + function ScrollableContainer( + { nativeGesture, ScrollableComponent, ...rest }, + ref + ) { + return ( + + + + ); + } +); diff --git a/src/components/bottomSheetScrollable/createBottomSheetScrollableComponent.tsx b/src/components/bottomSheetScrollable/createBottomSheetScrollableComponent.tsx index 49237cb9d..e0137d1f4 100644 --- a/src/components/bottomSheetScrollable/createBottomSheetScrollableComponent.tsx +++ b/src/components/bottomSheetScrollable/createBottomSheetScrollableComponent.tsx @@ -1,21 +1,23 @@ -import React, { forwardRef, useImperativeHandle, useMemo, useRef } from 'react'; -import { Platform } from 'react-native'; +import React, { + forwardRef, + useContext, + useImperativeHandle, + useMemo, +} from 'react'; import { useAnimatedProps, useAnimatedStyle } from 'react-native-reanimated'; -import { NativeViewGestureHandler } from 'react-native-gesture-handler'; -import BottomSheetDraggableView from '../bottomSheetDraggableView'; -import BottomSheetRefreshControl from '../bottomSheetRefreshControl'; +import { Gesture } from 'react-native-gesture-handler'; +import { BottomSheetDraggableContext } from '../../contexts/gesture'; import { useScrollHandler, useScrollableSetter, useBottomSheetInternal, } from '../../hooks'; import { - GESTURE_SOURCE, SCROLLABLE_DECELERATION_RATE_MAPPER, SCROLLABLE_STATE, SCROLLABLE_TYPE, } from '../../constants'; -import { styles } from './styles'; +import { ScrollableContainer } from './ScrollableContainer'; export function createBottomSheetScrollableComponent( type: SCROLLABLE_TYPE, @@ -44,12 +46,8 @@ export function createBottomSheetScrollableComponent( ...rest }: any = props; - //#region refs - const nativeGestureRef = useRef(null); - const refreshControlGestureRef = useRef(null); - //#endregion - //#region hooks + const draggableGesture = useContext(BottomSheetDraggableContext); const { scrollableRef, scrollableContentOffsetY, scrollHandler } = useScrollHandler( scrollEventsHandlersHook, @@ -57,11 +55,8 @@ export function createBottomSheetScrollableComponent( onScrollBeginDrag, onScrollEndDrag ); - const { - enableContentPanningGesture, - animatedFooterHeight, - animatedScrollableState, - } = useBottomSheetInternal(); + const { animatedFooterHeight, animatedScrollableState } = + useBottomSheetInternal(); //#endregion //#region variables @@ -75,6 +70,15 @@ export function createBottomSheetScrollableComponent( }), [showsVerticalScrollIndicator] ); + + const nativeGesture = useMemo( + () => + Gesture.Simultaneous( + Gesture.Native().shouldCancelWhenOutside(false), + draggableGesture! + ), + [draggableGesture] + ); //#endregion //#region styles @@ -109,75 +113,23 @@ export function createBottomSheetScrollableComponent( //#endregion //#region render - if (Platform.OS === 'android') { - const scrollableContent = ( - - - - ); - return ( - - {onRefresh ? ( - - {scrollableContent} - - ) : ( - scrollableContent - )} - - ); - } return ( - - - - - + ); //#endregion }); diff --git a/src/contexts/gesture.ts b/src/contexts/gesture.ts index 79ce72d30..a6b2d217a 100644 --- a/src/contexts/gesture.ts +++ b/src/contexts/gesture.ts @@ -1,11 +1,13 @@ import { createContext } from 'react'; -import type { PanGestureHandlerGestureEvent } from 'react-native-gesture-handler'; +import type { Gesture } from 'react-native-gesture-handler/lib/typescript/handlers/gestures/gesture'; +import type { GestureHandlersHookType } from '../types'; export interface BottomSheetGestureHandlersContextType { - contentPanGestureHandler: (event: PanGestureHandlerGestureEvent) => void; - handlePanGestureHandler: (event: PanGestureHandlerGestureEvent) => void; - scrollablePanGestureHandler: (event: PanGestureHandlerGestureEvent) => void; + contentPanGestureHandler: ReturnType; + handlePanGestureHandler: ReturnType; } export const BottomSheetGestureHandlersContext = createContext(null); + +export const BottomSheetDraggableContext = createContext(null); diff --git a/src/contexts/internal.ts b/src/contexts/internal.ts index fd313de29..8f3a96fe3 100644 --- a/src/contexts/internal.ts +++ b/src/contexts/internal.ts @@ -1,11 +1,9 @@ import { createContext, RefObject } from 'react'; -import type { - PanGestureHandlerProps, - State, -} from 'react-native-gesture-handler'; +import type { State } from 'react-native-gesture-handler'; import type Animated from 'react-native-reanimated'; import type { AnimateToPositionType, + BottomSheetGestureProps, BottomSheetProps, } from '../components/bottomSheet/types'; import type { @@ -18,15 +16,7 @@ import type { import type { Scrollable, ScrollableRef } from '../types'; export interface BottomSheetInternalContextType - extends Pick< - PanGestureHandlerProps, - | 'activeOffsetY' - | 'activeOffsetX' - | 'failOffsetY' - | 'failOffsetX' - | 'waitFor' - | 'simultaneousHandlers' - >, + extends Partial, Required< Pick< BottomSheetProps, diff --git a/src/hooks/useGestureEventsHandlersDefault.tsx b/src/hooks/useGestureEventsHandlersDefault.tsx index b44bfa510..0ded828d9 100644 --- a/src/hooks/useGestureEventsHandlersDefault.tsx +++ b/src/hooks/useGestureEventsHandlersDefault.tsx @@ -1,5 +1,9 @@ import { Keyboard, Platform } from 'react-native'; -import { runOnJS, useWorkletCallback } from 'react-native-reanimated'; +import { + runOnJS, + useSharedValue, + useWorkletCallback, +} from 'react-native-reanimated'; import { useBottomSheetInternal } from './useBottomSheetInternal'; import { ANIMATION_SOURCE, @@ -21,6 +25,19 @@ type GestureEventContextType = { isScrollablePositionLocked: boolean; }; +const INITIAL_CONTEXT: GestureEventContextType = { + initialPosition: 0, + initialKeyboardState: KEYBOARD_STATE.UNDETERMINED, + isScrollablePositionLocked: false, +}; + +const resetContext = (context: any) => { + 'worklet'; + Object.keys(context).map(key => { + context[key] = undefined; + }); +}; + export const useGestureEventsHandlersDefault: GestureEventsHandlersHookType = () => { //#region variables @@ -42,332 +59,346 @@ export const useGestureEventsHandlersDefault: GestureEventsHandlersHookType = animateToPosition, stopAnimation, } = useBottomSheetInternal(); + + const context = useSharedValue({ + ...INITIAL_CONTEXT, + }); //#endregion //#region gesture methods - const handleOnStart: GestureEventHandlerCallbackType = - useWorkletCallback( - function handleOnStart(__, _, context) { - // cancel current animation - stopAnimation(); + const handleOnStart: GestureEventHandlerCallbackType = useWorkletCallback( + function handleOnStart(__, _) { + // cancel current animation + stopAnimation(); - // store current animated position - context.initialPosition = animatedPosition.value; - context.initialKeyboardState = animatedKeyboardState.value; + // store current animated position + context.value = { + ...context.value, + initialPosition: animatedPosition.value, + initialKeyboardState: animatedKeyboardState.value, + }; - /** - * if the scrollable content is scrolled, then - * we lock the position. - */ - if (animatedScrollableContentOffsetY.value > 0) { - context.isScrollablePositionLocked = true; - } - }, - [ - stopAnimation, - animatedPosition, - animatedKeyboardState, - animatedScrollableContentOffsetY, - ] - ); - const handleOnActive: GestureEventHandlerCallbackType = - useWorkletCallback( - function handleOnActive(source, { translationY }, context) { - let highestSnapPoint = animatedHighestSnapPoint.value; + /** + * if the scrollable content is scrolled, then + * we lock the position. + */ + if (animatedScrollableContentOffsetY.value > 0) { + context.value = { + ...context.value, + isScrollablePositionLocked: true, + }; + } + }, + [ + stopAnimation, + animatedPosition, + animatedKeyboardState, + animatedScrollableContentOffsetY, + ] + ); + const handleOnChange: GestureEventHandlerCallbackType = useWorkletCallback( + function handleOnChange(source, { translationY }) { + let highestSnapPoint = animatedHighestSnapPoint.value; - /** - * if keyboard is shown, then we set the highest point to the current - * position which includes the keyboard height. - */ - if ( - isInTemporaryPosition.value && - context.initialKeyboardState === KEYBOARD_STATE.SHOWN - ) { - highestSnapPoint = context.initialPosition; - } + /** + * if keyboard is shown, then we set the highest point to the current + * position which includes the keyboard height. + */ + if ( + isInTemporaryPosition.value && + context.value.initialKeyboardState === KEYBOARD_STATE.SHOWN + ) { + highestSnapPoint = context.value.initialPosition; + } - /** - * if current position is out of provided `snapPoints` and smaller then - * highest snap pont, then we set the highest point to the current position. - */ - if ( - isInTemporaryPosition.value && - context.initialPosition < highestSnapPoint - ) { - highestSnapPoint = context.initialPosition; - } + /** + * if current position is out of provided `snapPoints` and smaller then + * highest snap pont, then we set the highest point to the current position. + */ + if ( + isInTemporaryPosition.value && + context.value.initialPosition < highestSnapPoint + ) { + highestSnapPoint = context.value.initialPosition; + } - const lowestSnapPoint = enablePanDownToClose - ? animatedContainerHeight.value - : animatedSnapPoints.value[0]; + const lowestSnapPoint = enablePanDownToClose + ? animatedContainerHeight.value + : animatedSnapPoints.value[0]; - /** - * if scrollable is refreshable and sheet position at the highest - * point, then do not interact with current gesture. - */ - if ( - source === GESTURE_SOURCE.SCROLLABLE && - isScrollableRefreshable.value && - animatedPosition.value === highestSnapPoint - ) { - return; - } + /** + * if scrollable is refreshable and sheet position at the highest + * point, then do not interact with current gesture. + */ + if ( + source === GESTURE_SOURCE.CONTENT && + isScrollableRefreshable.value && + animatedPosition.value === highestSnapPoint + ) { + return; + } - /** - * a negative scrollable content offset to be subtracted from accumulated - * current position and gesture translation Y to allow user to drag the sheet, - * when scrollable position at the top. - * a negative scrollable content offset when the scrollable is not locked. - */ - const negativeScrollableContentOffset = - (context.initialPosition === highestSnapPoint && - source === GESTURE_SOURCE.SCROLLABLE) || - !context.isScrollablePositionLocked - ? animatedScrollableContentOffsetY.value * -1 - : 0; + /** + * a negative scrollable content offset to be subtracted from accumulated + * current position and gesture translation Y to allow user to drag the sheet, + * when scrollable position at the top. + * a negative scrollable content offset when the scrollable is not locked. + */ + const negativeScrollableContentOffset = + (context.value.initialPosition === highestSnapPoint && + source === GESTURE_SOURCE.CONTENT) || + !context.value.isScrollablePositionLocked + ? animatedScrollableContentOffsetY.value * -1 + : 0; - /** - * an accumulated value of starting position with gesture translation y. - */ - const draggedPosition = context.initialPosition + translationY; + /** + * an accumulated value of starting position with gesture translation y. + */ + const draggedPosition = context.value.initialPosition + translationY; - /** - * an accumulated value of dragged position and negative scrollable content offset, - * this will insure locking sheet position when user is scrolling the scrollable until, - * they reach to the top of the scrollable. - */ - const accumulatedDraggedPosition = - draggedPosition + negativeScrollableContentOffset; + /** + * an accumulated value of dragged position and negative scrollable content offset, + * this will insure locking sheet position when user is scrolling the scrollable until, + * they reach to the top of the scrollable. + */ + const accumulatedDraggedPosition = + draggedPosition + negativeScrollableContentOffset; - /** - * a clamped value of the accumulated dragged position, to insure keeping the dragged - * position between the highest and lowest snap points. - */ - const clampedPosition = clamp( - accumulatedDraggedPosition, - highestSnapPoint, - lowestSnapPoint - ); + /** + * a clamped value of the accumulated dragged position, to insure keeping the dragged + * position between the highest and lowest snap points. + */ + const clampedPosition = clamp( + accumulatedDraggedPosition, + highestSnapPoint, + lowestSnapPoint + ); - /** - * if scrollable position is locked and the animated position - * reaches the highest point, then we unlock the scrollable position. - */ + /** + * if scrollable position is locked and the animated position + * reaches the highest point, then we unlock the scrollable position. + */ + if ( + context.value.isScrollablePositionLocked && + source === GESTURE_SOURCE.CONTENT && + animatedPosition.value === highestSnapPoint + ) { + context.value = { + ...context.value, + isScrollablePositionLocked: false, + }; + } + + /** + * over-drag implementation. + */ + if (enableOverDrag) { if ( - context.isScrollablePositionLocked && - source === GESTURE_SOURCE.SCROLLABLE && - animatedPosition.value === highestSnapPoint + (source === GESTURE_SOURCE.HANDLE || + animatedScrollableType.value === SCROLLABLE_TYPE.VIEW) && + draggedPosition < highestSnapPoint ) { - context.isScrollablePositionLocked = false; - } - - /** - * over-drag implementation. - */ - if (enableOverDrag) { - if ( - (source === GESTURE_SOURCE.HANDLE || - animatedScrollableType.value === SCROLLABLE_TYPE.VIEW) && - draggedPosition < highestSnapPoint - ) { - const resistedPosition = - highestSnapPoint - - Math.sqrt(1 + (highestSnapPoint - draggedPosition)) * - overDragResistanceFactor; - animatedPosition.value = resistedPosition; - return; - } - - if ( - source === GESTURE_SOURCE.HANDLE && - draggedPosition > lowestSnapPoint - ) { - const resistedPosition = - lowestSnapPoint + - Math.sqrt(1 + (draggedPosition - lowestSnapPoint)) * - overDragResistanceFactor; - animatedPosition.value = resistedPosition; - return; - } - - if ( - source === GESTURE_SOURCE.SCROLLABLE && - draggedPosition + negativeScrollableContentOffset > - lowestSnapPoint - ) { - const resistedPosition = - lowestSnapPoint + - Math.sqrt( - 1 + - (draggedPosition + - negativeScrollableContentOffset - - lowestSnapPoint) - ) * - overDragResistanceFactor; - animatedPosition.value = resistedPosition; - return; - } + const resistedPosition = + highestSnapPoint - + Math.sqrt(1 + (highestSnapPoint - draggedPosition)) * + overDragResistanceFactor; + animatedPosition.value = resistedPosition; + return; } - animatedPosition.value = clampedPosition; - }, - [ - enableOverDrag, - enablePanDownToClose, - overDragResistanceFactor, - isInTemporaryPosition, - isScrollableRefreshable, - animatedHighestSnapPoint, - animatedContainerHeight, - animatedSnapPoints, - animatedPosition, - animatedScrollableType, - animatedScrollableContentOffsetY, - ] - ); - const handleOnEnd: GestureEventHandlerCallbackType = - useWorkletCallback( - function handleOnEnd( - source, - { translationY, absoluteY, velocityY }, - context - ) { - const highestSnapPoint = animatedHighestSnapPoint.value; - const isSheetAtHighestSnapPoint = - animatedPosition.value === highestSnapPoint; - - /** - * if scrollable is refreshable and sheet position at the highest - * point, then do not interact with current gesture. - */ if ( - source === GESTURE_SOURCE.SCROLLABLE && - isScrollableRefreshable.value && - isSheetAtHighestSnapPoint + source === GESTURE_SOURCE.HANDLE && + draggedPosition > lowestSnapPoint ) { + const resistedPosition = + lowestSnapPoint + + Math.sqrt(1 + (draggedPosition - lowestSnapPoint)) * + overDragResistanceFactor; + animatedPosition.value = resistedPosition; return; } - /** - * if the sheet is in a temporary position and the gesture ended above - * the current position, then we snap back to the temporary position. - */ if ( - isInTemporaryPosition.value && - context.initialPosition >= animatedPosition.value + source === GESTURE_SOURCE.CONTENT && + draggedPosition + negativeScrollableContentOffset > lowestSnapPoint ) { - if (context.initialPosition > animatedPosition.value) { - animateToPosition( - context.initialPosition, - ANIMATION_SOURCE.GESTURE, - velocityY / 2 - ); - } + const resistedPosition = + lowestSnapPoint + + Math.sqrt( + 1 + + (draggedPosition + + negativeScrollableContentOffset - + lowestSnapPoint) + ) * + overDragResistanceFactor; + animatedPosition.value = resistedPosition; return; } + } - /** - * close keyboard if current position is below the recorded - * start position and keyboard still shown. - */ - const isScrollable = - animatedScrollableType.value !== SCROLLABLE_TYPE.UNDETERMINED && - animatedScrollableType.value !== SCROLLABLE_TYPE.VIEW; + animatedPosition.value = clampedPosition; + }, + [ + enableOverDrag, + enablePanDownToClose, + overDragResistanceFactor, + isInTemporaryPosition, + isScrollableRefreshable, + animatedHighestSnapPoint, + animatedContainerHeight, + animatedSnapPoints, + animatedPosition, + animatedScrollableType, + animatedScrollableContentOffsetY, + ] + ); + const handleOnEnd: GestureEventHandlerCallbackType = useWorkletCallback( + function handleOnEnd(source, { translationY, absoluteY, velocityY }) { + const highestSnapPoint = animatedHighestSnapPoint.value; + const isSheetAtHighestSnapPoint = + animatedPosition.value === highestSnapPoint; + + /** + * if scrollable is refreshable and sheet position at the highest + * point, then do not interact with current gesture. + */ + if ( + source === GESTURE_SOURCE.CONTENT && + isScrollableRefreshable.value && + isSheetAtHighestSnapPoint + ) { + return; + } + + /** + * if the sheet is in a temporary position and the gesture ended above + * the current position, then we snap back to the temporary position. + */ + if ( + isInTemporaryPosition.value && + context.value.initialPosition >= animatedPosition.value + ) { + if (context.value.initialPosition > animatedPosition.value) { + animateToPosition( + context.value.initialPosition, + ANIMATION_SOURCE.GESTURE, + velocityY / 2 + ); + } + return; + } + + /** + * close keyboard if current position is below the recorded + * start position and keyboard still shown. + */ + const isScrollable = + animatedScrollableType.value !== SCROLLABLE_TYPE.UNDETERMINED && + animatedScrollableType.value !== SCROLLABLE_TYPE.VIEW; + /** + * if keyboard is shown and the sheet is dragged down, + * then we dismiss the keyboard. + */ + if ( + context.value.initialKeyboardState === KEYBOARD_STATE.SHOWN && + animatedPosition.value > context.value.initialPosition + ) { /** - * if keyboard is shown and the sheet is dragged down, - * then we dismiss the keyboard. + * if the platform is ios, current content is scrollable and + * the end touch point is below the keyboard position then + * we exit the method. + * + * because the the keyboard dismiss is interactive in iOS. */ if ( - context.initialKeyboardState === KEYBOARD_STATE.SHOWN && - animatedPosition.value > context.initialPosition + !( + Platform.OS === 'ios' && + isScrollable && + absoluteY > WINDOW_HEIGHT - animatedKeyboardHeight.value + ) ) { - /** - * if the platform is ios, current content is scrollable and - * the end touch point is below the keyboard position then - * we exit the method. - * - * because the the keyboard dismiss is interactive in iOS. - */ - if ( - !( - Platform.OS === 'ios' && - isScrollable && - absoluteY > WINDOW_HEIGHT - animatedKeyboardHeight.value - ) - ) { - runOnJS(Keyboard.dismiss)(); - } + runOnJS(Keyboard.dismiss)(); } + } - /** - * reset isInTemporaryPosition value - */ - if (isInTemporaryPosition.value) { - isInTemporaryPosition.value = false; - } + /** + * reset isInTemporaryPosition value + */ + if (isInTemporaryPosition.value) { + isInTemporaryPosition.value = false; + } - /** - * clone snap points array, and insert the container height - * if pan down to close is enabled. - */ - const snapPoints = animatedSnapPoints.value.slice(); - if (enablePanDownToClose) { - snapPoints.unshift(animatedClosedPosition.value); - } + /** + * clone snap points array, and insert the container height + * if pan down to close is enabled. + */ + const snapPoints = animatedSnapPoints.value.slice(); + if (enablePanDownToClose) { + snapPoints.unshift(animatedClosedPosition.value); + } - /** - * calculate the destination point, using redash. - */ - const destinationPoint = snapPoint( - translationY + context.initialPosition, - velocityY, - snapPoints - ); + /** + * calculate the destination point, using redash. + */ + const destinationPoint = snapPoint( + translationY + context.value.initialPosition, + velocityY, + snapPoints + ); - /** - * if destination point is the same as the current position, - * then no need to perform animation. - */ - if (destinationPoint === animatedPosition.value) { - return; - } + /** + * if destination point is the same as the current position, + * then no need to perform animation. + */ + if (destinationPoint === animatedPosition.value) { + return; + } - const wasGestureHandledByScrollView = - source === GESTURE_SOURCE.SCROLLABLE && - animatedScrollableContentOffsetY.value > 0; - /** - * prevents snapping from top to middle / bottom with repeated interrupted scrolls - */ - if (wasGestureHandledByScrollView && isSheetAtHighestSnapPoint) { - return; - } + const wasGestureHandledByScrollView = + source === GESTURE_SOURCE.CONTENT && + animatedScrollableContentOffsetY.value > 0; + /** + * prevents snapping from top to middle / bottom with repeated interrupted scrolls + */ + if (wasGestureHandledByScrollView && isSheetAtHighestSnapPoint) { + return; + } - animateToPosition( - destinationPoint, - ANIMATION_SOURCE.GESTURE, - velocityY / 2 - ); + animateToPosition( + destinationPoint, + ANIMATION_SOURCE.GESTURE, + velocityY / 2 + ); + }, + [ + enablePanDownToClose, + isInTemporaryPosition, + isScrollableRefreshable, + animatedClosedPosition, + animatedHighestSnapPoint, + animatedKeyboardHeight, + animatedPosition, + animatedScrollableType, + animatedSnapPoints, + animatedScrollableContentOffsetY, + animateToPosition, + ] + ); + + const handleOnFinalize: GestureEventHandlerCallbackType = + useWorkletCallback( + function handleOnFinalize() { + resetContext(context); }, - [ - enablePanDownToClose, - isInTemporaryPosition, - isScrollableRefreshable, - animatedClosedPosition, - animatedHighestSnapPoint, - animatedKeyboardHeight, - animatedPosition, - animatedScrollableType, - animatedSnapPoints, - animatedScrollableContentOffsetY, - animateToPosition, - ] + [context] ); //#endregion return { handleOnStart, - handleOnActive, + handleOnChange, handleOnEnd, + handleOnFinalize, }; }; diff --git a/src/hooks/useGestureEventsHandlersDefault.web.tsx b/src/hooks/useGestureEventsHandlersDefault.web.tsx index 740698de6..cc5f636ca 100644 --- a/src/hooks/useGestureEventsHandlersDefault.web.tsx +++ b/src/hooks/useGestureEventsHandlersDefault.web.tsx @@ -1,5 +1,9 @@ import { Keyboard, Platform } from 'react-native'; -import { runOnJS, useWorkletCallback } from 'react-native-reanimated'; +import { + runOnJS, + useSharedValue, + useWorkletCallback, +} from 'react-native-reanimated'; import { useBottomSheetInternal } from './useBottomSheetInternal'; import { ANIMATION_SOURCE, @@ -8,10 +12,7 @@ import { SCROLLABLE_TYPE, WINDOW_HEIGHT, } from '../constants'; -import type { - GestureEventsHandlersHookType, - GestureEventHandlerCallbackType, -} from '../types'; +import type { GestureEventHandlerCallbackType } from '../types'; import { clamp } from '../utilities/clamp'; import { snapPoint } from '../utilities/snapPoint'; @@ -22,357 +23,376 @@ type GestureEventContextType = { isScrollablePositionLocked: boolean; }; -export const useGestureEventsHandlersDefault: GestureEventsHandlersHookType = - () => { - //#region variables - const { +const INITIAL_CONTEXT: GestureEventContextType = { + initialPosition: 0, + initialTranslationY: 0, + initialKeyboardState: KEYBOARD_STATE.UNDETERMINED, + isScrollablePositionLocked: false, +}; + +const resetContext = (context: any) => { + 'worklet'; + Object.keys(context).map(key => { + context[key] = undefined; + }); +}; + +export const useGestureEventsHandlersDefault = () => { + //#region variables + const { + animatedPosition, + animatedSnapPoints, + animatedKeyboardState, + animatedKeyboardHeight, + animatedContainerHeight, + animatedScrollableType, + animatedHighestSnapPoint, + animatedClosedPosition, + animatedScrollableContentOffsetY, + enableOverDrag, + enablePanDownToClose, + overDragResistanceFactor, + isInTemporaryPosition, + isScrollableRefreshable, + animateToPosition, + stopAnimation, + } = useBottomSheetInternal(); + + const context = useSharedValue({ + ...INITIAL_CONTEXT, + }); + //#endregion + + //#region gesture methods + const handleOnStart: GestureEventHandlerCallbackType = useWorkletCallback( + function handleOnStart(__, { translationY }) { + // console.log('handleOnStart'); + // cancel current animation + stopAnimation(); + + // store current animated position + context.value = { + ...context.value, + initialPosition: animatedPosition.value, + initialKeyboardState: animatedKeyboardState.value, + initialTranslationY: translationY, + }; + + /** + * if the scrollable content is scrolled, then + * we lock the position. + */ + if (animatedScrollableContentOffsetY.value > 0) { + context.value.isScrollablePositionLocked = true; + } + }, + [ + stopAnimation, animatedPosition, - animatedSnapPoints, animatedKeyboardState, - animatedKeyboardHeight, - animatedContainerHeight, - animatedScrollableType, - animatedHighestSnapPoint, - animatedClosedPosition, animatedScrollableContentOffsetY, + ] + ); + const handleOnActive: GestureEventHandlerCallbackType = useWorkletCallback( + function handleOnActive(source, { translationY }) { + // console.log('handleOnActive'); + let highestSnapPoint = animatedHighestSnapPoint.value; + + translationY = translationY - context.value.initialTranslationY; + /** + * if keyboard is shown, then we set the highest point to the current + * position which includes the keyboard height. + */ + if ( + isInTemporaryPosition.value && + context.value.initialKeyboardState === KEYBOARD_STATE.SHOWN + ) { + highestSnapPoint = context.value.initialPosition; + } + + /** + * if current position is out of provided `snapPoints` and smaller then + * highest snap pont, then we set the highest point to the current position. + */ + if ( + isInTemporaryPosition.value && + context.value.initialPosition < highestSnapPoint + ) { + highestSnapPoint = context.value.initialPosition; + } + + const lowestSnapPoint = enablePanDownToClose + ? animatedContainerHeight.value + : animatedSnapPoints.value[0]; + + /** + * if scrollable is refreshable and sheet position at the highest + * point, then do not interact with current gesture. + */ + if ( + source === GESTURE_SOURCE.SCROLLABLE && + isScrollableRefreshable.value && + animatedPosition.value === highestSnapPoint + ) { + return; + } + + /** + * a negative scrollable content offset to be subtracted from accumulated + * current position and gesture translation Y to allow user to drag the sheet, + * when scrollable position at the top. + * a negative scrollable content offset when the scrollable is not locked. + */ + const negativeScrollableContentOffset = + (context.value.initialPosition === highestSnapPoint && + source === GESTURE_SOURCE.SCROLLABLE) || + !context.value.isScrollablePositionLocked + ? animatedScrollableContentOffsetY.value * -1 + : 0; + + /** + * an accumulated value of starting position with gesture translation y. + */ + const draggedPosition = context.value.initialPosition + translationY; + + /** + * an accumulated value of dragged position and negative scrollable content offset, + * this will insure locking sheet position when user is scrolling the scrollable until, + * they reach to the top of the scrollable. + */ + const accumulatedDraggedPosition = + draggedPosition + negativeScrollableContentOffset; + + /** + * a clamped value of the accumulated dragged position, to insure keeping the dragged + * position between the highest and lowest snap points. + */ + const clampedPosition = clamp( + accumulatedDraggedPosition, + highestSnapPoint, + lowestSnapPoint + ); + + /** + * if scrollable position is locked and the animated position + * reaches the highest point, then we unlock the scrollable position. + */ + if ( + context.value.isScrollablePositionLocked && + source === GESTURE_SOURCE.SCROLLABLE && + animatedPosition.value === highestSnapPoint + ) { + context.value.isScrollablePositionLocked = false; + } + + /** + * over-drag implementation. + */ + if (enableOverDrag) { + if ( + (source === GESTURE_SOURCE.HANDLE || + animatedScrollableType.value === SCROLLABLE_TYPE.VIEW) && + draggedPosition < highestSnapPoint + ) { + const resistedPosition = + highestSnapPoint - + Math.sqrt(1 + (highestSnapPoint - draggedPosition)) * + overDragResistanceFactor; + animatedPosition.value = resistedPosition; + return; + } + + if ( + source === GESTURE_SOURCE.HANDLE && + draggedPosition > lowestSnapPoint + ) { + const resistedPosition = + lowestSnapPoint + + Math.sqrt(1 + (draggedPosition - lowestSnapPoint)) * + overDragResistanceFactor; + animatedPosition.value = resistedPosition; + return; + } + + if ( + source === GESTURE_SOURCE.SCROLLABLE && + draggedPosition + negativeScrollableContentOffset > lowestSnapPoint + ) { + const resistedPosition = + lowestSnapPoint + + Math.sqrt( + 1 + + (draggedPosition + + negativeScrollableContentOffset - + lowestSnapPoint) + ) * + overDragResistanceFactor; + animatedPosition.value = resistedPosition; + return; + } + } + + animatedPosition.value = clampedPosition; + }, + [ enableOverDrag, enablePanDownToClose, overDragResistanceFactor, isInTemporaryPosition, isScrollableRefreshable, - animateToPosition, - stopAnimation, - } = useBottomSheetInternal(); - //#endregion - - //#region gesture methods - const handleOnStart: GestureEventHandlerCallbackType = - useWorkletCallback( - function handleOnStart(__, { translationY }, context) { - console.log("handleOnStart"); - // cancel current animation - stopAnimation(); - - // store current animated position - context.initialPosition = animatedPosition.value; - context.initialKeyboardState = animatedKeyboardState.value; - context.initialTranslationY = translationY; - - /** - * if the scrollable content is scrolled, then - * we lock the position. - */ - if (animatedScrollableContentOffsetY.value > 0) { - context.isScrollablePositionLocked = true; - } - }, - [ - stopAnimation, - animatedPosition, - animatedKeyboardState, - animatedScrollableContentOffsetY, - ] - ); - const handleOnActive: GestureEventHandlerCallbackType = - useWorkletCallback( - function handleOnActive(source, { translationY }, context) { - console.log("handleOnActive"); - let highestSnapPoint = animatedHighestSnapPoint.value; - - translationY = translationY - context.initialTranslationY; - /** - * if keyboard is shown, then we set the highest point to the current - * position which includes the keyboard height. - */ - if ( - isInTemporaryPosition.value && - context.initialKeyboardState === KEYBOARD_STATE.SHOWN - ) { - highestSnapPoint = context.initialPosition; - } - - /** - * if current position is out of provided `snapPoints` and smaller then - * highest snap pont, then we set the highest point to the current position. - */ - if ( - isInTemporaryPosition.value && - context.initialPosition < highestSnapPoint - ) { - highestSnapPoint = context.initialPosition; - } - - const lowestSnapPoint = enablePanDownToClose - ? animatedContainerHeight.value - : animatedSnapPoints.value[0]; - - /** - * if scrollable is refreshable and sheet position at the highest - * point, then do not interact with current gesture. - */ - if ( - source === GESTURE_SOURCE.SCROLLABLE && - isScrollableRefreshable.value && - animatedPosition.value === highestSnapPoint - ) { - return; - } - - /** - * a negative scrollable content offset to be subtracted from accumulated - * current position and gesture translation Y to allow user to drag the sheet, - * when scrollable position at the top. - * a negative scrollable content offset when the scrollable is not locked. - */ - const negativeScrollableContentOffset = - (context.initialPosition === highestSnapPoint && - source === GESTURE_SOURCE.SCROLLABLE) || - !context.isScrollablePositionLocked - ? animatedScrollableContentOffsetY.value * -1 - : 0; - - /** - * an accumulated value of starting position with gesture translation y. - */ - const draggedPosition = context.initialPosition + translationY; - - /** - * an accumulated value of dragged position and negative scrollable content offset, - * this will insure locking sheet position when user is scrolling the scrollable until, - * they reach to the top of the scrollable. - */ - const accumulatedDraggedPosition = - draggedPosition + negativeScrollableContentOffset; - - /** - * a clamped value of the accumulated dragged position, to insure keeping the dragged - * position between the highest and lowest snap points. - */ - const clampedPosition = clamp( - accumulatedDraggedPosition, - highestSnapPoint, - lowestSnapPoint - ); - - /** - * if scrollable position is locked and the animated position - * reaches the highest point, then we unlock the scrollable position. - */ - if ( - context.isScrollablePositionLocked && - source === GESTURE_SOURCE.SCROLLABLE && - animatedPosition.value === highestSnapPoint - ) { - context.isScrollablePositionLocked = false; - } - - /** - * over-drag implementation. - */ - if (enableOverDrag) { - if ( - (source === GESTURE_SOURCE.HANDLE || - animatedScrollableType.value === SCROLLABLE_TYPE.VIEW) && - draggedPosition < highestSnapPoint - ) { - const resistedPosition = - highestSnapPoint - - Math.sqrt(1 + (highestSnapPoint - draggedPosition)) * - overDragResistanceFactor; - animatedPosition.value = resistedPosition; - return; - } - - if ( - source === GESTURE_SOURCE.HANDLE && - draggedPosition > lowestSnapPoint - ) { - const resistedPosition = - lowestSnapPoint + - Math.sqrt(1 + (draggedPosition - lowestSnapPoint)) * - overDragResistanceFactor; - animatedPosition.value = resistedPosition; - return; - } - - if ( - source === GESTURE_SOURCE.SCROLLABLE && - draggedPosition + negativeScrollableContentOffset > - lowestSnapPoint - ) { - const resistedPosition = - lowestSnapPoint + - Math.sqrt( - 1 + - (draggedPosition + - negativeScrollableContentOffset - - lowestSnapPoint) - ) * - overDragResistanceFactor; - animatedPosition.value = resistedPosition; - return; - } - } - - animatedPosition.value = clampedPosition; - }, - [ - enableOverDrag, - enablePanDownToClose, - overDragResistanceFactor, - isInTemporaryPosition, - isScrollableRefreshable, - animatedHighestSnapPoint, - animatedContainerHeight, - animatedSnapPoints, - animatedPosition, - animatedScrollableType, - animatedScrollableContentOffsetY, - ] - ); - const handleOnEnd: GestureEventHandlerCallbackType = - useWorkletCallback( - function handleOnEnd( - source, - { translationY, absoluteY, velocityY }, - context - ) { - const highestSnapPoint = animatedHighestSnapPoint.value; - const isSheetAtHighestSnapPoint = - animatedPosition.value === highestSnapPoint; - - /** - * if scrollable is refreshable and sheet position at the highest - * point, then do not interact with current gesture. - */ - if ( - source === GESTURE_SOURCE.SCROLLABLE && - isScrollableRefreshable.value && - isSheetAtHighestSnapPoint - ) { - return; - } - - /** - * if the sheet is in a temporary position and the gesture ended above - * the current position, then we snap back to the temporary position. - */ - if ( - isInTemporaryPosition.value && - context.initialPosition >= animatedPosition.value - ) { - if (context.initialPosition > animatedPosition.value) { - animateToPosition( - context.initialPosition, - ANIMATION_SOURCE.GESTURE, - velocityY / 2 - ); - } - return; - } - - /** - * close keyboard if current position is below the recorded - * start position and keyboard still shown. - */ - const isScrollable = - animatedScrollableType.value !== SCROLLABLE_TYPE.UNDETERMINED && - animatedScrollableType.value !== SCROLLABLE_TYPE.VIEW; - - /** - * if keyboard is shown and the sheet is dragged down, - * then we dismiss the keyboard. - */ - if ( - context.initialKeyboardState === KEYBOARD_STATE.SHOWN && - animatedPosition.value > context.initialPosition - ) { - /** - * if the platform is ios, current content is scrollable and - * the end touch point is below the keyboard position then - * we exit the method. - * - * because the the keyboard dismiss is interactive in iOS. - */ - if ( - !( - Platform.OS === 'ios' && - isScrollable && - absoluteY > WINDOW_HEIGHT - animatedKeyboardHeight.value - ) - ) { - runOnJS(Keyboard.dismiss)(); - } - } - - /** - * reset isInTemporaryPosition value - */ - if (isInTemporaryPosition.value) { - isInTemporaryPosition.value = false; - } - - /** - * clone snap points array, and insert the container height - * if pan down to close is enabled. - */ - const snapPoints = animatedSnapPoints.value.slice(); - if (enablePanDownToClose) { - snapPoints.unshift(animatedClosedPosition.value); - } - - /** - * calculate the destination point, using redash. - */ - const destinationPoint = snapPoint( - translationY + context.initialPosition, - velocityY, - snapPoints - ); + animatedHighestSnapPoint, + animatedContainerHeight, + animatedSnapPoints, + animatedPosition, + animatedScrollableType, + animatedScrollableContentOffsetY, + ] + ); + const handleOnEnd: GestureEventHandlerCallbackType = useWorkletCallback( + function handleOnEnd(source, { translationY, absoluteY, velocityY }) { + const highestSnapPoint = animatedHighestSnapPoint.value; + const isSheetAtHighestSnapPoint = + animatedPosition.value === highestSnapPoint; - /** - * if destination point is the same as the current position, - * then no need to perform animation. - */ - if (destinationPoint === animatedPosition.value) { - return; - } - - const wasGestureHandledByScrollView = - source === GESTURE_SOURCE.SCROLLABLE && - animatedScrollableContentOffsetY.value > 0; - /** - * prevents snapping from top to middle / bottom with repeated interrupted scrolls - */ - if (wasGestureHandledByScrollView && isSheetAtHighestSnapPoint) { - return; - } + /** + * if scrollable is refreshable and sheet position at the highest + * point, then do not interact with current gesture. + */ + if ( + source === GESTURE_SOURCE.SCROLLABLE && + isScrollableRefreshable.value && + isSheetAtHighestSnapPoint + ) { + return; + } + /** + * if the sheet is in a temporary position and the gesture ended above + * the current position, then we snap back to the temporary position. + */ + if ( + isInTemporaryPosition.value && + context.value.initialPosition >= animatedPosition.value + ) { + if (context.value.initialPosition > animatedPosition.value) { animateToPosition( - destinationPoint, + context.value.initialPosition, ANIMATION_SOURCE.GESTURE, velocityY / 2 ); - }, - [ - enablePanDownToClose, - isInTemporaryPosition, - isScrollableRefreshable, - animatedClosedPosition, - animatedHighestSnapPoint, - animatedKeyboardHeight, - animatedPosition, - animatedScrollableType, - animatedSnapPoints, - animatedScrollableContentOffsetY, - animateToPosition, - ] + } + return; + } + + /** + * close keyboard if current position is below the recorded + * start position and keyboard still shown. + */ + const isScrollable = + animatedScrollableType.value !== SCROLLABLE_TYPE.UNDETERMINED && + animatedScrollableType.value !== SCROLLABLE_TYPE.VIEW; + + /** + * if keyboard is shown and the sheet is dragged down, + * then we dismiss the keyboard. + */ + if ( + context.value.initialKeyboardState === KEYBOARD_STATE.SHOWN && + animatedPosition.value > context.value.initialPosition + ) { + /** + * if the platform is ios, current content is scrollable and + * the end touch point is below the keyboard position then + * we exit the method. + * + * because the the keyboard dismiss is interactive in iOS. + */ + if ( + !( + Platform.OS === 'ios' && + isScrollable && + absoluteY > WINDOW_HEIGHT - animatedKeyboardHeight.value + ) + ) { + runOnJS(Keyboard.dismiss)(); + } + } + + /** + * reset isInTemporaryPosition value + */ + if (isInTemporaryPosition.value) { + isInTemporaryPosition.value = false; + } + + /** + * clone snap points array, and insert the container height + * if pan down to close is enabled. + */ + const snapPoints = animatedSnapPoints.value.slice(); + if (enablePanDownToClose) { + snapPoints.unshift(animatedClosedPosition.value); + } + + /** + * calculate the destination point, using redash. + */ + const destinationPoint = snapPoint( + translationY + context.value.initialPosition, + velocityY, + snapPoints ); - //#endregion - return { - handleOnStart, - handleOnActive, - handleOnEnd, - }; + /** + * if destination point is the same as the current position, + * then no need to perform animation. + */ + if (destinationPoint === animatedPosition.value) { + return; + } + + const wasGestureHandledByScrollView = + source === GESTURE_SOURCE.SCROLLABLE && + animatedScrollableContentOffsetY.value > 0; + /** + * prevents snapping from top to middle / bottom with repeated interrupted scrolls + */ + if (wasGestureHandledByScrollView && isSheetAtHighestSnapPoint) { + return; + } + + animateToPosition( + destinationPoint, + ANIMATION_SOURCE.GESTURE, + velocityY / 2 + ); + }, + [ + enablePanDownToClose, + isInTemporaryPosition, + isScrollableRefreshable, + animatedClosedPosition, + animatedHighestSnapPoint, + animatedKeyboardHeight, + animatedPosition, + animatedScrollableType, + animatedSnapPoints, + animatedScrollableContentOffsetY, + animateToPosition, + ] + ); + const handleOnFinalize: GestureEventHandlerCallbackType = useWorkletCallback( + function handleOnFinalize() { + resetContext(context); + }, + [context] + ); + //#endregion + + return { + handleOnStart, + handleOnActive, + handleOnEnd, + handleOnFinalize, }; +}; diff --git a/src/hooks/useGestureHandler.ts b/src/hooks/useGestureHandler.ts index eb50e72be..8e4168a2d 100644 --- a/src/hooks/useGestureHandler.ts +++ b/src/hooks/useGestureHandler.ts @@ -1,96 +1,79 @@ -import Animated, { useAnimatedGestureHandler } from 'react-native-reanimated'; +import Animated, { useWorkletCallback } from 'react-native-reanimated'; import { State, - PanGestureHandlerGestureEvent, + GestureStateChangeEvent, + PanGestureHandlerEventPayload, } from 'react-native-gesture-handler'; import { GESTURE_SOURCE } from '../constants'; import type { - GestureEventContextType, GestureEventHandlerCallbackType, + GestureHandlersHookType, } from '../types'; -const resetContext = (context: any) => { - 'worklet'; - - Object.keys(context).map(key => { - context[key] = undefined; - }); -}; - -export const useGestureHandler = ( - type: GESTURE_SOURCE, +export const useGestureHandler: GestureHandlersHookType = ( + source: GESTURE_SOURCE, state: Animated.SharedValue, gestureSource: Animated.SharedValue, - handleOnStart: GestureEventHandlerCallbackType, - handleOnActive: GestureEventHandlerCallbackType, - handleOnEnd: GestureEventHandlerCallbackType -): ((event: PanGestureHandlerGestureEvent) => void) => { - const gestureHandler = useAnimatedGestureHandler< - PanGestureHandlerGestureEvent, - GestureEventContextType - >( - { - onActive: (payload, context) => { - if (!context.didStart) { - context.didStart = true; - - state.value = State.BEGAN; - gestureSource.value = type; + onStart: GestureEventHandlerCallbackType, + onChange: GestureEventHandlerCallbackType, + onEnd: GestureEventHandlerCallbackType, + onFinalize: GestureEventHandlerCallbackType +) => { + const handleOnStart = useWorkletCallback( + (event: GestureStateChangeEvent) => { + state.value = State.BEGAN; + gestureSource.value = source; - handleOnStart(type, payload, context); - return; - } - - if (gestureSource.value !== type) { - return; - } - - state.value = payload.state; - handleOnActive(type, payload, context); - }, - onEnd: (payload, context) => { - if (gestureSource.value !== type) { - return; - } + onStart(source, event); + return; + }, + [state, gestureSource, source, onStart] + ); - state.value = payload.state; - gestureSource.value = GESTURE_SOURCE.UNDETERMINED; + const handleOnChange = useWorkletCallback( + (event: GestureStateChangeEvent) => { + if (gestureSource.value !== source) { + return; + } - handleOnEnd(type, payload, context); - resetContext(context); - }, - onCancel: (payload, context) => { - if (gestureSource.value !== type) { - return; - } + state.value = event.state; + onChange(source, event); + }, + [state, gestureSource, source, onChange] + ); - state.value = payload.state; - gestureSource.value = GESTURE_SOURCE.UNDETERMINED; + const handleOnEnd = useWorkletCallback( + (event: GestureStateChangeEvent) => { + if (gestureSource.value !== source) { + return; + } - resetContext(context); - }, - onFail: (payload, context) => { - if (gestureSource.value !== type) { - return; - } + state.value = event.state; + gestureSource.value = GESTURE_SOURCE.UNDETERMINED; - state.value = payload.state; - gestureSource.value = GESTURE_SOURCE.UNDETERMINED; + onEnd(source, event); + }, + [state, gestureSource, source, onEnd] + ); - resetContext(context); - }, - onFinish: (payload, context) => { - if (gestureSource.value !== type) { - return; - } + const handleOnFinalize = useWorkletCallback( + (event: GestureStateChangeEvent) => { + if (gestureSource.value !== source) { + return; + } - state.value = payload.state; - gestureSource.value = GESTURE_SOURCE.UNDETERMINED; + state.value = event.state; + gestureSource.value = GESTURE_SOURCE.UNDETERMINED; - resetContext(context); - }, + onFinalize(source, event); }, - [type, state, handleOnStart, handleOnActive, handleOnEnd] + [state, gestureSource, source, onFinalize] ); - return gestureHandler; + + return { + handleOnStart, + handleOnChange, + handleOnEnd, + handleOnFinalize, + }; }; diff --git a/src/types.d.ts b/src/types.d.ts index 803ac5097..7357f0506 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -135,16 +135,39 @@ export type GestureEventContextType = { didStart?: boolean; }; -export type GestureEventHandlerCallbackType = ( +export type GestureEventHandlerCallbackType = ( source: GESTURE_SOURCE, - payload: GestureEventPayloadType, - context: C + payload: GestureEventPayloadType ) => void; export type GestureEventsHandlersHookType = () => { handleOnStart: GestureEventHandlerCallbackType; - handleOnActive: GestureEventHandlerCallbackType; + handleOnChange: GestureEventHandlerCallbackType; handleOnEnd: GestureEventHandlerCallbackType; + handleOnFinalize: GestureEventHandlerCallbackType; +}; + +export type GestureHandlersHookType = ( + source: GESTURE_SOURCE, + state: Animated.SharedValue, + gestureSource: Animated.SharedValue, + onStart: GestureEventHandlerCallbackType, + onChange: GestureEventHandlerCallbackType, + onEnd: GestureEventHandlerCallbackType, + onFinalize: GestureEventHandlerCallbackType +) => { + handleOnStart: ( + event: GestureStateChangeEvent + ) => void; + handleOnChange: ( + event: GestureStateChangeEvent + ) => void; + handleOnEnd: ( + event: GestureStateChangeEvent + ) => void; + handleOnFinalize: ( + event: GestureStateChangeEvent + ) => void; }; type ScrollEventHandlerCallbackType = ( diff --git a/yarn.lock b/yarn.lock index cbb00b119..eae10e6f2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10,13 +10,6 @@ "@jridgewell/gen-mapping" "^0.1.0" "@jridgewell/trace-mapping" "^0.3.9" -"@babel/code-frame@7.12.11": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" - integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== - dependencies: - "@babel/highlight" "^7.10.4" - "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" @@ -24,26 +17,26 @@ dependencies: "@babel/highlight" "^7.18.6" -"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.18.8", "@babel/compat-data@^7.19.1": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.19.1.tgz#72d647b4ff6a4f82878d184613353af1dd0290f9" - integrity sha512-72a9ghR0gnESIa7jBN53U32FOVCEoztyIlKaNoU05zRhEecduGK9L9c3ww7Mp06JiR+0ls0GBPFJQwwtjn9ksg== +"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.18.8", "@babel/compat-data@^7.19.3": + version "7.19.3" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.19.3.tgz#707b939793f867f5a73b2666e6d9a3396eb03151" + integrity sha512-prBHMK4JYYK+wDjJF1q99KK4JLL+egWS4nmNqdlMUgCExMZ+iZW0hGhyC3VEbsPjvaN0TBhW//VIFwBrk8sEiw== "@babel/core@^7.0.0", "@babel/core@^7.14.0", "@babel/core@^7.18.5": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.19.1.tgz#c8fa615c5e88e272564ace3d42fbc8b17bfeb22b" - integrity sha512-1H8VgqXme4UXCRv7/Wa1bq7RVymKOzC7znjyFM8KiEzwFqcKUKYNoQef4GhdklgNvoBXyW4gYhuBNCM5o1zImw== + version "7.19.3" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.19.3.tgz#2519f62a51458f43b682d61583c3810e7dcee64c" + integrity sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ== dependencies: "@ampproject/remapping" "^2.1.0" "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.19.0" - "@babel/helper-compilation-targets" "^7.19.1" + "@babel/generator" "^7.19.3" + "@babel/helper-compilation-targets" "^7.19.3" "@babel/helper-module-transforms" "^7.19.0" "@babel/helpers" "^7.19.0" - "@babel/parser" "^7.19.1" + "@babel/parser" "^7.19.3" "@babel/template" "^7.18.10" - "@babel/traverse" "^7.19.1" - "@babel/types" "^7.19.0" + "@babel/traverse" "^7.19.3" + "@babel/types" "^7.19.3" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" @@ -59,12 +52,12 @@ eslint-visitor-keys "^2.1.0" semver "^6.3.0" -"@babel/generator@^7.19.0", "@babel/generator@^7.5.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.19.0.tgz#785596c06425e59334df2ccee63ab166b738419a" - integrity sha512-S1ahxf1gZ2dpoiFgA+ohK9DIpz50bJ0CWs7Zlzb54Z4sG8qmdIrGrVqmy1sAtTVRb+9CU6U8VqT9L0Zj7hxHVg== +"@babel/generator@^7.19.3", "@babel/generator@^7.5.0": + version "7.19.3" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.19.3.tgz#d7f4d1300485b4547cb6f94b27d10d237b42bf59" + integrity sha512-fqVZnmp1ncvZU757UzDheKZpfPgatqY59XtW2/j/18H7u76akb8xqvjw82f+i2UKd/ksYsSick/BCLQUUtJ/qQ== dependencies: - "@babel/types" "^7.19.0" + "@babel/types" "^7.19.3" "@jridgewell/gen-mapping" "^0.3.2" jsesc "^2.5.1" @@ -83,12 +76,12 @@ "@babel/helper-explode-assignable-expression" "^7.18.6" "@babel/types" "^7.18.9" -"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9", "@babel/helper-compilation-targets@^7.19.0", "@babel/helper-compilation-targets@^7.19.1": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.1.tgz#7f630911d83b408b76fe584831c98e5395d7a17c" - integrity sha512-LlLkkqhCMyz2lkQPvJNdIYU7O5YjWRgC2R4omjCTpZd8u8KMQzZvX4qce+/BluN1rcQiV7BoGUpmQ0LeHerbhg== +"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9", "@babel/helper-compilation-targets@^7.19.0", "@babel/helper-compilation-targets@^7.19.3": + version "7.19.3" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.3.tgz#a10a04588125675d7c7ae299af86fa1b2ee038ca" + integrity sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg== dependencies: - "@babel/compat-data" "^7.19.1" + "@babel/compat-data" "^7.19.3" "@babel/helper-validator-option" "^7.18.6" browserslist "^4.21.3" semver "^6.3.0" @@ -240,7 +233,7 @@ resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz#181f22d28ebe1b3857fa575f5c290b1aaf659b56" integrity sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw== -"@babel/helper-validator-identifier@^7.18.6": +"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": version "7.19.1" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== @@ -269,7 +262,7 @@ "@babel/traverse" "^7.19.0" "@babel/types" "^7.19.0" -"@babel/highlight@^7.10.4", "@babel/highlight@^7.18.6": +"@babel/highlight@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== @@ -278,10 +271,10 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.0.0", "@babel/parser@^7.18.10", "@babel/parser@^7.19.1": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.19.1.tgz#6f6d6c2e621aad19a92544cc217ed13f1aac5b4c" - integrity sha512-h7RCSorm1DdTVGJf3P2Mhj3kdnkmF/EiysUkzS2TdgAYqyjFdMQJbVuXOBej2SBJaXan/lIVtT6KkGbyyq753A== +"@babel/parser@^7.0.0", "@babel/parser@^7.18.10", "@babel/parser@^7.19.3": + version "7.19.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.19.3.tgz#8dd36d17c53ff347f9e55c328710321b49479a9a" + integrity sha512-pJ9xOlNWHiy9+FuFP09DEAFbAn4JskgRsVcc169w2xRBC3FRGuQEwjeIMMND9L2zc0iEhO/tGv4Zq+km+hxNpQ== "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6": version "7.18.6" @@ -889,9 +882,9 @@ "@babel/helper-plugin-utils" "^7.18.9" "@babel/plugin-transform-typescript@^7.18.6", "@babel/plugin-transform-typescript@^7.5.0": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.19.1.tgz#adcf180a041dcbd29257ad31b0c65d4de531ce8d" - integrity sha512-+ILcOU+6mWLlvCwnL920m2Ow3wWx3Wo8n2t5aROQmV55GZt+hOiLvBaa3DNzRjSEHa1aauRs4/YLmkCfFkhhRQ== + version "7.19.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.19.3.tgz#4f1db1e0fe278b42ddbc19ec2f6cd2f8262e35d6" + integrity sha512-z6fnuK9ve9u/0X0rRvI9MY0xg+DOUaABDYOe+/SQTxtlptaBB/V9JIUxJn6xp3lMBeb9qe8xSFmHU35oZDXD+w== dependencies: "@babel/helper-create-class-features-plugin" "^7.19.0" "@babel/helper-plugin-utils" "^7.19.0" @@ -913,12 +906,12 @@ "@babel/helper-plugin-utils" "^7.18.6" "@babel/preset-env@^7.18.2": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.19.1.tgz#9f04c916f9c0205a48ebe5cc1be7768eb1983f67" - integrity sha512-c8B2c6D16Lp+Nt6HcD+nHl0VbPKVnNPTpszahuxJJnurfMtKeZ80A+qUv48Y7wqvS+dTFuLuaM9oYxyNHbCLWA== + version "7.19.3" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.19.3.tgz#52cd19abaecb3f176a4ff9cc5e15b7bf06bec754" + integrity sha512-ziye1OTc9dGFOAXSWKUqQblYHNlBOaDl8wzqf2iKXJAltYiR3hKHUKmkt+S9PppW7RQpq4fFCrwwpIDj/f5P4w== dependencies: - "@babel/compat-data" "^7.19.1" - "@babel/helper-compilation-targets" "^7.19.1" + "@babel/compat-data" "^7.19.3" + "@babel/helper-compilation-targets" "^7.19.3" "@babel/helper-plugin-utils" "^7.19.0" "@babel/helper-validator-option" "^7.18.6" "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.18.6" @@ -986,7 +979,7 @@ "@babel/plugin-transform-unicode-escapes" "^7.18.10" "@babel/plugin-transform-unicode-regex" "^7.18.6" "@babel/preset-modules" "^0.1.5" - "@babel/types" "^7.19.0" + "@babel/types" "^7.19.3" babel-plugin-polyfill-corejs2 "^0.3.3" babel-plugin-polyfill-corejs3 "^0.6.0" babel-plugin-polyfill-regenerator "^0.4.1" @@ -1061,29 +1054,29 @@ "@babel/parser" "^7.18.10" "@babel/types" "^7.18.10" -"@babel/traverse@^7.0.0", "@babel/traverse@^7.19.0", "@babel/traverse@^7.19.1", "@babel/traverse@^7.7.4": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.19.1.tgz#0fafe100a8c2a603b4718b1d9bf2568d1d193347" - integrity sha512-0j/ZfZMxKukDaag2PtOPDbwuELqIar6lLskVPPJDjXMXjfLb1Obo/1yjxIGqqAJrmfaTIY3z2wFLAQ7qSkLsuA== +"@babel/traverse@^7.0.0", "@babel/traverse@^7.19.0", "@babel/traverse@^7.19.1", "@babel/traverse@^7.19.3", "@babel/traverse@^7.7.4": + version "7.19.3" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.19.3.tgz#3a3c5348d4988ba60884e8494b0592b2f15a04b4" + integrity sha512-qh5yf6149zhq2sgIXmwjnsvmnNQC2iw70UFjp4olxucKrWd/dvlUsBI88VSLUsnMNF7/vnOiA+nk1+yLoCqROQ== dependencies: "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.19.0" + "@babel/generator" "^7.19.3" "@babel/helper-environment-visitor" "^7.18.9" "@babel/helper-function-name" "^7.19.0" "@babel/helper-hoist-variables" "^7.18.6" "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/parser" "^7.19.1" - "@babel/types" "^7.19.0" + "@babel/parser" "^7.19.3" + "@babel/types" "^7.19.3" debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.19.0", "@babel/types@^7.4.4": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.19.0.tgz#75f21d73d73dc0351f3368d28db73465f4814600" - integrity sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA== +"@babel/types@^7.0.0", "@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.19.0", "@babel/types@^7.19.3", "@babel/types@^7.4.4": + version "7.19.3" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.19.3.tgz#fc420e6bbe54880bce6779ffaf315f5e43ec9624" + integrity sha512-hGCaQzIY22DJlDh9CH7NOxgKkFjBk0Cw9xDO1Xmh2151ti7wiGfQ3LauXzL4HP1fmFlTX6XjpRETTpUcv7wQLw== dependencies: "@babel/helper-string-parser" "^7.18.10" - "@babel/helper-validator-identifier" "^7.18.6" + "@babel/helper-validator-identifier" "^7.19.1" to-fast-properties "^2.0.0" "@cnakazawa/watch@^1.0.3": @@ -1263,19 +1256,19 @@ dependencies: "@types/hammerjs" "^2.0.36" -"@eslint/eslintrc@^0.4.3": - version "0.4.3" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c" - integrity sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw== +"@eslint/eslintrc@^1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.2.tgz#58b69582f3b7271d8fa67fe5251767a5b38ea356" + integrity sha512-AXYd23w1S/bv3fTs3Lz0vjiYemS08jWkI3hYyS9I1ry+0f+Yjs1wm+sU0BS8qDOPrBIkp4qHYC16I8uVtpLajQ== dependencies: ajv "^6.12.4" - debug "^4.1.1" - espree "^7.3.0" - globals "^13.9.0" - ignore "^4.0.6" + debug "^4.3.2" + espree "^9.4.0" + globals "^13.15.0" + ignore "^5.2.0" import-fresh "^3.2.1" - js-yaml "^3.13.1" - minimatch "^3.0.4" + js-yaml "^4.1.0" + minimatch "^3.1.2" strip-json-comments "^3.1.1" "@gorhom/portal@1.0.14": @@ -1317,16 +1310,26 @@ dependencies: "@hapi/hoek" "^8.3.0" -"@humanwhocodes/config-array@^0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9" - integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg== +"@humanwhocodes/config-array@^0.10.5": + version "0.10.7" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.10.7.tgz#6d53769fd0c222767e6452e8ebda825c22e9f0dc" + integrity sha512-MDl6D6sBsaV452/QSdX+4CXIjZhIcI0PELsxUjk4U828yd58vk3bTIvk/6w5FY+4hIy9sLW0sfrV7K7Kc++j/w== dependencies: - "@humanwhocodes/object-schema" "^1.2.0" + "@humanwhocodes/object-schema" "^1.2.1" debug "^4.1.1" minimatch "^3.0.4" -"@humanwhocodes/object-schema@^1.2.0": +"@humanwhocodes/gitignore-to-minimatch@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz#316b0a63b91c10e53f242efb4ace5c3b34e8728d" + integrity sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA== + +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + +"@humanwhocodes/object-schema@^1.2.1": version "1.2.1" resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== @@ -1511,9 +1514,9 @@ universal-user-agent "^6.0.0" "@octokit/openapi-types@^13.11.0": - version "13.12.0" - resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-13.12.0.tgz#cd49f28127ee06ee3edc6f2b5f5648c7332f6014" - integrity sha512-1QYzZrwnn3rTQE7ZoSxXrO8lhu0aIbac1c+qIPOPEaVXBWSaUyLV1x9yt4uDQOwmu6u5ywVS8OJgs+ErDLf6vQ== + version "13.13.1" + resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-13.13.1.tgz#a783bacb1817c9f61a2a0c3f81ea22ad62340fdf" + integrity sha512-4EuKSk3N95UBWFau3Bz9b3pheQ8jQYbKmBL5+GSuY8YDPDwu03J4BjI+66yNi8aaX/3h1qDpb0mbBkLdr+cfGQ== "@octokit/plugin-paginate-rest@^4.0.0": version "4.3.1" @@ -1567,9 +1570,9 @@ "@octokit/plugin-rest-endpoint-methods" "^6.0.0" "@octokit/types@^7.0.0", "@octokit/types@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@octokit/types/-/types-7.5.0.tgz#85646021bd618467b7cc465d9734b3f2878c9fae" - integrity sha512-aHm+olfIZjQpzoODpl+RCZzchKOrdSLJs+yfI7pMMcmB19Li6vidgx0DwUDO/Ic4Q3fq/lOjJORVCcLZefcrJw== + version "7.5.1" + resolved "https://registry.yarnpkg.com/@octokit/types/-/types-7.5.1.tgz#4e8b182933c17e1f41cc25d44757dbdb7bd76c1b" + integrity sha512-Zk4OUMLCSpXNI8KZZn47lVLJSsgMyCimsWWQI5hyjZg7hdYm0kjotaIkbG0Pp8SfU2CofMBzonboTqvzn3FrJA== dependencies: "@octokit/openapi-types" "^13.11.0" @@ -1779,22 +1782,12 @@ resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e" integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ== -"@types/cacheable-request@^6.0.2": - version "6.0.2" - resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.2.tgz#c324da0197de0a98a2312156536ae262429ff6b9" - integrity sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA== - dependencies: - "@types/http-cache-semantics" "*" - "@types/keyv" "*" - "@types/node" "*" - "@types/responselike" "*" - "@types/hammerjs@^2.0.36": version "2.0.41" resolved "https://registry.yarnpkg.com/@types/hammerjs/-/hammerjs-2.0.41.tgz#f6ecf57d1b12d2befcce00e928a6a097c22980aa" integrity sha512-ewXv/ceBaJprikMcxCmWU1FKyMAQ2X7a9Gtmzw8fcg2kIePI1crERDM818W+XYrxqdBBOdlf2rm137bU+BltCA== -"@types/http-cache-semantics@*": +"@types/http-cache-semantics@^4.0.1": version "4.0.1" resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz#0ea7b61496902b95890dc4c3a116b60cb8dae812" integrity sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ== @@ -1829,27 +1822,15 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== -"@types/keyv@*": - version "3.1.4" - resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.4.tgz#3ccdb1c6751b0c7e52300bcdacd5bcbf8faa75b6" - integrity sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg== - dependencies: - "@types/node" "*" - "@types/minimist@^1.2.0": version "1.2.2" resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c" integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== -"@types/node@*": - version "18.7.18" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.18.tgz#633184f55c322e4fb08612307c274ee6d5ed3154" - integrity sha512-m+6nTEOadJZuTPkKR/SYK3A2d7FZrgElol9UP1Kae90VVU4a6mxnPuLiIW1m4Cq4gZ/nWb9GrdVXJCoCazDAbg== - "@types/node@^14.0.0": - version "14.18.29" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.29.tgz#a0c58d67a42f8953c13d32f0acda47ed26dfce40" - integrity sha512-LhF+9fbIX4iPzhsRLpK5H7iPdvW8L4IwGciXQIOEcuF62+9nw/VQVsOViAOOGxY3OlOKGLFv0sWwJXdwQeTn6A== + version "14.18.31" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.31.tgz#4b873dea3122e71af4f77e65ec5841397ff254d3" + integrity sha512-vQAnaReSQkEDa8uwAyQby8bYGKu84R/deEc6mg5T8fX6gzCn8QW6rziSgsti1fNvsrswKUKPnVTi7uoB+u62Mw== "@types/normalize-package-data@^2.4.0": version "2.4.1" @@ -1867,9 +1848,9 @@ integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== "@types/react-native@^0.67.7": - version "0.67.14" - resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.67.14.tgz#011d9d814067f91f41de7b3b618c7b96a9fc5a8f" - integrity sha512-wAMGueaLav3OAhe62ivJ2FDcaYkOc4UGeCNPgxm0FXJotV4dRxpc5HxAvLkBnxH7CWqYhND94DHn4Mb8aHJIZg== + version "0.67.15" + resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.67.15.tgz#a81ac5cd2e59cecad04104a13e727bc4f6d5bdb9" + integrity sha512-I4aE4NlBnZLgGQZa4YFpyqAKzbC4F31wWnKkI6T2ahijXZ5NwUMLaYNL0DBJnukFeYyUoyj7Wqyt6cXHrysIIw== dependencies: "@types/react" "^17" @@ -1890,13 +1871,6 @@ "@types/scheduler" "*" csstype "^3.0.2" -"@types/responselike@*": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29" - integrity sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA== - dependencies: - "@types/node" "*" - "@types/scheduler@*": version "0.16.2" resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39" @@ -1927,84 +1901,83 @@ "@types/yargs-parser" "*" "@typescript-eslint/eslint-plugin@^5.30.5": - version "5.37.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.37.0.tgz#5ccdd5d9004120f28fc6e717fb4b5c9bddcfbc04" - integrity sha512-Fde6W0IafXktz1UlnhGkrrmnnGpAo1kyX7dnyHHVrmwJOn72Oqm3eYtddrpOwwel2W8PAK9F3pIL5S+lfoM0og== + version "5.39.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.39.0.tgz#778b2d9e7f293502c7feeea6c74dca8eb3e67511" + integrity sha512-xVfKOkBm5iWMNGKQ2fwX5GVgBuHmZBO1tCRwXmY5oAIsPscfwm2UADDuNB8ZVYCtpQvJK4xpjrK7jEhcJ0zY9A== dependencies: - "@typescript-eslint/scope-manager" "5.37.0" - "@typescript-eslint/type-utils" "5.37.0" - "@typescript-eslint/utils" "5.37.0" + "@typescript-eslint/scope-manager" "5.39.0" + "@typescript-eslint/type-utils" "5.39.0" + "@typescript-eslint/utils" "5.39.0" debug "^4.3.4" - functional-red-black-tree "^1.0.1" ignore "^5.2.0" regexpp "^3.2.0" semver "^7.3.7" tsutils "^3.21.0" "@typescript-eslint/parser@^5.30.5": - version "5.37.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.37.0.tgz#c382077973f3a4ede7453fb14cadcad3970cbf3b" - integrity sha512-01VzI/ipYKuaG5PkE5+qyJ6m02fVALmMPY3Qq5BHflDx3y4VobbLdHQkSMg9VPRS4KdNt4oYTMaomFoHonBGAw== + version "5.39.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.39.0.tgz#93fa0bc980a3a501e081824f6097f7ca30aaa22b" + integrity sha512-PhxLjrZnHShe431sBAGHaNe6BDdxAASDySgsBCGxcBecVCi8NQWxQZMcizNA4g0pN51bBAn/FUfkWG3SDVcGlA== dependencies: - "@typescript-eslint/scope-manager" "5.37.0" - "@typescript-eslint/types" "5.37.0" - "@typescript-eslint/typescript-estree" "5.37.0" + "@typescript-eslint/scope-manager" "5.39.0" + "@typescript-eslint/types" "5.39.0" + "@typescript-eslint/typescript-estree" "5.39.0" debug "^4.3.4" -"@typescript-eslint/scope-manager@5.37.0": - version "5.37.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.37.0.tgz#044980e4f1516a774a418dafe701a483a6c9f9ca" - integrity sha512-F67MqrmSXGd/eZnujjtkPgBQzgespu/iCZ+54Ok9X5tALb9L2v3G+QBSoWkXG0p3lcTJsL+iXz5eLUEdSiJU9Q== +"@typescript-eslint/scope-manager@5.39.0": + version "5.39.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.39.0.tgz#873e1465afa3d6c78d8ed2da68aed266a08008d0" + integrity sha512-/I13vAqmG3dyqMVSZPjsbuNQlYS082Y7OMkwhCfLXYsmlI0ca4nkL7wJ/4gjX70LD4P8Hnw1JywUVVAwepURBw== dependencies: - "@typescript-eslint/types" "5.37.0" - "@typescript-eslint/visitor-keys" "5.37.0" + "@typescript-eslint/types" "5.39.0" + "@typescript-eslint/visitor-keys" "5.39.0" -"@typescript-eslint/type-utils@5.37.0": - version "5.37.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.37.0.tgz#43ed2f567ada49d7e33a6e4b6f9babd060445fe5" - integrity sha512-BSx/O0Z0SXOF5tY0bNTBcDEKz2Ec20GVYvq/H/XNKiUorUFilH7NPbFUuiiyzWaSdN3PA8JV0OvYx0gH/5aFAQ== +"@typescript-eslint/type-utils@5.39.0": + version "5.39.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.39.0.tgz#0a8c00f95dce4335832ad2dc6bc431c14e32a0a6" + integrity sha512-KJHJkOothljQWzR3t/GunL0TPKY+fGJtnpl+pX+sJ0YiKTz3q2Zr87SGTmFqsCMFrLt5E0+o+S6eQY0FAXj9uA== dependencies: - "@typescript-eslint/typescript-estree" "5.37.0" - "@typescript-eslint/utils" "5.37.0" + "@typescript-eslint/typescript-estree" "5.39.0" + "@typescript-eslint/utils" "5.39.0" debug "^4.3.4" tsutils "^3.21.0" -"@typescript-eslint/types@5.37.0": - version "5.37.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.37.0.tgz#09e4870a5f3af7af3f84e08d792644a87d232261" - integrity sha512-3frIJiTa5+tCb2iqR/bf7XwU20lnU05r/sgPJnRpwvfZaqCJBrl8Q/mw9vr3NrNdB/XtVyMA0eppRMMBqdJ1bA== +"@typescript-eslint/types@5.39.0": + version "5.39.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.39.0.tgz#f4e9f207ebb4579fd854b25c0bf64433bb5ed78d" + integrity sha512-gQMZrnfEBFXK38hYqt8Lkwt8f4U6yq+2H5VDSgP/qiTzC8Nw8JO3OuSUOQ2qW37S/dlwdkHDntkZM6SQhKyPhw== -"@typescript-eslint/typescript-estree@5.37.0": - version "5.37.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.37.0.tgz#956dcf5c98363bcb97bdd5463a0a86072ff79355" - integrity sha512-JkFoFIt/cx59iqEDSgIGnQpCTRv96MQnXCYvJi7QhBC24uyuzbD8wVbajMB1b9x4I0octYFJ3OwjAwNqk1AjDA== +"@typescript-eslint/typescript-estree@5.39.0": + version "5.39.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.39.0.tgz#c0316aa04a1a1f4f7f9498e3c13ef1d3dc4cf88b" + integrity sha512-qLFQP0f398sdnogJoLtd43pUgB18Q50QSA+BTE5h3sUxySzbWDpTSdgt4UyxNSozY/oDK2ta6HVAzvGgq8JYnA== dependencies: - "@typescript-eslint/types" "5.37.0" - "@typescript-eslint/visitor-keys" "5.37.0" + "@typescript-eslint/types" "5.39.0" + "@typescript-eslint/visitor-keys" "5.39.0" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/utils@5.37.0", "@typescript-eslint/utils@^5.10.0": - version "5.37.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.37.0.tgz#7784cb8e91390c4f90ccaffd24a0cf9874df81b2" - integrity sha512-jUEJoQrWbZhmikbcWSMDuUSxEE7ID2W/QCV/uz10WtQqfOuKZUqFGjqLJ+qhDd17rjgp+QJPqTdPIBWwoob2NQ== +"@typescript-eslint/utils@5.39.0", "@typescript-eslint/utils@^5.10.0": + version "5.39.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.39.0.tgz#b7063cca1dcf08d1d21b0d91db491161ad0be110" + integrity sha512-+DnY5jkpOpgj+EBtYPyHRjXampJfC0yUZZzfzLuUWVZvCuKqSdJVC8UhdWipIw7VKNTfwfAPiOWzYkAwuIhiAg== dependencies: "@types/json-schema" "^7.0.9" - "@typescript-eslint/scope-manager" "5.37.0" - "@typescript-eslint/types" "5.37.0" - "@typescript-eslint/typescript-estree" "5.37.0" + "@typescript-eslint/scope-manager" "5.39.0" + "@typescript-eslint/types" "5.39.0" + "@typescript-eslint/typescript-estree" "5.39.0" eslint-scope "^5.1.1" eslint-utils "^3.0.0" -"@typescript-eslint/visitor-keys@5.37.0": - version "5.37.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.37.0.tgz#7b72dd343295ea11e89b624995abc7103c554eee" - integrity sha512-Hp7rT4cENBPIzMwrlehLW/28EVCOcE9U1Z1BQTc8EA8v5qpr7GRGuG+U58V5tTY48zvUOA3KHvw3rA8tY9fbdA== +"@typescript-eslint/visitor-keys@5.39.0": + version "5.39.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.39.0.tgz#8f41f7d241b47257b081ddba5d3ce80deaae61e2" + integrity sha512-yyE3RPwOG+XJBLrhvsxAidUgybJVQ/hG8BhiJo0k8JSAYfk/CshVcxf0HwP4Jt7WZZ6vLmxdo1p6EyN3tzFTkg== dependencies: - "@typescript-eslint/types" "5.37.0" + "@typescript-eslint/types" "5.39.0" eslint-visitor-keys "^3.3.0" JSONStream@^1.0.4: @@ -2035,7 +2008,7 @@ accepts@~1.3.5, accepts@~1.3.7: mime-types "~2.1.34" negotiator "0.6.3" -acorn-jsx@^5.3.1: +acorn-jsx@^5.3.2: version "5.3.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== @@ -2045,12 +2018,7 @@ acorn-walk@^8.1.1, acorn-walk@^8.2.0: resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== -acorn@^7.4.0: - version "7.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" - integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== - -acorn@^8.4.1, acorn@^8.7.0: +acorn@^8.4.1, acorn@^8.7.0, acorn@^8.8.0: version "8.8.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== @@ -2085,7 +2053,7 @@ ajv@^6.10.0, ajv@^6.12.4: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.1, ajv@^8.11.0: +ajv@^8.11.0: version "8.11.0" resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f" integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg== @@ -2114,11 +2082,6 @@ ansi-colors@^1.0.1: dependencies: ansi-wrap "^0.1.0" -ansi-colors@^4.1.1: - version "4.1.3" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" - integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== - ansi-cyan@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/ansi-cyan/-/ansi-cyan-0.1.1.tgz#538ae528af8982f28ae30d86f2f17456d2609873" @@ -2202,7 +2165,7 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" -ansi-styles@^6.1.0: +ansi-styles@^6.0.0, ansi-styles@^6.1.0: version "6.1.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.1.1.tgz#63cd61c72283a71cb30bd881dbb60adada74bc70" integrity sha512-qDOv24WjnYuL+wbwHdlsYZFy+cgPtrYw0Tn7GLORicQp9BkQLzrgI3Pm4VyR9ERZ41YTn7KlMPuL1n05WdZvmg== @@ -2232,6 +2195,11 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + arr-diff@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-1.1.0.tgz#687c32758163588fef7de7b36fabe495eb1a399a" @@ -2638,16 +2606,17 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" -cacheable-lookup@^6.0.4: - version "6.1.0" - resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-6.1.0.tgz#0330a543471c61faa4e9035db583aad753b36385" - integrity sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww== +cacheable-lookup@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz#3476a8215d046e5a3202a9209dd13fec1f933a27" + integrity sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w== -cacheable-request@^10.1.2: - version "10.1.2" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-10.1.2.tgz#93f77290eebfdff7f4d813ba7d0fa2502c180eec" - integrity sha512-N7F4os5ZI+8mWHSbeJmxn+qimf5uK3WU53FD1b298XLGtOLPpSA/1xAchfP4NJlDwqgaviZ0SQfxTQD0K6lr9w== +cacheable-request@^10.2.1: + version "10.2.1" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-10.2.1.tgz#cbc7480bf057fb7bd5bc7520f7e5a43d9c865626" + integrity sha512-3tLJyBjGuXw1s5gpKFSG3iS4kaKT4id04dZi98wzHQp/8cqZNweBnrF9J+rrlvrf4M53OdtDGNctNHFias8BEA== dependencies: + "@types/http-cache-semantics" "^4.0.1" get-stream "^6.0.1" http-cache-semantics "^4.1.0" keyv "^4.5.0" @@ -2655,19 +2624,6 @@ cacheable-request@^10.1.2: normalize-url "^7.1.0" responselike "^3.0.0" -cacheable-request@^7.0.2: - version "7.0.2" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.2.tgz#ea0d0b889364a25854757301ca12b2da77f91d27" - integrity sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew== - dependencies: - clone-response "^1.0.2" - get-stream "^5.1.0" - http-cache-semantics "^4.0.0" - keyv "^4.0.0" - lowercase-keys "^2.0.0" - normalize-url "^6.0.1" - responselike "^2.0.0" - call-bind@^1.0.0, call-bind@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" @@ -2720,9 +2676,9 @@ camelcase@^7.0.0: integrity sha512-JToIvOmz6nhGsUhAYScbo2d6Py5wojjNfoxoc2mEVLUdJ70gJK2gnd+ABY1Tc3sVMyK7QDPtN0T/XdlCQWITyQ== caniuse-lite@^1.0.30001400: - version "1.0.30001406" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001406.tgz#d0146e7919635479f873b4507517b627f66ab269" - integrity sha512-bWTlaXUy/rq0BBtYShc/jArYfBPjEV95euvZ8JVtO43oQExEN/WquoqpufFjNu4kSpi5cy5kMbNvzztWDfv1Jg== + version "1.0.30001414" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001414.tgz#5f1715e506e71860b4b07c50060ea6462217611e" + integrity sha512-t55jfSaWjCdocnFdKQoO+d2ct9C59UZg4dY3OnUlSZ447r8pUtIKdp0hpAzrGFultmTC+Us+KpKi4GZl/LXlFg== capture-exit@^2.0.0: version "2.0.0" @@ -2827,7 +2783,7 @@ cli-spinners@^2.0.0, cli-spinners@^2.6.1: resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.7.0.tgz#f815fd30b5f9eaac02db604c7a231ed7cb2f797a" integrity sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw== -cli-truncate@2.1.0, cli-truncate@^2.1.0: +cli-truncate@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== @@ -2835,6 +2791,14 @@ cli-truncate@2.1.0, cli-truncate@^2.1.0: slice-ansi "^3.0.0" string-width "^4.2.0" +cli-truncate@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-3.1.0.tgz#3f23ab12535e3d73e839bb43e73c9de487db1389" + integrity sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA== + dependencies: + slice-ansi "^5.0.0" + string-width "^5.0.0" + cli-width@^2.0.0: version "2.2.1" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.1.tgz#b0433d0b4e9c847ef18868a4ef16fd5fc8271c48" @@ -2872,6 +2836,15 @@ cliui@^7.0.2: strip-ansi "^6.0.0" wrap-ansi "^7.0.0" +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.1" + wrap-ansi "^7.0.0" + clone-deep@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" @@ -2881,13 +2854,6 @@ clone-deep@^4.0.1: kind-of "^6.0.2" shallow-clone "^3.0.0" -clone-response@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.3.tgz#af2032aa47816399cf5f0a1d0db902f517abb8c3" - integrity sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA== - dependencies: - mimic-response "^1.0.0" - clone@^1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" @@ -2930,12 +2896,12 @@ color-support@^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== -colorette@^1.0.7, colorette@^1.4.0: +colorette@^1.0.7: version "1.4.0" resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.4.0.tgz#5190fbb87276259a86ad700bff2c6d6faa3fca40" integrity sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g== -colorette@^2.0.16: +colorette@^2.0.16, colorette@^2.0.17: version "2.0.19" resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== @@ -2962,10 +2928,10 @@ commander@^7.2.0: resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== -commander@^8.2.0: - version "8.3.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" - integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== +commander@^9.3.0: + version "9.4.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-9.4.1.tgz#d1dd8f2ce6faf93147295c0df13c7c21141cfbdd" + integrity sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw== commander@~2.13.0: version "2.13.0" @@ -3262,9 +3228,9 @@ copyfiles@^2.4.1: yargs "^16.1.0" core-js-compat@^3.25.1: - version "3.25.2" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.25.2.tgz#7875573586809909c69e03ef310810c1969ee138" - integrity sha512-TxfyECD4smdn3/CjWxczVtJqVLEEC2up7/82t7vC0AzNogr+4nQ8vyF7abxAuTXWvjTClSbvGhU0RgqA4ToQaQ== + version "3.25.5" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.25.5.tgz#0016e8158c904f7b059486639e6e82116eafa7d9" + integrity sha512-ovcyhs2DEBUIE0MGEKHP4olCUW/XYte3Vroyxuh38rD1wAO4dHohsovUC4eAOuzFxE6b+RXvBU3UZ9o0YhUTkA== dependencies: browserslist "^4.21.4" @@ -3279,9 +3245,9 @@ core-util-is@~1.0.0: integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== cosmiconfig-typescript-loader@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.1.0.tgz#39b2f8e302d587d27a2d5fc10106635abef4a6e4" - integrity sha512-HbWIuR5O+XO5Oj9SZ5bzgrD4nN+rfhrm2PMb0FVx+t+XIvC45n8F0oTNnztXtspWGw0i2IzHaUWFD5LzV1JB4A== + version "4.1.1" + resolved "https://registry.yarnpkg.com/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.1.1.tgz#38dd3578344038dae40fdf09792bc2e9df529f78" + integrity sha512-9DHpa379Gp0o0Zefii35fcmuuin6q92FnLDffzdZ0l9tVd3nEobG3O+MZ06+kuBvFTSVScvNb/oHA13Nd4iipg== cosmiconfig@7.0.1, cosmiconfig@^7.0.0, cosmiconfig@^7.0.1: version "7.0.1" @@ -3390,7 +3356,7 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3: dependencies: ms "2.0.0" -debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: +debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -3589,9 +3555,9 @@ ee-first@1.1.1: integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== electron-to-chromium@^1.4.251: - version "1.4.254" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.254.tgz#c6203583890abf88dfc0be046cd72d3b48f8beb6" - integrity sha512-Sh/7YsHqQYkA6ZHuHMy24e6TE4eX6KZVsZb9E/DvU1nQRIrH4BflO/4k+83tfdYvDl+MObvlqHPRICzEdC9c6Q== + version "1.4.270" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.270.tgz#2c6ea409b45cdb5c3e0cb2c08cf6c0ba7e0f2c26" + integrity sha512-KNhIzgLiJmDDC444dj9vEOpZEgsV96ult9Iff98Vanumn+ShJHd5se8aX6KeVxdc0YQeqdrezBZv89rleDbvSg== emoji-regex@^7.0.1: version "7.0.3" @@ -3627,13 +3593,6 @@ end-of-stream@^1.1.0: dependencies: once "^1.4.0" -enquirer@^2.3.5, enquirer@^2.3.6: - version "2.3.6" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" - integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== - dependencies: - ansi-colors "^4.1.1" - envinfo@^7.7.2: version "7.8.1" resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" @@ -3662,21 +3621,21 @@ errorhandler@^1.5.0: escape-html "~1.0.3" es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19.2, es-abstract@^1.19.5: - version "1.20.2" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.2.tgz#8495a07bc56d342a3b8ea3ab01bd986700c2ccb3" - integrity sha512-XxXQuVNrySBNlEkTYJoDNFe5+s2yIOpzq80sUHEdPdQr0S5nTLz4ZPPPswNIpKseDDUS5yghX1gfLIHQZ1iNuQ== + version "1.20.3" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.3.tgz#90b143ff7aedc8b3d189bcfac7f1e3e3f81e9da1" + integrity sha512-AyrnaKVpMzljIdwjzrj+LxGmj8ik2LckwXacHqrJJ/jxz6dDDBcZ7I7nlHM0FvEW8MfbWJwOd+yT2XzYW49Frw== dependencies: call-bind "^1.0.2" es-to-primitive "^1.2.1" function-bind "^1.1.1" function.prototype.name "^1.1.5" - get-intrinsic "^1.1.2" + get-intrinsic "^1.1.3" get-symbol-description "^1.0.0" has "^1.0.3" has-property-descriptors "^1.0.0" has-symbols "^1.0.3" internal-slot "^1.0.3" - is-callable "^1.2.4" + is-callable "^1.2.6" is-negative-zero "^2.0.2" is-regex "^1.1.4" is-shared-array-buffer "^1.0.2" @@ -3686,6 +3645,7 @@ es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19.2, es-abstract@^1.19 object-keys "^1.1.1" object.assign "^4.1.4" regexp.prototype.flags "^1.4.3" + safe-regex-test "^1.0.0" string.prototype.trimend "^1.0.5" string.prototype.trimstart "^1.0.5" unbox-primitive "^1.0.2" @@ -3772,7 +3732,7 @@ escodegen@^1.8.1: optionalDependencies: source-map "~0.6.1" -eslint-config-prettier@^8.3.0, eslint-config-prettier@^8.5.0: +eslint-config-prettier@^8.5.0: version "8.5.0" resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz#5a81680ec934beca02c7b1a61cf8ca34b66feab1" integrity sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q== @@ -3800,13 +3760,6 @@ eslint-plugin-jest@^26.5.3: dependencies: "@typescript-eslint/utils" "^5.10.0" -eslint-plugin-prettier@^3.4.0: - version "3.4.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz#e9ddb200efb6f3d05ffe83b1665a716af4a387e5" - integrity sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g== - dependencies: - prettier-linter-helpers "^1.0.0" - eslint-plugin-prettier@^4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz#651cbb88b1dab98bfd42f017a12fa6b2d993f94b" @@ -3867,12 +3820,13 @@ eslint-scope@5.1.1, eslint-scope@^5.1.1: esrecurse "^4.3.0" estraverse "^4.1.1" -eslint-utils@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" - integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== +eslint-scope@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642" + integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw== dependencies: - eslint-visitor-keys "^1.1.0" + esrecurse "^4.3.0" + estraverse "^5.2.0" eslint-utils@^3.0.0: version "3.0.0" @@ -3881,11 +3835,6 @@ eslint-utils@^3.0.0: dependencies: eslint-visitor-keys "^2.0.0" -eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" - integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== - eslint-visitor-keys@^2.0.0, eslint-visitor-keys@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" @@ -3896,60 +3845,59 @@ eslint-visitor-keys@^3.3.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== -eslint@^7.32.0: - version "7.32.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d" - integrity sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA== +eslint@^8.21.0: + version "8.24.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.24.0.tgz#489516c927a5da11b3979dbfb2679394523383c8" + integrity sha512-dWFaPhGhTAiPcCgm3f6LI2MBWbogMnTJzFBbhXVRQDJPkr9pGZvVjlVfXd+vyDcWPA2Ic9L2AXPIQM0+vk/cSQ== dependencies: - "@babel/code-frame" "7.12.11" - "@eslint/eslintrc" "^0.4.3" - "@humanwhocodes/config-array" "^0.5.0" + "@eslint/eslintrc" "^1.3.2" + "@humanwhocodes/config-array" "^0.10.5" + "@humanwhocodes/gitignore-to-minimatch" "^1.0.2" + "@humanwhocodes/module-importer" "^1.0.1" ajv "^6.10.0" chalk "^4.0.0" cross-spawn "^7.0.2" - debug "^4.0.1" + debug "^4.3.2" doctrine "^3.0.0" - enquirer "^2.3.5" escape-string-regexp "^4.0.0" - eslint-scope "^5.1.1" - eslint-utils "^2.1.0" - eslint-visitor-keys "^2.0.0" - espree "^7.3.1" + eslint-scope "^7.1.1" + eslint-utils "^3.0.0" + eslint-visitor-keys "^3.3.0" + espree "^9.4.0" esquery "^1.4.0" esutils "^2.0.2" fast-deep-equal "^3.1.3" file-entry-cache "^6.0.1" - functional-red-black-tree "^1.0.1" - glob-parent "^5.1.2" - globals "^13.6.0" - ignore "^4.0.6" + find-up "^5.0.0" + glob-parent "^6.0.1" + globals "^13.15.0" + globby "^11.1.0" + grapheme-splitter "^1.0.4" + ignore "^5.2.0" import-fresh "^3.0.0" imurmurhash "^0.1.4" is-glob "^4.0.0" - js-yaml "^3.13.1" + js-sdsl "^4.1.4" + js-yaml "^4.1.0" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.4.1" lodash.merge "^4.6.2" - minimatch "^3.0.4" + minimatch "^3.1.2" natural-compare "^1.4.0" optionator "^0.9.1" - progress "^2.0.0" - regexpp "^3.1.0" - semver "^7.2.1" - strip-ansi "^6.0.0" + regexpp "^3.2.0" + strip-ansi "^6.0.1" strip-json-comments "^3.1.0" - table "^6.0.9" text-table "^0.2.0" - v8-compile-cache "^2.0.3" -espree@^7.3.0, espree@^7.3.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" - integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== +espree@^9.4.0: + version "9.4.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.4.0.tgz#cd4bc3d6e9336c433265fc0aa016fc1aaf182f8a" + integrity sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw== dependencies: - acorn "^7.4.0" - acorn-jsx "^5.3.1" - eslint-visitor-keys "^1.3.0" + acorn "^8.8.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.3.0" esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" @@ -4005,7 +3953,7 @@ exec-sh@^0.3.2: resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.6.tgz#ff264f9e325519a60cb5e273692943483cca63bc" integrity sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w== -execa@6.1.0: +execa@6.1.0, execa@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/execa/-/execa-6.1.0.tgz#cea16dee211ff011246556388effa0818394fb20" integrity sha512-QVWlX2e50heYJcCPG0iWtf8r0xjEYfz/OYLGDYH+IyjWezzPNxz63qNFOu0l4YftGWuizFVZHHs8PrLU5p2IDA== @@ -4179,9 +4127,9 @@ fastq@^1.6.0: reusify "^1.0.4" fb-watchman@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" - integrity sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg== + version "2.0.2" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" + integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== dependencies: bser "2.1.1" @@ -4354,10 +4302,10 @@ for-in@^1.0.2: resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" integrity sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ== -form-data-encoder@^2.1.0, form-data-encoder@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/form-data-encoder/-/form-data-encoder-2.1.2.tgz#5996b7c236e8c418d08316055a2235226c5e4061" - integrity sha512-FCaIOVTRA9E0siY6FeXid7D5yrCqpsErplUkE2a1BEiKj1BE9z6FbKB4ntDTwC4NVLie9p+4E9nX4mWwEOT05A== +form-data-encoder@^2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/form-data-encoder/-/form-data-encoder-2.1.3.tgz#682cd821a8423605093992ff895e6b2ed5a9d429" + integrity sha512-KqU0nnPMgIJcCOFTNJFEA8epcseEaoox4XZffTgy8jlI6pL/5EFyR54NRG7CnCJN0biY7q52DO3MH6/sJ/TKlQ== form-data@4.0.0: version "4.0.0" @@ -4450,11 +4398,6 @@ function.prototype.name@^1.1.5: es-abstract "^1.19.0" functions-have-names "^1.2.2" -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== - functions-have-names@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" @@ -4470,7 +4413,7 @@ get-caller-file@^2.0.1, get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1, get-intrinsic@^1.1.2: +get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz#063c84329ad93e83893c7f4f243ef63ffa351385" integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A== @@ -4479,11 +4422,6 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1, get-intrinsic@ has "^1.0.3" has-symbols "^1.0.3" -get-own-enumerable-property-symbols@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" - integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== - get-pkg-repo@^4.0.0: version "4.2.1" resolved "https://registry.yarnpkg.com/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz#75973e1c8050c73f48190c52047c4cee3acbf385" @@ -4501,7 +4439,7 @@ get-stream@^4.0.0: dependencies: pump "^3.0.0" -get-stream@^5.0.0, get-stream@^5.1.0: +get-stream@^5.0.0: version "5.2.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== @@ -4573,10 +4511,10 @@ git-up@^7.0.0: is-ssh "^1.4.0" parse-url "^8.1.0" -git-url-parse@13.0.0: - version "13.0.0" - resolved "https://registry.yarnpkg.com/git-url-parse/-/git-url-parse-13.0.0.tgz#9a18d0eaec579fb6379c368aecb09f00b544669c" - integrity sha512-X1kozCqKL82dMrCLi4vie9SHDC+QugKskAMs4VUbIkhURKg5yDwxDmf6Ixg73J+/xVgK5TXKhzn8a94nHJHpnA== +git-url-parse@13.1.0: + version "13.1.0" + resolved "https://registry.yarnpkg.com/git-url-parse/-/git-url-parse-13.1.0.tgz#07e136b5baa08d59fabdf0e33170de425adf07b4" + integrity sha512-5FvPJP/70WkIprlUZ33bm4UAaFdjcLkJLpWft1BeZKqwR0uhhNGoKwlUaPtVb4LxCSQ++erHapRak9kWGj+FCA== dependencies: git-up "^7.0.0" @@ -4594,6 +4532,13 @@ glob-parent@^5.1.2: dependencies: is-glob "^4.0.1" +glob-parent@^6.0.1: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + glob@^7.0.0, glob@^7.0.5, glob@^7.1.3: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" @@ -4636,7 +4581,7 @@ globals@^11.1.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== -globals@^13.6.0, globals@^13.9.0: +globals@^13.15.0: version "13.17.0" resolved "https://registry.yarnpkg.com/globals/-/globals-13.17.0.tgz#902eb1e680a41da93945adbdcb5a9f361ba69bd4" integrity sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw== @@ -4666,33 +4611,15 @@ globby@^11.0.1, globby@^11.1.0: merge2 "^1.4.1" slash "^3.0.0" -got@12.4.1: - version "12.4.1" - resolved "https://registry.yarnpkg.com/got/-/got-12.4.1.tgz#8598311b42591dfd2ed3ca4cdb9a591e2769a0bd" - integrity sha512-Sz1ojLt4zGNkcftIyJKnulZT/yEDvifhUjccHA8QzOuTgPs/+njXYNMFE3jR4/2OODQSSbH8SdnoLCkbh41ieA== - dependencies: - "@sindresorhus/is" "^5.2.0" - "@szmarczak/http-timer" "^5.0.1" - "@types/cacheable-request" "^6.0.2" - cacheable-lookup "^6.0.4" - cacheable-request "^7.0.2" - decompress-response "^6.0.0" - form-data-encoder "^2.1.0" - get-stream "^6.0.1" - http2-wrapper "^2.1.10" - lowercase-keys "^3.0.0" - p-cancelable "^3.0.0" - responselike "^3.0.0" - -got@^12.1.0: - version "12.5.0" - resolved "https://registry.yarnpkg.com/got/-/got-12.5.0.tgz#b31c556aa25a14ea06f173da888860984f323d3b" - integrity sha512-/Bneo/L6bLN1wDyJCeRZ3CLoixvwb9v3rE3IHulFSfTHwP85xSr4QatA8K0c6GlL5+mc4IZ57BzluNZJiXvHIg== +got@12.5.1, got@^12.1.0: + version "12.5.1" + resolved "https://registry.yarnpkg.com/got/-/got-12.5.1.tgz#0796191c61478273f4cdbeb19d358a75a54a008d" + integrity sha512-sD16AK8cCyUoPtKr/NMvLTFFa+T3i3S+zoiuvhq0HP2YiqBZA9AtlBjAdsQBsLBK7slPuvmfE0OxhGi7N5dD4w== dependencies: "@sindresorhus/is" "^5.2.0" "@szmarczak/http-timer" "^5.0.1" - cacheable-lookup "^6.0.4" - cacheable-request "^10.1.2" + cacheable-lookup "^7.0.0" + cacheable-request "^10.2.1" decompress-response "^6.0.0" form-data-encoder "^2.1.2" get-stream "^6.0.1" @@ -4706,6 +4633,11 @@ graceful-fs@4.2.10, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3, resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== +grapheme-splitter@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" + integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== + graphql@^14.0.0: version "14.7.0" resolved "https://registry.yarnpkg.com/graphql/-/graphql-14.7.0.tgz#7fa79a80a69be4a31c27dda824dc04dac2035a72" @@ -4838,7 +4770,7 @@ hosted-git-info@^4.0.0, hosted-git-info@^4.0.1: dependencies: lru-cache "^6.0.0" -http-cache-semantics@^4.0.0, http-cache-semantics@^4.1.0: +http-cache-semantics@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== @@ -4929,11 +4861,6 @@ ieee754@^1.2.1: resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== -ignore@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== - ignore@^5.0.5, ignore@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" @@ -4998,10 +4925,10 @@ ini@^1.3.2, ini@^1.3.4, ini@~1.3.0: resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== -inquirer@9.1.1: - version "9.1.1" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-9.1.1.tgz#e15a12723f4f607d1b4489b56a0ecc7a6965e17d" - integrity sha512-hfS9EJ1pVkGNbYKqzdGwMj0Dqosd36Qvxd5pFy4657QT23gmtFTSqoYBisZR75DReeSMWPNa8J0Lf6TQCz8PvA== +inquirer@9.1.2: + version "9.1.2" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-9.1.2.tgz#37f5486f3de0e38820aad83a1f75c52c747e2f9a" + integrity sha512-Hj2Ml1WpxKJU2npP2Rj0OURGkHV+GtNW2CwFdHDiXlqUBAUrWTcZHxCkFywX/XHzOS7wrG/kExgJFbUkVgyHzg== dependencies: ansi-escapes "^5.0.0" chalk "^5.0.1" @@ -5125,10 +5052,10 @@ is-buffer@^1.1.5: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== -is-callable@^1.1.4, is-callable@^1.2.4: - version "1.2.6" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.6.tgz#fd6170b0b8c7e2cc73de342ef8284a2202023c44" - integrity sha512-krO72EO2NptOGAX2KYyqbP9vYMlNAXdB53rq6f8LXY6RY7JdSR/3BD6wLUlPHSAesmY9vstNrjvqGaCiRK/91Q== +is-callable@^1.1.4, is-callable@^1.2.6: + version "1.2.7" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" + integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== is-ci@3.0.1, is-ci@^3.0.1: version "3.0.1" @@ -5227,6 +5154,11 @@ is-fullwidth-code-point@^3.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== +is-fullwidth-code-point@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz#fae3167c729e7463f8461ce512b080a49268aa88" + integrity sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ== + is-git-dirty@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/is-git-dirty/-/is-git-dirty-2.0.1.tgz#29ca82fb0924ccbeaa0bae08de217546df593012" @@ -5297,11 +5229,6 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== -is-obj@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" - integrity sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg== - is-obj@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" @@ -5342,11 +5269,6 @@ is-regex@^1.1.4: call-bind "^1.0.2" has-tostringtag "^1.0.0" -is-regexp@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" - integrity sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA== - is-relative@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d" @@ -5611,6 +5533,11 @@ jetifier@^2.0.0: resolved "https://registry.yarnpkg.com/jetifier/-/jetifier-2.0.0.tgz#699391367ca1fe7bc4da5f8bf691eb117758e4cb" integrity sha512-J4Au9KuT74te+PCCCHKgAjyLlEa+2VyIAEPNCdE5aNkAJ6FAJcAqcdzEkSnzNksIa9NkGmC4tPiClk2e7tCJuQ== +js-sdsl@^4.1.4: + version "4.1.5" + resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.1.5.tgz#1ff1645e6b4d1b028cd3f862db88c9d887f26e2a" + integrity sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q== + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -5624,6 +5551,13 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + jsc-android@^245459.0.0: version "245459.0.0" resolved "https://registry.yarnpkg.com/jsc-android/-/jsc-android-245459.0.0.tgz#e584258dd0b04c9159a27fb104cd5d491fd202c9" @@ -5727,7 +5661,7 @@ jsonparse@^1.2.0: array-includes "^3.1.5" object.assign "^4.1.3" -keyv@^4.0.0, keyv@^4.5.0: +keyv@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.0.tgz#dbce9ade79610b6e641a9a65f2f6499ba06b9bc6" integrity sha512-2YvuMsA+jnFGtBareKqgANOEKe1mk3HKiXu2fRmAfyxG0MJAywNhi5ttWA3PMjl4NmpyjZNbFifR2vNjW1znfA== @@ -5808,42 +5742,46 @@ levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" +lilconfig@2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.5.tgz#19e57fd06ccc3848fd1891655b5a447092225b25" + integrity sha512-xaYmXZtTHPAw5m+xLN8ab9C+3a8YmV3asNSPOATITbtwrfbwaLJj8h66H1WMIpALCkqsIzK3h7oQ+PdX+LQ9Eg== + lines-and-columns@^1.1.6: version "1.2.4" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== -lint-staged@^11.1.2: - version "11.2.6" - resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-11.2.6.tgz#f477b1af0294db054e5937f171679df63baa4c43" - integrity sha512-Vti55pUnpvPE0J9936lKl0ngVeTdSZpEdTNhASbkaWX7J5R9OEifo1INBGQuGW4zmy6OG+TcWPJ3m5yuy5Q8Tg== +lint-staged@^13.0.3: + version "13.0.3" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-13.0.3.tgz#d7cdf03a3830b327a2b63c6aec953d71d9dc48c6" + integrity sha512-9hmrwSCFroTSYLjflGI8Uk+GWAwMB4OlpU4bMJEAT5d/llQwtYKoim4bLOyLCuWFAhWEupE0vkIFqtw/WIsPug== dependencies: - cli-truncate "2.1.0" - colorette "^1.4.0" - commander "^8.2.0" - cosmiconfig "^7.0.1" - debug "^4.3.2" - enquirer "^2.3.6" - execa "^5.1.1" - listr2 "^3.12.2" - micromatch "^4.0.4" + cli-truncate "^3.1.0" + colorette "^2.0.17" + commander "^9.3.0" + debug "^4.3.4" + execa "^6.1.0" + lilconfig "2.0.5" + listr2 "^4.0.5" + micromatch "^4.0.5" normalize-path "^3.0.0" - please-upgrade-node "^3.2.0" - string-argv "0.3.1" - stringify-object "3.3.0" - supports-color "8.1.1" + object-inspect "^1.12.2" + pidtree "^0.6.0" + string-argv "^0.3.1" + yaml "^2.1.1" -listr2@^3.12.2: - version "3.14.0" - resolved "https://registry.yarnpkg.com/listr2/-/listr2-3.14.0.tgz#23101cc62e1375fd5836b248276d1d2b51fdbe9e" - integrity sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g== +listr2@^4.0.5: + version "4.0.5" + resolved "https://registry.yarnpkg.com/listr2/-/listr2-4.0.5.tgz#9dcc50221583e8b4c71c43f9c7dfd0ef546b75d5" + integrity sha512-juGHV1doQdpNT3GSTs9IUN43QJb7KHdF9uqg7Vufs/tG9VTzpFphqF4pm/ICdAABGQxsyNn9CiYA3StkI6jpwA== dependencies: cli-truncate "^2.1.0" colorette "^2.0.16" log-update "^4.0.0" p-map "^4.0.0" rfdc "^1.3.0" - rxjs "^7.5.1" + rxjs "^7.5.5" through "^2.3.8" wrap-ansi "^7.0.0" @@ -5912,11 +5850,6 @@ lodash.throttle@^4.1.1: resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" integrity sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ== -lodash.truncate@^4.4.2: - version "4.4.2" - resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" - integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw== - lodash@4.17.21, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.3.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" @@ -5963,11 +5896,6 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1, loose-envify@^1.4 dependencies: js-tokens "^3.0.0 || ^4.0.0" -lowercase-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" - integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== - lowercase-keys@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-3.0.0.tgz#c5e7d442e37ead247ae9db117a9d0a467c89d4f2" @@ -6415,7 +6343,7 @@ micromatch@^3.1.10, micromatch@^3.1.4: snapdragon "^0.8.1" to-regex "^3.0.2" -micromatch@^4.0.4: +micromatch@^4.0.4, micromatch@^4.0.5: version "4.0.5" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== @@ -6472,11 +6400,6 @@ mimic-fn@^4.0.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== -mimic-response@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" - integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== - mimic-response@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" @@ -6718,15 +6641,10 @@ normalize-path@^3.0.0: resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -normalize-url@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" - integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== - normalize-url@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-7.1.0.tgz#967f4c7345314d05cf9b2a05fb4948e140d491b2" - integrity sha512-JgkdydFdLe1E5Q7DpLvKVyBZOOwXYGhIbMbOMm3lJ06XKzaiit+qo1HciO3z3IFklStfarzJHVQf9ZcNPTvZlw== + version "7.2.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-7.2.0.tgz#5317f78cff95f5fa1e76cc0b5e33245c43781e11" + integrity sha512-uhXOdZry0L6M2UIo9BTt7FdpBDiAGN/7oItedQwPKh8jh31ZlvC8U9Xl/EJ3aijDHaywXTW3QbZ6LuCocur1YA== npm-run-path@^2.0.0: version "2.0.2" @@ -7210,6 +7128,11 @@ picomatch@^2.3.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +pidtree@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.6.0.tgz#90ad7b6d42d5841e69e0a2419ef38f8883aa057c" + integrity sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g== + pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" @@ -7292,7 +7215,7 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" -prettier@^2.3.2: +prettier@^2.7.1: version "2.7.1" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.7.1.tgz#e235806850d057f97bb08368a4f7d899f7760c64" integrity sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g== @@ -7322,11 +7245,6 @@ process-nextick-args@~2.0.0: resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== -progress@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== - promise.allsettled@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/promise.allsettled/-/promise.allsettled-1.0.5.tgz#2443f3d4b2aa8dfa560f6ac2aa6c4ea999d75f53" @@ -7475,7 +7393,7 @@ react-is@^16.12.0, react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.4: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== -react-native-builder-bob@^0.18.1: +react-native-builder-bob@^0.18.3: version "0.18.3" resolved "https://registry.yarnpkg.com/react-native-builder-bob/-/react-native-builder-bob-0.18.3.tgz#fb4d3e50a3b2290db3c88de6d40403ac7eb9f85f" integrity sha512-togj+ClsPAsTK3ZFmFZVIftUIkxvN1YxJws0/6sQIlAr14U3rvtBseOQAQM0Pora1GD2aObdBVHDVhKBHWojLA== @@ -7502,10 +7420,10 @@ react-native-builder-bob@^0.18.1: optionalDependencies: jetifier "^2.0.0" -react-native-gesture-handler@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-2.6.1.tgz#66c40c8d720eb4729b301836a40fd34d14ec840f" - integrity sha512-0MXjRgNCrsQJSo3B9oXORw5spdm/9dkDbP2JU/3zrVyV9/MnRz5Oo3oy7hREKYWVMF9Gk2UpsCquFLRFQxeSxQ== +react-native-gesture-handler@^2.5.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-2.7.0.tgz#53ad828add926c8e025f68ea581758c0f8893054" + integrity sha512-0jr3FNm2R3gv/v6XTtENgjv0fewD6LEct8EWmXw/oHw36M3YiIIpxnW57thL+0YiKwyLBXN0QHL4JZbs/heW2Q== dependencies: "@egjs/hammerjs" "^2.0.17" hoist-non-react-statics "^3.3.0" @@ -7513,7 +7431,7 @@ react-native-gesture-handler@^2.6.1: lodash "^4.17.21" prop-types "^15.7.2" -react-native-reanimated@^2.10.0: +react-native-reanimated@^2.9.1: version "2.10.0" resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-2.10.0.tgz#ed53be66bbb553b5b5e93e93ef4217c87b8c73db" integrity sha512-jKm3xz5nX7ABtHzzuuLmawP0pFWP77lXNdIC6AWOceBs23OHUaJ29p4prxr/7Sb588GwTbkPsYkDqVFaE3ezNQ== @@ -7711,7 +7629,7 @@ regexp.prototype.flags@^1.4.1, regexp.prototype.flags@^1.4.3: define-properties "^1.1.3" functions-have-names "^1.2.2" -regexpp@^3.1.0, regexpp@^3.2.0: +regexpp@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== @@ -7755,9 +7673,9 @@ regjsparser@^0.9.1: jsesc "~0.5.0" release-it@^15.4.2: - version "15.4.2" - resolved "https://registry.yarnpkg.com/release-it/-/release-it-15.4.2.tgz#0796a4870bec093d339f6d7e84d373c1628f2f18" - integrity sha512-8UszvMbV/+aNZ03TRIpPiKOyO7s6fWkSHZ0Bz08qUBpO8F+o2j6o4+TEygPygJznW8UcfO1SDldagqBMIfOh5Q== + version "15.4.3" + resolved "https://registry.yarnpkg.com/release-it/-/release-it-15.4.3.tgz#1767a6a542113fd9e585ed85766dd365ad206099" + integrity sha512-+GPciiCLhb9AUNlRNmajHtGAr6ud8uu2qHLRQRPJgqO3KE5RnVXjRgmJPn5MIupaAavrEltklMC4vpnl8pydsA== dependencies: "@iarna/toml" "2.2.5" "@octokit/rest" "19.0.4" @@ -7766,10 +7684,10 @@ release-it@^15.4.2: cosmiconfig "7.0.1" execa "6.1.0" form-data "4.0.0" - git-url-parse "13.0.0" + git-url-parse "13.1.0" globby "13.1.2" - got "12.4.1" - inquirer "9.1.1" + got "12.5.1" + inquirer "9.1.2" is-ci "3.0.1" lodash "4.17.21" mime-types "2.1.35" @@ -7867,13 +7785,6 @@ resolve@^2.0.0-next.3: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -responselike@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.1.tgz#9a0bc8fdc252f3fb1cca68b016591059ba1422bc" - integrity sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw== - dependencies: - lowercase-keys "^2.0.0" - responselike@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/responselike/-/responselike-3.0.0.tgz#20decb6c298aff0dbee1c355ca95461d42823626" @@ -7973,10 +7884,10 @@ rx-lite@*, rx-lite@^4.0.8: resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" integrity sha512-Cun9QucwK6MIrp3mry/Y7hqD1oFqTYLQ4pGxaHTjIdaFDWRGGLikqp6u8LcWJnzpoALg9hap+JGk8sFIUuEGNA== -rxjs@^7.5.1, rxjs@^7.5.6: - version "7.5.6" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.6.tgz#0446577557862afd6903517ce7cae79ecb9662bc" - integrity sha512-dnyv2/YsXhnm461G+R/Pe5bWP41Nm6LBXEYWI6eiFP4fiwx6WRI/CD0zbdVAudd9xwLEF2IDcKXLHit0FYjUzw== +rxjs@^7.5.5, rxjs@^7.5.6: + version "7.5.7" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.7.tgz#2ec0d57fdc89ece220d2e702730ae8f1e49def39" + integrity sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA== dependencies: tslib "^2.1.0" @@ -7990,6 +7901,15 @@ safe-buffer@~5.2.0: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== +safe-regex-test@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" + integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.3" + is-regex "^1.1.4" + safe-regex@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" @@ -8052,7 +7972,7 @@ semver-regex@^3.1.2: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -semver@7.3.7, semver@^7.2.1, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7: +semver@7.3.7, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7: version "7.3.7" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== @@ -8248,6 +8168,14 @@ slice-ansi@^4.0.0: astral-regex "^2.0.0" is-fullwidth-code-point "^3.0.0" +slice-ansi@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-5.0.0.tgz#b73063c57aa96f9cd881654b15294d95d285c42a" + integrity sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ== + dependencies: + ansi-styles "^6.0.0" + is-fullwidth-code-point "^4.0.0" + smart-buffer@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" @@ -8293,9 +8221,9 @@ socks-proxy-agent@5, socks-proxy-agent@^5.0.0: socks "^2.3.3" socks@^2.3.3: - version "2.7.0" - resolved "https://registry.yarnpkg.com/socks/-/socks-2.7.0.tgz#f9225acdb841e874dca25f870e9130990f3913d0" - integrity sha512-scnOe9y4VuiNUULJN72GrM26BNOjVsfPXI+j+98PkyEfsIXroa5ofyjT+FzGvn/xHs73U2JtoBYAVx9Hl4quSA== + version "2.7.1" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.7.1.tgz#d8e651247178fde79c0663043e07240196857d55" + integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ== dependencies: ip "^2.0.0" smart-buffer "^4.2.0" @@ -8433,7 +8361,7 @@ stream-buffers@2.2.x: resolved "https://registry.yarnpkg.com/stream-buffers/-/stream-buffers-2.2.0.tgz#91d5f5130d1cef96dcfa7f726945188741d09ee4" integrity sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg== -string-argv@0.3.1: +string-argv@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== @@ -8474,7 +8402,7 @@ string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string-width@^5.0.1, string-width@^5.1.2: +string-width@^5.0.0, string-width@^5.0.1, string-width@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== @@ -8534,15 +8462,6 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -stringify-object@3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" - integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== - dependencies: - get-own-enumerable-property-symbols "^3.0.0" - is-obj "^1.0.1" - is-regexp "^1.0.0" - strip-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" @@ -8613,13 +8532,6 @@ sudo-prompt@^9.0.0: resolved "https://registry.yarnpkg.com/sudo-prompt/-/sudo-prompt-9.2.1.tgz#77efb84309c9ca489527a4e749f287e6bdd52afd" integrity sha512-Mu7R0g4ig9TUuGSxJavny5Rv0egCEtpZRNMrZaYS1vxkiIxGiGUwoezU3LazIQ+KE04hTrTfNPgxU5gzi7F5Pw== -supports-color@8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -8646,17 +8558,6 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== -table@^6.0.9: - version "6.8.0" - resolved "https://registry.yarnpkg.com/table/-/table-6.8.0.tgz#87e28f14fa4321c3377ba286f07b79b281a3b3ca" - integrity sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA== - dependencies: - ajv "^8.0.1" - lodash.truncate "^4.4.2" - slice-ansi "^4.0.0" - string-width "^4.2.3" - strip-ansi "^6.0.1" - temp@0.8.3: version "0.8.3" resolved "https://registry.yarnpkg.com/temp/-/temp-0.8.3.tgz#e0c6bc4d26b903124410e4fed81103014dfc1f59" @@ -8872,9 +8773,9 @@ typedarray@^0.0.6: integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== typescript@^4.2.4, typescript@^4.6.4: - version "4.8.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.3.tgz#d59344522c4bc464a65a730ac695007fdb66dd88" - integrity sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig== + version "4.8.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.4.tgz#c464abca159669597be5f96b8943500b238e60e6" + integrity sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ== ua-parser-js@^0.7.18: version "0.7.31" @@ -8890,9 +8791,9 @@ uglify-es@^3.1.9: source-map "~0.6.1" uglify-js@^3.1.4: - version "3.17.0" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.0.tgz#55bd6e9d19ce5eef0d5ad17cd1f587d85b180a85" - integrity sha512-aTeNPVmgIMPpm1cxXr2Q/nEbvkmV8yq66F3om7X3P/cvOXQ0TMQ64Wk63iyT1gPlmdmGzjGpyLh1f3y8MZWXGg== + version "3.17.2" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.2.tgz#f55f668b9a64b213977ae688703b6bbb7ca861c6" + integrity sha512-bbxglRjsGQMchfvXZNusUcYgiB9Hx2K4AHYXQy2DITZ9Rd+JzhX7+hoocE5Winr7z2oHvPsekkBwXtigvxevXg== ultron@1.0.x: version "1.0.2" @@ -9069,11 +8970,6 @@ v8-compile-cache-lib@^3.0.1: resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== -v8-compile-cache@^2.0.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" - integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== - validate-npm-package-license@^3.0.1: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" @@ -9335,6 +9231,11 @@ yaml@^1.10.0: resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== +yaml@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.1.2.tgz#eb0f535eb309811b60276a9cc8c02af4355db420" + integrity sha512-VSdf2/K3FqAetooKQv45Hcu6sA00aDgWZeGcG6V9IYJnVLTnb6988Tie79K5nx2vK7cEpf+yW8Oy+7iPAbdiHA== + yargs-parser@21.1.1, yargs-parser@^21.0.0: version "21.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" @@ -9409,11 +9310,11 @@ yargs@^16.1.0, yargs@^16.2.0: yargs-parser "^20.2.2" yargs@^17.0.0, yargs@^17.5.1: - version "17.5.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.5.1.tgz#e109900cab6fcb7fd44b1d8249166feb0b36e58e" - integrity sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA== + version "17.6.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.6.0.tgz#e134900fc1f218bc230192bdec06a0a5f973e46c" + integrity sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g== dependencies: - cliui "^7.0.2" + cliui "^8.0.1" escalade "^3.1.1" get-caller-file "^2.0.5" require-directory "^2.1.1" From c74eaac40973b157c5f617e113edcbd2f5db7a23 Mon Sep 17 00:00:00 2001 From: gorhom Date: Mon, 3 Oct 2022 22:10:43 +0100 Subject: [PATCH 09/13] fix(#1119): fixed race condition between onmount and keyboard animations --- src/components/bottomSheet/BottomSheet.tsx | 71 ++++++++++++++-------- 1 file changed, 46 insertions(+), 25 deletions(-) diff --git a/src/components/bottomSheet/BottomSheet.tsx b/src/components/bottomSheet/BottomSheet.tsx index 616a6014a..bd5ebddaf 100644 --- a/src/components/bottomSheet/BottomSheet.tsx +++ b/src/components/bottomSheet/BottomSheet.tsx @@ -567,6 +567,10 @@ const BottomSheetComponent = forwardRef( return animatedPosition.value; } + if (!isAnimatedOnMount.value) { + return snapPoints[_providedIndex]; + } + return snapPoints[currentIndex]; }, [ @@ -579,8 +583,10 @@ const BottomSheetComponent = forwardRef( animatedPosition, animatedSnapPoints, isInTemporaryPosition, + isAnimatedOnMount, keyboardBehavior, keyboardBlurBehavior, + _providedIndex, ] ); const handleOnChange = useCallback( @@ -1238,7 +1244,7 @@ const BottomSheetComponent = forwardRef( nextPosition = animatedClosedPosition.value; animatedNextPositionIndex.value = -1; } else { - nextPosition = animatedSnapPoints.value[_providedIndex]; + nextPosition = getNextPosition(); } runOnJS(print)({ @@ -1371,37 +1377,52 @@ const BottomSheetComponent = forwardRef( ) : Math.abs(_keyboardHeight - animatedContainerOffset.value.bottom); + /** + * if keyboard state is equal to the previous state, then exit the method + */ + if ( + _keyboardState === _previousKeyboardState && + _keyboardHeight === _previousKeyboardHeight + ) { + return; + } + + /** + * if user is interacting with sheet, then exit the method + */ const hasActiveGesture = animatedContentGestureState.value === State.ACTIVE || animatedContentGestureState.value === State.BEGAN || animatedHandleGestureState.value === State.ACTIVE || animatedHandleGestureState.value === State.BEGAN; + if (hasActiveGesture) { + return; + } + + /** + * if sheet not animated on mount yet, then exit the method + */ + if (!isAnimatedOnMount.value) { + return; + } + + /** + * if new keyboard state is hidden and blur behavior is none, then exit the method + */ + if ( + _keyboardState === KEYBOARD_STATE.HIDDEN && + keyboardBlurBehavior === KEYBOARD_BLUR_BEHAVIOR.none + ) { + return; + } + /** + * if platform is android and the input mode is resize, then exit the method + */ if ( - /** - * if keyboard state is equal to the previous state, then exit the method - */ - (_keyboardState === _previousKeyboardState && - _keyboardHeight === _previousKeyboardHeight) || - /** - * if user is interacting with sheet, then exit the method - */ - hasActiveGesture || - /** - * if sheet not animated on mount yet, then exit the method - */ - !isAnimatedOnMount.value || - /** - * if new keyboard state is hidden and blur behavior is none, then exit the method - */ - (_keyboardState === KEYBOARD_STATE.HIDDEN && - keyboardBlurBehavior === KEYBOARD_BLUR_BEHAVIOR.none) || - /** - * if platform is android and the input mode is resize, then exit the method - */ - (Platform.OS === 'android' && - keyboardBehavior === KEYBOARD_BEHAVIOR.interactive && - android_keyboardInputMode === KEYBOARD_INPUT_MODE.adjustResize) + Platform.OS === 'android' && + keyboardBehavior === KEYBOARD_BEHAVIOR.interactive && + android_keyboardInputMode === KEYBOARD_INPUT_MODE.adjustResize ) { animatedKeyboardHeightInContainer.value = 0; return; From 3ea7a416861b9c377a8465ced5719c825c63d2af Mon Sep 17 00:00:00 2001 From: gorhom Date: Sat, 15 Oct 2022 16:12:05 +0100 Subject: [PATCH 10/13] fix: update ref handler for web --- .../src/components/contactList/styles.web.ts | 2 +- example/expo/index.ts | 3 + example/expo/package.json | 6 +- example/expo/web/index.html | 121 ++++++++++++++++++ .../createBottomSheetScrollableComponent.tsx | 8 +- .../useGestureEventsHandlersDefault.web.tsx | 20 ++- src/hooks/useScrollHandler.web.ts | 13 +- src/utilities/getRefNativeTag.web.ts | 3 +- 8 files changed, 146 insertions(+), 30 deletions(-) create mode 100644 example/expo/web/index.html diff --git a/example/app/src/components/contactList/styles.web.ts b/example/app/src/components/contactList/styles.web.ts index b4f6f8ff0..44e5b1e37 100644 --- a/example/app/src/components/contactList/styles.web.ts +++ b/example/app/src/components/contactList/styles.web.ts @@ -9,10 +9,10 @@ export const styles = StyleSheet.create({ sectionHeaderTitle: { fontSize: 16, textTransform: 'uppercase', + color: 'black', }, container: { flex: 1, - paddingHorizontal: 16, }, contentContainer: { paddingHorizontal: 16, diff --git a/example/expo/index.ts b/example/expo/index.ts index d70a55804..58a0f2985 100644 --- a/example/expo/index.ts +++ b/example/expo/index.ts @@ -1,5 +1,8 @@ import { registerRootComponent } from 'expo'; +import { enableExperimentalWebImplementation } from 'react-native-gesture-handler'; +enableExperimentalWebImplementation(true); + import { enableScreens } from 'react-native-screens'; enableScreens(true); diff --git a/example/expo/package.json b/example/expo/package.json index 28327fa75..fa6ae7897 100644 --- a/example/expo/package.json +++ b/example/expo/package.json @@ -20,14 +20,14 @@ "@react-navigation/native": "^6.0.10", "@react-navigation/native-stack": "^6.6.2", "@react-navigation/stack": "^6.2.1", - "expo": "^46.0.10", + "expo": "^46.0.14", "expo-status-bar": "~1.4.0", "faker": "^4.1.0", "nanoid": "^3.3.3", "react": "18.0.0", "react-dom": "18.0.0", "react-native": "0.69.4", - "react-native-gesture-handler": "~2.6.0", + "react-native-gesture-handler": "^2.6.2", "react-native-pager-view": "5.4.24", "react-native-reanimated": "~2.9.1", "react-native-redash": "^16.2.4", @@ -41,7 +41,7 @@ "@types/react": "~18.0.0", "@types/react-native": "~0.69.1", "babel-plugin-module-resolver": "^4.1.0", - "expo-cli": "^6.0.5", + "expo-cli": "^6.0.6", "typescript": "^4.6.3" }, "resolutions": { diff --git a/example/expo/web/index.html b/example/expo/web/index.html new file mode 100644 index 000000000..b98004386 --- /dev/null +++ b/example/expo/web/index.html @@ -0,0 +1,121 @@ + + + + + + + + + + %WEB_TITLE% + + + + + + + +
+ + diff --git a/src/components/bottomSheetScrollable/createBottomSheetScrollableComponent.tsx b/src/components/bottomSheetScrollable/createBottomSheetScrollableComponent.tsx index e0137d1f4..cb0872ffa 100644 --- a/src/components/bottomSheetScrollable/createBottomSheetScrollableComponent.tsx +++ b/src/components/bottomSheetScrollable/createBottomSheetScrollableComponent.tsx @@ -73,10 +73,10 @@ export function createBottomSheetScrollableComponent( const nativeGesture = useMemo( () => - Gesture.Simultaneous( - Gesture.Native().shouldCancelWhenOutside(false), - draggableGesture! - ), + Gesture.Native() + // @ts-ignore + .simultaneousWithExternalGesture(draggableGesture!) + .shouldCancelWhenOutside(false), [draggableGesture] ); //#endregion diff --git a/src/hooks/useGestureEventsHandlersDefault.web.tsx b/src/hooks/useGestureEventsHandlersDefault.web.tsx index cc5f636ca..fc4204ff6 100644 --- a/src/hooks/useGestureEventsHandlersDefault.web.tsx +++ b/src/hooks/useGestureEventsHandlersDefault.web.tsx @@ -66,7 +66,6 @@ export const useGestureEventsHandlersDefault = () => { //#region gesture methods const handleOnStart: GestureEventHandlerCallbackType = useWorkletCallback( function handleOnStart(__, { translationY }) { - // console.log('handleOnStart'); // cancel current animation stopAnimation(); @@ -93,9 +92,8 @@ export const useGestureEventsHandlersDefault = () => { animatedScrollableContentOffsetY, ] ); - const handleOnActive: GestureEventHandlerCallbackType = useWorkletCallback( - function handleOnActive(source, { translationY }) { - // console.log('handleOnActive'); + const handleOnChange: GestureEventHandlerCallbackType = useWorkletCallback( + function handleOnChange(source, { translationY }) { let highestSnapPoint = animatedHighestSnapPoint.value; translationY = translationY - context.value.initialTranslationY; @@ -130,7 +128,7 @@ export const useGestureEventsHandlersDefault = () => { * point, then do not interact with current gesture. */ if ( - source === GESTURE_SOURCE.SCROLLABLE && + source === GESTURE_SOURCE.CONTENT && isScrollableRefreshable.value && animatedPosition.value === highestSnapPoint ) { @@ -145,7 +143,7 @@ export const useGestureEventsHandlersDefault = () => { */ const negativeScrollableContentOffset = (context.value.initialPosition === highestSnapPoint && - source === GESTURE_SOURCE.SCROLLABLE) || + source === GESTURE_SOURCE.CONTENT) || !context.value.isScrollablePositionLocked ? animatedScrollableContentOffsetY.value * -1 : 0; @@ -179,7 +177,7 @@ export const useGestureEventsHandlersDefault = () => { */ if ( context.value.isScrollablePositionLocked && - source === GESTURE_SOURCE.SCROLLABLE && + source === GESTURE_SOURCE.CONTENT && animatedPosition.value === highestSnapPoint ) { context.value.isScrollablePositionLocked = false; @@ -215,7 +213,7 @@ export const useGestureEventsHandlersDefault = () => { } if ( - source === GESTURE_SOURCE.SCROLLABLE && + source === GESTURE_SOURCE.CONTENT && draggedPosition + negativeScrollableContentOffset > lowestSnapPoint ) { const resistedPosition = @@ -259,7 +257,7 @@ export const useGestureEventsHandlersDefault = () => { * point, then do not interact with current gesture. */ if ( - source === GESTURE_SOURCE.SCROLLABLE && + source === GESTURE_SOURCE.CONTENT && isScrollableRefreshable.value && isSheetAtHighestSnapPoint ) { @@ -352,7 +350,7 @@ export const useGestureEventsHandlersDefault = () => { } const wasGestureHandledByScrollView = - source === GESTURE_SOURCE.SCROLLABLE && + source === GESTURE_SOURCE.CONTENT && animatedScrollableContentOffsetY.value > 0; /** * prevents snapping from top to middle / bottom with repeated interrupted scrolls @@ -391,7 +389,7 @@ export const useGestureEventsHandlersDefault = () => { return { handleOnStart, - handleOnActive, + handleOnChange, handleOnEnd, handleOnFinalize, }; diff --git a/src/hooks/useScrollHandler.web.ts b/src/hooks/useScrollHandler.web.ts index 002568431..6b11a17e7 100644 --- a/src/hooks/useScrollHandler.web.ts +++ b/src/hooks/useScrollHandler.web.ts @@ -2,6 +2,7 @@ import { useEffect, useRef, TouchEvent } from 'react'; import { useSharedValue } from 'react-native-reanimated'; import { useBottomSheetInternal } from './useBottomSheetInternal'; import { ANIMATION_STATE, SCROLLABLE_STATE } from '../constants'; +import { getRefNativeTag } from '../utilities/getRefNativeTag'; import type { Scrollable } from '../types'; export type ScrollEventContextType = { @@ -28,7 +29,7 @@ export const useScrollHandler = () => { //#region effects useEffect(() => { - const element = scrollableRef.current as any; + const element = getRefNativeTag(scrollableRef) as any; var scrollOffset = 0; var supportsPassive = false; @@ -39,7 +40,6 @@ export const useScrollHandler = () => { var shouldLockInitialPosition = false; function handleOnTouchStart(event: TouchEvent) { - // console.log('handleOnTouchStart'); if (event.touches.length !== 1) return; initialContentOffsetY = element.scrollTop; @@ -48,11 +48,6 @@ export const useScrollHandler = () => { } function handleOnTouchMove(event: TouchEvent) { - // console.log( - // 'handleOnTouchMove', - // animatedScrollableState.value === SCROLLABLE_STATE.LOCKED - // ); - if (animatedScrollableState.value === SCROLLABLE_STATE.LOCKED) { return event.preventDefault(); } @@ -72,13 +67,10 @@ export const useScrollHandler = () => { } function handleOnTouchEnd() { - // console.log('handleOnTouchEnd'); - // console.log(''); if (animatedScrollableState.value === SCROLLABLE_STATE.LOCKED) { const lockPosition = shouldLockInitialPosition ? initialContentOffsetY ?? 0 : 0; - // @ts-ignore element.scroll({ top: 0, left: 0, @@ -172,6 +164,7 @@ export const useScrollHandler = () => { //#endregion return { + scrollHandler: undefined, scrollableRef, scrollableContentOffsetY, }; diff --git a/src/utilities/getRefNativeTag.web.ts b/src/utilities/getRefNativeTag.web.ts index 5cece79bd..08c3ca2ff 100644 --- a/src/utilities/getRefNativeTag.web.ts +++ b/src/utilities/getRefNativeTag.web.ts @@ -1,5 +1,6 @@ import type { RefObject } from 'react'; +import { findNodeHandle } from 'react-native'; export function getRefNativeTag(ref: RefObject) { - return ref?.current || null; + return findNodeHandle(ref?.current) || null; } From d7dbd145dfe0277efef5abe9f0adca528e8775d5 Mon Sep 17 00:00:00 2001 From: gorhom Date: Sun, 16 Oct 2022 18:15:44 +0100 Subject: [PATCH 11/13] chore: removed unused component --- ...eateBottomSheetScrollableComponent.web.tsx | 101 ------------------ 1 file changed, 101 deletions(-) delete mode 100644 src/components/bottomSheetScrollable/createBottomSheetScrollableComponent.web.tsx diff --git a/src/components/bottomSheetScrollable/createBottomSheetScrollableComponent.web.tsx b/src/components/bottomSheetScrollable/createBottomSheetScrollableComponent.web.tsx deleted file mode 100644 index f89ad6d04..000000000 --- a/src/components/bottomSheetScrollable/createBottomSheetScrollableComponent.web.tsx +++ /dev/null @@ -1,101 +0,0 @@ -import React, { forwardRef, useImperativeHandle, useMemo } from 'react'; -import { useAnimatedProps, useAnimatedStyle } from 'react-native-reanimated'; -import { - useScrollHandler, - useScrollableSetter, - useBottomSheetInternal, -} from '../../hooks'; -import { - SCROLLABLE_DECELERATION_RATE_MAPPER, - SCROLLABLE_STATE, - SCROLLABLE_TYPE, -} from '../../constants'; - -export function createBottomSheetScrollableComponent( - type: SCROLLABLE_TYPE, - ScrollableComponent: any -) { - return forwardRef((props, ref) => { - // props - const { - // hooks - focusHook, - scrollEventsHandlersHook, - // props - enableFooterMarginAdjustment = false, - overScrollMode = 'never', - keyboardDismissMode = 'interactive', - showsVerticalScrollIndicator = true, - style, - progressViewOffset, - ...rest - }: any = props; - - //#region hooks - const { scrollableRef, scrollableContentOffsetY } = useScrollHandler( - scrollEventsHandlersHook - ); - const { animatedFooterHeight, animatedScrollableState } = - useBottomSheetInternal(); - //#endregion - - //#region variables - const scrollableAnimatedProps = useAnimatedProps( - () => ({ - decelerationRate: - SCROLLABLE_DECELERATION_RATE_MAPPER[animatedScrollableState.value], - showsVerticalScrollIndicator: showsVerticalScrollIndicator - ? animatedScrollableState.value === SCROLLABLE_STATE.UNLOCKED - : showsVerticalScrollIndicator, - }), - [showsVerticalScrollIndicator] - ); - //#endregion - - //#region styles - const containerAnimatedStyle = useAnimatedStyle( - () => ({ - marginBottom: enableFooterMarginAdjustment - ? animatedFooterHeight.value - : 0, - }), - [enableFooterMarginAdjustment] - ); - const containerStyle = useMemo(() => { - return enableFooterMarginAdjustment - ? [ - ...(style ? ('length' in style ? style : [style]) : []), - containerAnimatedStyle, - ] - : style; - }, [enableFooterMarginAdjustment, style, containerAnimatedStyle]); - //#endregion - - //#region effects - // @ts-ignore - useImperativeHandle(ref, () => scrollableRef.current); - useScrollableSetter( - scrollableRef, - type, - scrollableContentOffsetY, - false, - focusHook - ); - //#endregion - - //#region render - return ( - - ); - //#endregion - }); -} From 435fdf0f1d90368f9a024903ee27e9ede94f67b6 Mon Sep 17 00:00:00 2001 From: gorhom Date: Sun, 19 Feb 2023 16:20:30 +0100 Subject: [PATCH 12/13] chore: updated expo --- example/expo/babel.config.js | 1 + example/expo/package.json | 39 ++++++++++++++++++------------------ 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/example/expo/babel.config.js b/example/expo/babel.config.js index 8c702fa88..dd6659691 100644 --- a/example/expo/babel.config.js +++ b/example/expo/babel.config.js @@ -16,6 +16,7 @@ module.exports = function (api) { return { presets: ['babel-preset-expo'], plugins: [ + '@babel/plugin-proposal-export-namespace-from', 'react-native-reanimated/plugin', [ 'module-resolver', diff --git a/example/expo/package.json b/example/expo/package.json index fa6ae7897..e7adbb90d 100644 --- a/example/expo/package.json +++ b/example/expo/package.json @@ -5,13 +5,13 @@ "private": true, "main": "./index.ts", "scripts": { - "start": "expo start", - "android": "expo start --android", - "ios": "expo start --ios", - "web": "expo start --web", - "eject": "expo eject" + "start": "npx expo start", + "android": "npx expo start --android", + "ios": "npx expo start --ios", + "web": "npx expo start --web" }, "dependencies": { + "@expo/webpack-config": "^0.17.2", "@gorhom/portal": "^1.0.13", "@gorhom/showcase-template": "^2.1.0", "@react-navigation/bottom-tabs": "^6.3.1", @@ -20,28 +20,29 @@ "@react-navigation/native": "^6.0.10", "@react-navigation/native-stack": "^6.6.2", "@react-navigation/stack": "^6.2.1", - "expo": "^46.0.14", - "expo-status-bar": "~1.4.0", + "expo": "^47.0.0", + "expo-status-bar": "~1.4.2", "faker": "^4.1.0", "nanoid": "^3.3.3", - "react": "18.0.0", - "react-dom": "18.0.0", - "react-native": "0.69.4", - "react-native-gesture-handler": "^2.6.2", - "react-native-pager-view": "5.4.24", - "react-native-reanimated": "~2.9.1", + "react": "18.1.0", + "react-dom": "18.1.0", + "react-native": "0.70.5", + "react-native-gesture-handler": "~2.8.0", + "react-native-pager-view": "6.0.1", + "react-native-reanimated": "~2.12.0", "react-native-redash": "^16.2.4", - "react-native-safe-area-context": "4.3.1", - "react-native-screens": "~3.15.0", + "react-native-safe-area-context": "4.4.1", + "react-native-screens": "~3.18.0", "react-native-tab-view": "^3.1.1", "react-native-web": "~0.18.7" }, "devDependencies": { - "@babel/core": "^7.18.6", - "@types/react": "~18.0.0", - "@types/react-native": "~0.69.1", + "@babel/core": "^7.19.3", + "@babel/plugin-proposal-export-namespace-from": "^7.18.9", + "@types/react": "~18.0.24", + "@types/react-native": "~0.70.6", + "babel-loader": "^8.2.3", "babel-plugin-module-resolver": "^4.1.0", - "expo-cli": "^6.0.6", "typescript": "^4.6.3" }, "resolutions": { From 345cfbbd4f1ae897f8de823b7373dd09ad1187de Mon Sep 17 00:00:00 2001 From: gorhom Date: Sun, 19 Feb 2023 20:55:44 +0100 Subject: [PATCH 13/13] fix: detached example on web --- example/app/package.json | 4 +-- .../app/src/screens/modal/DetachedExample.tsx | 4 +-- src/components/bottomSheet/BottomSheet.tsx | 15 ++++---- .../bottomSheetView/BottomSheetView.tsx | 36 ++++++++++++------- src/hooks/useBottomSheetDynamicSnapPoints.ts | 3 +- 5 files changed, 39 insertions(+), 23 deletions(-) diff --git a/example/app/package.json b/example/app/package.json index f30108a27..5d6cbf9bd 100644 --- a/example/app/package.json +++ b/example/app/package.json @@ -20,10 +20,10 @@ "nanoid": "^3.3.3", "react": "17.0.2", "react-native": "0.68.1", - "react-native-gesture-handler": "^2.6.0", + "react-native-gesture-handler": "~2.8.0", "react-native-maps": "^0.30.1", "react-native-pager-view": "^5.4.24", - "react-native-reanimated": "^2.10.0", + "react-native-reanimated": "~2.12.0", "react-native-redash": "^16.0.11", "react-native-safe-area-context": "4.2.4", "react-native-screens": "^3.15.0", diff --git a/example/app/src/screens/modal/DetachedExample.tsx b/example/app/src/screens/modal/DetachedExample.tsx index 2e06327fc..456b995a6 100644 --- a/example/app/src/screens/modal/DetachedExample.tsx +++ b/example/app/src/screens/modal/DetachedExample.tsx @@ -76,7 +76,7 @@ const DetachedExample = () => { snapPoints={animatedSnapPoints} handleHeight={animatedHandleHeight} contentHeight={animatedContentHeight} - bottomInset={safeBottomArea + 34} + bottomInset={safeBottomArea + 16} enablePanDownToClose={true} style={styles.sheetContainer} backgroundComponent={null} @@ -118,7 +118,7 @@ const styles = StyleSheet.create({ contentContainerStyle: { paddingTop: 12, paddingBottom: 12, - paddingHorizontal: 16, + paddingHorizontal: 12, }, footer: { justifyContent: 'center', diff --git a/src/components/bottomSheet/BottomSheet.tsx b/src/components/bottomSheet/BottomSheet.tsx index bd5ebddaf..8f6013255 100644 --- a/src/components/bottomSheet/BottomSheet.tsx +++ b/src/components/bottomSheet/BottomSheet.tsx @@ -1370,12 +1370,15 @@ const BottomSheetComponent = forwardRef( /** * Calculate the keyboard height in the container. */ - animatedKeyboardHeightInContainer.value = $modal - ? Math.abs( - _keyboardHeight - - Math.abs(bottomInset - animatedContainerOffset.value.bottom) - ) - : Math.abs(_keyboardHeight - animatedContainerOffset.value.bottom); + animatedKeyboardHeightInContainer.value = + _keyboardHeight === 0 + ? 0 + : $modal + ? Math.abs( + _keyboardHeight - + Math.abs(bottomInset - animatedContainerOffset.value.bottom) + ) + : Math.abs(_keyboardHeight - animatedContainerOffset.value.bottom); /** * if keyboard state is equal to the previous state, then exit the method diff --git a/src/components/bottomSheetView/BottomSheetView.tsx b/src/components/bottomSheetView/BottomSheetView.tsx index 12a2df6c7..16005ef62 100644 --- a/src/components/bottomSheetView/BottomSheetView.tsx +++ b/src/components/bottomSheetView/BottomSheetView.tsx @@ -19,27 +19,38 @@ function BottomSheetViewComponent({ animatedFooterHeight, } = useBottomSheetInternal(); - // styles + //#region styles + const flattenContainerStyle = useMemo( + () => StyleSheet.flatten(style), + [style] + ); const containerStylePaddingBottom = useMemo(() => { - const flattenStyle = StyleSheet.flatten(style); const paddingBottom = - flattenStyle && 'paddingBottom' in flattenStyle - ? flattenStyle.paddingBottom + flattenContainerStyle && 'paddingBottom' in flattenContainerStyle + ? flattenContainerStyle.paddingBottom : 0; return typeof paddingBottom === 'number' ? paddingBottom : 0; - }, [style]); - const containerAnimatedStyle = useAnimatedStyle( + }, [flattenContainerStyle]); + const containerStyle = useMemo(() => { + return { + ...flattenContainerStyle, + paddingBottom: 0, + }; + }, [flattenContainerStyle]); + const spaceStyle = useAnimatedStyle( () => ({ - paddingBottom: enableFooterMarginAdjustment + opacity: 0, + height: enableFooterMarginAdjustment ? animatedFooterHeight.value + containerStylePaddingBottom : containerStylePaddingBottom, }), - [containerStylePaddingBottom, enableFooterMarginAdjustment] - ); - const containerStyle = useMemo( - () => [style, containerAnimatedStyle], - [style, containerAnimatedStyle] + [ + enableFooterMarginAdjustment, + containerStylePaddingBottom, + animatedFooterHeight, + ] ); + //#endregion // callback const handleSettingScrollable = useCallback(() => { @@ -54,6 +65,7 @@ function BottomSheetViewComponent({ return ( {children} + ); } diff --git a/src/hooks/useBottomSheetDynamicSnapPoints.ts b/src/hooks/useBottomSheetDynamicSnapPoints.ts index a1c25735d..cb3f471cd 100644 --- a/src/hooks/useBottomSheetDynamicSnapPoints.ts +++ b/src/hooks/useBottomSheetDynamicSnapPoints.ts @@ -1,4 +1,5 @@ import { useCallback } from 'react'; +import { LayoutChangeEvent } from 'react-native'; import { useDerivedValue, useSharedValue } from 'react-native-reanimated'; import { INITIAL_HANDLE_HEIGHT, @@ -45,7 +46,7 @@ export const useBottomSheetDynamicSnapPoints = ( nativeEvent: { layout: { height }, }, - }) => { + }: LayoutChangeEvent) => { animatedContentHeight.value = height; }, [animatedContentHeight]