From e5856dae79c061a2ab81b4dc1d2610e863fc0ce9 Mon Sep 17 00:00:00 2001 From: Satyajit Sahoo Date: Sun, 22 Nov 2020 14:13:52 +0100 Subject: [PATCH] chore: sync latest stack --- packages/stack/package.json | 2 +- packages/stack/scripts/stack.patch | Bin 31351 -> 24866 bytes .../NestedNavigator.test.tsx.snap | 4 +- .../StackNavigator.test.tsx.snap | 4 +- .../src/vendor/views/KeyboardManager.tsx | 34 +++++++----- .../stack/src/vendor/views/Stack/Card.tsx | 6 +-- .../src/vendor/views/Stack/CardContainer.tsx | 50 ++++++++++++------ .../src/vendor/views/Stack/CardStack.tsx | 2 +- yarn.lock | 8 +-- 9 files changed, 67 insertions(+), 43 deletions(-) diff --git a/packages/stack/package.json b/packages/stack/package.json index 2ef6a661..7ada3171 100644 --- a/packages/stack/package.json +++ b/packages/stack/package.json @@ -45,7 +45,7 @@ "devDependencies": { "@react-native-community/bob": "^0.16.2", "@react-native-community/masked-view": "0.1.10", - "@react-navigation/stack": "^5.12.6", + "@react-navigation/stack": "^5.12.8", "@types/color": "^3.0.1", "@types/react": "^16.9.53", "@types/react-native": "^0.63.30", diff --git a/packages/stack/scripts/stack.patch b/packages/stack/scripts/stack.patch index 219b4962df5f87cbdbd030e4aa11fe15459892f0..645695722e5af5b03f22459c47aafc6bc82cf03a 100644 GIT binary patch delta 264 zcmezVg>lg##?1zj^B6aum+BXq9Isn2`GW4f&Fl5nvuutxj%VDw--MfyiA!PfK@;i8 zFHH3}OPHNz1S*rAd_abMGlvB~(`E^)M@&pyx|28Bh)fo=-M9IIZ6u>Gmx6*qPHG7d zr9?E`a` ztU&4RtJOqtj4?L);9HX#)2weM#`s{2Ce;U%KB?50_~uWdF+P}h?%Y{GHehOCO`E;s z-tU}q&(EH3cIS_GKf!>sOZVt<|dhZ)K#i`oHl{f5UZX0VzmEIkfqA{CP5~Dy9_*-N7}rp1OVY9On(v zzy03e#n>f17qcX5-i%1bB-Nslbt&n}aa~tkIiHJ5$uULFB?Mo;u33_z$%YfHq-F4# zdR~DOS}vl`YiZL-6k{74$MbwbXkA`D8t&~PJv~pabdlw7m@3D@M^{#O?%-qLzQLKf z#iivdD_7rQyka;ZIir!mM*r8ru&GlewcwtyaIw_scY;vrmG=f49@_tKqtMiRpvl+d z_xoE8`VY0Xwk3oENhx)C)}WubUsrV_qRz{cvxbt6Wu=s&&5m303sy{7k`qF6GXGEC zQ8_)m5guR6f|GB<;N&}F$g<`n9LZ!%*&0s>jb_TwRW+)cilyk<#HQVeDHGTqwB)%# zEu%xp1t5DQOWn*d*~pt9lqDFSkPJi8X64A@MO8}5>WCK6ElZ!Ho-|!b*P@0@Q;jPi z({4IW{=z8j5Qj>_<4h1x2NU3eA>gK70~ChX?Txj^gupl;x}`9ntnu4Tg9UaMJ-@h#8uyYqMZ2 zMS!?*{8?0`*ZZcv%Nf_OyA0ho{qJtu>)ERPuT$~A2vz=fnRa@fATTM4E*2O%rw~}2 z=L0|wm>K_|&_@j#L|hbIEHH!}7?{NZ(pajq2N2A{K_{+Vbg{sYg(K`fnqU@=Fy|hB z?39Ou#PLU1WVq*R_4~Ky6z^D|%Kwh^Y`;k#3}6WKe&F;DZwVZ)?UyS5+jCQiohtv8 zV0rr*4-Ws>GY}hyK&S4twybA*?Ikd0VA4VT3bcO^oETW#>$4-!OZy?1&VW5a1whfo z0zc`O*u4@>>HZFWTcfg9qpMGrI0|t@eMfjP0&}a(B{sr^v8QG&!fj`#U08 z1pW;{^bE-;s%)<{o>+aEztum9F)6--Uumu-USfy*ZT3$*XOH@ZKo5f6ZQu62x4tJH zF+nPkA8jiNgsR{$g7Lc3fU+YqM{)cY|rI{R?KI8Q0G4E8adL)PVh4@;!k4 zamUx7y#D9}_Cr}hRM~==vCh)>S|_~Zwa%Ncf3x!|4&X|6kcQp}ch&-Y+1m+5`uU5Y zz7J^mAD&$Tu&2cySXadvSbr6R%*QUA7K+NLJ9XeEp1Ddt^hZN)Q1|$`HCTIxPs6%6 zd>vNb2*|~Wkucr97R^FS0lVqK;bP1AA8DPxMw{zlCpz9<3|ye8>>JZ}!G10ACjJ|2 CTXDkx diff --git a/packages/stack/src/navigators/__tests__/__snapshots__/NestedNavigator.test.tsx.snap b/packages/stack/src/navigators/__tests__/__snapshots__/NestedNavigator.test.tsx.snap index 87cced32..096456c0 100644 --- a/packages/stack/src/navigators/__tests__/__snapshots__/NestedNavigator.test.tsx.snap +++ b/packages/stack/src/navigators/__tests__/__snapshots__/NestedNavigator.test.tsx.snap @@ -152,7 +152,7 @@ exports[`Nested navigators renders succesfully as direct child 1`] = ` onGestureCanceled={[Function]} onGestureEnd={[Function]} onOpen={[Function]} - onTransitionStart={[Function]} + onTransition={[Function]} pointerEvents="box-none" style={ Array [ @@ -432,7 +432,7 @@ exports[`Nested navigators renders succesfully as direct child 1`] = ` onGestureCanceled={[Function]} onGestureEnd={[Function]} onOpen={[Function]} - onTransitionStart={[Function]} + onTransition={[Function]} pointerEvents="box-none" style={ Array [ diff --git a/packages/stack/src/navigators/__tests__/__snapshots__/StackNavigator.test.tsx.snap b/packages/stack/src/navigators/__tests__/__snapshots__/StackNavigator.test.tsx.snap index 79eee638..2fd21776 100644 --- a/packages/stack/src/navigators/__tests__/__snapshots__/StackNavigator.test.tsx.snap +++ b/packages/stack/src/navigators/__tests__/__snapshots__/StackNavigator.test.tsx.snap @@ -169,7 +169,7 @@ exports[`StackNavigator applies correct values when headerRight is present 1`] = onGestureCanceled={[Function]} onGestureEnd={[Function]} onOpen={[Function]} - onTransitionStart={[Function]} + onTransition={[Function]} pointerEvents="box-none" style={ Array [ @@ -462,7 +462,7 @@ exports[`StackNavigator renders successfully 1`] = ` onGestureCanceled={[Function]} onGestureEnd={[Function]} onOpen={[Function]} - onTransitionStart={[Function]} + onTransition={[Function]} pointerEvents="box-none" style={ Array [ diff --git a/packages/stack/src/vendor/views/KeyboardManager.tsx b/packages/stack/src/vendor/views/KeyboardManager.tsx index 0f96ef92..60a4d451 100644 --- a/packages/stack/src/vendor/views/KeyboardManager.tsx +++ b/packages/stack/src/vendor/views/KeyboardManager.tsx @@ -1,15 +1,17 @@ import * as React from 'react'; -import { TextInput, Platform, Keyboard } from 'react-native'; +import { TextInput, Keyboard, HostComponent } from 'react-native'; type Props = { enabled: boolean; children: (props: { onPageChangeStart: () => void; - onPageChangeConfirm: () => void; + onPageChangeConfirm: (force: boolean) => void; onPageChangeCancel: () => void; }) => React.ReactNode; }; +type InputRef = React.ElementRef> | undefined; + export default class KeyboardManager extends React.Component { componentWillUnmount() { this.clearKeyboardTimeout(); @@ -17,7 +19,7 @@ export default class KeyboardManager extends React.Component { // Numeric id of the previously focused text input // When a gesture didn't change the tab, we can restore the focused input with this - private previouslyFocusedTextInput: any | null = null; + private previouslyFocusedTextInput: InputRef = undefined; private startTimestamp: number = 0; private keyboardTimeout: any; @@ -35,7 +37,8 @@ export default class KeyboardManager extends React.Component { this.clearKeyboardTimeout(); - const input: any = TextInput.State.currentlyFocusedInput + // @ts-expect-error: blurTextInput accepts both number and ref, but types say only ref + const input: InputRef = TextInput.State.currentlyFocusedInput ? TextInput.State.currentlyFocusedInput() : TextInput.State.currentlyFocusedField(); @@ -49,25 +52,30 @@ export default class KeyboardManager extends React.Component { this.startTimestamp = Date.now(); }; - private handlePageChangeConfirm = () => { + private handlePageChangeConfirm = (force: boolean) => { if (!this.props.enabled) { return; } this.clearKeyboardTimeout(); - const input = this.previouslyFocusedTextInput; + if (force) { + // Always dismiss input, even if we don't have a ref to it + // We might not have the ref if onPageChangeStart was never called + // This can happen if page change was not from a gesture + Keyboard.dismiss(); + } else { + const input = this.previouslyFocusedTextInput; - if (input) { - if (Platform.OS === 'android') { - Keyboard.dismiss(); - } else { + if (input) { + // Dismiss the keyboard only if an input was a focused before + // This makes sure we don't dismiss input on going back and focusing an input TextInput.State.blurTextInput(input); } } // Cleanup the ID on successful page change - this.previouslyFocusedTextInput = null; + this.previouslyFocusedTextInput = undefined; }; private handlePageChangeCancel = () => { @@ -91,11 +99,11 @@ export default class KeyboardManager extends React.Component { if (Date.now() - this.startTimestamp < 100) { this.keyboardTimeout = setTimeout(() => { TextInput.State.focusTextInput(input); - this.previouslyFocusedTextInput = null; + this.previouslyFocusedTextInput = undefined; }, 100); } else { TextInput.State.focusTextInput(input); - this.previouslyFocusedTextInput = null; + this.previouslyFocusedTextInput = undefined; } } }; diff --git a/packages/stack/src/vendor/views/Stack/Card.tsx b/packages/stack/src/vendor/views/Stack/Card.tsx index 4c0a4031..6848f4be 100755 --- a/packages/stack/src/vendor/views/Stack/Card.tsx +++ b/packages/stack/src/vendor/views/Stack/Card.tsx @@ -41,7 +41,7 @@ type Props = ViewProps & { gestureDirection: GestureDirection; onOpen: () => void; onClose: () => void; - onTransitionStart?: (props: { closing: boolean }) => void; + onTransition?: (props: { closing: boolean; gesture: boolean }) => void; onGestureBegin?: () => void; onGestureCanceled?: () => void; onGestureEnd?: () => void; @@ -178,7 +178,7 @@ export default class Card extends React.Component { transitionSpec, onOpen, onClose, - onTransitionStart, + onTransition, } = this.props; const toValue = this.getAnimateToValue({ @@ -198,7 +198,7 @@ export default class Card extends React.Component { clearTimeout(this.pendingGestureCallback); - onTransitionStart?.({ closing }); + onTransition?.({ closing, gesture: velocity !== undefined }); animation(gesture, { ...spec.config, velocity, diff --git a/packages/stack/src/vendor/views/Stack/CardContainer.tsx b/packages/stack/src/vendor/views/Stack/CardContainer.tsx index 8790e8ef..7dcea3c1 100644 --- a/packages/stack/src/vendor/views/Stack/CardContainer.tsx +++ b/packages/stack/src/vendor/views/Stack/CardContainer.tsx @@ -47,7 +47,7 @@ type Props = TransitionPreset & { ) => void; onTransitionEnd?: (props: { route: Route }, closing: boolean) => void; onPageChangeStart?: () => void; - onPageChangeConfirm?: () => void; + onPageChangeConfirm?: (force: boolean) => void; onPageChangeCancel?: () => void; onGestureStart?: (props: { route: Route }) => void; onGestureEnd?: (props: { route: Route }) => void; @@ -117,42 +117,58 @@ function CardContainer({ scene, transitionSpec, }: Props) { - React.useEffect(() => { - onPageChangeConfirm?.(); - }, [active, onPageChangeConfirm]); - const handleOpen = () => { - onTransitionEnd?.({ route: scene.route }, false); - onOpenRoute({ route: scene.route }); + const { route } = scene; + + onTransitionEnd?.({ route }, false); + onOpenRoute({ route }); }; const handleClose = () => { - onTransitionEnd?.({ route: scene.route }, true); - onCloseRoute({ route: scene.route }); + const { route } = scene; + + onTransitionEnd?.({ route }, true); + onCloseRoute({ route }); }; const handleGestureBegin = () => { + const { route } = scene; + onPageChangeStart?.(); - onGestureStart?.({ route: scene.route }); + onGestureStart?.({ route }); }; const handleGestureCanceled = () => { + const { route } = scene; + onPageChangeCancel?.(); - onGestureCancel?.({ route: scene.route }); + onGestureCancel?.({ route }); }; const handleGestureEnd = () => { - onGestureEnd?.({ route: scene.route }); + const { route } = scene; + + onGestureEnd?.({ route }); }; - const handleTransitionStart = ({ closing }: { closing: boolean }) => { - if (active && closing) { - onPageChangeConfirm?.(); + const handleTransition = ({ + closing, + gesture, + }: { + closing: boolean; + gesture: boolean; + }) => { + const { route } = scene; + + if (!gesture) { + onPageChangeConfirm?.(true); + } else if (active && closing) { + onPageChangeConfirm?.(false); } else { onPageChangeCancel?.(); } - onTransitionStart?.({ route: scene.route }, closing); + onTransitionStart?.({ route }, closing); }; const insets = { @@ -202,7 +218,7 @@ function CardContainer({ overlay={cardOverlay} overlayEnabled={cardOverlayEnabled} shadowEnabled={cardShadowEnabled} - onTransitionStart={handleTransitionStart} + onTransition={handleTransition} onGestureBegin={handleGestureBegin} onGestureCanceled={handleGestureCanceled} onGestureEnd={handleGestureEnd} diff --git a/packages/stack/src/vendor/views/Stack/CardStack.tsx b/packages/stack/src/vendor/views/Stack/CardStack.tsx index 1b77ad7a..1d4ce463 100755 --- a/packages/stack/src/vendor/views/Stack/CardStack.tsx +++ b/packages/stack/src/vendor/views/Stack/CardStack.tsx @@ -62,7 +62,7 @@ type Props = { ) => void; onTransitionEnd: (props: { route: Route }, closing: boolean) => void; onPageChangeStart?: () => void; - onPageChangeConfirm?: () => void; + onPageChangeConfirm?: (force: boolean) => void; onPageChangeCancel?: () => void; onGestureStart?: (props: { route: Route }) => void; onGestureEnd?: (props: { route: Route }) => void; diff --git a/yarn.lock b/yarn.lock index ef9c4603..5439aecb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4179,10 +4179,10 @@ resolved "https://registry.yarnpkg.com/@react-native-community/masked-view/-/masked-view-0.1.10.tgz#5dda643e19e587793bc2034dd9bf7398ad43d401" integrity sha512-rk4sWFsmtOw8oyx8SD3KSvawwaK7gRBSEIy2TAwURyGt+3TizssXP1r8nx3zY+R7v2vYYHXZ+k2/GULAT/bcaQ== -"@react-navigation/stack@^5.12.6": - version "5.12.6" - resolved "https://registry.yarnpkg.com/@react-navigation/stack/-/stack-5.12.6.tgz#a6f2caf66da78ad2afa80f7a960c36db6b83bcff" - integrity sha512-pf9AigAIVtCQuCpZAZqBux4kNqQwj98ngvd6JEryFrqTQ1CYsUH6jfpQE7SKyHggVRFSQVMf24aCgwtRixBvjw== +"@react-navigation/stack@^5.12.8": + version "5.12.8" + resolved "https://registry.yarnpkg.com/@react-navigation/stack/-/stack-5.12.8.tgz#31e54e05d8a3ffaaa3e39a1a9b7969f8316a35bf" + integrity sha512-wUJFbU0v606RBXOUxHToCXJNmiwxtFYhN2TFvjxCZ3PJU+OWWx8HTmn99pT3rVH4Ax2cfO5BDUy9v+r74ZrIWw== dependencies: color "^3.1.3" react-native-iphone-x-helper "^1.3.0"